diff --git a/internal/sm9/sm9_key.go b/internal/sm9/sm9_key.go index 32d3663..f124b92 100644 --- a/internal/sm9/sm9_key.go +++ b/internal/sm9/sm9_key.go @@ -1,7 +1,6 @@ package sm9 import ( - _subtle "crypto/subtle" "encoding/binary" "errors" "io" @@ -19,12 +18,13 @@ import ( // SignMasterPrivateKey is a signature master private key, generated by KGC type SignMasterPrivateKey struct { *SignMasterPublicKey // master public key - privateKey []byte // master private key + d []byte // master private key bytes } // SignMasterPublicKey is a signature master public key, generated by KGC type SignMasterPublicKey struct { MasterPublicKey *bn256.G2 // master public key + q []byte // uncompressed public key point output pairOnce sync.Once basePoint *bn256.GT // the result of Pair(Gen1, pub.MasterPublicKey) tableGenOnce sync.Once @@ -34,18 +34,20 @@ type SignMasterPublicKey struct { // SignPrivateKey is a signature private key, generated by KGC type SignPrivateKey struct { PrivateKey *bn256.G1 // user private key + d []byte // uncompressed private key point output *SignMasterPublicKey // master public key } // EncryptMasterPrivateKey is an encryption master private key, generated by KGC type EncryptMasterPrivateKey struct { *EncryptMasterPublicKey // master public key - privateKey []byte // master private key + d []byte // master private key bytes } // EncryptMasterPublicKey is an encryption master public key, generated by KGC type EncryptMasterPublicKey struct { MasterPublicKey *bn256.G1 // public key + q []byte // uncompressed public key point output pairOnce sync.Once basePoint *bn256.GT // the result of Pair(pub.MasterPublicKey, Gen2) tableGenOnce sync.Once @@ -55,6 +57,7 @@ type EncryptMasterPublicKey struct { // EncryptPrivateKey is an encryption private key, generated by KGC type EncryptPrivateKey struct { PrivateKey *bn256.G2 // user private key + d []byte // uncompressed private key point output *EncryptMasterPublicKey // master public key } @@ -103,24 +106,18 @@ func NewSignMasterPrivateKey(key []byte) (*SignMasterPrivateKey, error) { return nil, err } priv := new(SignMasterPrivateKey) - priv.privateKey = slices.Clone(key) + priv.d = slices.Clone(key) priv.SignMasterPublicKey = new(SignMasterPublicKey) priv.MasterPublicKey = p + priv.q = p.MarshalUncompressed() return priv, nil } -// Equal compares the receiver SignMasterPrivateKey with another SignMasterPrivateKey x. -// It returns true if both the MasterPublicKey and privateKey fields are equal, using -// constant time comparison for the privateKey to prevent timing attacks. -func (master *SignMasterPrivateKey) Equal(x *SignMasterPrivateKey) bool { - return master.SignMasterPublicKey.Equal(x.SignMasterPublicKey) && _subtle.ConstantTimeCompare(master.privateKey, x.privateKey) == 1 -} - // Bytes returns the byte representation of the SignMasterPrivateKey. // It creates a new byte slice and appends the private key bytes to it, // ensuring that the original private key data is not modified. func (master *SignMasterPrivateKey) Bytes() []byte { - return slices.Clone(master.privateKey) + return master.d } // GenerateUserKey generate an user dsa key. @@ -130,7 +127,7 @@ func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*Sign t1Nat := hashH1(id) - d, err := bigmod.NewNat().SetBytes(master.privateKey, orderNat) + d, err := bigmod.NewNat().SetBytes(master.d, orderNat) if err != nil { return nil, err } @@ -150,27 +147,20 @@ func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*Sign return nil, err } priv.PrivateKey = g1 + priv.d = g1.MarshalUncompressed() return priv, nil } // Public returns the public key corresponding to the private key. -func (master *SignMasterPrivateKey) Public() *SignMasterPublicKey { +func (master *SignMasterPrivateKey) PublicKey() *SignMasterPublicKey { return master.SignMasterPublicKey } -// Equal compares the receiver SignMasterPublicKey with another SignMasterPublicKey -// and returns true if they are equal, otherwise it returns false. -func (pub *SignMasterPublicKey) Equal(x *SignMasterPublicKey) bool { - pubBytes := pub.MasterPublicKey.MarshalUncompressed() - xBytes := x.MasterPublicKey.MarshalUncompressed() - return _subtle.ConstantTimeCompare(pubBytes, xBytes) == 1 -} - // Bytes returns the byte representation of the SignMasterPublicKey // by marshaling the MasterPublicKey in an uncompressed format. func (pub *SignMasterPublicKey) Bytes() []byte { - return pub.MasterPublicKey.MarshalUncompressed() + return pub.q } // pair generate the basepoint once @@ -208,16 +198,10 @@ func (pub *SignMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *bn2 return p } -// Equal compares the SignPrivateKey receiver with another SignPrivateKey x -// and returns true if they are equal, otherwise it returns false. -func (priv *SignPrivateKey) Equal(x *SignPrivateKey) bool { - return priv.PrivateKey.Equal(x.PrivateKey) -} - // Bytes returns the byte representation of the SignPrivateKey. // It marshals the private key in an uncompressed format. func (priv *SignPrivateKey) Bytes() []byte { - return priv.PrivateKey.MarshalUncompressed() + return priv.d } // MasterPublic returns the master public key corresponding to the private key. @@ -258,6 +242,7 @@ func (pub *SignMasterPublicKey) UnmarshalRaw(bytes []byte) error { return err } pub.MasterPublicKey = g2 + pub.q = g2.MarshalUncompressed() return nil } @@ -288,6 +273,7 @@ func (priv *SignPrivateKey) UnmarshalRaw(bytes []byte) error { return err } priv.PrivateKey = g + priv.d = g.MarshalUncompressed() return nil } @@ -336,9 +322,10 @@ func NewEncryptMasterPrivateKey(key []byte) (*EncryptMasterPrivateKey, error) { return nil, err } priv := new(EncryptMasterPrivateKey) - priv.privateKey = slices.Clone(key) + priv.d = slices.Clone(key) priv.EncryptMasterPublicKey = new(EncryptMasterPublicKey) priv.MasterPublicKey = p + priv.q = p.MarshalUncompressed() return priv, nil } @@ -346,14 +333,7 @@ func NewEncryptMasterPrivateKey(key []byte) (*EncryptMasterPrivateKey, error) { // This method ensures that the original private key data is not modified by // returning a new slice containing the same data. func (master *EncryptMasterPrivateKey) Bytes() []byte { - return slices.Clone(master.privateKey) -} - -// Equal compares the receiver EncryptMasterPrivateKey with another EncryptMasterPrivateKey x. -// It returns true if both the public keys and private keys are equal, otherwise it returns false. -// The comparison of private keys is done in constant time to prevent timing attacks. -func (master *EncryptMasterPrivateKey) Equal(x *EncryptMasterPrivateKey) bool { - return master.EncryptMasterPublicKey.Equal(x.EncryptMasterPublicKey) && _subtle.ConstantTimeCompare(master.privateKey, x.privateKey) == 1 + return master.d } // GenerateUserKey generate an encryption private key for the given user. @@ -363,7 +343,7 @@ func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*E t1Nat := hashH1(id) - d, err := bigmod.NewNat().SetBytes(master.privateKey, orderNat) + d, err := bigmod.NewNat().SetBytes(master.d, orderNat) if err != nil { return nil, err } @@ -383,25 +363,18 @@ func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*E panic(err) } priv.PrivateKey = p + priv.d = p.MarshalUncompressed() return priv, nil } // Public returns the public key corresponding to the private key. -func (master *EncryptMasterPrivateKey) Public() *EncryptMasterPublicKey { +func (master *EncryptMasterPrivateKey) PublicKey() *EncryptMasterPublicKey { return master.EncryptMasterPublicKey } -// Equal compares the receiver EncryptMasterPublicKey with another EncryptMasterPublicKey -// and returns true if they are equal, otherwise false. -func (pub *EncryptMasterPublicKey) Equal(x *EncryptMasterPublicKey) bool { - pubBytes := pub.MasterPublicKey.MarshalUncompressed() - xBytes := x.MasterPublicKey.MarshalUncompressed() - return _subtle.ConstantTimeCompare(pubBytes, xBytes) == 1 -} - func (pub *EncryptMasterPublicKey) Bytes() []byte { - return pub.MasterPublicKey.MarshalUncompressed() + return pub.q } // pair generate the basepoint once @@ -439,16 +412,10 @@ func (pub *EncryptMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) * return p } -// Equal compares the calling EncryptPrivateKey with another EncryptPrivateKey -// and returns true if they are equal, otherwise it returns false. -func (priv *EncryptPrivateKey) Equal(x *EncryptPrivateKey) bool { - return priv.PrivateKey.Equal(x.PrivateKey) -} - // Bytes returns the byte representation of the EncryptPrivateKey. // It marshals the private key in an uncompressed format. func (priv *EncryptPrivateKey) Bytes() []byte { - return priv.PrivateKey.MarshalUncompressed() + return priv.d } // MasterPublic returns the master public key corresponding to priv. @@ -470,6 +437,7 @@ func (pub *EncryptMasterPublicKey) UnmarshalRaw(bytes []byte) error { return err } pub.MasterPublicKey = g + pub.q = g.MarshalUncompressed() return nil } @@ -481,6 +449,7 @@ func (priv *EncryptPrivateKey) UnmarshalRaw(bytes []byte) error { return err } priv.PrivateKey = g + priv.d = g.MarshalUncompressed() return nil } diff --git a/internal/sm9/sm9_test.go b/internal/sm9/sm9_test.go index 6c267f2..c5f1c52 100644 --- a/internal/sm9/sm9_test.go +++ b/internal/sm9/sm9_test.go @@ -52,17 +52,17 @@ func TestSign(t *testing.T) { if err != nil { t.Fatal(err) } - if !masterKey.Public().Verify(uid, hid, hashed, h, s) { + if !masterKey.PublicKey().Verify(uid, hid, hashed, h, s) { t.Errorf("Verify failed") } sNeg := new(bn256.G1) sNeg.Unmarshal(s[1:]) sNeg.Neg(sNeg) - if masterKey.Public().Verify(uid, hid, hashed, h, sNeg.MarshalUncompressed()) { + if masterKey.PublicKey().Verify(uid, hid, hashed, h, sNeg.MarshalUncompressed()) { t.Errorf("Verify with s=-s succeeded") } hashed[0] ^= 0xff - if masterKey.Public().Verify(uid, hid, hashed, h, s) { + if masterKey.PublicKey().Verify(uid, hid, hashed, h, s) { t.Errorf("Verify always works!") } } @@ -78,7 +78,7 @@ func TestNegativeInputs(t *testing.T) { h := new(big.Int).SetInt64(1) h.Lsh(h, 550 /* larger than any supported curve */) h.Neg(h) - if masterKey.Public().Verify(uid, hid, hashed, h.Bytes(), bn256.Gen1.MarshalUncompressed()) { + if masterKey.PublicKey().Verify(uid, hid, hashed, h.Bytes(), bn256.Gen1.MarshalUncompressed()) { t.Errorf("bogus signature accepted") } } @@ -91,10 +91,10 @@ func TestZeroSignature(t *testing.T) { if err != nil { t.Fatal(err) } - if masterKey.Public().Verify(uid, hid, hashed, big.NewInt(0).Bytes(), bn256.Gen1.MarshalUncompressed()) { + if masterKey.PublicKey().Verify(uid, hid, hashed, big.NewInt(0).Bytes(), bn256.Gen1.MarshalUncompressed()) { t.Error("Verify with h=0 succeeded") } - if masterKey.Public().Verify(uid, hid, hashed, bn256.OrderBytes, bn256.Gen1.MarshalUncompressed()) { + if masterKey.PublicKey().Verify(uid, hid, hashed, bn256.OrderBytes, bn256.Gen1.MarshalUncompressed()) { t.Error("Verify with h=order succeeded") } } @@ -162,7 +162,7 @@ func TestWrapKey(t *testing.T) { if err != nil { t.Fatal(err) } - key, cipher, err := masterKey.Public().WrapKey(rand.Reader, uid, hid, 16) + key, cipher, err := masterKey.PublicKey().WrapKey(rand.Reader, uid, hid, 16) if err != nil { t.Fatal(err) } @@ -224,7 +224,7 @@ func TestWrapKeySM9Sample(t *testing.T) { t.Errorf("not expected user private key") } - q := masterKey.Public().GenerateUserPublicKey(uid, hid) + q := masterKey.PublicKey().GenerateUserPublicKey(uid, hid) if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey { t.Errorf("not expected user public key") } @@ -239,7 +239,7 @@ func TestWrapKeySM9Sample(t *testing.T) { t.Errorf("not expected cipher") } - g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2) + g := bn256.Pair(masterKey.PublicKey().MasterPublicKey, bn256.Gen2) w := new(bn256.GT).ScalarMult(g, r) var buffer []byte @@ -292,7 +292,7 @@ func TestEncryptSM9Sample(t *testing.T) { t.Errorf("not expected user private key") } - q := masterKey.Public().GenerateUserPublicKey(uid, hid) + q := masterKey.PublicKey().GenerateUserPublicKey(uid, hid) if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey { t.Errorf("not expected user public key") } @@ -307,7 +307,7 @@ func TestEncryptSM9Sample(t *testing.T) { t.Errorf("not expected cipher") } - g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2) + g := bn256.Pair(masterKey.PublicKey().MasterPublicKey, bn256.Gen2) w := new(bn256.GT).ScalarMult(g, r) var buffer []byte @@ -362,7 +362,7 @@ func TestEncryptSM9SampleBlockMode(t *testing.T) { t.Errorf("not expected user private key") } - q := masterKey.Public().GenerateUserPublicKey(uid, hid) + q := masterKey.PublicKey().GenerateUserPublicKey(uid, hid) if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey { t.Errorf("not expected user public key") } @@ -377,7 +377,7 @@ func TestEncryptSM9SampleBlockMode(t *testing.T) { t.Errorf("not expected cipher") } - g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2) + g := bn256.Pair(masterKey.PublicKey().MasterPublicKey, bn256.Gen2) w := new(bn256.GT).ScalarMult(g, r) var buffer []byte diff --git a/sm9/sm9.go b/sm9/sm9.go index af27353..f2f5b96 100644 --- a/sm9/sm9.go +++ b/sm9/sm9.go @@ -33,7 +33,7 @@ const ( // as rand. Note that the returned signature does not depend deterministically on // the bytes read from rand, and may change between calls and/or between versions. func Sign(rand io.Reader, priv *SignPrivateKey, hash []byte) (*big.Int, []byte, error) { - h, s, err := priv.privateKey.Sign(rand, hash, nil) + h, s, err := priv.internal.Sign(rand, hash, nil) if err != nil { return nil, nil, err } @@ -49,7 +49,7 @@ func Sign(rand io.Reader, priv *SignPrivateKey, hash []byte) (*big.Int, []byte, // as rand. Note that the returned signature does not depend deterministically on // the bytes read from rand, and may change between calls and/or between versions. func (priv *SignPrivateKey) Sign(rand io.Reader, hash []byte, opts crypto.SignerOpts) ([]byte, error) { - h, s, err := priv.privateKey.Sign(rand, hash, opts) + h, s, err := priv.internal.Sign(rand, hash, opts) if err != nil { return nil, err } @@ -72,7 +72,7 @@ func Verify(pub *SignMasterPublicKey, uid []byte, hid byte, hash []byte, h *big. if h.Sign() <= 0 { return false } - return pub.publicKey.Verify(uid, hid, hash, h.Bytes(), s) + return pub.internal.Verify(uid, hid, hash, h.Bytes(), s) } func encodeSignature(h, s []byte) ([]byte, error) { @@ -111,7 +111,7 @@ func VerifyASN1(pub *SignMasterPublicKey, uid []byte, hid byte, hash, sig []byte if err != nil { return false } - return pub.publicKey.Verify(uid, hid, hash, h, s) + return pub.internal.Verify(uid, hid, hash, h, s) } // Verify verifies the ASN.1 encoded signature, sig, of hash using the @@ -126,7 +126,7 @@ func (pub *SignMasterPublicKey) Verify(uid []byte, hid byte, hash, sig []byte) b // calls this function twice doesn't result in the same key. // Most applications should use [crypto/rand.Reader] as random. func WrapKey(rand io.Reader, pub *EncryptMasterPublicKey, uid []byte, hid byte, kLen int) ([]byte, []byte, error) { - return pub.publicKey.WrapKey(rand, uid, hid, kLen) + return pub.internal.WrapKey(rand, uid, hid, kLen) } // WrapKey wraps key and converts the cipher as ASN1 format, SM9PublicKey1 definition. @@ -190,7 +190,7 @@ var ErrEmptyPlaintext = errors.New("sm9: empty plaintext") // UnwrapKey unwraps key from cipher, user id and aligned key length func UnwrapKey(priv *EncryptPrivateKey, uid, cipher []byte, kLen int) ([]byte, error) { - return priv.privateKey.UnwrapKey(uid, cipher, kLen) + return priv.internal.UnwrapKey(uid, cipher, kLen) } // UnwrapKey unwraps key from cipherDer, user id and aligned key length. @@ -402,7 +402,7 @@ type keyExchange struct { } func (priv *EncryptPrivateKey) NewKeyExchange(uid, peerUID []byte, keyLen int, genSignature bool) *keyExchange { - return &keyExchange{ke: priv.privateKey.NewKeyExchange(uid, peerUID, keyLen, genSignature)} + return &keyExchange{ke: priv.internal.NewKeyExchange(uid, peerUID, keyLen, genSignature)} } func (ke *keyExchange) Destroy() { diff --git a/sm9/sm9_key.go b/sm9/sm9_key.go index 819985e..b3cc735 100644 --- a/sm9/sm9_key.go +++ b/sm9/sm9_key.go @@ -1,6 +1,8 @@ package sm9 import ( + "crypto" + "crypto/subtle" "encoding/pem" "errors" @@ -14,32 +16,40 @@ import ( // SignMasterPrivateKey is a signature master private key, generated by KGC type SignMasterPrivateKey struct { - privateKey *sm9.SignMasterPrivateKey + privateKey []byte + publicKey *SignMasterPublicKey + internal *sm9.SignMasterPrivateKey } // SignMasterPublicKey is a signature master public key, generated by KGC type SignMasterPublicKey struct { - publicKey *sm9.SignMasterPublicKey + publicKey []byte + internal *sm9.SignMasterPublicKey } // SignPrivateKey is a signature private key, generated by KGC type SignPrivateKey struct { - privateKey *sm9.SignPrivateKey + privateKey []byte + internal *sm9.SignPrivateKey } // EncryptMasterPrivateKey is an encryption master private key, generated by KGC type EncryptMasterPrivateKey struct { - privateKey *sm9.EncryptMasterPrivateKey + privateKey []byte + publicKey *EncryptMasterPublicKey + internal *sm9.EncryptMasterPrivateKey } // EncryptMasterPublicKey is an encryption master public key, generated by KGC type EncryptMasterPublicKey struct { - publicKey *sm9.EncryptMasterPublicKey + publicKey []byte + internal *sm9.EncryptMasterPublicKey } // EncryptPrivateKey is an encryption private key, generated by KGC type EncryptPrivateKey struct { - privateKey *sm9.EncryptPrivateKey + privateKey []byte + internal *sm9.EncryptPrivateKey } // GenerateSignMasterKey generates a signature master key pair for DSA usage. @@ -48,25 +58,32 @@ func GenerateSignMasterKey(rand io.Reader) (*SignMasterPrivateKey, error) { if err != nil { return nil, err } - return &SignMasterPrivateKey{privateKey: priv}, nil + master := &SignMasterPrivateKey{privateKey: priv.Bytes(), internal: priv} + master.publicKey = &SignMasterPublicKey{publicKey: priv.PublicKey().Bytes(), internal: priv.PublicKey()} + return master, nil } // Equal compares the receiver SignMasterPrivateKey with another SignMasterPrivateKey // and returns true if they are equal, otherwise it returns false. -func (master *SignMasterPrivateKey) Equal(x *SignMasterPrivateKey) bool { - return master.privateKey.Equal(x.privateKey) +func (master *SignMasterPrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(*SignMasterPrivateKey) + if !ok { + return false + } + return subtle.ConstantTimeCompare(master.privateKey, xx.privateKey) == 1 } // Bytes returns the byte representation of the SignMasterPrivateKey. // It converts the private key to a byte slice. func (master *SignMasterPrivateKey) Bytes() []byte { - return master.privateKey.Bytes() + var buf [32]byte + return append(buf[:0], master.privateKey...) } // MarshalASN1 marshal sign master private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (master *SignMasterPrivateKey) MarshalASN1() ([]byte, error) { - d := new(big.Int).SetBytes(master.privateKey.Bytes()) + d := new(big.Int).SetBytes(master.privateKey) var b cryptobyte.Builder b.AddASN1BigInt(d) return b.Bytes() @@ -93,44 +110,53 @@ func UnmarshalSignMasterPrivateKeyASN1(der []byte) (*SignMasterPrivateKey, error return nil, errors.New("sm9: invalid ASN.1 data for signature master private key") } - privateKey, err := sm9.NewSignMasterPrivateKey(d.Bytes()) + priv, err := sm9.NewSignMasterPrivateKey(d.Bytes()) if err != nil { return nil, err } - return &SignMasterPrivateKey{privateKey: privateKey}, nil + return &SignMasterPrivateKey{privateKey: priv.Bytes(), internal: priv}, nil } // GenerateUserKey generate a signature private key for the given user. func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*SignPrivateKey, error) { - priv, err := master.privateKey.GenerateUserKey(uid, hid) + priv, err := master.internal.GenerateUserKey(uid, hid) if err != nil { return nil, err } - return &SignPrivateKey{privateKey: priv}, nil + return &SignPrivateKey{privateKey: priv.Bytes(), internal: priv}, nil } // Public returns the public key corresponding to the private key. -func (master *SignMasterPrivateKey) Public() *SignMasterPublicKey { - return &SignMasterPublicKey{master.privateKey.Public()} +func (master *SignMasterPrivateKey) PublicKey() *SignMasterPublicKey { + return master.publicKey +} + +func (master *SignMasterPrivateKey) Public() crypto.PublicKey { + return master.PublicKey() } // Equal compares the receiver SignMasterPublicKey with another SignMasterPublicKey // and returns true if they are equal, otherwise false. -func (pub *SignMasterPublicKey) Equal(x *SignMasterPublicKey) bool { - return pub.publicKey.Equal(x.publicKey) +func (pub *SignMasterPublicKey) Equal(x crypto.PublicKey) bool { + xx, ok := x.(*SignMasterPublicKey) + if !ok { + return false + } + return subtle.ConstantTimeCompare(pub.publicKey, xx.publicKey) == 1 } // Bytes returns the byte representation of the SignMasterPublicKey. // It calls the Bytes method on the underlying publicKey field. func (pub *SignMasterPublicKey) Bytes() []byte { - return pub.publicKey.Bytes() + var buf [129]byte + return append(buf[:0], pub.publicKey...) } // MarshalASN1 marshal signature master public key to asn.1 format data according // SM9 cryptographic algorithm application specification func (pub *SignMasterPublicKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalUncompressed()) + b.AddASN1BitString(pub.publicKey) return b.Bytes() } @@ -138,15 +164,16 @@ func (pub *SignMasterPublicKey) MarshalASN1() ([]byte, error) { // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (pub *SignMasterPublicKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalCompressed()) + b.AddASN1BitString(pub.publicKey) return b.Bytes() } // UnmarshalSignMasterPublicKeyRaw unmarsal raw bytes data to signature master public key func UnmarshalSignMasterPublicKeyRaw(bytes []byte) (pub *SignMasterPublicKey, err error) { pub = new(SignMasterPublicKey) - pub.publicKey = new(sm9.SignMasterPublicKey) - err = pub.publicKey.UnmarshalRaw(bytes) + pub.internal = new(sm9.SignMasterPublicKey) + err = pub.internal.UnmarshalRaw(bytes) + pub.publicKey = pub.internal.Bytes() return } @@ -177,29 +204,30 @@ func ParseSignMasterPublicKeyPEM(data []byte) (*SignMasterPublicKey, error) { return UnmarshalSignMasterPublicKeyASN1(block.Bytes) } -func (priv *SignPrivateKey) Equal(x *SignPrivateKey) bool { - return priv.privateKey.Equal(x.privateKey) +func (priv *SignPrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(*SignPrivateKey) + if !ok { + return false + } + return subtle.ConstantTimeCompare(priv.privateKey, xx.privateKey) == 1 } func (priv *SignPrivateKey) Bytes() []byte { - return priv.privateKey.Bytes() + var buf [65]byte + return append(buf[:0], priv.privateKey...) } // MasterPublic returns the signature master public key corresponding to priv. func (priv *SignPrivateKey) MasterPublic() *SignMasterPublicKey { - return &SignMasterPublicKey{priv.privateKey.MasterPublic()} -} - -// setMasterPublicKey bind the signature master public key to it. -func (priv *SignPrivateKey) setMasterPublicKey(pub *SignMasterPublicKey) { - priv.privateKey.SetMasterPublicKey(pub.publicKey) + masterKey := priv.internal.MasterPublic() + return &SignMasterPublicKey{internal: masterKey, publicKey: masterKey.Bytes()} } // MarshalASN1 marshal signature private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (priv *SignPrivateKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalUncompressed()) + b.AddASN1BitString(priv.privateKey) return b.Bytes() } @@ -207,7 +235,7 @@ func (priv *SignPrivateKey) MarshalASN1() ([]byte, error) { // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (priv *SignPrivateKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalCompressed()) + b.AddASN1BitString(priv.privateKey) return b.Bytes() } @@ -215,11 +243,12 @@ func (priv *SignPrivateKey) MarshalCompressedASN1() ([]byte, error) { // Note, priv's SignMasterPublicKey should be handled separately. func UnmarshalSignPrivateKeyRaw(bytes []byte) (*SignPrivateKey, error) { priv := new(SignPrivateKey) - priv.privateKey = new(sm9.SignPrivateKey) - err := priv.privateKey.UnmarshalRaw(bytes) + priv.internal = new(sm9.SignPrivateKey) + err := priv.internal.UnmarshalRaw(bytes) if err != nil { return nil, err } + priv.privateKey = priv.internal.Bytes() return priv, nil } @@ -252,7 +281,7 @@ func UnmarshalSignPrivateKeyASN1(der []byte) (*SignPrivateKey, error) { if err != nil { return nil, err } - priv.setMasterPublicKey(masterPK) + priv.internal.SetMasterPublicKey(masterPK.internal) } return priv, nil } @@ -263,39 +292,50 @@ func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error) if err != nil { return nil, err } - return &EncryptMasterPrivateKey{privateKey: priv}, nil + master := &EncryptMasterPrivateKey{privateKey: priv.Bytes(), internal: priv} + master.publicKey = &EncryptMasterPublicKey{publicKey: priv.PublicKey().Bytes(), internal: priv.PublicKey()} + return master, nil } // Bytes returns the byte representation of the EncryptMasterPrivateKey. // It delegates the call to the Bytes method of the underlying privateKey. func (master *EncryptMasterPrivateKey) Bytes() []byte { - return master.privateKey.Bytes() + var buf [32]byte + return append(buf[:0], master.privateKey...) } // Equal compares the receiver EncryptMasterPrivateKey with another EncryptMasterPrivateKey // and returns true if they are equal, otherwise it returns false. -func (master *EncryptMasterPrivateKey) Equal(x *EncryptMasterPrivateKey) bool { - return master.privateKey.Equal(x.privateKey) +func (master *EncryptMasterPrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(*EncryptMasterPrivateKey) + if !ok { + return false + } + return subtle.ConstantTimeCompare(master.privateKey, xx.privateKey) == 1 } // GenerateUserKey generate an encryption private key for the given user. func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*EncryptPrivateKey, error) { - priv, err := master.privateKey.GenerateUserKey(uid, hid) + priv, err := master.internal.GenerateUserKey(uid, hid) if err != nil { return nil, err } - return &EncryptPrivateKey{privateKey: priv}, nil + return &EncryptPrivateKey{privateKey: priv.Bytes(), internal: priv}, nil } // Public returns the public key corresponding to the private key. -func (master *EncryptMasterPrivateKey) Public() *EncryptMasterPublicKey { - return &EncryptMasterPublicKey{publicKey: master.privateKey.Public()} +func (master *EncryptMasterPrivateKey) PublicKey() *EncryptMasterPublicKey { + return master.publicKey +} + +func (master *EncryptMasterPrivateKey) Public() crypto.PublicKey { + return master.PublicKey() } // MarshalASN1 marshal encryption master private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (master *EncryptMasterPrivateKey) MarshalASN1() ([]byte, error) { - d := new(big.Int).SetBytes(master.privateKey.Bytes()) + d := new(big.Int).SetBytes(master.privateKey) var b cryptobyte.Builder b.AddASN1BigInt(d) return b.Bytes() @@ -324,26 +364,31 @@ func UnmarshalEncryptMasterPrivateKeyASN1(der []byte) (*EncryptMasterPrivateKey, if err != nil { return nil, err } - return &EncryptMasterPrivateKey{privateKey: privateKey}, nil + return &EncryptMasterPrivateKey{privateKey: privateKey.Bytes(), internal: privateKey}, nil } // Equal compares the receiver EncryptMasterPublicKey with another EncryptMasterPublicKey // and returns true if they are equal, otherwise it returns false. -func (pub *EncryptMasterPublicKey) Equal(x *EncryptMasterPublicKey) bool { - return pub.publicKey.Equal(x.publicKey) +func (pub *EncryptMasterPublicKey) Equal(x crypto.PublicKey) bool { + xx, ok := x.(*EncryptMasterPublicKey) + if !ok { + return false + } + return subtle.ConstantTimeCompare(pub.publicKey, xx.publicKey) == 1 } // Bytes returns the byte representation of the EncryptMasterPublicKey. // It delegates the call to the Bytes method of the underlying publicKey. func (pub *EncryptMasterPublicKey) Bytes() []byte { - return pub.publicKey.Bytes() + var buf [65]byte + return append(buf[:0], pub.publicKey...) } // MarshalASN1 marshal encryption master public key to asn.1 format data according // SM9 cryptographic algorithm application specification func (pub *EncryptMasterPublicKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalUncompressed()) + b.AddASN1BitString(pub.publicKey) return b.Bytes() } @@ -351,18 +396,19 @@ func (pub *EncryptMasterPublicKey) MarshalASN1() ([]byte, error) { // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (pub *EncryptMasterPublicKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalCompressed()) + b.AddASN1BitString(pub.publicKey) return b.Bytes() } // UnmarshalEncryptMasterPublicKeyRaw unmarsal raw bytes data to encryption master public key func UnmarshalEncryptMasterPublicKeyRaw(bytes []byte) (*EncryptMasterPublicKey, error) { pub := new(EncryptMasterPublicKey) - pub.publicKey = new(sm9.EncryptMasterPublicKey) - err := pub.publicKey.UnmarshalRaw(bytes) + pub.internal = new(sm9.EncryptMasterPublicKey) + err := pub.internal.UnmarshalRaw(bytes) if err != nil { return nil, err } + pub.publicKey = pub.internal.Bytes() return pub, nil } @@ -395,19 +441,15 @@ func UnmarshalEncryptMasterPublicKeyASN1(der []byte) (*EncryptMasterPublicKey, e // MasterPublic returns the master public key corresponding to priv. func (priv *EncryptPrivateKey) MasterPublic() *EncryptMasterPublicKey { - return &EncryptMasterPublicKey{priv.privateKey.MasterPublic()} -} - -// setMasterPublicKey bind the encrypt master public key to it. -func (priv *EncryptPrivateKey) setMasterPublicKey(pub *EncryptMasterPublicKey) { - priv.privateKey.SetMasterPublicKey(pub.publicKey) + master := priv.internal.MasterPublic() + return &EncryptMasterPublicKey{publicKey: master.Bytes(), internal: master} } // MarshalASN1 marshal encryption private key to asn.1 format data according // SM9 cryptographic algorithm application specification func (priv *EncryptPrivateKey) MarshalASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalUncompressed()) + b.AddASN1BitString(priv.privateKey) return b.Bytes() } @@ -415,7 +457,7 @@ func (priv *EncryptPrivateKey) MarshalASN1() ([]byte, error) { // SM9 cryptographic algorithm application specification, the curve point is in compressed form. func (priv *EncryptPrivateKey) MarshalCompressedASN1() ([]byte, error) { var b cryptobyte.Builder - b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalCompressed()) + b.AddASN1BitString(priv.privateKey) return b.Bytes() } @@ -423,11 +465,12 @@ func (priv *EncryptPrivateKey) MarshalCompressedASN1() ([]byte, error) { // Note, priv's EncryptMasterPublicKey should be handled separately. func UnmarshalEncryptPrivateKeyRaw(bytes []byte) (*EncryptPrivateKey, error) { priv := new(EncryptPrivateKey) - priv.privateKey = new(sm9.EncryptPrivateKey) - err := priv.privateKey.UnmarshalRaw(bytes) + priv.internal = new(sm9.EncryptPrivateKey) + err := priv.internal.UnmarshalRaw(bytes) if err != nil { return nil, err } + priv.privateKey = priv.internal.Bytes() return priv, nil } @@ -459,19 +502,24 @@ func UnmarshalEncryptPrivateKeyASN1(der []byte) (*EncryptPrivateKey, error) { if err != nil { return nil, err } - priv.setMasterPublicKey(masterPK) + priv.internal.SetMasterPublicKey(masterPK.internal) } return priv, nil } // Equal compares the receiver EncryptPrivateKey with another EncryptPrivateKey x // and returns true if they are equal, otherwise false. -func (priv *EncryptPrivateKey) Equal(x *EncryptPrivateKey) bool { - return priv.privateKey.Equal(x.privateKey) +func (priv *EncryptPrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(*EncryptPrivateKey) + if !ok { + return false + } + return subtle.ConstantTimeCompare(priv.privateKey, xx.privateKey) == 1 } // Bytes returns the byte representation of the EncryptPrivateKey. // It delegates the call to the Bytes method of the underlying privateKey. func (priv *EncryptPrivateKey) Bytes() []byte { - return priv.privateKey.Bytes() + var buf [129]byte + return append(buf[:0], priv.privateKey...) } diff --git a/sm9/sm9_key_test.go b/sm9/sm9_key_test.go index c057c22..70cc12b 100644 --- a/sm9/sm9_key_test.go +++ b/sm9/sm9_key_test.go @@ -34,7 +34,7 @@ func TestSignMasterPublicKeyMarshalASN1(t *testing.T) { if err != nil { t.Fatal(err) } - der, err := masterKey.Public().MarshalASN1() + der, err := masterKey.PublicKey().MarshalASN1() if err != nil { t.Fatal(err) } @@ -42,7 +42,7 @@ func TestSignMasterPublicKeyMarshalASN1(t *testing.T) { if err != nil { t.Fatal(err) } - if !masterKey.Public().Equal(pub2) { + if !pub2.Equal(masterKey.Public()) { t.Errorf("not same") } } @@ -52,7 +52,7 @@ func TestSignMasterPublicKeyMarshalCompressedASN1(t *testing.T) { if err != nil { t.Fatal(err) } - der, err := masterKey.Public().MarshalCompressedASN1() + der, err := masterKey.PublicKey().MarshalCompressedASN1() if err != nil { t.Fatal(err) } @@ -60,7 +60,7 @@ func TestSignMasterPublicKeyMarshalCompressedASN1(t *testing.T) { if err != nil { t.Fatal(err) } - if !masterKey.Public().Equal(pub2) { + if !pub2.Equal(masterKey.Public()) { t.Errorf("not same") } } @@ -136,7 +136,7 @@ func TestEncryptMasterPublicKeyMarshalASN1(t *testing.T) { if err != nil { t.Fatal(err) } - der, err := masterKey.Public().MarshalASN1() + der, err := masterKey.PublicKey().MarshalASN1() if err != nil { t.Fatal(err) } @@ -144,7 +144,7 @@ func TestEncryptMasterPublicKeyMarshalASN1(t *testing.T) { if err != nil { t.Fatal(err) } - if !masterKey.Public().Equal(pub2) { + if !pub2.Equal(masterKey.Public()) { t.Errorf("not same") } } @@ -154,7 +154,7 @@ func TestEncryptMasterPublicKeyMarshalCompressedASN1(t *testing.T) { if err != nil { t.Fatal(err) } - der, err := masterKey.Public().MarshalCompressedASN1() + der, err := masterKey.PublicKey().MarshalCompressedASN1() if err != nil { t.Fatal(err) } @@ -162,7 +162,7 @@ func TestEncryptMasterPublicKeyMarshalCompressedASN1(t *testing.T) { if err != nil { t.Fatal(err) } - if !masterKey.Public().Equal(pub2) { + if !pub2.Equal(masterKey.Public()) { t.Errorf("not same") } } diff --git a/sm9/sm9_test.go b/sm9/sm9_test.go index 1fb601d..28d60d7 100644 --- a/sm9/sm9_test.go +++ b/sm9/sm9_test.go @@ -25,11 +25,11 @@ func TestSignASN1(t *testing.T) { if err != nil { t.Fatal(err) } - if !masterKey.Public().Verify(uid, hid, hashed, sig) { + if !masterKey.PublicKey().Verify(uid, hid, hashed, sig) { t.Errorf("Verify failed") } sig[0] = 0xff - if masterKey.Public().Verify(uid, hid, hashed, sig) { + if masterKey.PublicKey().Verify(uid, hid, hashed, sig) { t.Errorf("Verify with invalid asn1 format successed") } } @@ -45,7 +45,7 @@ func TestWrapKey(t *testing.T) { if err != nil { t.Fatal(err) } - key, cipher, err := masterKey.Public().WrapKey(rand.Reader, uid, hid, 16) + key, cipher, err := masterKey.PublicKey().WrapKey(rand.Reader, uid, hid, 16) if err != nil { t.Fatal(err) } @@ -71,7 +71,7 @@ func TestWrapKeyASN1(t *testing.T) { if err != nil { t.Fatal(err) } - keyPackage, err := masterKey.Public().WrapKeyASN1(rand.Reader, uid, hid, 16) + keyPackage, err := masterKey.PublicKey().WrapKeyASN1(rand.Reader, uid, hid, 16) if err != nil { t.Fatal(err) } @@ -107,7 +107,7 @@ func TestEncryptDecrypt(t *testing.T) { sm9.DefaultEncrypterOpts, sm9.SM4ECBEncrypterOpts, sm9.SM4CBCEncrypterOpts, sm9.SM4CFBEncrypterOpts, sm9.SM4OFBEncrypterOpts, } for _, opts := range encTypes { - cipher, err := sm9.Encrypt(rand.Reader, masterKey.Public(), uid, hid, plaintext, opts) + cipher, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, opts) if err != nil { t.Fatal(err) } @@ -142,7 +142,7 @@ func TestEncryptEmptyPlaintext(t *testing.T) { sm9.DefaultEncrypterOpts, sm9.SM4ECBEncrypterOpts, sm9.SM4CBCEncrypterOpts, sm9.SM4CFBEncrypterOpts, sm9.SM4OFBEncrypterOpts, } for _, opts := range encTypes { - _, err := sm9.Encrypt(rand.Reader, masterKey.Public(), uid, hid, nil, opts) + _, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, nil, opts) if err != sm9.ErrEmptyPlaintext { t.Fatalf("should be ErrEmptyPlaintext") } @@ -165,7 +165,7 @@ func TestEncryptDecryptASN1(t *testing.T) { sm9.DefaultEncrypterOpts, sm9.SM4ECBEncrypterOpts, sm9.SM4CBCEncrypterOpts, sm9.SM4CFBEncrypterOpts, sm9.SM4OFBEncrypterOpts, } for _, opts := range encTypes { - cipher, err := sm9.EncryptASN1(rand.Reader, masterKey.Public(), uid, hid, plaintext, opts) + cipher, err := sm9.EncryptASN1(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, opts) if err != nil { t.Fatal(err) } @@ -201,7 +201,7 @@ func TestUnmarshalSM9KeyPackage(t *testing.T) { if err != nil { t.Fatal(err) } - p, err := masterKey.Public().WrapKeyASN1(rand.Reader, uid, hid, 16) + p, err := masterKey.PublicKey().WrapKeyASN1(rand.Reader, uid, hid, 16) if err != nil { t.Fatal(err) } @@ -379,7 +379,7 @@ func BenchmarkVerify(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - if !sm9.VerifyASN1(masterKey.Public(), uid, hid, hashed, sig) { + if !sm9.VerifyASN1(masterKey.PublicKey(), uid, hid, hashed, sig) { b.Fatal("verify failed") } } @@ -396,7 +396,7 @@ func BenchmarkEncrypt(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - cipher, err := sm9.Encrypt(rand.Reader, masterKey.Public(), uid, hid, plaintext, nil) + cipher, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, nil) if err != nil { b.Fatal(err) } @@ -417,7 +417,7 @@ func BenchmarkDecrypt(b *testing.B) { if err != nil { b.Fatal(err) } - cipher, err := sm9.Encrypt(rand.Reader, masterKey.Public(), uid, hid, plaintext, nil) + cipher, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, nil) if err != nil { b.Fatal(err) } @@ -446,7 +446,7 @@ func BenchmarkDecryptASN1(b *testing.B) { if err != nil { b.Fatal(err) } - cipher, err := sm9.EncryptASN1(rand.Reader, masterKey.Public(), uid, hid, plaintext, nil) + cipher, err := sm9.EncryptASN1(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, nil) if err != nil { b.Fatal(err) } diff --git a/smx509/pkcs8.go b/smx509/pkcs8.go index a38d440..0370035 100644 --- a/smx509/pkcs8.go +++ b/smx509/pkcs8.go @@ -212,7 +212,7 @@ func marshalPKCS8SM9SignMasterPrivateKey(k *sm9.SignMasterPrivateKey) ([]byte, e if err != nil { return nil, err } - pubasn1, err := k.Public().MarshalASN1() + pubasn1, err := k.PublicKey().MarshalASN1() if err != nil { return nil, err } @@ -244,7 +244,7 @@ func marshalPKCS8SM9EncMasterPrivateKey(k *sm9.EncryptMasterPrivateKey) ([]byte, if err != nil { return nil, err } - pubasn1, err := k.Public().MarshalASN1() + pubasn1, err := k.PublicKey().MarshalASN1() if err != nil { return nil, err }