crypto: hide internals of keys

This commit is contained in:
Michael Muré
2025-06-25 16:46:43 +02:00
parent 8d96b49622
commit a2188adc68
12 changed files with 122 additions and 111 deletions

View File

@@ -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 (

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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 (

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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 (

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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 (

View File

@@ -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")
}

View File

@@ -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
}