From a2188adc68e08b5b6865e4a0b5f62b6673e2c373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 25 Jun 2025 16:46:43 +0200 Subject: [PATCH] crypto: hide internals of keys --- crypto/p256/key.go | 2 +- crypto/p256/private.go | 36 ++++++++++++++++++++---------------- crypto/p256/public.go | 27 +++++++++++++-------------- crypto/p384/key.go | 2 +- crypto/p384/private.go | 36 ++++++++++++++++++++---------------- crypto/p384/public.go | 27 +++++++++++++-------------- crypto/p521/key.go | 2 +- crypto/p521/private.go | 36 ++++++++++++++++++++---------------- crypto/p521/public.go | 27 +++++++++++++-------------- crypto/x25519/key.go | 2 +- crypto/x25519/private.go | 19 ++++++++++--------- crypto/x25519/public.go | 17 +++++++++-------- 12 files changed, 122 insertions(+), 111 deletions(-) diff --git a/crypto/p256/key.go b/crypto/p256/key.go index 963576f..fe33c06 100644 --- a/crypto/p256/key.go +++ b/crypto/p256/key.go @@ -23,7 +23,7 @@ func GenerateKeyPair() (*PublicKey, *PrivateKey, error) { return nil, nil, err } pub := priv.Public().(*ecdsa.PublicKey) - return (*PublicKey)(pub), (*PrivateKey)(priv), nil + return &PublicKey{k: pub}, &PrivateKey{k: priv}, nil } const ( diff --git a/crypto/p256/private.go b/crypto/p256/private.go index da2bb47..ce3ffc7 100644 --- a/crypto/p256/private.go +++ b/crypto/p256/private.go @@ -16,7 +16,9 @@ import ( var _ crypto.SigningPrivateKey = (*PrivateKey)(nil) var _ crypto.KeyExchangePrivateKey = (*PrivateKey)(nil) -type PrivateKey ecdsa.PrivateKey +type PrivateKey struct { + k *ecdsa.PrivateKey +} // PrivateKeyFromBytes converts a serialized public key to a PrivateKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -26,15 +28,17 @@ func PrivateKeyFromBytes(b []byte) (*PrivateKey, error) { return nil, fmt.Errorf("invalid P-256 private key size") } - res := &ecdsa.PrivateKey{ - D: new(big.Int).SetBytes(b), - PublicKey: ecdsa.PublicKey{Curve: elliptic.P256()}, + res := &PrivateKey{ + k: &ecdsa.PrivateKey{ + D: new(big.Int).SetBytes(b), + PublicKey: ecdsa.PublicKey{Curve: elliptic.P256()}, + }, } // recompute the public key - res.PublicKey.X, res.PublicKey.Y = res.PublicKey.Curve.ScalarBaseMult(b) + res.k.PublicKey.X, res.k.PublicKey.Y = res.k.PublicKey.Curve.ScalarBaseMult(b) - return (*PrivateKey)(res), nil + return res, nil } // PrivateKeyFromPKCS8DER decodes a PKCS#8 DER (binary) encoded private key. @@ -44,7 +48,7 @@ func PrivateKeyFromPKCS8DER(bytes []byte) (*PrivateKey, error) { return nil, err } ecdsaPriv := priv.(*ecdsa.PrivateKey) - return (*PrivateKey)(ecdsaPriv), nil + return &PrivateKey{k: ecdsaPriv}, nil } // PrivateKeyFromPKCS8PEM decodes an PKCS#8 PEM (string) encoded private key. @@ -61,25 +65,25 @@ func PrivateKeyFromPKCS8PEM(str string) (*PrivateKey, error) { func (p *PrivateKey) Equal(other crypto.PrivateKey) bool { if other, ok := other.(*PrivateKey); ok { - return (*ecdsa.PrivateKey)(p).Equal((*ecdsa.PrivateKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PrivateKey) Public() crypto.PublicKey { - ecdhPub := (*ecdsa.PrivateKey)(p).Public().(*ecdsa.PublicKey) - return (*PublicKey)(ecdhPub) + ecdhPub := p.k.Public().(*ecdsa.PublicKey) + return &PublicKey{k: ecdhPub} } func (p *PrivateKey) ToBytes() []byte { // fixed size buffer that can get allocated on the caller's stack after inlining. var buf [PrivateKeyBytesSize]byte - ((*ecdsa.PrivateKey)(p)).D.FillBytes(buf[:]) + (p.k).D.FillBytes(buf[:]) return buf[:] } func (p *PrivateKey) ToPKCS8DER() []byte { - res, _ := x509.MarshalPKCS8PrivateKey((*ecdsa.PrivateKey)(p)) + res, _ := x509.MarshalPKCS8PrivateKey(p.k) return res } @@ -101,7 +105,7 @@ func (p *PrivateKey) SignToBytes(message []byte) ([]byte, error) { // Hash the message with SHA-256 hash := sha256.Sum256(message) - r, s, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(p), hash[:]) + r, s, err := ecdsa.Sign(rand.Reader, p.k, hash[:]) if err != nil { return nil, err } @@ -117,7 +121,7 @@ func (p *PrivateKey) SignToASN1(message []byte) ([]byte, error) { // Hash the message with SHA-256 hash := sha256.Sum256(message) - return ecdsa.SignASN1(rand.Reader, (*ecdsa.PrivateKey)(p), hash[:]) + return ecdsa.SignASN1(rand.Reader, p.k, hash[:]) } func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool { @@ -130,11 +134,11 @@ func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool { func (p *PrivateKey) KeyExchange(remote crypto.PublicKey) ([]byte, error) { if remote, ok := remote.(*PublicKey); ok { // First, we need to convert the ECDSA (signing only) to the equivalent ECDH keys - ecdhPriv, err := (*ecdsa.PrivateKey)(p).ECDH() + ecdhPriv, err := p.k.ECDH() if err != nil { return nil, err } - ecdhPub, err := (*ecdsa.PublicKey)(remote).ECDH() + ecdhPub, err := remote.k.ECDH() if err != nil { return nil, err } diff --git a/crypto/p256/public.go b/crypto/p256/public.go index df9804e..db9b445 100644 --- a/crypto/p256/public.go +++ b/crypto/p256/public.go @@ -13,9 +13,11 @@ import ( helpers "github.com/INFURA/go-did/crypto/internal" ) -var _ crypto.SigningPublicKey = (*PublicKey)(nil) +var _ crypto.SigningPublicKey = &PublicKey{} -type PublicKey ecdsa.PublicKey +type PublicKey struct { + k *ecdsa.PublicKey +} // PublicKeyFromBytes converts a serialized public key to a PublicKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -28,7 +30,7 @@ func PublicKeyFromBytes(b []byte) (*PublicKey, error) { if x == nil { return nil, fmt.Errorf("invalid P-256 public key") } - return (*PublicKey)(&ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}), nil + return &PublicKey{k: &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}}, nil } // PublicKeyFromXY converts x and y coordinates into a PublicKey. @@ -36,7 +38,7 @@ func PublicKeyFromXY(x, y *big.Int) (*PublicKey, error) { if !elliptic.P256().IsOnCurve(x, y) { return nil, fmt.Errorf("invalid P-256 public key") } - return (*PublicKey)(&ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}), nil + return &PublicKey{k: &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}}, nil } // PublicKeyFromPublicKeyMultibase decodes the public key from its Multibase form @@ -57,8 +59,7 @@ func PublicKeyFromX509DER(bytes []byte) (*PublicKey, error) { if err != nil { return nil, err } - ecdsaPub := pub.(*ecdsa.PublicKey) - return (*PublicKey)(ecdsaPub), nil + return &PublicKey{k: pub.(*ecdsa.PublicKey)}, nil } // PublicKeyFromX509PEM decodes an X.509 PEM (string) encoded public key. @@ -75,24 +76,22 @@ func PublicKeyFromX509PEM(str string) (*PublicKey, error) { func (p *PublicKey) Equal(other crypto.PublicKey) bool { if other, ok := other.(*PublicKey); ok { - return (*ecdsa.PublicKey)(p).Equal((*ecdsa.PublicKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PublicKey) ToBytes() []byte { - ecdsaPub := (*ecdsa.PublicKey)(p) - return elliptic.MarshalCompressed(elliptic.P256(), ecdsaPub.X, ecdsaPub.Y) + return elliptic.MarshalCompressed(elliptic.P256(), p.k.X, p.k.Y) } func (p *PublicKey) ToPublicKeyMultibase() string { - ecdsaPub := (*ecdsa.PublicKey)(p) - bytes := elliptic.MarshalCompressed(elliptic.P256(), ecdsaPub.X, ecdsaPub.Y) + bytes := elliptic.MarshalCompressed(elliptic.P256(), p.k.X, p.k.Y) return helpers.PublicKeyMultibaseEncode(MultibaseCode, bytes) } func (p *PublicKey) ToX509DER() []byte { - res, _ := x509.MarshalPKIXPublicKey((*ecdsa.PublicKey)(p)) + res, _ := x509.MarshalPKIXPublicKey(p.k) return res } @@ -121,12 +120,12 @@ func (p *PublicKey) VerifyBytes(message, signature []byte) bool { r := new(big.Int).SetBytes(signature[:SignatureBytesSize/2]) s := new(big.Int).SetBytes(signature[SignatureBytesSize/2:]) - return ecdsa.Verify((*ecdsa.PublicKey)(p), hash[:], r, s) + return ecdsa.Verify(p.k, hash[:], r, s) } func (p *PublicKey) VerifyASN1(message, signature []byte) bool { // Hash the message with SHA-256 hash := sha256.Sum256(message) - return ecdsa.VerifyASN1((*ecdsa.PublicKey)(p), hash[:], signature) + return ecdsa.VerifyASN1(p.k, hash[:], signature) } diff --git a/crypto/p384/key.go b/crypto/p384/key.go index 733faa5..f9c4a3c 100644 --- a/crypto/p384/key.go +++ b/crypto/p384/key.go @@ -23,7 +23,7 @@ func GenerateKeyPair() (*PublicKey, *PrivateKey, error) { return nil, nil, err } pub := priv.Public().(*ecdsa.PublicKey) - return (*PublicKey)(pub), (*PrivateKey)(priv), nil + return &PublicKey{k: pub}, &PrivateKey{k: priv}, nil } const ( diff --git a/crypto/p384/private.go b/crypto/p384/private.go index 7f421fb..a258446 100644 --- a/crypto/p384/private.go +++ b/crypto/p384/private.go @@ -16,7 +16,9 @@ import ( var _ crypto.SigningPrivateKey = (*PrivateKey)(nil) var _ crypto.KeyExchangePrivateKey = (*PrivateKey)(nil) -type PrivateKey ecdsa.PrivateKey +type PrivateKey struct { + k *ecdsa.PrivateKey +} // PrivateKeyFromBytes converts a serialized public key to a PrivateKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -26,15 +28,17 @@ func PrivateKeyFromBytes(b []byte) (*PrivateKey, error) { return nil, fmt.Errorf("invalid P-384 private key size") } - res := &ecdsa.PrivateKey{ - D: new(big.Int).SetBytes(b), - PublicKey: ecdsa.PublicKey{Curve: elliptic.P384()}, + res := &PrivateKey{ + k: &ecdsa.PrivateKey{ + D: new(big.Int).SetBytes(b), + PublicKey: ecdsa.PublicKey{Curve: elliptic.P384()}, + }, } // recompute the public key - res.PublicKey.X, res.PublicKey.Y = res.PublicKey.Curve.ScalarBaseMult(b) + res.k.PublicKey.X, res.k.PublicKey.Y = res.k.PublicKey.Curve.ScalarBaseMult(b) - return (*PrivateKey)(res), nil + return res, nil } // PrivateKeyFromPKCS8DER decodes a PKCS#8 DER (binary) encoded private key. @@ -44,7 +48,7 @@ func PrivateKeyFromPKCS8DER(bytes []byte) (*PrivateKey, error) { return nil, err } ecdsaPriv := priv.(*ecdsa.PrivateKey) - return (*PrivateKey)(ecdsaPriv), nil + return &PrivateKey{k: ecdsaPriv}, nil } // PrivateKeyFromPKCS8PEM decodes an PKCS#8 PEM (string) encoded private key. @@ -61,25 +65,25 @@ func PrivateKeyFromPKCS8PEM(str string) (*PrivateKey, error) { func (p *PrivateKey) Equal(other crypto.PrivateKey) bool { if other, ok := other.(*PrivateKey); ok { - return (*ecdsa.PrivateKey)(p).Equal((*ecdsa.PrivateKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PrivateKey) Public() crypto.PublicKey { - ecdhPub := (*ecdsa.PrivateKey)(p).Public().(*ecdsa.PublicKey) - return (*PublicKey)(ecdhPub) + ecdhPub := p.k.Public().(*ecdsa.PublicKey) + return &PublicKey{k: ecdhPub} } func (p *PrivateKey) ToBytes() []byte { // fixed size buffer that can get allocated on the caller's stack after inlining. var buf [PrivateKeyBytesSize]byte - ((*ecdsa.PrivateKey)(p)).D.FillBytes(buf[:]) + (p.k).D.FillBytes(buf[:]) return buf[:] } func (p *PrivateKey) ToPKCS8DER() []byte { - res, _ := x509.MarshalPKCS8PrivateKey((*ecdsa.PrivateKey)(p)) + res, _ := x509.MarshalPKCS8PrivateKey(p.k) return res } @@ -101,7 +105,7 @@ func (p *PrivateKey) SignToBytes(message []byte) ([]byte, error) { // Hash the message with SHA-384 hash := sha512.Sum384(message) - r, s, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(p), hash[:]) + r, s, err := ecdsa.Sign(rand.Reader, p.k, hash[:]) if err != nil { return nil, err } @@ -117,7 +121,7 @@ func (p *PrivateKey) SignToASN1(message []byte) ([]byte, error) { // Hash the message with SHA-384 hash := sha512.Sum384(message) - return ecdsa.SignASN1(rand.Reader, (*ecdsa.PrivateKey)(p), hash[:]) + return ecdsa.SignASN1(rand.Reader, p.k, hash[:]) } func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool { @@ -130,11 +134,11 @@ func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool { func (p *PrivateKey) KeyExchange(remote crypto.PublicKey) ([]byte, error) { if remote, ok := remote.(*PublicKey); ok { // First, we need to convert the ECDSA (signing only) to the equivalent ECDH keys - ecdhPriv, err := (*ecdsa.PrivateKey)(p).ECDH() + ecdhPriv, err := p.k.ECDH() if err != nil { return nil, err } - ecdhPub, err := (*ecdsa.PublicKey)(remote).ECDH() + ecdhPub, err := remote.k.ECDH() if err != nil { return nil, err } diff --git a/crypto/p384/public.go b/crypto/p384/public.go index 15fca37..96499e6 100644 --- a/crypto/p384/public.go +++ b/crypto/p384/public.go @@ -13,9 +13,11 @@ import ( helpers "github.com/INFURA/go-did/crypto/internal" ) -var _ crypto.SigningPublicKey = (*PublicKey)(nil) +var _ crypto.SigningPublicKey = &PublicKey{} -type PublicKey ecdsa.PublicKey +type PublicKey struct { + k *ecdsa.PublicKey +} // PublicKeyFromBytes converts a serialized public key to a PublicKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -28,7 +30,7 @@ func PublicKeyFromBytes(b []byte) (*PublicKey, error) { if x == nil { return nil, fmt.Errorf("invalid P-384 public key") } - return (*PublicKey)(&ecdsa.PublicKey{Curve: elliptic.P384(), X: x, Y: y}), nil + return &PublicKey{k: &ecdsa.PublicKey{Curve: elliptic.P384(), X: x, Y: y}}, nil } // PublicKeyFromXY converts x and y coordinates into a PublicKey. @@ -36,7 +38,7 @@ func PublicKeyFromXY(x, y *big.Int) (*PublicKey, error) { if !elliptic.P384().IsOnCurve(x, y) { return nil, fmt.Errorf("invalid P-384 public key") } - return (*PublicKey)(&ecdsa.PublicKey{Curve: elliptic.P384(), X: x, Y: y}), nil + return &PublicKey{k: &ecdsa.PublicKey{Curve: elliptic.P384(), X: x, Y: y}}, nil } // PublicKeyFromPublicKeyMultibase decodes the public key from its Multibase form @@ -57,8 +59,7 @@ func PublicKeyFromX509DER(bytes []byte) (*PublicKey, error) { if err != nil { return nil, err } - ecdsaPub := pub.(*ecdsa.PublicKey) - return (*PublicKey)(ecdsaPub), nil + return &PublicKey{k: pub.(*ecdsa.PublicKey)}, nil } // PublicKeyFromX509PEM decodes an X.509 PEM (string) encoded public key. @@ -75,24 +76,22 @@ func PublicKeyFromX509PEM(str string) (*PublicKey, error) { func (p *PublicKey) Equal(other crypto.PublicKey) bool { if other, ok := other.(*PublicKey); ok { - return (*ecdsa.PublicKey)(p).Equal((*ecdsa.PublicKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PublicKey) ToBytes() []byte { - ecdsaPub := (*ecdsa.PublicKey)(p) - return elliptic.MarshalCompressed(elliptic.P384(), ecdsaPub.X, ecdsaPub.Y) + return elliptic.MarshalCompressed(elliptic.P384(), p.k.X, p.k.Y) } func (p *PublicKey) ToPublicKeyMultibase() string { - ecdsaPub := (*ecdsa.PublicKey)(p) - bytes := elliptic.MarshalCompressed(elliptic.P384(), ecdsaPub.X, ecdsaPub.Y) + bytes := elliptic.MarshalCompressed(elliptic.P384(), p.k.X, p.k.Y) return helpers.PublicKeyMultibaseEncode(MultibaseCode, bytes) } func (p *PublicKey) ToX509DER() []byte { - res, _ := x509.MarshalPKIXPublicKey((*ecdsa.PublicKey)(p)) + res, _ := x509.MarshalPKIXPublicKey(p.k) return res } @@ -121,12 +120,12 @@ func (p *PublicKey) VerifyBytes(message, signature []byte) bool { r := new(big.Int).SetBytes(signature[:SignatureBytesSize/2]) s := new(big.Int).SetBytes(signature[SignatureBytesSize/2:]) - return ecdsa.Verify((*ecdsa.PublicKey)(p), hash[:], r, s) + return ecdsa.Verify(p.k, hash[:], r, s) } func (p *PublicKey) VerifyASN1(message, signature []byte) bool { // Hash the message with SHA-384 hash := sha512.Sum384(message) - return ecdsa.VerifyASN1((*ecdsa.PublicKey)(p), hash[:], signature) + return ecdsa.VerifyASN1(p.k, hash[:], signature) } diff --git a/crypto/p521/key.go b/crypto/p521/key.go index c461528..ced58f6 100644 --- a/crypto/p521/key.go +++ b/crypto/p521/key.go @@ -23,7 +23,7 @@ func GenerateKeyPair() (*PublicKey, *PrivateKey, error) { return nil, nil, err } pub := priv.Public().(*ecdsa.PublicKey) - return (*PublicKey)(pub), (*PrivateKey)(priv), nil + return &PublicKey{k: pub}, &PrivateKey{k: priv}, nil } const ( diff --git a/crypto/p521/private.go b/crypto/p521/private.go index 71d7301..253f850 100644 --- a/crypto/p521/private.go +++ b/crypto/p521/private.go @@ -16,7 +16,9 @@ import ( var _ crypto.SigningPrivateKey = (*PrivateKey)(nil) var _ crypto.KeyExchangePrivateKey = (*PrivateKey)(nil) -type PrivateKey ecdsa.PrivateKey +type PrivateKey struct { + k *ecdsa.PrivateKey +} // PrivateKeyFromBytes converts a serialized public key to a PrivateKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -26,15 +28,17 @@ func PrivateKeyFromBytes(b []byte) (*PrivateKey, error) { return nil, fmt.Errorf("invalid P-521 private key size") } - res := &ecdsa.PrivateKey{ - D: new(big.Int).SetBytes(b), - PublicKey: ecdsa.PublicKey{Curve: elliptic.P521()}, + res := &PrivateKey{ + k: &ecdsa.PrivateKey{ + D: new(big.Int).SetBytes(b), + PublicKey: ecdsa.PublicKey{Curve: elliptic.P521()}, + }, } // recompute the public key - res.PublicKey.X, res.PublicKey.Y = res.PublicKey.Curve.ScalarBaseMult(b) + res.k.PublicKey.X, res.k.PublicKey.Y = res.k.PublicKey.Curve.ScalarBaseMult(b) - return (*PrivateKey)(res), nil + return res, nil } // PrivateKeyFromPKCS8DER decodes a PKCS#8 DER (binary) encoded private key. @@ -44,7 +48,7 @@ func PrivateKeyFromPKCS8DER(bytes []byte) (*PrivateKey, error) { return nil, err } ecdsaPriv := priv.(*ecdsa.PrivateKey) - return (*PrivateKey)(ecdsaPriv), nil + return &PrivateKey{k: ecdsaPriv}, nil } // PrivateKeyFromPKCS8PEM decodes an PKCS#8 PEM (string) encoded private key. @@ -61,25 +65,25 @@ func PrivateKeyFromPKCS8PEM(str string) (*PrivateKey, error) { func (p *PrivateKey) Equal(other crypto.PrivateKey) bool { if other, ok := other.(*PrivateKey); ok { - return (*ecdsa.PrivateKey)(p).Equal((*ecdsa.PrivateKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PrivateKey) Public() crypto.PublicKey { - ecdhPub := (*ecdsa.PrivateKey)(p).Public().(*ecdsa.PublicKey) - return (*PublicKey)(ecdhPub) + ecdhPub := p.k.Public().(*ecdsa.PublicKey) + return &PublicKey{k: ecdhPub} } func (p *PrivateKey) ToBytes() []byte { // fixed size buffer that can get allocated on the caller's stack after inlining. var buf [PrivateKeyBytesSize]byte - ((*ecdsa.PrivateKey)(p)).D.FillBytes(buf[:]) + (p.k).D.FillBytes(buf[:]) return buf[:] } func (p *PrivateKey) ToPKCS8DER() []byte { - res, _ := x509.MarshalPKCS8PrivateKey((*ecdsa.PrivateKey)(p)) + res, _ := x509.MarshalPKCS8PrivateKey(p.k) return res } @@ -101,7 +105,7 @@ func (p *PrivateKey) SignToBytes(message []byte) ([]byte, error) { // Hash the message with SHA-512 hash := sha512.Sum512(message) - r, s, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(p), hash[:]) + r, s, err := ecdsa.Sign(rand.Reader, p.k, hash[:]) if err != nil { return nil, err } @@ -117,7 +121,7 @@ func (p *PrivateKey) SignToASN1(message []byte) ([]byte, error) { // Hash the message with SHA-512 hash := sha512.Sum512(message) - return ecdsa.SignASN1(rand.Reader, (*ecdsa.PrivateKey)(p), hash[:]) + return ecdsa.SignASN1(rand.Reader, p.k, hash[:]) } func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool { @@ -130,11 +134,11 @@ func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool { func (p *PrivateKey) KeyExchange(remote crypto.PublicKey) ([]byte, error) { if remote, ok := remote.(*PublicKey); ok { // First, we need to convert the ECDSA (signing only) to the equivalent ECDH keys - ecdhPriv, err := (*ecdsa.PrivateKey)(p).ECDH() + ecdhPriv, err := p.k.ECDH() if err != nil { return nil, err } - ecdhPub, err := (*ecdsa.PublicKey)(remote).ECDH() + ecdhPub, err := remote.k.ECDH() if err != nil { return nil, err } diff --git a/crypto/p521/public.go b/crypto/p521/public.go index 5abab1e..fc26bb7 100644 --- a/crypto/p521/public.go +++ b/crypto/p521/public.go @@ -13,9 +13,11 @@ import ( helpers "github.com/INFURA/go-did/crypto/internal" ) -var _ crypto.SigningPublicKey = (*PublicKey)(nil) +var _ crypto.SigningPublicKey = &PublicKey{} -type PublicKey ecdsa.PublicKey +type PublicKey struct { + k *ecdsa.PublicKey +} // PublicKeyFromBytes converts a serialized public key to a PublicKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -28,7 +30,7 @@ func PublicKeyFromBytes(b []byte) (*PublicKey, error) { if x == nil { return nil, fmt.Errorf("invalid P-521 public key") } - return (*PublicKey)(&ecdsa.PublicKey{Curve: elliptic.P521(), X: x, Y: y}), nil + return &PublicKey{k: &ecdsa.PublicKey{Curve: elliptic.P521(), X: x, Y: y}}, nil } // PublicKeyFromXY converts x and y coordinates into a PublicKey. @@ -36,7 +38,7 @@ func PublicKeyFromXY(x, y *big.Int) (*PublicKey, error) { if !elliptic.P521().IsOnCurve(x, y) { return nil, fmt.Errorf("invalid P-521 public key") } - return (*PublicKey)(&ecdsa.PublicKey{Curve: elliptic.P521(), X: x, Y: y}), nil + return &PublicKey{k: &ecdsa.PublicKey{Curve: elliptic.P521(), X: x, Y: y}}, nil } // PublicKeyFromPublicKeyMultibase decodes the public key from its Multibase form @@ -57,8 +59,7 @@ func PublicKeyFromX509DER(bytes []byte) (*PublicKey, error) { if err != nil { return nil, err } - ecdsaPub := pub.(*ecdsa.PublicKey) - return (*PublicKey)(ecdsaPub), nil + return &PublicKey{k: pub.(*ecdsa.PublicKey)}, nil } // PublicKeyFromX509PEM decodes an X.509 PEM (string) encoded public key. @@ -75,24 +76,22 @@ func PublicKeyFromX509PEM(str string) (*PublicKey, error) { func (p *PublicKey) Equal(other crypto.PublicKey) bool { if other, ok := other.(*PublicKey); ok { - return (*ecdsa.PublicKey)(p).Equal((*ecdsa.PublicKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PublicKey) ToBytes() []byte { - ecdsaPub := (*ecdsa.PublicKey)(p) - return elliptic.MarshalCompressed(elliptic.P521(), ecdsaPub.X, ecdsaPub.Y) + return elliptic.MarshalCompressed(elliptic.P521(), p.k.X, p.k.Y) } func (p *PublicKey) ToPublicKeyMultibase() string { - ecdsaPub := (*ecdsa.PublicKey)(p) - bytes := elliptic.MarshalCompressed(elliptic.P521(), ecdsaPub.X, ecdsaPub.Y) + bytes := elliptic.MarshalCompressed(elliptic.P521(), p.k.X, p.k.Y) return helpers.PublicKeyMultibaseEncode(MultibaseCode, bytes) } func (p *PublicKey) ToX509DER() []byte { - res, _ := x509.MarshalPKIXPublicKey((*ecdsa.PublicKey)(p)) + res, _ := x509.MarshalPKIXPublicKey(p.k) return res } @@ -121,12 +120,12 @@ func (p *PublicKey) VerifyBytes(message, signature []byte) bool { r := new(big.Int).SetBytes(signature[:SignatureBytesSize/2]) s := new(big.Int).SetBytes(signature[SignatureBytesSize/2:]) - return ecdsa.Verify((*ecdsa.PublicKey)(p), hash[:], r, s) + return ecdsa.Verify(p.k, hash[:], r, s) } func (p *PublicKey) VerifyASN1(message, signature []byte) bool { // Hash the message with SHA-512 hash := sha512.Sum512(message) - return ecdsa.VerifyASN1((*ecdsa.PublicKey)(p), hash[:], signature) + return ecdsa.VerifyASN1(p.k, hash[:], signature) } diff --git a/crypto/x25519/key.go b/crypto/x25519/key.go index 95e7964..fa76bde 100644 --- a/crypto/x25519/key.go +++ b/crypto/x25519/key.go @@ -20,7 +20,7 @@ func GenerateKeyPair() (*PublicKey, *PrivateKey, error) { return nil, nil, err } pub := priv.Public().(*ecdh.PublicKey) - return (*PublicKey)(pub), (*PrivateKey)(priv), nil + return &PublicKey{k: pub}, &PrivateKey{k: priv}, nil } const ( diff --git a/crypto/x25519/private.go b/crypto/x25519/private.go index e18cc93..34c063b 100644 --- a/crypto/x25519/private.go +++ b/crypto/x25519/private.go @@ -13,7 +13,9 @@ import ( var _ crypto.KeyExchangePrivateKey = (*PrivateKey)(nil) -type PrivateKey ecdh.PrivateKey +type PrivateKey struct { + k *ecdh.PrivateKey +} // PrivateKeyFromBytes converts a serialized private key to a PrivateKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -24,7 +26,7 @@ func PrivateKeyFromBytes(b []byte) (*PrivateKey, error) { if err != nil { return nil, err } - return (*PrivateKey)(priv), nil + return &PrivateKey{k: priv}, nil } // PrivateKeyFromEd25519 converts an ed25519 private key to a x25519 private key. @@ -52,7 +54,7 @@ func PrivateKeyFromPKCS8DER(bytes []byte) (*PrivateKey, error) { return nil, err } ecdhPriv := priv.(*ecdh.PrivateKey) - return (*PrivateKey)(ecdhPriv), nil + return &PrivateKey{k: ecdhPriv}, nil } // PrivateKeyFromPKCS8PEM decodes an PKCS#8 PEM (string) encoded private key. @@ -69,22 +71,21 @@ func PrivateKeyFromPKCS8PEM(str string) (*PrivateKey, error) { func (p *PrivateKey) Equal(other crypto.PrivateKey) bool { if other, ok := other.(*PrivateKey); ok { - return (*ecdh.PrivateKey)(p).Equal((*ecdh.PrivateKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PrivateKey) Public() crypto.PublicKey { - ecdhPub := (*ecdh.PrivateKey)(p).Public().(*ecdh.PublicKey) - return (*PublicKey)(ecdhPub) + return &PublicKey{k: p.k.Public().(*ecdh.PublicKey)} } func (p *PrivateKey) ToBytes() []byte { - return (*ecdh.PrivateKey)(p).Bytes() + return p.k.Bytes() } func (p *PrivateKey) ToPKCS8DER() []byte { - res, _ := x509.MarshalPKCS8PrivateKey((*ecdh.PrivateKey)(p)) + res, _ := x509.MarshalPKCS8PrivateKey(p.k) return res } @@ -105,7 +106,7 @@ func (p *PrivateKey) PublicKeyIsCompatible(remote crypto.PublicKey) bool { func (p *PrivateKey) KeyExchange(remote crypto.PublicKey) ([]byte, error) { if local, ok := remote.(*PublicKey); ok { - return (*ecdh.PrivateKey)(p).ECDH((*ecdh.PublicKey)(local)) + return p.k.ECDH(local.k) } return nil, fmt.Errorf("incompatible public key") } diff --git a/crypto/x25519/public.go b/crypto/x25519/public.go index 62da6bc..6abdcee 100644 --- a/crypto/x25519/public.go +++ b/crypto/x25519/public.go @@ -14,7 +14,9 @@ import ( var _ crypto.PublicKey = (*PublicKey)(nil) -type PublicKey ecdh.PublicKey +type PublicKey struct { + k *ecdh.PublicKey +} // PublicKeyFromBytes converts a serialized public key to a PublicKey. // This compact serialization format is the raw key material, without metadata or structure. @@ -24,7 +26,7 @@ func PublicKeyFromBytes(b []byte) (*PublicKey, error) { if err != nil { return nil, err } - return (*PublicKey)(pub), nil + return &PublicKey{k: pub}, nil } // PublicKeyFromEd25519 converts an ed25519 public key to a x25519 public key. @@ -101,8 +103,7 @@ func PublicKeyFromX509DER(bytes []byte) (*PublicKey, error) { if err != nil { return nil, err } - ecdhPub := pub.(*ecdh.PublicKey) - return (*PublicKey)(ecdhPub), nil + return &PublicKey{k: pub.(*ecdh.PublicKey)}, nil } // PublicKeyFromX509PEM decodes an X.509 PEM (string) encoded public key. @@ -119,21 +120,21 @@ func PublicKeyFromX509PEM(str string) (*PublicKey, error) { func (p *PublicKey) Equal(other crypto.PublicKey) bool { if other, ok := other.(*PublicKey); ok { - return (*ecdh.PublicKey)(p).Equal((*ecdh.PublicKey)(other)) + return p.k.Equal(other.k) } return false } func (p *PublicKey) ToBytes() []byte { - return (*ecdh.PublicKey)(p).Bytes() + return p.k.Bytes() } func (p *PublicKey) ToPublicKeyMultibase() string { - return helpers.PublicKeyMultibaseEncode(MultibaseCode, (*ecdh.PublicKey)(p).Bytes()) + return helpers.PublicKeyMultibaseEncode(MultibaseCode, p.k.Bytes()) } func (p *PublicKey) ToX509DER() []byte { - res, _ := x509.MarshalPKIXPublicKey((*ecdh.PublicKey)(p)) + res, _ := x509.MarshalPKIXPublicKey(p.k) return res }