sm9: refactoring, do not expose bn256 types to caller #314

This commit is contained in:
Sun Yimin 2025-03-13 13:46:14 +08:00 committed by GitHub
parent e9692d23ab
commit 43ffd49e2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
64 changed files with 1957 additions and 1322 deletions

View File

@ -1,5 +1,7 @@
package bn256
import "math/big"
// u is the BN parameter that determines the prime: 600000000058f98a.
var u = bigFromHex("600000000058f98a")
@ -17,8 +19,29 @@ var sixU2Plus1 = bigFromHex("d8000000019062ed0000b98b0cb27659")
// p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.
var p = bigFromHex("b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457d")
var OrderBytes = []byte{
0xb6, 0x40, 0x00, 0x00, 0x02, 0xa3, 0xa6, 0xf1,
0xd6, 0x03, 0xab, 0x4f, 0xf5, 0x8e, 0xc7, 0x44,
0x49, 0xf2, 0x93, 0x4b, 0x18, 0xea, 0x8b, 0xee,
0xe5, 0x6e, 0xe1, 0x9c, 0xd6, 0x9e, 0xcf, 0x25,
}
// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1.
var Order = bigFromHex("b640000002a3a6f1d603ab4ff58ec74449f2934b18ea8beee56ee19cd69ecf25")
var Order = new(big.Int).SetBytes(OrderBytes)
var OrderMinus1Bytes = []byte{
0xb6, 0x40, 0x00, 0x00, 0x02, 0xa3, 0xa6, 0xf1,
0xd6, 0x03, 0xab, 0x4f, 0xf5, 0x8e, 0xc7, 0x44,
0x49, 0xf2, 0x93, 0x4b, 0x18, 0xea, 0x8b, 0xee,
0xe5, 0x6e, 0xe1, 0x9c, 0xd6, 0x9e, 0xcf, 0x24,
}
var OrderMinus2Bytes = []byte{
0xb6, 0x40, 0x00, 0x00, 0x02, 0xa3, 0xa6, 0xf1,
0xd6, 0x03, 0xab, 0x4f, 0xf5, 0x8e, 0xc7, 0x44,
0x49, 0xf2, 0x93, 0x4b, 0x18, 0xea, 0x8b, 0xee,
0xe5, 0x6e, 0xe1, 0x9c, 0xd6, 0x9e, 0xcf, 0x23,
}
// p2 is p, represented as little-endian 64-bit words.
var p2 = [4]uint64{0xe56f9b27e351457d, 0x21f2934b1a7aeedb, 0xd603ab4ff58ec745, 0xb640000002a3a6f1}

454
internal/sm9/sm9.go Normal file
View File

@ -0,0 +1,454 @@
// Package sm9 implements ShangMi(SM) sm9 digital signature, encryption and key exchange algorithms.
package sm9
import (
"crypto"
goSubtle "crypto/subtle"
"errors"
"io"
"github.com/emmansun/gmsm/internal/bigmod"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/randutil"
"github.com/emmansun/gmsm/internal/sm3"
"github.com/emmansun/gmsm/internal/sm9/bn256"
"github.com/emmansun/gmsm/internal/subtle"
)
// SM9 ASN.1 format reference: Information security technology - SM9 cryptographic algorithm application specification
var (
orderNat *bigmod.Modulus
)
func init() {
orderNat, _ = bigmod.NewModulus(bn256.OrderBytes)
}
type hashMode byte
const (
// hashmode used in h1: 0x01
H1 hashMode = 1 + iota
// hashmode used in h2: 0x02
H2
)
// hash implements H1(Z,n) or H2(Z,n) in sm9 algorithm.
func hash(z []byte, h hashMode) *bigmod.Nat {
md := sm3.New()
var ha [64]byte
var countBytes [4]byte
var ct uint32 = 1
byteorder.BEPutUint32(countBytes[:], ct)
md.Write([]byte{byte(h)})
md.Write(z)
md.Write(countBytes[:])
copy(ha[:], md.Sum(nil))
ct++
md.Reset()
byteorder.BEPutUint32(countBytes[:], ct)
md.Write([]byte{byte(h)})
md.Write(z)
md.Write(countBytes[:])
copy(ha[sm3.Size:], md.Sum(nil))
return bigmod.NewNat().SetOverflowedBytes(ha[:40], orderNat)
}
func hashH1(z []byte) *bigmod.Nat {
return hash(z, H1)
}
func hashH2(z []byte) *bigmod.Nat {
return hash(z, H2)
}
func randomScalar(rand io.Reader) (k *bigmod.Nat, err error) {
k = bigmod.NewNat()
for {
b := make([]byte, orderNat.Size())
if _, err = io.ReadFull(rand, b); err != nil {
return
}
// Mask off any excess bits to increase the chance of hitting a value in
// (0, N). These are the most dangerous lines in the package and maybe in
// the library: a single bit of bias in the selection of nonces would likely
// lead to key recovery, but no tests would fail. Look but DO NOT TOUCH.
if excess := len(b)*8 - orderNat.BitLen(); excess > 0 {
// Just to be safe, assert that this only happens for the one curve that
// doesn't have a round number of bits.
if excess != 0 {
panic("sm9: internal error: unexpectedly masking off bits")
}
b[0] >>= excess
}
// FIPS 186-4 makes us check k <= N - 2 and then add one.
// Checking 0 < k <= N - 1 is strictly equivalent.
// None of this matters anyway because the chance of selecting
// zero is cryptographically negligible.
if _, err = k.SetBytes(b, orderNat); err == nil && k.IsZero() == 0 {
break
}
}
return
}
// Sign signs digest with user's DSA key, reading randomness from rand. The opts argument
// is not currently used but, in keeping with the crypto.Signer interface.
//
// The signature is randomized. Most applications should use [crypto/rand.Reader]
// 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, []byte, error) {
var (
hNat *bigmod.Nat
s *bn256.G1
)
randutil.MaybeReadByte(rand)
for {
r, err := randomScalar(rand)
if err != nil {
return nil, nil, err
}
w, err := priv.SignMasterPublicKey.ScalarBaseMult(r.Bytes(orderNat))
if err != nil {
return nil, nil, err
}
var buffer []byte
buffer = append(append(buffer, hash...), w.Marshal()...)
hNat = hashH2(buffer)
r.Sub(hNat, orderNat)
if r.IsZero() == 0 {
s, err = new(bn256.G1).ScalarMult(priv.PrivateKey, r.Bytes(orderNat))
if err != nil {
return nil, nil, err
}
break
}
}
return hNat.Bytes(orderNat), s.MarshalUncompressed(), nil
}
// Verify checks the validity of a signature using the provided parameters.
func (pub *SignMasterPublicKey) Verify(uid []byte, hid byte, hash, h, s []byte) bool {
sPoint := new(bn256.G1)
_, err := sPoint.Unmarshal(s[1:])
if err != nil || !sPoint.IsOnCurve() {
return false
}
hNat, err := bigmod.NewNat().SetBytes(h, orderNat)
if err != nil || hNat.IsZero() == 1 {
return false
}
t, err := pub.ScalarBaseMult(hNat.Bytes(orderNat))
if err != nil {
return false
}
// user sign public key p generation
p := pub.GenerateUserPublicKey(uid, hid)
u := bn256.Pair(sPoint, p)
w := new(bn256.GT).Add(u, t)
var buffer []byte
buffer = append(append(buffer, hash...), w.Marshal()...)
h2 := hashH2(buffer)
return h2.Equal(hNat) == 1
}
// WrapKey generates a wrapped key and its corresponding ciphertext.
//
// Parameters:
// - rand: an io.Reader used to generate random values.
// - uid: a byte slice representing the user ID.
// - hid: a byte representing the hash ID.
// - kLen: an integer specifying the desired key length.
//
// Returns:
// - A byte slice containing the generated key.
// - A byte slice containing the uncompressed ciphertext.
// - An error if any occurs during the key wrapping process.
func (pub *EncryptMasterPublicKey) WrapKey(rand io.Reader, uid []byte, hid byte, kLen int) ([]byte, []byte, error) {
q := pub.GenerateUserPublicKey(uid, hid)
var (
err error
r *bigmod.Nat
w *bn256.GT
cipher *bn256.G1
key []byte
)
for {
r, err = randomScalar(rand)
if err != nil {
return nil, nil, err
}
rBytes := r.Bytes(orderNat)
cipher, err = new(bn256.G1).ScalarMult(q, rBytes)
if err != nil {
return nil, nil, err
}
w, err = pub.ScalarBaseMult(rBytes)
if err != nil {
return nil, nil, err
}
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key = sm3.Kdf(buffer, kLen)
if subtle.ConstantTimeAllZero(key) == 0 {
break
}
}
return key, cipher.MarshalUncompressed(), nil
}
// UnwrapKey decrypts the given cipher text using the private key and user ID (uid).
// It returns the decrypted key of the specified length (kLen) or an error if decryption fails.
func (priv *EncryptPrivateKey) UnwrapKey(uid, cipher []byte, kLen int) ([]byte, error) {
if len(cipher) == 65 && cipher[0] != 0x04 {
return nil, ErrDecryption
}
if len(cipher) == 65 {
cipher = cipher[1:]
}
p := new(bn256.G1)
_, err := p.Unmarshal(cipher)
if err != nil || !p.IsOnCurve() {
return nil, ErrDecryption
}
w := bn256.Pair(p, priv.PrivateKey)
var buffer []byte
buffer = append(buffer, cipher...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, kLen)
if subtle.ConstantTimeAllZero(key) == 1 {
return nil, ErrDecryption
}
return key, nil
}
// ErrDecryption represents a failure to decrypt a message.
// It is deliberately vague to avoid adaptive attacks.
var ErrDecryption = errors.New("sm9: decryption error")
// KeyExchange represents key exchange struct, include internal stat in whole key exchange flow.
// Initiator's flow will be: NewKeyExchange -> InitKeyExchange -> transmission -> ConfirmResponder
// Responder's flow will be: NewKeyExchange -> waiting ... -> RepondKeyExchange -> transmission -> ConfirmInitiator
type KeyExchange struct {
genSignature bool // control the optional sign/verify step triggered by responsder
keyLength int // key length
privateKey *EncryptPrivateKey // owner's encryption private key
uid []byte // owner uid
peerUID []byte // peer uid
r *bigmod.Nat // random which will be used to compute secret
secret []byte // generated secret which will be passed to peer
peerSecret []byte // received peer's secret
g1 *bn256.GT // internal state which will be used when compute the key and signature
g2 *bn256.GT // internal state which will be used when compute the key and signature
g3 *bn256.GT // internal state which will be used when compute the key and signature
}
// NewKeyExchange creates one new KeyExchange object
func (priv *EncryptPrivateKey) NewKeyExchange(uid, peerUID []byte, keyLen int, genSignature bool) *KeyExchange {
ke := &KeyExchange{}
ke.genSignature = genSignature
ke.keyLength = keyLen
ke.privateKey = priv
ke.uid = uid
ke.peerUID = peerUID
return ke
}
// Destroy clears all internal state and Ephemeral private/public keys
func (ke *KeyExchange) Destroy() {
if ke.r != nil {
ke.r.SetBytes([]byte{0}, orderNat)
}
if ke.g1 != nil {
ke.g1.SetOne()
}
if ke.g2 != nil {
ke.g2.SetOne()
}
if ke.g3 != nil {
ke.g3.SetOne()
}
}
func initKeyExchange(ke *KeyExchange, hid byte, r *bigmod.Nat) {
pubB := ke.privateKey.GenerateUserPublicKey(ke.peerUID, hid)
ke.r = r
rA, err := new(bn256.G1).ScalarMult(pubB, ke.r.Bytes(orderNat))
if err != nil {
panic(err)
}
ke.secret = rA.MarshalUncompressed()
}
// InitKeyExchange generates random with responder uid, for initiator's step A1-A4
func (ke *KeyExchange) InitKeyExchange(rand io.Reader, hid byte) ([]byte, error) {
r, err := randomScalar(rand)
if err != nil {
return nil, err
}
initKeyExchange(ke, hid, r)
return ke.secret, nil
}
func (ke *KeyExchange) sign(isResponder bool, prefix byte) []byte {
var buffer []byte
hash := sm3.New()
hash.Write(ke.g2.Marshal())
hash.Write(ke.g3.Marshal())
if isResponder {
hash.Write(ke.peerUID)
hash.Write(ke.uid)
hash.Write(ke.peerSecret[1:])
hash.Write(ke.secret[1:])
} else {
hash.Write(ke.uid)
hash.Write(ke.peerUID)
hash.Write(ke.secret[1:])
hash.Write(ke.peerSecret[1:])
}
buffer = hash.Sum(nil)
hash.Reset()
hash.Write([]byte{prefix})
hash.Write(ke.g1.Marshal())
hash.Write(buffer)
return hash.Sum(nil)
}
func (ke *KeyExchange) generateSharedKey(isResponder bool) ([]byte, error) {
var buffer []byte
if isResponder {
buffer = append(buffer, ke.peerUID...)
buffer = append(buffer, ke.uid...)
buffer = append(buffer, ke.peerSecret[1:]...)
buffer = append(buffer, ke.secret[1:]...)
} else {
buffer = append(buffer, ke.uid...)
buffer = append(buffer, ke.peerUID...)
buffer = append(buffer, ke.secret[1:]...)
buffer = append(buffer, ke.peerSecret[1:]...)
}
buffer = append(buffer, ke.g1.Marshal()...)
buffer = append(buffer, ke.g2.Marshal()...)
buffer = append(buffer, ke.g3.Marshal()...)
return sm3.Kdf(buffer, ke.keyLength), nil
}
func respondKeyExchange(ke *KeyExchange, hid byte, r *bigmod.Nat, rA []byte) ([]byte, []byte, error) {
rP := new(bn256.G1)
_, err := rP.Unmarshal(rA[1:])
if err != nil || !rP.IsOnCurve() {
return nil, nil, errors.New("sm9: invalid initiator's ephemeral public key")
}
ke.peerSecret = rA
pubA := ke.privateKey.GenerateUserPublicKey(ke.peerUID, hid)
ke.r = r
rBytes := r.Bytes(orderNat)
rB, err := new(bn256.G1).ScalarMult(pubA, rBytes)
if err != nil {
return nil, nil, err
}
ke.secret = rB.MarshalUncompressed()
ke.g1 = bn256.Pair(rP, ke.privateKey.PrivateKey)
ke.g3 = &bn256.GT{}
g3, err := bn256.ScalarMultGT(ke.g1, rBytes)
if err != nil {
return nil, nil, err
}
ke.g3 = g3
g2, err := ke.privateKey.EncryptMasterPublicKey.ScalarBaseMult(rBytes)
if err != nil {
return nil, nil, err
}
ke.g2 = g2
if !ke.genSignature {
return ke.secret, nil, nil
}
return ke.secret, ke.sign(true, 0x82), nil
}
// RespondKeyExchange when responder receive rA, for responder's step B1-B7
func (ke *KeyExchange) RespondKeyExchange(rand io.Reader, hid byte, rA []byte) ([]byte, []byte, error) {
r, err := randomScalar(rand)
if err != nil {
return nil, nil, err
}
return respondKeyExchange(ke, hid, r, rA)
}
// ConfirmResponder for initiator's step A5-A7
func (ke *KeyExchange) ConfirmResponder(rB, sB []byte) ([]byte, []byte, error) {
pB := new(bn256.G1)
_, err := pB.Unmarshal(rB[1:])
if err != nil || !pB.IsOnCurve() {
return nil, nil, errors.New("sm9: invalid responder's ephemeral public key")
}
// step 5
ke.peerSecret = rB
g1, err := ke.privateKey.EncryptMasterPublicKey.ScalarBaseMult(ke.r.Bytes(orderNat))
if err != nil {
return nil, nil, err
}
ke.g1 = g1
ke.g2 = bn256.Pair(pB, ke.privateKey.PrivateKey)
ke.g3 = &bn256.GT{}
g3, err := bn256.ScalarMultGT(ke.g2, ke.r.Bytes(orderNat))
if err != nil {
return nil, nil, err
}
ke.g3 = g3
// step 6, verify signature
if len(sB) > 0 {
signature := ke.sign(false, 0x82)
if goSubtle.ConstantTimeCompare(signature, sB) != 1 {
return nil, nil, errors.New("sm9: invalid responder's signature")
}
}
key, err := ke.generateSharedKey(false)
if err != nil {
return nil, nil, err
}
if !ke.genSignature {
return key, nil, nil
}
return key, ke.sign(false, 0x83), nil
}
// ConfirmInitiator for responder's step B8
func (ke *KeyExchange) ConfirmInitiator(s1 []byte) ([]byte, error) {
if s1 != nil {
buffer := ke.sign(true, 0x83)
if goSubtle.ConstantTimeCompare(buffer, s1) != 1 {
return nil, errors.New("sm9: invalid initiator's signature")
}
}
return ke.generateSharedKey(true)
}

510
internal/sm9/sm9_key.go Normal file
View File

@ -0,0 +1,510 @@
package sm9
import (
_subtle "crypto/subtle"
"encoding/binary"
"errors"
"io"
"math/bits"
"sync"
"slices"
"github.com/emmansun/gmsm/internal/bigmod"
"github.com/emmansun/gmsm/internal/randutil"
"github.com/emmansun/gmsm/internal/sm9/bn256"
"github.com/emmansun/gmsm/internal/subtle"
)
// SignMasterPrivateKey master private key for sign, generated by KGC
type SignMasterPrivateKey struct {
*SignMasterPublicKey // master public key
privateKey []byte // master private key
}
// SignMasterPublicKey master public key for sign, generated by KGC
type SignMasterPublicKey struct {
MasterPublicKey *bn256.G2 // master public key
pairOnce sync.Once
basePoint *bn256.GT // the result of Pair(Gen1, pub.MasterPublicKey)
tableGenOnce sync.Once
table *[32 * 2]bn256.GTFieldTable // precomputed basePoint^n
}
// SignPrivateKey user private key for sign, generated by KGC
type SignPrivateKey struct {
PrivateKey *bn256.G1 // user private key
*SignMasterPublicKey // master public key
}
// EncryptMasterPrivateKey master private key for encryption, generated by KGC
type EncryptMasterPrivateKey struct {
*EncryptMasterPublicKey // master public key
privateKey []byte // master private key
}
// EncryptMasterPublicKey master private key for encryption, generated by KGC
type EncryptMasterPublicKey struct {
MasterPublicKey *bn256.G1 // public key
pairOnce sync.Once
basePoint *bn256.GT // the result of Pair(pub.MasterPublicKey, Gen2)
tableGenOnce sync.Once
table *[32 * 2]bn256.GTFieldTable // precomputed basePoint^n
}
// EncryptPrivateKey user private key for encryption, generated by KGC
type EncryptPrivateKey struct {
PrivateKey *bn256.G2 // user private key
*EncryptMasterPublicKey // master public key
}
// GenerateSignMasterKey generates a master public and private key pair for DSA usage.
func GenerateSignMasterKey(rand io.Reader) (*SignMasterPrivateKey, error) {
key := make([]byte, len(bn256.OrderMinus1Bytes))
randutil.MaybeReadByte(rand)
for {
if _, err := io.ReadFull(rand, key); err != nil {
return nil, err
}
// In tests, rand will return all zeros and NewPrivateKey will reject
// the zero key as it generates the identity as a public key. This also
// makes this function consistent with crypto/elliptic.GenerateKey.
key[1] ^= 0x42
k, err := NewSignMasterPrivateKey(key)
if err == errInvalidPrivateKey {
continue
}
return k, err
}
}
// NewSignMasterPrivateKey creates a new SignMasterPrivateKey from the given byte slice.
// The provided key must have the same length as bn256.OrderMinus1Bytes and must be less than bn256.OrderMinus1Bytes.
// If the key is invalid, an error is returned.
//
// Parameters:
// - key: A byte slice representing the master private key.
//
// Returns:
// - *SignMasterPrivateKey: A pointer to the newly created SignMasterPrivateKey.
// - error: An error if the key is invalid or if there is an issue during key generation.
func NewSignMasterPrivateKey(key []byte) (*SignMasterPrivateKey, error) {
if len(key) != len(bn256.OrderMinus1Bytes) {
return nil, errors.New("sm9: invalid master sign private key size")
}
if subtle.ConstantTimeAllZero(key) == 1 || !isLess(key, bn256.OrderMinus1Bytes) {
return nil, errInvalidPrivateKey
}
p, err := new(bn256.G2).ScalarBaseMult(key)
if err != nil {
return nil, err
}
priv := new(SignMasterPrivateKey)
priv.privateKey = append([]byte{}, key...)
priv.SignMasterPublicKey = new(SignMasterPublicKey)
priv.MasterPublicKey = p
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.MasterPublicKey.Equal(x.MasterPublicKey) && _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)
}
// GenerateUserKey generate an user dsa key.
func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*SignPrivateKey, error) {
var id []byte
id = append(append(id, uid...), hid)
t1Nat := hashH1(id)
d, err := bigmod.NewNat().SetBytes(master.privateKey, orderNat)
if err != nil {
return nil, err
}
t1Nat.Add(d, orderNat)
if t1Nat.IsZero() == 1 {
return nil, errors.New("sm9: need to re-generate sign master private key")
}
t1Nat = bigmod.NewNat().Exp(t1Nat, bn256.OrderMinus2Bytes, orderNat)
t1Nat.Mul(d, orderNat)
priv := new(SignPrivateKey)
priv.SignMasterPublicKey = master.SignMasterPublicKey
g1, err := new(bn256.G1).ScalarBaseMult(t1Nat.Bytes(orderNat))
if err != nil {
return nil, err
}
priv.PrivateKey = g1
return priv, nil
}
// Public returns the public key corresponding to priv.
func (master *SignMasterPrivateKey) Public() *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 {
return pub.MasterPublicKey.Equal(x.MasterPublicKey)
}
// 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()
}
// pair generate the basepoint once
func (pub *SignMasterPublicKey) pair() *bn256.GT {
pub.pairOnce.Do(func() {
pub.basePoint = bn256.Pair(bn256.Gen1, pub.MasterPublicKey)
})
return pub.basePoint
}
func (pub *SignMasterPublicKey) generatorTable() *[32 * 2]bn256.GTFieldTable {
pub.tableGenOnce.Do(func() {
pub.table = bn256.GenerateGTFieldTable(pub.pair())
})
return pub.table
}
// ScalarBaseMult compute basepoint^r with precomputed table
// The base point = pair(Gen1, <master public key>)
func (pub *SignMasterPublicKey) ScalarBaseMult(scalar []byte) (*bn256.GT, error) {
tables := pub.generatorTable()
return bn256.ScalarBaseMultGT(tables, scalar)
}
// GenerateUserPublicKey generate user sign public key
func (pub *SignMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *bn256.G2 {
var buffer []byte
buffer = append(append(buffer, uid...), hid)
h1 := hashH1(buffer)
p, err := new(bn256.G2).ScalarBaseMult(h1.Bytes(orderNat))
if err != nil {
panic(err)
}
p.Add(p, pub.MasterPublicKey)
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()
}
// MasterPublic returns the master public key corresponding to priv.
func (priv *SignPrivateKey) MasterPublic() *SignMasterPublicKey {
return priv.SignMasterPublicKey
}
// SetMasterPublicKey bind the sign master public key to it.
func (priv *SignPrivateKey) SetMasterPublicKey(pub *SignMasterPublicKey) {
if priv.SignMasterPublicKey == nil || priv.SignMasterPublicKey.MasterPublicKey == nil {
priv.SignMasterPublicKey = pub
}
}
func unmarshalG2(bytes []byte) (*bn256.G2, error) {
g2 := new(bn256.G2)
switch bytes[0] {
case 4:
_, err := g2.Unmarshal(bytes[1:])
if err != nil {
return nil, err
}
case 2, 3:
_, err := g2.UnmarshalCompressed(bytes)
if err != nil {
return nil, err
}
default:
return nil, errors.New("sm9: invalid point identity byte")
}
return g2, nil
}
// UnmarshalRaw unmarsal raw bytes data to sign master public key
func (pub *SignMasterPublicKey) UnmarshalRaw(bytes []byte) error {
g2, err := unmarshalG2(bytes)
if err != nil {
return err
}
pub.MasterPublicKey = g2
return nil
}
func unmarshalG1(bytes []byte) (*bn256.G1, error) {
g := new(bn256.G1)
switch bytes[0] {
case 4:
_, err := g.Unmarshal(bytes[1:])
if err != nil {
return nil, err
}
case 2, 3:
_, err := g.UnmarshalCompressed(bytes)
if err != nil {
return nil, err
}
default:
return nil, errors.New("sm9: invalid point identity byte")
}
return g, nil
}
// UnmarshalRaw unmarsal raw bytes data to sign user private key
// Note, priv's SignMasterPublicKey should be handled separately.
func (priv *SignPrivateKey) UnmarshalRaw(bytes []byte) error {
g, err := unmarshalG1(bytes)
if err != nil {
return err
}
priv.PrivateKey = g
return nil
}
// GenerateEncryptMasterKey generates a master public and private key pair for encryption usage.
func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error) {
key := make([]byte, len(bn256.OrderMinus1Bytes))
randutil.MaybeReadByte(rand)
for {
if _, err := io.ReadFull(rand, key); err != nil {
return nil, err
}
// In tests, rand will return all zeros and NewPrivateKey will reject
// the zero key as it generates the identity as a public key. This also
// makes this function consistent with crypto/elliptic.GenerateKey.
key[1] ^= 0x42
k, err := NewEncryptMasterPrivateKey(key)
if err == errInvalidPrivateKey {
continue
}
return k, err
}
}
// NewEncryptMasterPrivateKey creates a new EncryptMasterPrivateKey from the given key bytes.
// The key must have a length equal to bn256.OrderMinus1Bytes. If the key is all zeros or not
// less than bn256.OrderMinus1Bytes, an error is returned.
//
// Parameters:
// - key: A byte slice representing the master private key.
//
// Returns:
// - *EncryptMasterPrivateKey: A pointer to the newly created EncryptMasterPrivateKey.
// - error: An error if the key is invalid or if there is an issue during key generation.
func NewEncryptMasterPrivateKey(key []byte) (*EncryptMasterPrivateKey, error) {
if len(key) != len(bn256.OrderMinus1Bytes) {
return nil, errors.New("sm9: invalid master encrypt private key size")
}
if subtle.ConstantTimeAllZero(key) == 1 || !isLess(key, bn256.OrderMinus1Bytes) {
return nil, errInvalidPrivateKey
}
p, err := new(bn256.G1).ScalarBaseMult(key)
if err != nil {
return nil, err
}
priv := new(EncryptMasterPrivateKey)
priv.privateKey = append([]byte{}, key...)
priv.EncryptMasterPublicKey = new(EncryptMasterPublicKey)
priv.MasterPublicKey = p
return priv, nil
}
// Bytes returns a copy of the private key bytes from the EncryptMasterPrivateKey.
// 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 append([]byte{}, 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
}
// GenerateUserKey generate an user key for encryption.
func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*EncryptPrivateKey, error) {
var id []byte
id = append(append(id, uid...), hid)
t1Nat := hashH1(id)
d, err := bigmod.NewNat().SetBytes(master.privateKey, orderNat)
if err != nil {
return nil, err
}
t1Nat.Add(d, orderNat)
if t1Nat.IsZero() == 1 {
return nil, errors.New("sm9: need to re-generate encrypt master private key")
}
t1Nat = bigmod.NewNat().Exp(t1Nat, bn256.OrderMinus2Bytes, orderNat)
t1Nat.Mul(d, orderNat)
priv := new(EncryptPrivateKey)
priv.EncryptMasterPublicKey = master.EncryptMasterPublicKey
p, err := new(bn256.G2).ScalarBaseMult(t1Nat.Bytes(orderNat))
if err != nil {
panic(err)
}
priv.PrivateKey = p
return priv, nil
}
// Public returns the public key corresponding to priv.
func (master *EncryptMasterPrivateKey) Public() *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 {
return pub.MasterPublicKey.Equal(x.MasterPublicKey)
}
func (pub *EncryptMasterPublicKey) Bytes() []byte {
return pub.MasterPublicKey.MarshalUncompressed()
}
// pair generate the basepoint once
func (pub *EncryptMasterPublicKey) pair() *bn256.GT {
pub.pairOnce.Do(func() {
pub.basePoint = bn256.Pair(pub.MasterPublicKey, bn256.Gen2)
})
return pub.basePoint
}
func (pub *EncryptMasterPublicKey) generatorTable() *[32 * 2]bn256.GTFieldTable {
pub.tableGenOnce.Do(func() {
pub.table = bn256.GenerateGTFieldTable(pub.pair())
})
return pub.table
}
// ScalarBaseMult compute basepoint^r with precomputed table.
// The base point = pair(<master public key>, Gen2)
func (pub *EncryptMasterPublicKey) ScalarBaseMult(scalar []byte) (*bn256.GT, error) {
tables := pub.generatorTable()
return bn256.ScalarBaseMultGT(tables, scalar)
}
// GenerateUserPublicKey generate user encrypt public key
func (pub *EncryptMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *bn256.G1 {
var buffer []byte
buffer = append(append(buffer, uid...), hid)
h1 := hashH1(buffer)
p, err := new(bn256.G1).ScalarBaseMult(h1.Bytes(orderNat))
if err != nil {
panic(err)
}
p.Add(p, pub.MasterPublicKey)
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()
}
// MasterPublic returns the master public key corresponding to priv.
func (priv *EncryptPrivateKey) MasterPublic() *EncryptMasterPublicKey {
return priv.EncryptMasterPublicKey
}
// SetMasterPublicKey bind the encrypt master public key to it.
func (priv *EncryptPrivateKey) SetMasterPublicKey(pub *EncryptMasterPublicKey) {
if priv.EncryptMasterPublicKey == nil || priv.EncryptMasterPublicKey.MasterPublicKey == nil {
priv.EncryptMasterPublicKey = pub
}
}
// UnmarshalRaw unmarsal raw bytes data to encrypt master public key
func (pub *EncryptMasterPublicKey) UnmarshalRaw(bytes []byte) error {
g, err := unmarshalG1(bytes)
if err != nil {
return err
}
pub.MasterPublicKey = g
return nil
}
// UnmarshalRaw unmarsal raw bytes data to encrypt user private key
// Note, priv's EncryptMasterPublicKey should be handled separately.
func (priv *EncryptPrivateKey) UnmarshalRaw(bytes []byte) error {
g, err := unmarshalG2(bytes)
if err != nil {
return err
}
priv.PrivateKey = g
return nil
}
// isLess returns whether a < b, where a and b are big-endian buffers of the
// same length and shorter than 72 bytes.
func isLess(a, b []byte) bool {
if len(a) != len(b) {
panic("sm9: internal error: mismatched isLess inputs")
}
// Copy the values into a fixed-size preallocated little-endian buffer.
// 72 bytes is enough for every scalar in this package, and having a fixed
// size lets us avoid heap allocations.
if len(a) > 72 {
panic("sm9: internal error: isLess input too large")
}
bufA, bufB := make([]byte, 72), make([]byte, 72)
for i := range a {
bufA[i], bufB[i] = a[len(a)-i-1], b[len(b)-i-1]
}
// Perform a subtraction with borrow.
var borrow uint64
for i := 0; i < len(bufA); i += 8 {
limbA, limbB := binary.LittleEndian.Uint64(bufA[i:]), binary.LittleEndian.Uint64(bufB[i:])
_, borrow = bits.Sub64(limbA, limbB, borrow)
}
// If there is a borrow at the end of the operation, then a < b.
return borrow == 1
}
var errInvalidPrivateKey = errors.New("sm9: invalid private key")

View File

@ -0,0 +1,40 @@
package sm9
import (
"crypto/rand"
"testing"
)
func BenchmarkGenerateSignPrivKey(b *testing.B) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := masterKey.GenerateUserKey(uid, hid); err != nil {
b.Fatal(err)
}
}
}
func BenchmarkGenerateEncryptPrivKey(b *testing.B) {
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := masterKey.GenerateUserKey(uid, hid); err != nil {
b.Fatal(err)
}
}
}

596
internal/sm9/sm9_test.go Normal file
View File

@ -0,0 +1,596 @@
package sm9
import (
"bytes"
"crypto/rand"
"crypto/subtle"
"encoding/hex"
"math/big"
"testing"
"github.com/emmansun/gmsm/internal/alias"
"github.com/emmansun/gmsm/internal/bigmod"
"github.com/emmansun/gmsm/internal/sm3"
"github.com/emmansun/gmsm/internal/sm4"
"github.com/emmansun/gmsm/internal/sm9/bn256"
)
func TestHashH1(t *testing.T) {
expected := "2acc468c3926b0bdb2767e99ff26e084de9ced8dbc7d5fbf418027b667862fab"
h := hashH1([]byte{0x41, 0x6c, 0x69, 0x63, 0x65, 0x01})
if hex.EncodeToString(h.Bytes(orderNat)) != expected {
t.Errorf("got %v, expected %v", h.Bytes(orderNat), expected)
}
}
func TestHashH2(t *testing.T) {
expected := "823c4b21e4bd2dfe1ed92c606653e996668563152fc33f55d7bfbb9bd9705adb"
zStr := "4368696E65736520494253207374616E6461726481377B8FDBC2839B4FA2D0E0F8AA6853BBBE9E9C4099608F8612C6078ACD7563815AEBA217AD502DA0F48704CC73CABB3C06209BD87142E14CBD99E8BCA1680F30DADC5CD9E207AEE32209F6C3CA3EC0D800A1A42D33C73153DED47C70A39D2E8EAF5D179A1836B359A9D1D9BFC19F2EFCDB829328620962BD3FDF15F2567F58A543D25609AE943920679194ED30328BB33FD15660BDE485C6B79A7B32B013983F012DB04BA59FE88DB889321CC2373D4C0C35E84F7AB1FF33679BCA575D67654F8624EB435B838CCA77B2D0347E65D5E46964412A096F4150D8C5EDE5440DDF0656FCB663D24731E80292188A2471B8B68AA993899268499D23C89755A1A89744643CEAD40F0965F28E1CD2895C3D118E4F65C9A0E3E741B6DD52C0EE2D25F5898D60848026B7EFB8FCC1B2442ECF0795F8A81CEE99A6248F294C82C90D26BD6A814AAF475F128AEF43A128E37F80154AE6CB92CAD7D1501BAE30F750B3A9BD1F96B08E97997363911314705BFB9A9DBB97F75553EC90FBB2DDAE53C8F68E42"
z, err := hex.DecodeString(zStr)
if err != nil {
t.Fatal(err)
}
h := hashH2(z)
if hex.EncodeToString(h.Bytes(orderNat)) != expected {
t.Errorf("got %v, expected %v", h.Bytes(orderNat), expected)
}
}
func TestSign(t *testing.T) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
h, s, err := userKey.Sign(rand.Reader, hashed, nil)
if err != nil {
t.Fatal(err)
}
if !masterKey.Public().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()) {
t.Errorf("Verify with s=-s succeeded")
}
hashed[0] ^= 0xff
if masterKey.Public().Verify(uid, hid, hashed, h, s) {
t.Errorf("Verify always works!")
}
}
func TestNegativeInputs(t *testing.T) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
t.Fatal(err)
}
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()) {
t.Errorf("bogus signature accepted")
}
}
func TestZeroSignature(t *testing.T) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
t.Fatal(err)
}
if masterKey.Public().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()) {
t.Error("Verify with h=order succeeded")
}
}
// SM9 Appendix A
func TestSignSM9Sample(t *testing.T) {
expectedH, _ := hex.DecodeString("823c4b21e4bd2dfe1ed92c606653e996668563152fc33f55d7bfbb9bd9705adb")
expectedHNat, err := bigmod.NewNat().SetBytes(expectedH, orderNat)
if err != nil {
t.Fatal(err)
}
expectedS := "0473bf96923ce58b6ad0e13e9643a406d8eb98417c50ef1b29cef9adb48b6d598c856712f1c2e0968ab7769f42a99586aed139d5b8b3e15891827cc2aced9baa05"
hash := []byte("Chinese IBS standard")
hid := byte(0x01)
uid := []byte("Alice")
r, _ := hex.DecodeString("033c8616b06704813203dfd00965022ed15975c662337aed648835dc4b1cbe")
rNat, err := bigmod.NewNat().SetBytes(r, orderNat)
if err != nil {
t.Fatal(err)
}
kb, _ := hex.DecodeString("000130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4")
masterKey, err := NewSignMasterPrivateKey(kb)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
w, err := userKey.SignMasterPublicKey.ScalarBaseMult(bn256.NormalizeScalar(r))
if err != nil {
t.Fatal(err)
}
var buffer []byte
buffer = append(buffer, hash...)
buffer = append(buffer, w.Marshal()...)
h := hashH2(buffer)
if h.Equal(expectedHNat) == 0 {
t.Fatal("not same h")
}
rNat.Sub(h, orderNat)
s, err := new(bn256.G1).ScalarMult(userKey.PrivateKey, rNat.Bytes(orderNat))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(s.MarshalUncompressed()) != expectedS {
t.Fatal("not same S")
}
}
func TestWrapKey(t *testing.T) {
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
key, cipher, err := masterKey.Public().WrapKey(rand.Reader, uid, hid, 16)
if err != nil {
t.Fatal(err)
}
key2, err := userKey.UnwrapKey(uid, cipher, 16)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(key, key2) {
t.Errorf("expected %x, got %x", key, key2)
}
}
// SM9 Appendix C
func TestWrapKeySM9Sample(t *testing.T) {
expectedMasterPublicKey := "787ed7b8a51f3ab84e0a66003f32da5c720b17eca7137d39abc66e3c80a892ff769de61791e5adc4b9ff85a31354900b202871279a8c49dc3f220f644c57a7b1"
expectedUserPrivateKey := "94736acd2c8c8796cc4785e938301a139a059d3537b6414140b2d31eecf41683115bae85f5d8bc6c3dbd9e5342979acccf3c2f4f28420b1cb4f8c0b59a19b1587aa5e47570da7600cd760a0cf7beaf71c447f3844753fe74fa7ba92ca7d3b55f27538a62e7f7bfb51dce08704796d94c9d56734f119ea44732b50e31cdeb75c1"
expectedUserPublicKey := "709d165808b0a43e2574e203fa885abcbab16a240c4c1916552e7c43d09763b8693269a6be2456f43333758274786b6051ff87b7f198da4ba1a2c6e336f51fcc"
expectedCipher := "1edee2c3f465914491de44cefb2cb434ab02c308d9dc5e2067b4fed5aaac8a0f1c9b4c435eca35ab83bb734174c0f78fde81a53374aff3b3602bbc5e37be9a4c"
expectedKey := "4ff5cf86d2ad40c8f4bac98d76abdbde0c0e2f0a829d3f911ef5b2bce0695480"
kb, _ := hex.DecodeString("0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
masterKey, err := NewEncryptMasterPrivateKey(kb)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedMasterPublicKey {
t.Errorf("not expected master public key")
}
uid := []byte("Bob")
hid := byte(0x03)
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(userKey.PrivateKey.Marshal()) != expectedUserPrivateKey {
t.Errorf("not expected user private key")
}
q := masterKey.Public().GenerateUserPublicKey(uid, hid)
if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey {
t.Errorf("not expected user public key")
}
rb, _ := hex.DecodeString("74015F8489C01EF4270456F9E6475BFB602BDE7F33FD482AB4E3684A6722")
var r *big.Int = new(big.Int).SetBytes(rb)
cipher, err := new(bn256.G1).ScalarMult(q, bn256.NormalizeScalar(r.Bytes()))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(cipher.Marshal()) != expectedCipher {
t.Errorf("not expected cipher")
}
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, 32)
if hex.EncodeToString(key) != expectedKey {
t.Errorf("expected %v, got %v\n", expectedKey, hex.EncodeToString(key))
}
key2, err := userKey.UnwrapKey(uid, cipher.MarshalUncompressed(), 32)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key2) != expectedKey {
t.Errorf("expected %v, got %v\n", expectedKey, hex.EncodeToString(key2))
}
}
// SM9 Appendix D
func TestEncryptSM9Sample(t *testing.T) {
plaintext := []byte("Chinese IBE standard")
expectedMasterPublicKey := "787ed7b8a51f3ab84e0a66003f32da5c720b17eca7137d39abc66e3c80a892ff769de61791e5adc4b9ff85a31354900b202871279a8c49dc3f220f644c57a7b1"
expectedUserPrivateKey := "94736acd2c8c8796cc4785e938301a139a059d3537b6414140b2d31eecf41683115bae85f5d8bc6c3dbd9e5342979acccf3c2f4f28420b1cb4f8c0b59a19b1587aa5e47570da7600cd760a0cf7beaf71c447f3844753fe74fa7ba92ca7d3b55f27538a62e7f7bfb51dce08704796d94c9d56734f119ea44732b50e31cdeb75c1"
expectedUserPublicKey := "709d165808b0a43e2574e203fa885abcbab16a240c4c1916552e7c43d09763b8693269a6be2456f43333758274786b6051ff87b7f198da4ba1a2c6e336f51fcc"
expectedCipher := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0"
expectedKey := "58373260f067ec48667c21c144f8bc33cd3049788651ffd5f738003e51df31174d0e4e402fd87f4581b612f74259db574f67ece6"
expectedCiphertext := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0ba672387bcd6de5016a158a52bb2e7fc429197bcab70b25afee37a2b9db9f3671b5f5b0e951489682f3e64e1378cdd5da9513b1c"
kb, _ := hex.DecodeString("0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
masterKey, err := NewEncryptMasterPrivateKey(kb)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedMasterPublicKey {
t.Errorf("not expected master public key")
}
uid := []byte("Bob")
hid := byte(0x03)
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(userKey.PrivateKey.Marshal()) != expectedUserPrivateKey {
t.Errorf("not expected user private key")
}
q := masterKey.Public().GenerateUserPublicKey(uid, hid)
if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey {
t.Errorf("not expected user public key")
}
rb, _ := hex.DecodeString("AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE8BB5EE2CBE5EC9E785C")
var r *big.Int = new(big.Int).SetBytes(rb)
cipher, err := new(bn256.G1).ScalarMult(q, bn256.NormalizeScalar(r.Bytes()))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(cipher.Marshal()) != expectedCipher {
t.Errorf("not expected cipher")
}
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, len(plaintext)+32)
if hex.EncodeToString(key) != expectedKey {
t.Errorf("not expected key")
}
subtle.XORBytes(key, key[:len(plaintext)], plaintext)
hash := sm3.New()
hash.Write(key)
c3 := hash.Sum(nil)
ciphertext := append(cipher.Marshal(), c3...)
ciphertext = append(ciphertext, key[:len(plaintext)]...)
if hex.EncodeToString(ciphertext) != expectedCiphertext {
t.Errorf("expected %v, got %v\n", expectedCiphertext, hex.EncodeToString(ciphertext))
}
}
func TestEncryptSM9SampleBlockMode(t *testing.T) {
plaintext := []byte("Chinese IBE standard")
expectedMasterPublicKey := "787ed7b8a51f3ab84e0a66003f32da5c720b17eca7137d39abc66e3c80a892ff769de61791e5adc4b9ff85a31354900b202871279a8c49dc3f220f644c57a7b1"
expectedUserPrivateKey := "94736acd2c8c8796cc4785e938301a139a059d3537b6414140b2d31eecf41683115bae85f5d8bc6c3dbd9e5342979acccf3c2f4f28420b1cb4f8c0b59a19b1587aa5e47570da7600cd760a0cf7beaf71c447f3844753fe74fa7ba92ca7d3b55f27538a62e7f7bfb51dce08704796d94c9d56734f119ea44732b50e31cdeb75c1"
expectedUserPublicKey := "709d165808b0a43e2574e203fa885abcbab16a240c4c1916552e7c43d09763b8693269a6be2456f43333758274786b6051ff87b7f198da4ba1a2c6e336f51fcc"
expectedCipher := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0"
expectedKey := "58373260f067ec48667c21c144f8bc33cd3049788651ffd5f738003e51df31174d0e4e402fd87f4581b612f74259db57"
expectedCiphertext := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0fd3c98dd92c44c68332675a370cceede31e0c5cd209c257601149d12b394a2bee05b6fac6f11b965268c994f00dba7a8bb00fd60583546cbdf4649250863f10a"
kb, _ := hex.DecodeString("0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
masterKey, err := NewEncryptMasterPrivateKey(kb)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedMasterPublicKey {
t.Errorf("not expected master public key")
}
uid := []byte("Bob")
hid := byte(0x03)
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(userKey.PrivateKey.Marshal()) != expectedUserPrivateKey {
t.Errorf("not expected user private key")
}
q := masterKey.Public().GenerateUserPublicKey(uid, hid)
if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey {
t.Errorf("not expected user public key")
}
rb, _ := hex.DecodeString("AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE8BB5EE2CBE5EC9E785C")
var r *big.Int = new(big.Int).SetBytes(rb)
cipher, err := new(bn256.G1).ScalarMult(q, bn256.NormalizeScalar(r.Bytes()))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(cipher.Marshal()) != expectedCipher {
t.Errorf("not expected cipher")
}
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, 16+32)
if hex.EncodeToString(key) != expectedKey {
t.Errorf("not expected key, expected %v, got %x\n", expectedKey, key)
}
// ECB mode with PKCS7 padding
block, err := sm4.NewCipher(key[:16])
if err != nil {
t.Fatal(err)
}
overhead := sm4.BlockSize - len(plaintext)%sm4.BlockSize
c2, out := alias.SliceForAppend(plaintext, overhead)
for i := range overhead {
out[i] = byte(overhead)
}
ret := c2
for len(ret) > 0 {
block.Encrypt(ret, ret)
ret = ret[sm4.BlockSize:]
}
hash := sm3.New()
hash.Write(c2)
hash.Write(key[16:])
c3 := hash.Sum(nil)
ciphertext := append(cipher.Marshal(), c3...)
ciphertext = append(ciphertext, c2...)
if hex.EncodeToString(ciphertext) != expectedCiphertext {
t.Errorf("expected %v, got %v\n", expectedCiphertext, hex.EncodeToString(ciphertext))
}
}
func TestKeyExchange(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := userKey.NewKeyExchange(userA, userB, 16, true)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := userKey.NewKeyExchange(userB, userA, 16, true)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RespondKeyExchange(rand.Reader, hid, rA)
if err != nil {
t.Fatal(err)
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
// B8
key2, err := responder.ConfirmInitiator(sigA)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
}
}
func TestKeyExchangeWithoutSignature(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := userKey.NewKeyExchange(userA, userB, 16, false)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := userKey.NewKeyExchange(userB, userA, 16, false)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RespondKeyExchange(rand.Reader, hid, rA)
if err != nil {
t.Fatal(err)
}
if len(sigB) != 0 {
t.Errorf("should no signature")
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
if len(sigA) != 0 {
t.Errorf("should no signature")
}
key2, err := responder.ConfirmInitiator(nil)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
}
}
// SM9 Appendix B
func TestKeyExchangeSample(t *testing.T) {
hid := byte(0x02)
expectedPube := "9174542668e8f14ab273c0945c3690c66e5dd09678b86f734c4350567ed0628354e598c6bf749a3dacc9fffedd9db6866c50457cfc7aa2a4ad65c3168ff74210"
expectedKey := "c5c13a8f59a97cdeae64f16a2272a9e7"
expectedSignatureB := "3bb4bcee8139c960b4d6566db1e0d5f0b2767680e5e1bf934103e6c66e40ffee"
expectedSignatureA := "195d1b7256ba7e0e67c71202a25f8c94ff8241702c2f55d613ae1c6b98215172"
kb, _ := hex.DecodeString("0002E65B0762D042F51F0D23542B13ED8CFA2E9A0E7206361E013A283905E31F")
masterKey, err := NewEncryptMasterPrivateKey(kb)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedPube {
t.Errorf("not expected master public key")
}
userA := []byte("Alice")
userB := []byte("Bob")
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := userKey.NewKeyExchange(userA, userB, 16, true)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := userKey.NewKeyExchange(userB, userA, 16, true)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
b, _ := hex.DecodeString("5879DD1D51E175946F23B1B41E93BA31C584AE59A426EC1046A4D03B06C8")
k, err := bigmod.NewNat().SetBytes(b, orderNat)
if err != nil {
t.Fatal(err)
}
initKeyExchange(initiator, hid, k)
if hex.EncodeToString(initiator.secret) != "047cba5b19069ee66aa79d490413d11846b9ba76dd22567f809cf23b6d964bb265a9760c99cb6f706343fed05637085864958d6c90902aba7d405fbedf7b781599" {
t.Fatal("not same")
}
// B1 - B7
b, _ = hex.DecodeString("018B98C44BEF9F8537FB7D071B2C928B3BC65BD3D69E1EEE213564905634FE")
k, err = bigmod.NewNat().SetBytes(b, orderNat)
if err != nil {
t.Fatal(err)
}
rB, sigB, err := respondKeyExchange(responder, hid, k, initiator.secret)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(sigB) != expectedSignatureB {
t.Errorf("not expected signature B")
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != expectedKey {
t.Errorf("not expected key %v\n", hex.EncodeToString(key1))
}
if hex.EncodeToString(sigA) != expectedSignatureA {
t.Errorf("not expected signature A")
}
// B8
key2, err := responder.ConfirmInitiator(sigA)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key2) != expectedKey {
t.Errorf("not expected key %v\n", hex.EncodeToString(key2))
}
}

View File

@ -622,7 +622,7 @@ func TestMarshalPrivateKey(t *testing.T) {
t.Fatalf("%d: ParseSM9SignPrivateKey should return error", i)
}
if sm9SignMasterPrivateKey.D.Cmp(decodedSM9SignMasterPrivateKey.D) != 0 {
if !sm9SignMasterPrivateKey.Equal(decodedSM9SignMasterPrivateKey) {
t.Fatalf("%d: Decoded key does not match original key", i)
}
@ -642,7 +642,7 @@ func TestMarshalPrivateKey(t *testing.T) {
if err == nil {
t.Fatalf("%d: ParseSM9SignMasterPrivateKey should return error", i)
}
if !sm9SignPrivateKey.PrivateKey.Equal(decodedSM9SignPrivateKey.PrivateKey) {
if !sm9SignPrivateKey.Equal(decodedSM9SignPrivateKey) {
t.Fatalf("%d: Decoded key does not match original key", i)
}
@ -663,7 +663,7 @@ func TestMarshalPrivateKey(t *testing.T) {
if err == nil {
t.Fatalf("%d: ParseSM9EncryptPrivateKey should return error", i)
}
if sm9EncMasterPrivateKey.D.Cmp(decodedSM9EncMasterPrivateKey.D) != 0 {
if !sm9EncMasterPrivateKey.Equal(decodedSM9EncMasterPrivateKey) {
t.Fatalf("%d: Decoded key does not match original key", i)
}
@ -683,7 +683,7 @@ func TestMarshalPrivateKey(t *testing.T) {
if err == nil {
t.Fatalf("%d: ParseSM9EncryptMasterPrivateKey should return error", i)
}
if !sm9EncPrivateKey.PrivateKey.Equal(decodedSM9EncPrivateKey.PrivateKey) {
if !sm9EncPrivateKey.Equal(decodedSM9EncPrivateKey) {
t.Fatalf("%d: Decoded key does not match original key", i)
}

View File

@ -8,36 +8,13 @@ import (
"io"
"math/big"
"github.com/emmansun/gmsm/internal/bigmod"
"github.com/emmansun/gmsm/internal/byteorder"
"github.com/emmansun/gmsm/internal/randutil"
"github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/internal/sm9"
"github.com/emmansun/gmsm/sm3"
"github.com/emmansun/gmsm/sm9/bn256"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
)
// SM9 ASN.1 format reference: Information security technology - SM9 cryptographic algorithm application specification
var (
orderMinus2 []byte
orderNat *bigmod.Modulus
)
func init() {
orderMinus2 = new(big.Int).Sub(bn256.Order, big.NewInt(2)).Bytes()
orderNat, _ = bigmod.NewModulus(bn256.Order.Bytes())
}
type hashMode byte
const (
// hashmode used in h1: 0x01
H1 hashMode = 1 + iota
// hashmode used in h2: 0x02
H2
)
type encryptType byte
const (
@ -48,70 +25,6 @@ const (
ENC_TYPE_CFB encryptType = 8
)
// hash implements H1(Z,n) or H2(Z,n) in sm9 algorithm.
func hash(z []byte, h hashMode) *bigmod.Nat {
md := sm3.New()
var ha [64]byte
var countBytes [4]byte
var ct uint32 = 1
byteorder.BEPutUint32(countBytes[:], ct)
md.Write([]byte{byte(h)})
md.Write(z)
md.Write(countBytes[:])
copy(ha[:], md.Sum(nil))
ct++
md.Reset()
byteorder.BEPutUint32(countBytes[:], ct)
md.Write([]byte{byte(h)})
md.Write(z)
md.Write(countBytes[:])
copy(ha[sm3.Size:], md.Sum(nil))
return bigmod.NewNat().SetOverflowedBytes(ha[:40], orderNat)
}
func hashH1(z []byte) *bigmod.Nat {
return hash(z, H1)
}
func hashH2(z []byte) *bigmod.Nat {
return hash(z, H2)
}
func randomScalar(rand io.Reader) (k *bigmod.Nat, err error) {
k = bigmod.NewNat()
for {
b := make([]byte, orderNat.Size())
if _, err = io.ReadFull(rand, b); err != nil {
return
}
// Mask off any excess bits to increase the chance of hitting a value in
// (0, N). These are the most dangerous lines in the package and maybe in
// the library: a single bit of bias in the selection of nonces would likely
// lead to key recovery, but no tests would fail. Look but DO NOT TOUCH.
if excess := len(b)*8 - orderNat.BitLen(); excess > 0 {
// Just to be safe, assert that this only happens for the one curve that
// doesn't have a round number of bits.
if excess != 0 {
panic("sm9: internal error: unexpectedly masking off bits")
}
b[0] >>= excess
}
// FIPS 186-4 makes us check k <= N - 2 and then add one.
// Checking 0 < k <= N - 1 is strictly equivalent.
// None of this matters anyway because the chance of selecting
// zero is cryptographically negligible.
if _, err = k.SetBytes(b, orderNat); err == nil && k.IsZero() == 0 {
break
}
}
return
}
// Sign signs a hash (which should be the result of hashing a larger message)
// using the user dsa key. It returns the signature as a pair of h and s.
// Please use SignASN1 instead.
@ -119,12 +32,13 @@ func randomScalar(rand io.Reader) (k *bigmod.Nat, err error) {
// The signature is randomized. Most applications should use [crypto/rand.Reader]
// 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) (h *big.Int, s *bn256.G1, err error) {
sig, err := SignASN1(rand, priv, hash)
func Sign(rand io.Reader, priv *SignPrivateKey, hash []byte) (*big.Int, []byte, error) {
h, s, err := priv.privateKey.Sign(rand, hash, nil)
if err != nil {
return nil, nil, err
}
return parseSignatureLegacy(sig)
return new(big.Int).SetBytes(h), s, nil
}
// Sign signs digest with user's DSA key, reading randomness from rand. The opts argument
@ -135,7 +49,11 @@ func Sign(rand io.Reader, priv *SignPrivateKey, hash []byte) (h *big.Int, s *bn2
// 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) {
return SignASN1(rand, priv, hash)
h, s, err := priv.privateKey.Sign(rand, hash, opts)
if err != nil {
return nil, err
}
return encodeSignature(h, s)
}
// SignASN1 signs a hash (which should be the result of hashing a larger message)
@ -145,63 +63,28 @@ func (priv *SignPrivateKey) Sign(rand io.Reader, hash []byte, opts crypto.Signer
// 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 SignASN1(rand io.Reader, priv *SignPrivateKey, hash []byte) ([]byte, error) {
var (
hNat *bigmod.Nat
s *bn256.G1
)
randutil.MaybeReadByte(rand)
for {
r, err := randomScalar(rand)
if err != nil {
return nil, err
}
w, err := priv.SignMasterPublicKey.ScalarBaseMult(r.Bytes(orderNat))
if err != nil {
return nil, err
}
var buffer []byte
buffer = append(append(buffer, hash...), w.Marshal()...)
hNat = hashH2(buffer)
r.Sub(hNat, orderNat)
if r.IsZero() == 0 {
s, err = new(bn256.G1).ScalarMult(priv.PrivateKey, r.Bytes(orderNat))
if err != nil {
return nil, err
}
break
}
}
return encodeSignature(hNat.Bytes(orderNat), s)
return priv.Sign(rand, hash, nil)
}
// Verify verifies the signature in h, s of hash using the master dsa public key and user id, uid and hid.
// Its return value records whether the signature is valid. Please use VerifyASN1 instead.
func Verify(pub *SignMasterPublicKey, uid []byte, hid byte, hash []byte, h *big.Int, s *bn256.G1) bool {
func Verify(pub *SignMasterPublicKey, uid []byte, hid byte, hash []byte, h *big.Int, s []byte) bool {
if h.Sign() <= 0 {
return false
}
sig, err := encodeSignature(h.Bytes(), s)
if err != nil {
return false
}
return VerifyASN1(pub, uid, hid, hash, sig)
return pub.publicKey.Verify(uid, hid, hash, h.Bytes(), s)
}
func encodeSignature(hBytes []byte, s *bn256.G1) ([]byte, error) {
func encodeSignature(h, s []byte) ([]byte, error) {
var b cryptobyte.Builder
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
b.AddASN1OctetString(hBytes)
b.AddASN1BitString(s.MarshalUncompressed())
b.AddASN1OctetString(h)
b.AddASN1BitString(s)
})
return b.Bytes()
}
func parseSignature(sig []byte) ([]byte, *bn256.G1, error) {
func parseSignature(sig []byte) ([]byte, []byte, error) {
var (
hBytes []byte
sBytes []byte
@ -218,20 +101,7 @@ func parseSignature(sig []byte) ([]byte, *bn256.G1, error) {
if sBytes[0] != 4 {
return nil, nil, errors.New("sm9: invalid point format")
}
s := new(bn256.G1)
_, err := s.Unmarshal(sBytes[1:])
if err != nil {
return nil, nil, err
}
return hBytes, s, nil
}
func parseSignatureLegacy(sig []byte) (*big.Int, *bn256.G1, error) {
hBytes, s, err := parseSignature(sig)
if err != nil {
return nil, nil, err
}
return new(big.Int).SetBytes(hBytes), s, nil
return hBytes, sBytes, nil
}
// VerifyASN1 verifies the ASN.1 encoded signature of type SM9Signature, sig, of hash using the
@ -241,34 +111,7 @@ func VerifyASN1(pub *SignMasterPublicKey, uid []byte, hid byte, hash, sig []byte
if err != nil {
return false
}
if !s.IsOnCurve() {
return false
}
hNat, err := bigmod.NewNat().SetBytes(h, orderNat)
if err != nil {
return false
}
if hNat.IsZero() == 1 {
return false
}
t, err := pub.ScalarBaseMult(hNat.Bytes(orderNat))
if err != nil {
return false
}
// user sign public key p generation
p := pub.GenerateUserPublicKey(uid, hid)
u := bn256.Pair(s, p)
w := new(bn256.GT).Add(u, t)
var buffer []byte
buffer = append(append(buffer, hash...), w.Marshal()...)
h2 := hashH2(buffer)
return h2.Equal(hNat) == 1
return pub.publicKey.Verify(uid, hid, hash, h, s)
}
// Verify verifies the ASN.1 encoded signature, sig, of hash using the
@ -282,39 +125,8 @@ func (pub *SignMasterPublicKey) Verify(uid []byte, hid byte, hash, sig []byte) b
// The rand parameter is used as a source of entropy to ensure that
// 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) (key []byte, cipher *bn256.G1, err error) {
q := pub.GenerateUserPublicKey(uid, hid)
var (
r *bigmod.Nat
w *bn256.GT
)
for {
r, err = randomScalar(rand)
if err != nil {
return
}
rBytes := r.Bytes(orderNat)
cipher, err = new(bn256.G1).ScalarMult(q, rBytes)
if err != nil {
return
}
w, err = pub.ScalarBaseMult(rBytes)
if err != nil {
return
}
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key = sm3.Kdf(buffer, kLen)
if subtle.ConstantTimeAllZero(key) == 0 {
break
}
}
return
func WrapKey(rand io.Reader, pub *EncryptMasterPublicKey, uid []byte, hid byte, kLen int) ([]byte, []byte, error) {
return pub.publicKey.WrapKey(rand, uid, hid, kLen)
}
// WrapKey wraps key and converts the cipher as ASN1 format, SM9PublicKey1 definition.
@ -328,7 +140,7 @@ func (pub *EncryptMasterPublicKey) WrapKey(rand io.Reader, uid []byte, hid byte,
return nil, nil, err
}
var b cryptobyte.Builder
b.AddASN1BitString(cipher.MarshalUncompressed())
b.AddASN1BitString(cipher)
cipherASN1, err := b.Bytes()
return key, cipherASN1, err
@ -348,31 +160,25 @@ func (pub *EncryptMasterPublicKey) WrapKeyASN1(rand io.Reader, uid []byte, hid b
var b cryptobyte.Builder
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
b.AddASN1OctetString(key)
b.AddASN1BitString(cipher.MarshalUncompressed())
b.AddASN1BitString(cipher)
})
return b.Bytes()
}
// UnmarshalSM9KeyPackage is an utility to unmarshal SM9KeyPackage
func UnmarshalSM9KeyPackage(der []byte) ([]byte, *bn256.G1, error) {
func UnmarshalSM9KeyPackage(der []byte) (key []byte, cipher []byte, err error) {
input := cryptobyte.String(der)
var (
key []byte
cipherBytes []byte
inner cryptobyte.String
inner cryptobyte.String
)
if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
!input.Empty() ||
!inner.ReadASN1Bytes(&key, asn1.OCTET_STRING) ||
!inner.ReadASN1BitStringAsBytes(&cipherBytes) ||
!inner.ReadASN1BitStringAsBytes(&cipher) ||
!inner.Empty() {
return nil, nil, errors.New("sm9: invalid SM9KeyPackage asn.1 data")
}
g, err := unmarshalG1(cipherBytes)
if err != nil {
return nil, nil, err
}
return key, g, nil
return
}
// ErrDecryption represents a failure to decrypt a message.
@ -383,23 +189,8 @@ var ErrDecryption = errors.New("sm9: decryption error")
var ErrEmptyPlaintext = errors.New("sm9: empty plaintext")
// UnwrapKey unwraps key from cipher, user id and aligned key length
func UnwrapKey(priv *EncryptPrivateKey, uid []byte, cipher *bn256.G1, kLen int) ([]byte, error) {
if !cipher.IsOnCurve() {
return nil, ErrDecryption
}
w := bn256.Pair(cipher, priv.PrivateKey)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, kLen)
if subtle.ConstantTimeAllZero(key) == 1 {
return nil, ErrDecryption
}
return key, nil
func UnwrapKey(priv *EncryptPrivateKey, uid, cipher []byte, kLen int) ([]byte, error) {
return priv.privateKey.UnwrapKey(uid, cipher, kLen)
}
// UnwrapKey unwraps key from cipherDer, user id and aligned key length.
@ -410,11 +201,7 @@ func (priv *EncryptPrivateKey) UnwrapKey(uid, cipherDer []byte, kLen int) ([]byt
if !input.ReadASN1BitStringAsBytes(&bytes) || !input.Empty() {
return nil, ErrDecryption
}
g, err := unmarshalG1(bytes)
if err != nil {
return nil, ErrDecryption
}
return UnwrapKey(priv, uid, g, kLen)
return UnwrapKey(priv, uid, bytes, kLen)
}
// Encrypt encrypts plaintext, returns ciphertext with format C1||C3||C2.
@ -423,12 +210,12 @@ func Encrypt(rand io.Reader, pub *EncryptMasterPublicKey, uid []byte, hid byte,
if err != nil {
return nil, err
}
ciphertext := append(c1.Marshal(), c3...)
ciphertext := append(c1[1:], c3...)
ciphertext = append(ciphertext, c2...)
return ciphertext, nil
}
func encrypt(rand io.Reader, pub *EncryptMasterPublicKey, uid []byte, hid byte, plaintext []byte, opts EncrypterOpts) (c1 *bn256.G1, c2, c3 []byte, err error) {
func encrypt(rand io.Reader, pub *EncryptMasterPublicKey, uid []byte, hid byte, plaintext []byte, opts EncrypterOpts) (c1, c2, c3 []byte, err error) {
if opts == nil {
opts = DefaultEncrypterOpts
}
@ -473,7 +260,7 @@ func (pub *EncryptMasterPublicKey) Encrypt(rand io.Reader, uid []byte, hid byte,
var b cryptobyte.Builder
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
b.AddASN1Int64(int64(opts.GetEncryptType()))
b.AddASN1BitString(c1.MarshalUncompressed())
b.AddASN1BitString(c1)
b.AddASN1OctetString(c3)
b.AddASN1OctetString(c2)
})
@ -486,26 +273,21 @@ func Decrypt(priv *EncryptPrivateKey, uid, ciphertext []byte, opts EncrypterOpts
opts = DefaultEncrypterOpts
}
c := &bn256.G1{}
c3c2, err := c.Unmarshal(ciphertext)
if err != nil {
return nil, ErrDecryption
}
_ = c3c2[sm3.Size] // bounds check elimination hint
c1 := ciphertext[:64]
c3c2 := ciphertext[64:]
c3 := c3c2[:sm3.Size]
c2 := c3c2[sm3.Size:]
key1Len := opts.GetKeySize(c2)
key, err := UnwrapKey(priv, uid, c, key1Len+sm3.Size)
key, err := UnwrapKey(priv, uid, c1, key1Len+sm3.Size)
if err != nil {
return nil, err
}
_ = key[key1Len] // bounds check elimination hint
return decrypt(c, key[:key1Len], key[key1Len:], c2, c3, opts)
return decrypt(key[:key1Len], key[key1Len:], c2, c3, opts)
}
func decrypt(cipher *bn256.G1, key1, key2, c2, c3 []byte, opts EncrypterOpts) ([]byte, error) {
func decrypt(key1, key2, c2, c3 []byte, opts EncrypterOpts) ([]byte, error) {
hash := sm3.New()
hash.Write(c2)
hash.Write(key2)
@ -546,19 +328,14 @@ func DecryptASN1(priv *EncryptPrivateKey, uid, ciphertext []byte) ([]byte, error
if opts == nil {
return nil, ErrDecryption
}
c, err := unmarshalG1(c1Bytes)
if err != nil {
return nil, ErrDecryption
}
key1Len := opts.GetKeySize(c2Bytes)
key, err := UnwrapKey(priv, uid, c, key1Len+sm3.Size)
key, err := UnwrapKey(priv, uid, c1Bytes, key1Len+sm3.Size)
if err != nil {
return nil, err
}
_ = key[key1Len] // bounds check elimination hint
return decrypt(c, key[:key1Len], key[key1Len:], c2Bytes, c3Bytes, opts)
return decrypt(key[:key1Len], key[key1Len:], c2Bytes, c3Bytes, opts)
}
// Decrypt decrypts chipher, the ciphertext should be with format C1||C3||C2
@ -576,197 +353,33 @@ func (priv *EncryptPrivateKey) DecryptASN1(uid, ciphertext []byte) ([]byte, erro
// Initiator's flow will be: NewKeyExchange -> InitKeyExchange -> transmission -> ConfirmResponder
// Responder's flow will be: NewKeyExchange -> waiting ... -> RepondKeyExchange -> transmission -> ConfirmInitiator
type KeyExchange struct {
genSignature bool // control the optional sign/verify step triggered by responsder
keyLength int // key length
privateKey *EncryptPrivateKey // owner's encryption private key
uid []byte // owner uid
peerUID []byte // peer uid
r *bigmod.Nat // random which will be used to compute secret
secret *bn256.G1 // generated secret which will be passed to peer
peerSecret *bn256.G1 // received peer's secret
g1 *bn256.GT // internal state which will be used when compute the key and signature
g2 *bn256.GT // internal state which will be used when compute the key and signature
g3 *bn256.GT // internal state which will be used when compute the key and signature
ke *sm9.KeyExchange
}
// NewKeyExchange creates one new KeyExchange object
func NewKeyExchange(priv *EncryptPrivateKey, uid, peerUID []byte, keyLen int, genSignature bool) *KeyExchange {
ke := &KeyExchange{}
ke.genSignature = genSignature
ke.keyLength = keyLen
ke.privateKey = priv
ke.uid = uid
ke.peerUID = peerUID
return ke
func (priv *EncryptPrivateKey) NewKeyExchange(uid, peerUID []byte, keyLen int, genSignature bool) *KeyExchange {
return &KeyExchange{ke: priv.privateKey.NewKeyExchange(uid, peerUID, keyLen, genSignature)}
}
// Destroy clears all internal state and Ephemeral private/public keys
func (ke *KeyExchange) Destroy() {
if ke.r != nil {
ke.r.SetBytes([]byte{0}, orderNat)
}
if ke.g1 != nil {
ke.g1.SetOne()
}
if ke.g2 != nil {
ke.g2.SetOne()
}
if ke.g3 != nil {
ke.g3.SetOne()
}
}
func initKeyExchange(ke *KeyExchange, hid byte, r *bigmod.Nat) {
pubB := ke.privateKey.GenerateUserPublicKey(ke.peerUID, hid)
ke.r = r
rA, err := new(bn256.G1).ScalarMult(pubB, ke.r.Bytes(orderNat))
if err != nil {
panic(err)
}
ke.secret = rA
ke.ke.Destroy()
}
// InitKeyExchange generates random with responder uid, for initiator's step A1-A4
func (ke *KeyExchange) InitKeyExchange(rand io.Reader, hid byte) (*bn256.G1, error) {
r, err := randomScalar(rand)
if err != nil {
return nil, err
}
initKeyExchange(ke, hid, r)
return ke.secret, nil
func (ke *KeyExchange) InitKeyExchange(rand io.Reader, hid byte) ([]byte, error) {
return ke.ke.InitKeyExchange(rand, hid)
}
func (ke *KeyExchange) sign(isResponder bool, prefix byte) []byte {
var buffer []byte
hash := sm3.New()
hash.Write(ke.g2.Marshal())
hash.Write(ke.g3.Marshal())
if isResponder {
hash.Write(ke.peerUID)
hash.Write(ke.uid)
hash.Write(ke.peerSecret.Marshal())
hash.Write(ke.secret.Marshal())
} else {
hash.Write(ke.uid)
hash.Write(ke.peerUID)
hash.Write(ke.secret.Marshal())
hash.Write(ke.peerSecret.Marshal())
}
buffer = hash.Sum(nil)
hash.Reset()
hash.Write([]byte{prefix})
hash.Write(ke.g1.Marshal())
hash.Write(buffer)
return hash.Sum(nil)
}
func (ke *KeyExchange) generateSharedKey(isResponder bool) ([]byte, error) {
var buffer []byte
if isResponder {
buffer = append(buffer, ke.peerUID...)
buffer = append(buffer, ke.uid...)
buffer = append(buffer, ke.peerSecret.Marshal()...)
buffer = append(buffer, ke.secret.Marshal()...)
} else {
buffer = append(buffer, ke.uid...)
buffer = append(buffer, ke.peerUID...)
buffer = append(buffer, ke.secret.Marshal()...)
buffer = append(buffer, ke.peerSecret.Marshal()...)
}
buffer = append(buffer, ke.g1.Marshal()...)
buffer = append(buffer, ke.g2.Marshal()...)
buffer = append(buffer, ke.g3.Marshal()...)
return sm3.Kdf(buffer, ke.keyLength), nil
}
func respondKeyExchange(ke *KeyExchange, hid byte, r *bigmod.Nat, rA *bn256.G1) (*bn256.G1, []byte, error) {
if !rA.IsOnCurve() {
return nil, nil, errors.New("sm9: invalid initiator's ephemeral public key")
}
ke.peerSecret = rA
pubA := ke.privateKey.GenerateUserPublicKey(ke.peerUID, hid)
ke.r = r
rBytes := r.Bytes(orderNat)
rB, err := new(bn256.G1).ScalarMult(pubA, rBytes)
if err != nil {
return nil, nil, err
}
ke.secret = rB
ke.g1 = bn256.Pair(ke.peerSecret, ke.privateKey.PrivateKey)
ke.g3 = &bn256.GT{}
g3, err := bn256.ScalarMultGT(ke.g1, rBytes)
if err != nil {
return nil, nil, err
}
ke.g3 = g3
g2, err := ke.privateKey.EncryptMasterPublicKey.ScalarBaseMult(rBytes)
if err != nil {
return nil, nil, err
}
ke.g2 = g2
if !ke.genSignature {
return ke.secret, nil, nil
}
return ke.secret, ke.sign(true, 0x82), nil
}
// RepondKeyExchange when responder receive rA, for responder's step B1-B7
func (ke *KeyExchange) RepondKeyExchange(rand io.Reader, hid byte, rA *bn256.G1) (*bn256.G1, []byte, error) {
r, err := randomScalar(rand)
if err != nil {
return nil, nil, err
}
return respondKeyExchange(ke, hid, r, rA)
// RespondKeyExchange when responder receive rA, for responder's step B1-B7
func (ke *KeyExchange) RespondKeyExchange(rand io.Reader, hid byte, peerData []byte) ([]byte, []byte, error) {
return ke.ke.RespondKeyExchange(rand, hid, peerData)
}
// ConfirmResponder for initiator's step A5-A7
func (ke *KeyExchange) ConfirmResponder(rB *bn256.G1, sB []byte) ([]byte, []byte, error) {
if !rB.IsOnCurve() {
return nil, nil, errors.New("sm9: invalid responder's ephemeral public key")
}
// step 5
ke.peerSecret = rB
g1, err := ke.privateKey.EncryptMasterPublicKey.ScalarBaseMult(ke.r.Bytes(orderNat))
if err != nil {
return nil, nil, err
}
ke.g1 = g1
ke.g2 = bn256.Pair(ke.peerSecret, ke.privateKey.PrivateKey)
ke.g3 = &bn256.GT{}
g3, err := bn256.ScalarMultGT(ke.g2, ke.r.Bytes(orderNat))
if err != nil {
return nil, nil, err
}
ke.g3 = g3
// step 6, verify signature
if len(sB) > 0 {
signature := ke.sign(false, 0x82)
if goSubtle.ConstantTimeCompare(signature, sB) != 1 {
return nil, nil, errors.New("sm9: invalid responder's signature")
}
}
key, err := ke.generateSharedKey(false)
if err != nil {
return nil, nil, err
}
if !ke.genSignature {
return key, nil, nil
}
return key, ke.sign(false, 0x83), nil
func (ke *KeyExchange) ConfirmResponder(rB, sB []byte) ([]byte, []byte, error) {
return ke.ke.ConfirmResponder(rB, sB)
}
// ConfirmInitiator for responder's step B8
func (ke *KeyExchange) ConfirmInitiator(s1 []byte) ([]byte, error) {
if s1 != nil {
buffer := ke.sign(true, 0x83)
if goSubtle.ConstantTimeCompare(buffer, s1) != 1 {
return nil, errors.New("sm9: invalid initiator's signature")
}
}
return ke.generateSharedKey(true)
func (ke *KeyExchange) ConfirmInitiator(peerData []byte) ([]byte, error) {
return ke.ke.ConfirmInitiator(peerData)
}

View File

@ -6,80 +6,69 @@ import (
"errors"
"io"
"math/big"
"sync"
"github.com/emmansun/gmsm/internal/bigmod"
"github.com/emmansun/gmsm/sm9/bn256"
"github.com/emmansun/gmsm/internal/sm9"
"golang.org/x/crypto/cryptobyte"
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
)
// SignMasterPrivateKey master private key for sign, generated by KGC
type SignMasterPrivateKey struct {
*SignMasterPublicKey // master public key
D *big.Int // master private key
privateKey *sm9.SignMasterPrivateKey
}
// SignMasterPublicKey master public key for sign, generated by KGC
type SignMasterPublicKey struct {
MasterPublicKey *bn256.G2 // master public key
pairOnce sync.Once
basePoint *bn256.GT // the result of Pair(Gen1, pub.MasterPublicKey)
tableGenOnce sync.Once
table *[32 * 2]bn256.GTFieldTable // precomputed basePoint^n
publicKey *sm9.SignMasterPublicKey
}
// SignPrivateKey user private key for sign, generated by KGC
type SignPrivateKey struct {
PrivateKey *bn256.G1 // user private key
*SignMasterPublicKey // master public key
privateKey *sm9.SignPrivateKey
}
// EncryptMasterPrivateKey master private key for encryption, generated by KGC
type EncryptMasterPrivateKey struct {
*EncryptMasterPublicKey // master public key
D *big.Int // master private key
privateKey *sm9.EncryptMasterPrivateKey
}
// EncryptMasterPublicKey master private key for encryption, generated by KGC
type EncryptMasterPublicKey struct {
MasterPublicKey *bn256.G1 // public key
pairOnce sync.Once
basePoint *bn256.GT // the result of Pair(pub.MasterPublicKey, Gen2)
tableGenOnce sync.Once
table *[32 * 2]bn256.GTFieldTable // precomputed basePoint^n
publicKey *sm9.EncryptMasterPublicKey
}
// EncryptPrivateKey user private key for encryption, generated by KGC
type EncryptPrivateKey struct {
PrivateKey *bn256.G2 // user private key
*EncryptMasterPublicKey // master public key
privateKey *sm9.EncryptPrivateKey
}
// GenerateSignMasterKey generates a master public and private key pair for DSA usage.
func GenerateSignMasterKey(rand io.Reader) (*SignMasterPrivateKey, error) {
k, err := randomScalar(rand)
if err != nil {
return nil, err
}
kBytes := k.Bytes(orderNat)
p, err := new(bn256.G2).ScalarBaseMult(kBytes)
priv, err := sm9.GenerateSignMasterKey(rand)
if err != nil {
return nil, err
}
return &SignMasterPrivateKey{privateKey: priv}, nil
}
priv := new(SignMasterPrivateKey)
priv.D = new(big.Int).SetBytes(kBytes)
priv.SignMasterPublicKey = new(SignMasterPublicKey)
priv.MasterPublicKey = p
return priv, 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)
}
// 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()
}
// 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())
var b cryptobyte.Builder
b.AddASN1BigInt(master.D)
b.AddASN1BigInt(d)
return b.Bytes()
}
@ -89,6 +78,7 @@ func (master *SignMasterPrivateKey) UnmarshalASN1(der []byte) error {
d := &big.Int{}
var inner cryptobyte.String
var pubBytes []byte
var err error
if der[0] == 0x30 {
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
!input.Empty() ||
@ -102,92 +92,44 @@ func (master *SignMasterPrivateKey) UnmarshalASN1(der []byte) error {
} else if !input.ReadASN1Integer(d) || !input.Empty() {
return errors.New("sm9: invalid sign master private key asn1 data")
}
master.D = d
master.SignMasterPublicKey = new(SignMasterPublicKey)
p, err := new(bn256.G2).ScalarBaseMult(bn256.NormalizeScalar(d.Bytes()))
master.privateKey, err = sm9.NewSignMasterPrivateKey(d.Bytes())
if err != nil {
return err
}
master.MasterPublicKey = p
return nil
}
// GenerateUserKey generate an user dsa key.
func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*SignPrivateKey, error) {
var id []byte
id = append(append(id, uid...), hid)
t1Nat := hashH1(id)
d, err := bigmod.NewNat().SetBytes(master.D.Bytes(), orderNat)
priv, err := master.privateKey.GenerateUserKey(uid, hid)
if err != nil {
return nil, err
}
t1Nat.Add(d, orderNat)
if t1Nat.IsZero() == 1 {
return nil, errors.New("sm9: need to re-generate sign master private key")
}
t1Nat = bigmod.NewNat().Exp(t1Nat, orderMinus2, orderNat)
t1Nat.Mul(d, orderNat)
priv := new(SignPrivateKey)
priv.SignMasterPublicKey = master.SignMasterPublicKey
g1, err := new(bn256.G1).ScalarBaseMult(t1Nat.Bytes(orderNat))
if err != nil {
return nil, err
}
priv.PrivateKey = g1
return priv, nil
return &SignPrivateKey{privateKey: priv}, nil
}
// Public returns the public key corresponding to priv.
func (master *SignMasterPrivateKey) Public() *SignMasterPublicKey {
return master.SignMasterPublicKey
return &SignMasterPublicKey{master.privateKey.Public()}
}
// pair generate the basepoint once
func (pub *SignMasterPublicKey) pair() *bn256.GT {
pub.pairOnce.Do(func() {
pub.basePoint = bn256.Pair(bn256.Gen1, pub.MasterPublicKey)
})
return pub.basePoint
// 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) generatorTable() *[32 * 2]bn256.GTFieldTable {
pub.tableGenOnce.Do(func() {
pub.table = bn256.GenerateGTFieldTable(pub.pair())
})
return pub.table
}
// ScalarBaseMult compute basepoint^r with precomputed table
// The base point = pair(Gen1, <master public key>)
func (pub *SignMasterPublicKey) ScalarBaseMult(scalar []byte) (*bn256.GT, error) {
tables := pub.generatorTable()
return bn256.ScalarBaseMultGT(tables, scalar)
}
// GenerateUserPublicKey generate user sign public key
func (pub *SignMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *bn256.G2 {
var buffer []byte
buffer = append(append(buffer, uid...), hid)
h1 := hashH1(buffer)
p, err := new(bn256.G2).ScalarBaseMult(h1.Bytes(orderNat))
if err != nil {
panic(err)
}
p.Add(p, pub.MasterPublicKey)
return p
// 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()
}
// MarshalASN1 marshal sign 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.MasterPublicKey.MarshalUncompressed())
b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalUncompressed())
return b.Bytes()
}
@ -195,37 +137,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.MasterPublicKey.MarshalCompressed())
b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalCompressed())
return b.Bytes()
}
func unmarshalG2(bytes []byte) (*bn256.G2, error) {
g2 := new(bn256.G2)
switch bytes[0] {
case 4:
_, err := g2.Unmarshal(bytes[1:])
if err != nil {
return nil, err
}
case 2, 3:
_, err := g2.UnmarshalCompressed(bytes)
if err != nil {
return nil, err
}
default:
return nil, errors.New("sm9: invalid point identity byte")
}
return g2, nil
}
// UnmarshalRaw unmarsal raw bytes data to sign master public key
func (pub *SignMasterPublicKey) UnmarshalRaw(bytes []byte) error {
g2, err := unmarshalG2(bytes)
if err != nil {
return err
if pub.publicKey == nil {
pub.publicKey = new(sm9.SignMasterPublicKey)
}
pub.MasterPublicKey = g2
return nil
return pub.publicKey.UnmarshalRaw(bytes)
}
// UnmarshalASN1 unmarsal der data to sign master public key
@ -255,23 +176,29 @@ func (pub *SignMasterPublicKey) ParseFromPEM(data []byte) error {
return pub.UnmarshalASN1(block.Bytes)
}
func (priv *SignPrivateKey) Equal(x *SignPrivateKey) bool {
return priv.privateKey.Equal(x.privateKey)
}
func (priv *SignPrivateKey) Bytes() []byte {
return priv.privateKey.Bytes()
}
// MasterPublic returns the master public key corresponding to priv.
func (priv *SignPrivateKey) MasterPublic() *SignMasterPublicKey {
return priv.SignMasterPublicKey
return &SignMasterPublicKey{priv.privateKey.MasterPublic()}
}
// SetMasterPublicKey bind the sign master public key to it.
func (priv *SignPrivateKey) SetMasterPublicKey(pub *SignMasterPublicKey) {
if priv.SignMasterPublicKey == nil || priv.SignMasterPublicKey.MasterPublicKey == nil {
priv.SignMasterPublicKey = pub
}
priv.privateKey.SetMasterPublicKey(pub.publicKey)
}
// MarshalASN1 marshal sign user 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.MarshalUncompressed())
b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalUncompressed())
return b.Bytes()
}
@ -279,38 +206,17 @@ 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.MarshalCompressed())
b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalCompressed())
return b.Bytes()
}
func unmarshalG1(bytes []byte) (*bn256.G1, error) {
g := new(bn256.G1)
switch bytes[0] {
case 4:
_, err := g.Unmarshal(bytes[1:])
if err != nil {
return nil, err
}
case 2, 3:
_, err := g.UnmarshalCompressed(bytes)
if err != nil {
return nil, err
}
default:
return nil, errors.New("sm9: invalid point identity byte")
}
return g, nil
}
// UnmarshalRaw unmarsal raw bytes data to sign user private key
// Note, priv's SignMasterPublicKey should be handled separately.
func (priv *SignPrivateKey) UnmarshalRaw(bytes []byte) error {
g, err := unmarshalG1(bytes)
if err != nil {
return err
if priv.privateKey == nil {
priv.privateKey = new(sm9.SignPrivateKey)
}
priv.PrivateKey = g
return nil
return priv.privateKey.UnmarshalRaw(bytes)
}
// UnmarshalASN1 unmarsal der data to sign user private key
@ -349,64 +255,45 @@ func (priv *SignPrivateKey) UnmarshalASN1(der []byte) error {
// GenerateEncryptMasterKey generates a master public and private key pair for encryption usage.
func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error) {
k, err := randomScalar(rand)
priv, err := sm9.GenerateEncryptMasterKey(rand)
if err != nil {
return nil, err
}
kBytes := k.Bytes(orderNat)
return &EncryptMasterPrivateKey{privateKey: priv}, nil
}
priv := new(EncryptMasterPrivateKey)
priv.D = new(big.Int).SetBytes(kBytes)
priv.EncryptMasterPublicKey = new(EncryptMasterPublicKey)
p, err := new(bn256.G1).ScalarBaseMult(kBytes)
if err != nil {
panic(err)
}
priv.MasterPublicKey = p
return priv, 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()
}
// 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)
}
// GenerateUserKey generate an user key for encryption.
func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*EncryptPrivateKey, error) {
var id []byte
id = append(append(id, uid...), hid)
t1Nat := hashH1(id)
d, err := bigmod.NewNat().SetBytes(master.D.Bytes(), orderNat)
priv, err := master.privateKey.GenerateUserKey(uid, hid)
if err != nil {
return nil, err
}
t1Nat.Add(d, orderNat)
if t1Nat.IsZero() == 1 {
return nil, errors.New("sm9: need to re-generate encrypt master private key")
}
t1Nat = bigmod.NewNat().Exp(t1Nat, orderMinus2, orderNat)
t1Nat.Mul(d, orderNat)
priv := new(EncryptPrivateKey)
priv.EncryptMasterPublicKey = master.EncryptMasterPublicKey
p, err := new(bn256.G2).ScalarBaseMult(t1Nat.Bytes(orderNat))
if err != nil {
panic(err)
}
priv.PrivateKey = p
return priv, nil
return &EncryptPrivateKey{privateKey: priv}, nil
}
// Public returns the public key corresponding to priv.
func (master *EncryptMasterPrivateKey) Public() *EncryptMasterPublicKey {
return master.EncryptMasterPublicKey
return &EncryptMasterPublicKey{publicKey: master.privateKey.Public()}
}
// MarshalASN1 marshal encrypt 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())
var b cryptobyte.Builder
b.AddASN1BigInt(master.D)
b.AddASN1BigInt(d)
return b.Bytes()
}
@ -429,56 +316,31 @@ func (master *EncryptMasterPrivateKey) UnmarshalASN1(der []byte) error {
} else if !input.ReadASN1Integer(d) || !input.Empty() {
return errors.New("sm9: invalid encrypt master private key asn1 data")
}
master.D = d
master.EncryptMasterPublicKey = new(EncryptMasterPublicKey)
p, err := new(bn256.G1).ScalarBaseMult(bn256.NormalizeScalar(d.Bytes()))
var err error
master.privateKey, err = sm9.NewEncryptMasterPrivateKey(d.Bytes())
if err != nil {
return err
}
master.MasterPublicKey = p
return nil
}
// pair generate the basepoint once
func (pub *EncryptMasterPublicKey) pair() *bn256.GT {
pub.pairOnce.Do(func() {
pub.basePoint = bn256.Pair(pub.MasterPublicKey, bn256.Gen2)
})
return pub.basePoint
// 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) generatorTable() *[32 * 2]bn256.GTFieldTable {
pub.tableGenOnce.Do(func() {
pub.table = bn256.GenerateGTFieldTable(pub.pair())
})
return pub.table
}
// ScalarBaseMult compute basepoint^r with precomputed table.
// The base point = pair(<master public key>, Gen2)
func (pub *EncryptMasterPublicKey) ScalarBaseMult(scalar []byte) (*bn256.GT, error) {
tables := pub.generatorTable()
return bn256.ScalarBaseMultGT(tables, scalar)
}
// GenerateUserPublicKey generate user encrypt public key
func (pub *EncryptMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *bn256.G1 {
var buffer []byte
buffer = append(append(buffer, uid...), hid)
h1 := hashH1(buffer)
p, err := new(bn256.G1).ScalarBaseMult(h1.Bytes(orderNat))
if err != nil {
panic(err)
}
p.Add(p, pub.MasterPublicKey)
return p
// 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()
}
// MarshalASN1 marshal encrypt 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.MasterPublicKey.MarshalUncompressed())
b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalUncompressed())
return b.Bytes()
}
@ -486,18 +348,16 @@ 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.MasterPublicKey.MarshalCompressed())
b.AddASN1BitString(pub.publicKey.MasterPublicKey.MarshalCompressed())
return b.Bytes()
}
// UnmarshalRaw unmarsal raw bytes data to encrypt master public key
func (pub *EncryptMasterPublicKey) UnmarshalRaw(bytes []byte) error {
g, err := unmarshalG1(bytes)
if err != nil {
return err
if pub.publicKey == nil {
pub.publicKey = new(sm9.EncryptMasterPublicKey)
}
pub.MasterPublicKey = g
return nil
return pub.publicKey.UnmarshalRaw(bytes)
}
// ParseFromPEM just for GMSSL, there are no Algorithm pkix.AlgorithmIdentifier
@ -529,21 +389,19 @@ func (pub *EncryptMasterPublicKey) UnmarshalASN1(der []byte) error {
// MasterPublic returns the master public key corresponding to priv.
func (priv *EncryptPrivateKey) MasterPublic() *EncryptMasterPublicKey {
return priv.EncryptMasterPublicKey
return &EncryptMasterPublicKey{priv.privateKey.MasterPublic()}
}
// SetMasterPublicKey bind the encrypt master public key to it.
func (priv *EncryptPrivateKey) SetMasterPublicKey(pub *EncryptMasterPublicKey) {
if priv.EncryptMasterPublicKey == nil || priv.EncryptMasterPublicKey.MasterPublicKey == nil {
priv.EncryptMasterPublicKey = pub
}
priv.privateKey.SetMasterPublicKey(pub.publicKey)
}
// MarshalASN1 marshal encrypt user 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.MarshalUncompressed())
b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalUncompressed())
return b.Bytes()
}
@ -551,19 +409,17 @@ 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.MarshalCompressed())
b.AddASN1BitString(priv.privateKey.PrivateKey.MarshalCompressed())
return b.Bytes()
}
// UnmarshalRaw unmarsal raw bytes data to encrypt user private key
// Note, priv's EncryptMasterPublicKey should be handled separately.
func (priv *EncryptPrivateKey) UnmarshalRaw(bytes []byte) error {
g, err := unmarshalG2(bytes)
if err != nil {
return err
if priv.privateKey == nil {
priv.privateKey = new(sm9.EncryptPrivateKey)
}
priv.PrivateKey = g
return nil
return priv.privateKey.UnmarshalRaw(bytes)
}
// UnmarshalASN1 unmarsal der data to encrypt user private key
@ -599,3 +455,15 @@ func (priv *EncryptPrivateKey) UnmarshalASN1(der []byte) error {
}
return 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)
}
// 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()
}

View File

@ -24,8 +24,8 @@ func TestSignMasterPrivateKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if masterKey.D.Cmp(masterKey2.D) != 0 {
t.Errorf("expected %v, got %v", hex.EncodeToString(masterKey.D.Bytes()), hex.EncodeToString(masterKey2.D.Bytes()))
if !masterKey.Equal(masterKey2) {
t.Errorf("expected %v, got %v", hex.EncodeToString(masterKey.Bytes()), hex.EncodeToString(masterKey2.Bytes()))
}
}
@ -43,7 +43,7 @@ func TestSignMasterPublicKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) {
if !masterKey.Public().Equal(pub2) {
t.Errorf("not same")
}
}
@ -62,7 +62,7 @@ func TestSignMasterPublicKeyMarshalCompressedASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) {
if !masterKey.Public().Equal(pub2) {
t.Errorf("not same")
}
}
@ -87,7 +87,7 @@ func TestSignUserPrivateKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !userKey.PrivateKey.Equal(userKey2.PrivateKey) {
if !userKey.Equal(userKey2) {
t.Errorf("not same")
}
}
@ -112,7 +112,7 @@ func TestSignUserPrivateKeyMarshalCompressedASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !userKey.PrivateKey.Equal(userKey2.PrivateKey) {
if !userKey.Equal(userKey2) {
t.Errorf("not same")
}
}
@ -131,8 +131,8 @@ func TestEncryptMasterPrivateKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if masterKey.D.Cmp(masterKey2.D) != 0 {
t.Errorf("expected %v, got %v", hex.EncodeToString(masterKey.D.Bytes()), hex.EncodeToString(masterKey2.D.Bytes()))
if !masterKey.Equal(masterKey2) {
t.Errorf("expected %v, got %v", hex.EncodeToString(masterKey.Bytes()), hex.EncodeToString(masterKey2.Bytes()))
}
}
@ -150,7 +150,7 @@ func TestEncryptMasterPublicKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) {
if !masterKey.Public().Equal(pub2) {
t.Errorf("not same")
}
}
@ -169,7 +169,7 @@ func TestEncryptMasterPublicKeyMarshalCompressedASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) {
if !masterKey.Public().Equal(pub2) {
t.Errorf("not same")
}
}
@ -194,7 +194,7 @@ func TestEncryptUserPrivateKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !userKey.PrivateKey.Equal(userKey2.PrivateKey) {
if !userKey.Equal(userKey2) {
t.Errorf("not same")
}
}
@ -219,7 +219,7 @@ func TestEncryptUserPrivateKeyMarshalCompressedASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !userKey.PrivateKey.Equal(userKey2.PrivateKey) {
if !userKey.Equal(userKey2) {
t.Errorf("not same")
}
}
@ -271,7 +271,7 @@ func TestParseSM9SignMasterPublicKey(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if key.MasterPublicKey == nil {
if key == nil {
t.Errorf("not expected nil")
}
@ -305,7 +305,7 @@ func TestParseSM9EncryptMasterPublicKey(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if key.MasterPublicKey == nil {
if key == nil {
t.Errorf("not expected nil")
}
@ -313,7 +313,7 @@ func TestParseSM9EncryptMasterPublicKey(t *testing.T) {
var b cryptobyte.Builder
b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
b.AddASN1BitString(key.MasterPublicKey.MarshalUncompressed())
b.AddASN1BitString(key.Bytes())
})
data, err := b.Bytes()
if err != nil {

View File

@ -1,108 +1,12 @@
package sm9
import (
"bytes"
"crypto/rand"
"encoding/hex"
"math/big"
"testing"
"github.com/emmansun/gmsm/internal/bigmod"
"github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/sm3"
"github.com/emmansun/gmsm/sm9/bn256"
"golang.org/x/crypto/cryptobyte"
)
func bigFromHex(s string) *big.Int {
b, ok := new(big.Int).SetString(s, 16)
if !ok {
panic("sm9/elliptic: internal error: invalid encoding")
}
return b
}
func TestHashH1(t *testing.T) {
expected := "2acc468c3926b0bdb2767e99ff26e084de9ced8dbc7d5fbf418027b667862fab"
h := hashH1([]byte{0x41, 0x6c, 0x69, 0x63, 0x65, 0x01})
if hex.EncodeToString(h.Bytes(orderNat)) != expected {
t.Errorf("got %v, expected %v", h.Bytes(orderNat), expected)
}
}
func TestHashH2(t *testing.T) {
expected := "823c4b21e4bd2dfe1ed92c606653e996668563152fc33f55d7bfbb9bd9705adb"
zStr := "4368696E65736520494253207374616E6461726481377B8FDBC2839B4FA2D0E0F8AA6853BBBE9E9C4099608F8612C6078ACD7563815AEBA217AD502DA0F48704CC73CABB3C06209BD87142E14CBD99E8BCA1680F30DADC5CD9E207AEE32209F6C3CA3EC0D800A1A42D33C73153DED47C70A39D2E8EAF5D179A1836B359A9D1D9BFC19F2EFCDB829328620962BD3FDF15F2567F58A543D25609AE943920679194ED30328BB33FD15660BDE485C6B79A7B32B013983F012DB04BA59FE88DB889321CC2373D4C0C35E84F7AB1FF33679BCA575D67654F8624EB435B838CCA77B2D0347E65D5E46964412A096F4150D8C5EDE5440DDF0656FCB663D24731E80292188A2471B8B68AA993899268499D23C89755A1A89744643CEAD40F0965F28E1CD2895C3D118E4F65C9A0E3E741B6DD52C0EE2D25F5898D60848026B7EFB8FCC1B2442ECF0795F8A81CEE99A6248F294C82C90D26BD6A814AAF475F128AEF43A128E37F80154AE6CB92CAD7D1501BAE30F750B3A9BD1F96B08E97997363911314705BFB9A9DBB97F75553EC90FBB2DDAE53C8F68E42"
z, err := hex.DecodeString(zStr)
if err != nil {
t.Fatal(err)
}
h := hashH2(z)
if hex.EncodeToString(h.Bytes(orderNat)) != expected {
t.Errorf("got %v, expected %v", h.Bytes(orderNat), expected)
}
}
func TestSign(t *testing.T) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
h, s, err := Sign(rand.Reader, userKey, hashed)
if err != nil {
t.Fatal(err)
}
if !Verify(masterKey.Public(), uid, hid, hashed, h, s) {
t.Errorf("Verify failed")
}
sNeg := new(bn256.G1).Neg(s)
if Verify(masterKey.Public(), uid, hid, hashed, h, sNeg) {
t.Errorf("Verify with s=-s succeeded")
}
hashed[0] ^= 0xff
if Verify(masterKey.Public(), uid, hid, hashed, h, s) {
t.Errorf("Verify always works!")
}
}
func TestNegativeInputs(t *testing.T) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
t.Fatal(err)
}
h := new(big.Int).SetInt64(1)
h.Lsh(h, 550 /* larger than any supported curve */)
h.Neg(h)
if Verify(masterKey.Public(), uid, hid, hashed, h, bn256.Gen1) {
t.Errorf("bogus signature accepted")
}
}
func TestZeroSignature(t *testing.T) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
t.Fatal(err)
}
if Verify(masterKey.Public(), uid, hid, hashed, big.NewInt(0), bn256.Gen1) {
t.Error("Verify with h=0 succeeded")
}
if Verify(masterKey.Public(), uid, hid, hashed, bn256.Order, bn256.Gen1) {
t.Error("Verify with h=order succeeded")
}
}
func TestSignASN1(t *testing.T) {
masterKey, err := GenerateSignMasterKey(rand.Reader)
hashed := []byte("Chinese IBS standard")
@ -149,266 +53,6 @@ func TestParseInvalidASN1(t *testing.T) {
}
}
func signMasterPrivateKeyFromHex(s string) (*SignMasterPrivateKey, error) {
kb, err := hex.DecodeString(s)
if err != nil {
return nil, err
}
var b cryptobyte.Builder
b.AddASN1BigInt(new(big.Int).SetBytes(kb))
kb, _ = b.Bytes()
testkey := new(SignMasterPrivateKey)
err = testkey.UnmarshalASN1(kb)
if err != nil {
return nil, err
}
return testkey, nil
}
// SM9 Appendix A
func TestSignSM9Sample(t *testing.T) {
expectedH := bigFromHex("823c4b21e4bd2dfe1ed92c606653e996668563152fc33f55d7bfbb9bd9705adb")
expectedHNat, err := bigmod.NewNat().SetBytes(expectedH.Bytes(), orderNat)
if err != nil {
t.Fatal(err)
}
expectedS := "0473bf96923ce58b6ad0e13e9643a406d8eb98417c50ef1b29cef9adb48b6d598c856712f1c2e0968ab7769f42a99586aed139d5b8b3e15891827cc2aced9baa05"
hash := []byte("Chinese IBS standard")
hid := byte(0x01)
uid := []byte("Alice")
r := bigFromHex("033c8616b06704813203dfd00965022ed15975c662337aed648835dc4b1cbe")
rNat, err := bigmod.NewNat().SetBytes(r.Bytes(), orderNat)
if err != nil {
t.Fatal(err)
}
masterKey, err := signMasterPrivateKeyFromHex("0130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4")
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
w, err := userKey.SignMasterPublicKey.ScalarBaseMult(bn256.NormalizeScalar(r.Bytes()))
if err != nil {
t.Fatal(err)
}
var buffer []byte
buffer = append(buffer, hash...)
buffer = append(buffer, w.Marshal()...)
h := hashH2(buffer)
if h.Equal(expectedHNat) == 0 {
t.Fatal("not same h")
}
rNat.Sub(h, orderNat)
s, err := new(bn256.G1).ScalarMult(userKey.PrivateKey, rNat.Bytes(orderNat))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(s.MarshalUncompressed()) != expectedS {
t.Fatal("not same S")
}
}
// SM9 Appendix B
func TestKeyExchangeSample(t *testing.T) {
hid := byte(0x02)
expectedPube := "9174542668e8f14ab273c0945c3690c66e5dd09678b86f734c4350567ed0628354e598c6bf749a3dacc9fffedd9db6866c50457cfc7aa2a4ad65c3168ff74210"
expectedKey := "c5c13a8f59a97cdeae64f16a2272a9e7"
expectedSignatureB := "3bb4bcee8139c960b4d6566db1e0d5f0b2767680e5e1bf934103e6c66e40ffee"
expectedSignatureA := "195d1b7256ba7e0e67c71202a25f8c94ff8241702c2f55d613ae1c6b98215172"
masterKey, err := encryptMasterPrivateKeyFromHex("02E65B0762D042F51F0D23542B13ED8CFA2E9A0E7206361E013A283905E31F")
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedPube {
t.Errorf("not expected master public key")
}
userA := []byte("Alice")
userB := []byte("Bob")
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := NewKeyExchange(userKey, userA, userB, 16, true)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := NewKeyExchange(userKey, userB, userA, 16, true)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
k, err := bigmod.NewNat().SetBytes(bigFromHex("5879DD1D51E175946F23B1B41E93BA31C584AE59A426EC1046A4D03B06C8").Bytes(), orderNat)
if err != nil {
t.Fatal(err)
}
initKeyExchange(initiator, hid, k)
if hex.EncodeToString(initiator.secret.Marshal()) != "7cba5b19069ee66aa79d490413d11846b9ba76dd22567f809cf23b6d964bb265a9760c99cb6f706343fed05637085864958d6c90902aba7d405fbedf7b781599" {
t.Fatal("not same")
}
// B1 - B7
k, err = bigmod.NewNat().SetBytes(bigFromHex("018B98C44BEF9F8537FB7D071B2C928B3BC65BD3D69E1EEE213564905634FE").Bytes(), orderNat)
if err != nil {
t.Fatal(err)
}
rB, sigB, err := respondKeyExchange(responder, hid, k, initiator.secret)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(sigB) != expectedSignatureB {
t.Errorf("not expected signature B")
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != expectedKey {
t.Errorf("not expected key %v\n", hex.EncodeToString(key1))
}
if hex.EncodeToString(sigA) != expectedSignatureA {
t.Errorf("not expected signature A")
}
// B8
key2, err := responder.ConfirmInitiator(sigA)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key2) != expectedKey {
t.Errorf("not expected key %v\n", hex.EncodeToString(key2))
}
}
func TestKeyExchange(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := NewKeyExchange(userKey, userA, userB, 16, true)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := NewKeyExchange(userKey, userB, userA, 16, true)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RepondKeyExchange(rand.Reader, hid, rA)
if err != nil {
t.Fatal(err)
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
// B8
key2, err := responder.ConfirmInitiator(sigA)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
}
}
func TestKeyExchangeWithoutSignature(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := NewKeyExchange(userKey, userA, userB, 16, false)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := NewKeyExchange(userKey, userB, userA, 16, false)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RepondKeyExchange(rand.Reader, hid, rA)
if err != nil {
t.Fatal(err)
}
if len(sigB) != 0 {
t.Errorf("should no signature")
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
if len(sigA) != 0 {
t.Errorf("should no signature")
}
key2, err := responder.ConfirmInitiator(nil)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
}
}
func TestWrapKey(t *testing.T) {
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
hid := byte(0x01)
@ -420,18 +64,18 @@ func TestWrapKey(t *testing.T) {
if err != nil {
t.Fatal(err)
}
key, cipher, err := WrapKey(rand.Reader, masterKey.Public(), uid, hid, 16)
key, cipher, err := masterKey.Public().WrapKey(rand.Reader, uid, hid, 16)
if err != nil {
t.Fatal(err)
}
key2, err := UnwrapKey(userKey, uid, cipher, 16)
key2, err := userKey.UnwrapKey(uid, cipher, 16)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key) != hex.EncodeToString(key2) {
t.Errorf("expected %v, got %v\n", hex.EncodeToString(key), hex.EncodeToString(key2))
if !bytes.Equal(key, key2) {
t.Errorf("expected %x, got %x", key, key2)
}
}
@ -461,260 +105,8 @@ func TestWrapKeyASN1(t *testing.T) {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("expected %v, got %v\n", hex.EncodeToString(key1), hex.EncodeToString(key2))
}
}
func TestUnmarshalSM9KeyPackage(t *testing.T) {
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
p, err := masterKey.Public().WrapKeyASN1(rand.Reader, uid, hid, 16)
if err != nil {
t.Fatal(err)
}
key, cipher, err := UnmarshalSM9KeyPackage(p)
if err != nil {
t.Fatal(err)
}
key2, err := UnwrapKey(userKey, uid, cipher, 16)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key) != hex.EncodeToString(key2) {
t.Errorf("expected %v, got %v\n", hex.EncodeToString(key), hex.EncodeToString(key2))
}
}
func encryptMasterPrivateKeyFromHex(s string) (*EncryptMasterPrivateKey, error) {
kb, err := hex.DecodeString(s)
if err != nil {
return nil, err
}
var b cryptobyte.Builder
b.AddASN1BigInt(new(big.Int).SetBytes(kb))
kb, _ = b.Bytes()
testkey := new(EncryptMasterPrivateKey)
err = testkey.UnmarshalASN1(kb)
if err != nil {
return nil, err
}
return testkey, nil
}
// SM9 Appendix C
func TestWrapKeySM9Sample(t *testing.T) {
expectedMasterPublicKey := "787ed7b8a51f3ab84e0a66003f32da5c720b17eca7137d39abc66e3c80a892ff769de61791e5adc4b9ff85a31354900b202871279a8c49dc3f220f644c57a7b1"
expectedUserPrivateKey := "94736acd2c8c8796cc4785e938301a139a059d3537b6414140b2d31eecf41683115bae85f5d8bc6c3dbd9e5342979acccf3c2f4f28420b1cb4f8c0b59a19b1587aa5e47570da7600cd760a0cf7beaf71c447f3844753fe74fa7ba92ca7d3b55f27538a62e7f7bfb51dce08704796d94c9d56734f119ea44732b50e31cdeb75c1"
expectedUserPublicKey := "709d165808b0a43e2574e203fa885abcbab16a240c4c1916552e7c43d09763b8693269a6be2456f43333758274786b6051ff87b7f198da4ba1a2c6e336f51fcc"
expectedCipher := "1edee2c3f465914491de44cefb2cb434ab02c308d9dc5e2067b4fed5aaac8a0f1c9b4c435eca35ab83bb734174c0f78fde81a53374aff3b3602bbc5e37be9a4c"
expectedKey := "4ff5cf86d2ad40c8f4bac98d76abdbde0c0e2f0a829d3f911ef5b2bce0695480"
masterKey, err := encryptMasterPrivateKeyFromHex("01EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedMasterPublicKey {
t.Errorf("not expected master public key")
}
uid := []byte("Bob")
hid := byte(0x03)
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(userKey.PrivateKey.Marshal()) != expectedUserPrivateKey {
t.Errorf("not expected user private key")
}
q := masterKey.Public().GenerateUserPublicKey(uid, hid)
if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey {
t.Errorf("not expected user public key")
}
var r *big.Int = bigFromHex("74015F8489C01EF4270456F9E6475BFB602BDE7F33FD482AB4E3684A6722")
cipher, err := new(bn256.G1).ScalarMult(q, bn256.NormalizeScalar(r.Bytes()))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(cipher.Marshal()) != expectedCipher {
t.Errorf("not expected cipher")
}
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, 32)
if hex.EncodeToString(key) != expectedKey {
t.Errorf("expected %v, got %v\n", expectedKey, hex.EncodeToString(key))
}
key2, err := UnwrapKey(userKey, uid, cipher, 32)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key2) != expectedKey {
t.Errorf("expected %v, got %v\n", expectedKey, hex.EncodeToString(key2))
}
}
// SM9 Appendix D
func TestEncryptSM9Sample(t *testing.T) {
plaintext := []byte("Chinese IBE standard")
expectedMasterPublicKey := "787ed7b8a51f3ab84e0a66003f32da5c720b17eca7137d39abc66e3c80a892ff769de61791e5adc4b9ff85a31354900b202871279a8c49dc3f220f644c57a7b1"
expectedUserPrivateKey := "94736acd2c8c8796cc4785e938301a139a059d3537b6414140b2d31eecf41683115bae85f5d8bc6c3dbd9e5342979acccf3c2f4f28420b1cb4f8c0b59a19b1587aa5e47570da7600cd760a0cf7beaf71c447f3844753fe74fa7ba92ca7d3b55f27538a62e7f7bfb51dce08704796d94c9d56734f119ea44732b50e31cdeb75c1"
expectedUserPublicKey := "709d165808b0a43e2574e203fa885abcbab16a240c4c1916552e7c43d09763b8693269a6be2456f43333758274786b6051ff87b7f198da4ba1a2c6e336f51fcc"
expectedCipher := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0"
expectedKey := "58373260f067ec48667c21c144f8bc33cd3049788651ffd5f738003e51df31174d0e4e402fd87f4581b612f74259db574f67ece6"
expectedCiphertext := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0ba672387bcd6de5016a158a52bb2e7fc429197bcab70b25afee37a2b9db9f3671b5f5b0e951489682f3e64e1378cdd5da9513b1c"
masterKey, err := encryptMasterPrivateKeyFromHex("01EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedMasterPublicKey {
t.Errorf("not expected master public key")
}
uid := []byte("Bob")
hid := byte(0x03)
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(userKey.PrivateKey.Marshal()) != expectedUserPrivateKey {
t.Errorf("not expected user private key")
}
q := masterKey.Public().GenerateUserPublicKey(uid, hid)
if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey {
t.Errorf("not expected user public key")
}
var r *big.Int = bigFromHex("AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE8BB5EE2CBE5EC9E785C")
cipher, err := new(bn256.G1).ScalarMult(q, bn256.NormalizeScalar(r.Bytes()))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(cipher.Marshal()) != expectedCipher {
t.Errorf("not expected cipher")
}
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, len(plaintext)+32)
if hex.EncodeToString(key) != expectedKey {
t.Errorf("not expected key")
}
subtle.XORBytes(key, key[:len(plaintext)], plaintext)
hash := sm3.New()
hash.Write(key)
c3 := hash.Sum(nil)
ciphertext := append(cipher.Marshal(), c3...)
ciphertext = append(ciphertext, key[:len(plaintext)]...)
if hex.EncodeToString(ciphertext) != expectedCiphertext {
t.Errorf("expected %v, got %v\n", expectedCiphertext, hex.EncodeToString(ciphertext))
}
}
func TestEncryptSM9SampleBlockMode(t *testing.T) {
plaintext := []byte("Chinese IBE standard")
expectedMasterPublicKey := "787ed7b8a51f3ab84e0a66003f32da5c720b17eca7137d39abc66e3c80a892ff769de61791e5adc4b9ff85a31354900b202871279a8c49dc3f220f644c57a7b1"
expectedUserPrivateKey := "94736acd2c8c8796cc4785e938301a139a059d3537b6414140b2d31eecf41683115bae85f5d8bc6c3dbd9e5342979acccf3c2f4f28420b1cb4f8c0b59a19b1587aa5e47570da7600cd760a0cf7beaf71c447f3844753fe74fa7ba92ca7d3b55f27538a62e7f7bfb51dce08704796d94c9d56734f119ea44732b50e31cdeb75c1"
expectedUserPublicKey := "709d165808b0a43e2574e203fa885abcbab16a240c4c1916552e7c43d09763b8693269a6be2456f43333758274786b6051ff87b7f198da4ba1a2c6e336f51fcc"
expectedCipher := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0"
expectedKey := "58373260f067ec48667c21c144f8bc33cd3049788651ffd5f738003e51df31174d0e4e402fd87f4581b612f74259db57"
expectedCiphertext := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0fd3c98dd92c44c68332675a370cceede31e0c5cd209c257601149d12b394a2bee05b6fac6f11b965268c994f00dba7a8bb00fd60583546cbdf4649250863f10a"
masterKey, err := encryptMasterPrivateKeyFromHex("01EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(masterKey.MasterPublicKey.Marshal()) != expectedMasterPublicKey {
t.Errorf("not expected master public key")
}
uid := []byte("Bob")
hid := byte(0x03)
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(userKey.PrivateKey.Marshal()) != expectedUserPrivateKey {
t.Errorf("not expected user private key")
}
q := masterKey.Public().GenerateUserPublicKey(uid, hid)
if hex.EncodeToString(q.Marshal()) != expectedUserPublicKey {
t.Errorf("not expected user public key")
}
var r *big.Int = bigFromHex("AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE8BB5EE2CBE5EC9E785C")
cipher, err := new(bn256.G1).ScalarMult(q, bn256.NormalizeScalar(r.Bytes()))
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(cipher.Marshal()) != expectedCipher {
t.Errorf("not expected cipher")
}
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
buffer = append(buffer, w.Marshal()...)
buffer = append(buffer, uid...)
key := sm3.Kdf(buffer, 16+32)
if hex.EncodeToString(key) != expectedKey {
t.Errorf("not expected key, expected %v, got %x\n", expectedKey, key)
}
c2, err := SM4ECBEncrypterOpts.Encrypt(nil, key[:16], plaintext)
if err != nil {
t.Fatal(err)
}
hash := sm3.New()
hash.Write(c2)
hash.Write(key[16:])
c3 := hash.Sum(nil)
ciphertext := append(cipher.Marshal(), c3...)
ciphertext = append(ciphertext, c2...)
if hex.EncodeToString(ciphertext) != expectedCiphertext {
t.Errorf("expected %v, got %v\n", expectedCiphertext, hex.EncodeToString(ciphertext))
if !bytes.Equal(key1, key2) {
t.Errorf("expected %x, got %x", key1, key2)
}
}
@ -817,6 +209,148 @@ func TestEncryptDecryptASN1(t *testing.T) {
}
}
func TestUnmarshalSM9KeyPackage(t *testing.T) {
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
p, err := masterKey.Public().WrapKeyASN1(rand.Reader, uid, hid, 16)
if err != nil {
t.Fatal(err)
}
key, cipher, err := UnmarshalSM9KeyPackage(p)
if err != nil {
t.Fatal(err)
}
key2, err := UnwrapKey(userKey, uid, cipher, 16)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key) != hex.EncodeToString(key2) {
t.Errorf("expected %v, got %v\n", hex.EncodeToString(key), hex.EncodeToString(key2))
}
}
func TestKeyExchange(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := userKey.NewKeyExchange(userA, userB, 16, true)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := userKey.NewKeyExchange(userB, userA, 16, true)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RespondKeyExchange(rand.Reader, hid, rA)
if err != nil {
t.Fatal(err)
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
// B8
key2, err := responder.ConfirmInitiator(sigA)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
}
}
func TestKeyExchangeWithoutSignature(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
masterKey, err := GenerateEncryptMasterKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(userA, hid)
if err != nil {
t.Fatal(err)
}
initiator := userKey.NewKeyExchange(userA, userB, 16, false)
userKey, err = masterKey.GenerateUserKey(userB, hid)
if err != nil {
t.Fatal(err)
}
responder := userKey.NewKeyExchange(userB, userA, 16, false)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RespondKeyExchange(rand.Reader, hid, rA)
if err != nil {
t.Fatal(err)
}
if len(sigB) != 0 {
t.Errorf("should no signature")
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
if len(sigA) != 0 {
t.Errorf("should no signature")
}
key2, err := responder.ConfirmInitiator(nil)
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
}
}
func BenchmarkSign(b *testing.B) {
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")

View File

@ -219,8 +219,7 @@ func TestMarshalPKCS8SM9SignPrivateKey(t *testing.T) {
if !ok {
t.Fatalf("not expected key")
}
if !privateKey.PrivateKey.Equal(privateKey2.PrivateKey) ||
!privateKey.MasterPublicKey.Equal(privateKey2.MasterPublicKey) {
if !privateKey.Equal(privateKey2) {
t.Fatalf("not same key")
}
}
@ -246,8 +245,7 @@ func TestMarshalPKCS8SM9EncPrivateKey(t *testing.T) {
if !ok {
t.Fatalf("not expected key")
}
if !privateKey.PrivateKey.Equal(privateKey2.PrivateKey) ||
!privateKey.MasterPublicKey.Equal(privateKey2.MasterPublicKey) {
if !privateKey.Equal(privateKey2) {
t.Fatalf("not same key")
}
}
@ -269,8 +267,8 @@ func TestMarshalPKCS8SM9SignMasterPrivateKey(t *testing.T) {
if !ok {
t.Fatalf("not expected key")
}
masterKey2.MasterPublicKey.Marshal()
if !(masterKey.D.Cmp(masterKey2.D) == 0 && masterKey.MasterPublicKey.Equal(masterKey2.MasterPublicKey)) {
if !masterKey.Equal(masterKey2) {
t.Fatalf("not same key")
}
}
@ -292,8 +290,7 @@ func TestMarshalPKCS8SM9EncMasterPrivateKey(t *testing.T) {
if !ok {
t.Fatalf("not expected key")
}
masterKey2.MasterPublicKey.Marshal()
if !(masterKey.D.Cmp(masterKey2.D) == 0 && masterKey.MasterPublicKey.Equal(masterKey2.MasterPublicKey)) {
if !masterKey.Equal(masterKey2) {
t.Fatalf("not same key")
}
}