internal/sm9,sm9: refactor all keys

This commit is contained in:
Sun Yimin 2025-03-25 11:10:53 +08:00 committed by GitHub
parent dd69d32930
commit 3eea15b3b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 185 additions and 168 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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