crypto: remove references to deprecated elliptic package

This PR removes all references to the elliptic functions that were deprecated in golang 1.22.
Instead this PR does the following:

We change S256() to return the raw bitcurve instead of the elliptic.Curve, this has two effects:
- Every instance of S256() can call the unmarshall and marshall operations
- The package is not neatly abstracted away anymore, which we can debate if we want to change that

We also modify the behavior in the ecies (and rlpx) package a bit.
Previously all curves were acceptable, now only curves that implement the marshaller and unmarshaller
interface are allowed. All common curves have this, so its not an issue in our code.
Dependencies maybe need to implement the (un-)marshaller interfaces though.
This commit is contained in:
Marius van der Wijden 2024-03-15 11:42:50 +01:00
parent d91f2e9d82
commit 29a7673986
6 changed files with 52 additions and 39 deletions

View file

@ -20,7 +20,6 @@ import (
"bytes" "bytes"
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/elliptic"
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
@ -72,11 +71,11 @@ func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSes
if err != nil { if err != nil {
return nil, fmt.Errorf("could not unmarshal public key from card: %v", err) return nil, fmt.Errorf("could not unmarshal public key from card: %v", err)
} }
secret, _ := key.Curve.ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes()) secret, _ := crypto.S256().ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes())
return &SecureChannelSession{ return &SecureChannelSession{
card: card, card: card,
secret: secret.Bytes(), secret: secret.Bytes(),
publicKey: elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y), publicKey: crypto.FromECDSAPub(&key.PublicKey),
}, nil }, nil
} }

View file

@ -19,7 +19,6 @@ package crypto
import ( import (
"bufio" "bufio"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic"
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"errors" "errors"
@ -148,7 +147,7 @@ func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
return nil, errors.New("invalid private key, zero or negative") return nil, errors.New("invalid private key, zero or negative")
} }
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d) priv.PublicKey.X, priv.PublicKey.Y = S256().ScalarBaseMult(d)
if priv.PublicKey.X == nil { if priv.PublicKey.X == nil {
return nil, errors.New("invalid private key") return nil, errors.New("invalid private key")
} }
@ -165,7 +164,7 @@ func FromECDSA(priv *ecdsa.PrivateKey) []byte {
// UnmarshalPubkey converts bytes to a secp256k1 public key. // UnmarshalPubkey converts bytes to a secp256k1 public key.
func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
x, y := elliptic.Unmarshal(S256(), pub) x, y := S256().Unmarshal(pub)
if x == nil { if x == nil {
return nil, errInvalidPubkey return nil, errInvalidPubkey
} }
@ -176,7 +175,7 @@ func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
if pub == nil || pub.X == nil || pub.Y == nil { if pub == nil || pub.X == nil || pub.Y == nil {
return nil return nil
} }
return elliptic.Marshal(S256(), pub.X, pub.Y) return S256().Marshal(pub.X, pub.Y)
} }
// HexToECDSA parses a secp256k1 private key. // HexToECDSA parses a secp256k1 private key.

View file

@ -95,15 +95,15 @@ func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey {
// Generate an elliptic curve public / private keypair. If params is nil, // Generate an elliptic curve public / private keypair. If params is nil,
// the recommended default parameters for the key will be chosen. // the recommended default parameters for the key will be chosen.
func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) { func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) {
pb, x, y, err := elliptic.GenerateKey(curve, rand) sk, err := ecdsa.GenerateKey(curve, rand)
if err != nil { if err != nil {
return return
} }
prv = new(PrivateKey) prv = new(PrivateKey)
prv.PublicKey.X = x prv.PublicKey.X = sk.X
prv.PublicKey.Y = y prv.PublicKey.Y = sk.Y
prv.PublicKey.Curve = curve prv.PublicKey.Curve = curve
prv.D = new(big.Int).SetBytes(pb) prv.D = new(big.Int).Set(sk.D)
if params == nil { if params == nil {
params = ParamsFromCurve(curve) params = ParamsFromCurve(curve)
} }
@ -255,13 +255,20 @@ func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err e
d := messageTag(params.Hash, Km, em, s2) d := messageTag(params.Hash, Km, em, s2)
Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y) type marshaller interface {
Marshal(x, y *big.Int) []byte
}
if curve, ok := pub.Curve.(marshaller); ok {
Rb := curve.Marshal(R.PublicKey.X, R.PublicKey.Y)
ct = make([]byte, len(Rb)+len(em)+len(d)) ct = make([]byte, len(Rb)+len(em)+len(d))
copy(ct, Rb) copy(ct, Rb)
copy(ct[len(Rb):], em) copy(ct[len(Rb):], em)
copy(ct[len(Rb)+len(em):], d) copy(ct[len(Rb)+len(em):], d)
return ct, nil return ct, nil
} }
return nil, ErrInvalidCurve
}
// Decrypt decrypts an ECIES ciphertext. // Decrypt decrypts an ECIES ciphertext.
func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) { func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
@ -297,7 +304,12 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
R := new(PublicKey) R := new(PublicKey)
R.Curve = prv.PublicKey.Curve R.Curve = prv.PublicKey.Curve
R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen])
type unmarshaler interface {
Unmarshal([]byte) (x, y *big.Int)
}
if curve, ok := R.Curve.(unmarshaler); ok {
R.X, R.Y = curve.Unmarshal(c[:rLen])
if R.X == nil { if R.X == nil {
return nil, ErrInvalidPublicKey return nil, ErrInvalidPublicKey
} }
@ -312,6 +324,7 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 {
return nil, ErrInvalidMessage return nil, ErrInvalidMessage
} }
return symDecrypt(params, Ke, c[mStart:mEnd]) return symDecrypt(params, Ke, c[mStart:mEnd])
} }
return nil, ErrInvalidCurve
}

View file

@ -10,7 +10,6 @@ package secp256k1
import ( import (
"bytes" "bytes"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic"
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"io" "io"
@ -24,7 +23,7 @@ func generateKeyPair() (pubkey, privkey []byte) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
pubkey = elliptic.Marshal(S256(), key.X, key.Y) pubkey = S256().Marshal(key.X, key.Y)
privkey = make([]byte, 32) privkey = make([]byte, 32)
blob := key.D.Bytes() blob := key.D.Bytes()

View file

@ -21,7 +21,6 @@ package crypto
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic"
"errors" "errors"
"fmt" "fmt"
@ -40,9 +39,7 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return UnmarshalPubkey(s)
x, y := elliptic.Unmarshal(S256(), s)
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
} }
// Sign calculates an ECDSA signature. // Sign calculates an ECDSA signature.
@ -84,6 +81,6 @@ func CompressPubkey(pubkey *ecdsa.PublicKey) []byte {
} }
// S256 returns an instance of the secp256k1 curve. // S256 returns an instance of the secp256k1 curve.
func S256() elliptic.Curve { func S256() *secp256k1.BitCurve {
return secp256k1.S256() return secp256k1.S256()
} }

View file

@ -22,7 +22,6 @@ import (
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic"
"crypto/hmac" "crypto/hmac"
"crypto/rand" "crypto/rand"
"encoding/binary" "encoding/binary"
@ -30,6 +29,7 @@ import (
"fmt" "fmt"
"hash" "hash"
"io" "io"
"math/big"
mrand "math/rand" mrand "math/rand"
"net" "net"
"time" "time"
@ -664,7 +664,13 @@ func exportPubkey(pub *ecies.PublicKey) []byte {
if pub == nil { if pub == nil {
panic("nil pubkey") panic("nil pubkey")
} }
return elliptic.Marshal(pub.Curve, pub.X, pub.Y)[1:] type marshaller interface {
Marshal(x, y *big.Int) []byte
}
if curve, ok := pub.Curve.(marshaller); ok {
return curve.Marshal(pub.X, pub.Y)[1:]
}
return []byte{}
} }
func xor(one, other []byte) (xor []byte) { func xor(one, other []byte) (xor []byte) {