SM9: refactoring, move separate SM9 & bn256

This commit is contained in:
Sun Yimin 2022-06-16 10:14:45 +08:00 committed by GitHub
parent 3320de17b8
commit 81c0dbb0fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 196 additions and 191 deletions

View File

@ -1,7 +1,4 @@
This part codes mainly refer two projects:
1. [bn256](https://github.com/cloudflare/bn256), 主要是基域运算
2. [gmssl sm9](https://github.com/guanzhi/GmSSL/blob/develop/src/sm9_alg.c)主要是2-4-12塔式扩域以及r-ate等
SM9 current performance:
**SM9 Sign Benchmark**

4
sm9/bn256/README.md Normal file
View File

@ -0,0 +1,4 @@
This part codes mainly refer two projects:
1. [bn256](https://github.com/cloudflare/bn256), 主要是基域运算
2. [gmssl sm9](https://github.com/guanzhi/GmSSL/blob/develop/src/sm9_alg.c)主要是2-4-12塔式扩域以及r-ate等

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
// u is the BN parameter that determines the prime: 600000000058f98a.
var u = bigFromHex("600000000058f98a")

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"crypto/subtle"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"io"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"crypto/rand"
@ -333,6 +333,20 @@ func (e *G1) Unmarshal(m []byte) ([]byte, error) {
return m[2*numBytes:], nil
}
func (e *G1) Equal(other *G1) bool {
if e.p == nil && other.p == nil {
return true
}
return e.p.x == other.p.x &&
e.p.y == other.p.y &&
e.p.z == other.p.z &&
e.p.t == other.p.t
}
func (e *G1) IsOnCurve() bool {
return e.p.IsOnCurve()
}
type G1Curve struct {
params *CurveParams
g G1

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"crypto/rand"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"errors"
@ -317,3 +317,17 @@ func (e *G2) Unmarshal(m []byte) ([]byte, error) {
}
return m[4*numBytes:], nil
}
func (e *G2) Equal(other *G2) bool {
if e.p == nil && other.p == nil {
return true
}
return e.p.x == other.p.x &&
e.p.y == other.p.y &&
e.p.z == other.p.z &&
e.p.t == other.p.t
}
func (e *G2) IsOnCurve() bool {
return e.p.IsOnCurve()
}

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"bytes"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"crypto/sha256"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import "math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import "math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"math/big"

View File

@ -1,7 +1,7 @@
//go:build (amd64 && !generic) || (arm64 && !generic)
// +build amd64,!generic arm64,!generic
package sm9
package bn256
// This file contains forward declarations for the architecture-specific
// assembly implementations of these functions, provided that they exist.

View File

@ -1,7 +1,7 @@
//go:build !amd64 && !arm64 || generic
// +build !amd64,!arm64 generic
package sm9
package bn256
func gfpCarry(a *gfP, head uint64) {
b := &gfP{}

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"encoding/hex"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"crypto/subtle"
@ -92,7 +92,7 @@ func (e *GT) SetOne() *GT {
e.p = &gfP12{}
}
e.p.SetOne()
return e
return e
}
// Finalize is a linear function from F_p^12 to GT.
@ -208,16 +208,16 @@ func (e *GT) Unmarshal(m []byte) ([]byte, error) {
return m[12*numBytes:], nil
}
// A gtPointTable holds the first 15 Exp of a value at offset -1, so P
// A GTFieldTable holds the first 15 Exp of a value at offset -1, so P
// is at table[0], P^15 is at table[14], and P^0 is implicitly the identity
// point.
type gtTable [15]*GT
type GTFieldTable [15]*GT
// Select selects the n-th multiple of the table base point into p. It works in
// constant time by iterating over every entry of the table. n must be in [0, 15].
func (table *gtTable) Select(p *GT, n uint8) {
func (table *GTFieldTable) Select(p *GT, n uint8) {
if n >= 16 {
panic("sm9: internal error: gtTable called with out-of-bounds value")
panic("sm9: internal error: GTFieldTable called with out-of-bounds value")
}
p.p.SetOne()
for i := uint8(1); i < 16; i++ {
@ -225,3 +225,52 @@ func (table *gtTable) Select(p *GT, n uint8) {
p.p.Select(table[i-1].p, p.p, cond)
}
}
func GenerateGTFieldTable(basePoint *GT) *[32 * 2]GTFieldTable {
table := new([32 * 2]GTFieldTable)
base := &GT{}
base.Set(basePoint)
for i := 0; i < 32*2; i++ {
table[i][0] = &GT{}
table[i][0].Set(base)
for j := 1; j < 15; j += 2 {
table[i][j] = &GT{}
table[i][j].p = &gfP12{}
table[i][j].p.Square(table[i][j/2].p)
table[i][j+1] = &GT{}
table[i][j+1].p = &gfP12{}
table[i][j+1].Add(table[i][j], base)
}
base.p.Square(base.p)
base.p.Square(base.p)
base.p.Square(base.p)
base.p.Square(base.p)
}
return table
}
// ScalarBaseMultGT compute basepoint^r with precomputed table
func ScalarBaseMultGT(tables *[32 * 2]GTFieldTable, r *big.Int) *GT {
scalar := normalizeScalar(r.Bytes())
// This is also a scalar multiplication with a four-bit window like in
// ScalarMult, but in this case the doublings are precomputed. The value
// [windowValue]G added at iteration k would normally get doubled
// (totIterations-k)×4 times, but with a larger precomputation we can
// instead add [2^((totIterations-k)×4)][windowValue]G and avoid the
// doublings between iterations.
e, t := &GT{}, &GT{}
tableIndex := len(tables) - 1
e.SetOne()
t.SetOne()
for _, byte := range scalar {
windowValue := byte >> 4
tables[tableIndex].Select(t, windowValue)
e.Add(e, t)
tableIndex--
windowValue = byte & 0b1111
tables[tableIndex].Select(t, windowValue)
e.Add(e, t)
tableIndex--
}
return e
}

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"bytes"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import "math/big"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"encoding/hex"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"crypto/subtle"

View File

@ -1,4 +1,4 @@
package sm9
package bn256
import (
"testing"

View File

@ -12,6 +12,7 @@ import (
"github.com/emmansun/gmsm/internal/xor"
"github.com/emmansun/gmsm/sm3"
"github.com/emmansun/gmsm/sm9/bn256"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
)
@ -56,7 +57,7 @@ func hash(z []byte, h hashMode) *big.Int {
md.Reset()
}
k := new(big.Int).SetBytes(ha[:40])
n := new(big.Int).Sub(Order, bigOne)
n := new(big.Int).Sub(bn256.Order, bigOne)
k.Mod(k, n)
k.Add(k, bigOne)
return k
@ -80,75 +81,36 @@ func randFieldElement(rand io.Reader) (k *big.Int, err error) {
}
k = new(big.Int).SetBytes(b)
n := new(big.Int).Sub(Order, bigOne)
n := new(big.Int).Sub(bn256.Order, bigOne)
k.Mod(k, n)
k.Add(k, bigOne)
return
}
// Pair generate the basepoint once
func (pub *SignMasterPublicKey) Pair() *GT {
func (pub *SignMasterPublicKey) Pair() *bn256.GT {
pub.pairOnce.Do(func() {
pub.basePoint = Pair(Gen1, pub.MasterPublicKey)
pub.basePoint = bn256.Pair(bn256.Gen1, pub.MasterPublicKey)
})
return pub.basePoint
}
func (pub *SignMasterPublicKey) generatorTable() *[32 * 2]gtTable {
func (pub *SignMasterPublicKey) generatorTable() *[32 * 2]bn256.GTFieldTable {
pub.tableGenOnce.Do(func() {
pub.table = new([32 * 2]gtTable)
base := &GT{}
base.Set(pub.Pair())
for i := 0; i < 32*2; i++ {
pub.table[i][0] = &GT{}
pub.table[i][0].Set(base)
for j := 1; j < 15; j += 2 {
pub.table[i][j] = &GT{}
pub.table[i][j].p = &gfP12{}
pub.table[i][j].p.Square(pub.table[i][j/2].p)
pub.table[i][j+1] = &GT{}
pub.table[i][j+1].p = &gfP12{}
pub.table[i][j+1].Add(pub.table[i][j], base)
}
base.p.Square(base.p)
base.p.Square(base.p)
base.p.Square(base.p)
base.p.Square(base.p)
}
pub.table = bn256.GenerateGTFieldTable(pub.Pair())
})
return pub.table
}
// ScalarBaseMult compute basepoint^r with precomputed table
func (pub *SignMasterPublicKey) ScalarBaseMult(r *big.Int) *GT {
scalar := normalizeScalar(r.Bytes())
func (pub *SignMasterPublicKey) ScalarBaseMult(r *big.Int) *bn256.GT {
tables := pub.generatorTable()
// This is also a scalar multiplication with a four-bit window like in
// ScalarMult, but in this case the doublings are precomputed. The value
// [windowValue]G added at iteration k would normally get doubled
// (totIterations-k)×4 times, but with a larger precomputation we can
// instead add [2^((totIterations-k)×4)][windowValue]G and avoid the
// doublings between iterations.
e, t := &GT{}, &GT{}
tableIndex := len(tables) - 1
e.SetOne()
t.SetOne()
for _, byte := range scalar {
windowValue := byte >> 4
tables[tableIndex].Select(t, windowValue)
e.Add(e, t)
tableIndex--
windowValue = byte & 0b1111
tables[tableIndex].Select(t, windowValue)
e.Add(e, t)
tableIndex--
}
return e
return bn256.ScalarBaseMultGT(tables, r)
}
// 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.
func Sign(rand io.Reader, priv *SignPrivateKey, hash []byte) (h *big.Int, s *G1, err error) {
func Sign(rand io.Reader, priv *SignPrivateKey, hash []byte) (h *big.Int, s *bn256.G1, err error) {
var r *big.Int
for {
r, err = randFieldElement(rand)
@ -167,11 +129,11 @@ func Sign(rand io.Reader, priv *SignPrivateKey, hash []byte) (h *big.Int, s *G1,
l := new(big.Int).Sub(r, h)
if l.Sign() < 0 {
l.Add(l, Order)
l.Add(l, bn256.Order)
}
if l.Sign() != 0 {
s = new(G1).ScalarMult(priv.PrivateKey, l)
s = new(bn256.G1).ScalarMult(priv.PrivateKey, l)
break
}
}
@ -206,11 +168,11 @@ func SignASN1(rand io.Reader, priv *SignPrivateKey, hash []byte) ([]byte, error)
// 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.
func Verify(pub *SignMasterPublicKey, uid []byte, hid byte, hash []byte, h *big.Int, s *G1) bool {
if h.Sign() <= 0 || h.Cmp(Order) >= 0 {
func Verify(pub *SignMasterPublicKey, uid []byte, hid byte, hash []byte, h *big.Int, s *bn256.G1) bool {
if h.Sign() <= 0 || h.Cmp(bn256.Order) >= 0 {
return false
}
if !s.p.IsOnCurve() {
if !s.IsOnCurve() {
return false
}
@ -219,8 +181,8 @@ func Verify(pub *SignMasterPublicKey, uid []byte, hid byte, hash []byte, h *big.
// user sign public key p generation
p := pub.GenerateUserPublicKey(uid, hid)
u := Pair(s, p)
w := new(GT).Add(u, t)
u := bn256.Pair(s, p)
w := new(bn256.GT).Add(u, t)
var buffer []byte
buffer = append(buffer, hash...)
@ -250,7 +212,7 @@ func VerifyASN1(pub *SignMasterPublicKey, uid []byte, hid byte, hash, sig []byte
if sBytes[0] != 4 {
return false
}
s := new(G1)
s := new(bn256.G1)
_, err := s.Unmarshal(sBytes[1:])
if err != nil {
return false
@ -266,67 +228,28 @@ func (pub *SignMasterPublicKey) Verify(uid []byte, hid byte, hash, sig []byte) b
}
// Pair generate the basepoint once
func (pub *EncryptMasterPublicKey) Pair() *GT {
func (pub *EncryptMasterPublicKey) Pair() *bn256.GT {
pub.pairOnce.Do(func() {
pub.basePoint = Pair(pub.MasterPublicKey, Gen2)
pub.basePoint = bn256.Pair(pub.MasterPublicKey, bn256.Gen2)
})
return pub.basePoint
}
func (pub *EncryptMasterPublicKey) generatorTable() *[32 * 2]gtTable {
func (pub *EncryptMasterPublicKey) generatorTable() *[32 * 2]bn256.GTFieldTable {
pub.tableGenOnce.Do(func() {
pub.table = new([32 * 2]gtTable)
base := &GT{}
base.Set(pub.Pair())
for i := 0; i < 32*2; i++ {
pub.table[i][0] = &GT{}
pub.table[i][0].Set(base)
for j := 1; j < 15; j += 2 {
pub.table[i][j] = &GT{}
pub.table[i][j].p = &gfP12{}
pub.table[i][j].p.Square(pub.table[i][j/2].p)
pub.table[i][j+1] = &GT{}
pub.table[i][j+1].p = &gfP12{}
pub.table[i][j+1].Add(pub.table[i][j], base)
}
base.p.Square(base.p)
base.p.Square(base.p)
base.p.Square(base.p)
base.p.Square(base.p)
}
pub.table = bn256.GenerateGTFieldTable(pub.Pair())
})
return pub.table
}
// ScalarBaseMult compute basepoint^r with precomputed table
func (pub *EncryptMasterPublicKey) ScalarBaseMult(r *big.Int) *GT {
scalar := normalizeScalar(r.Bytes())
func (pub *EncryptMasterPublicKey) ScalarBaseMult(r *big.Int) *bn256.GT {
tables := pub.generatorTable()
// This is also a scalar multiplication with a four-bit window like in
// ScalarMult, but in this case the doublings are precomputed. The value
// [windowValue]G added at iteration k would normally get doubled
// (totIterations-k)×4 times, but with a larger precomputation we can
// instead add [2^((totIterations-k)×4)][windowValue]G and avoid the
// doublings between iterations.
e, t := &GT{}, &GT{}
tableIndex := len(tables) - 1
e.SetOne()
t.SetOne()
for _, byte := range scalar {
windowValue := byte >> 4
tables[tableIndex].Select(t, windowValue)
e.Add(e, t)
tableIndex--
windowValue = byte & 0b1111
tables[tableIndex].Select(t, windowValue)
e.Add(e, t)
tableIndex--
}
return e
return bn256.ScalarBaseMultGT(tables, r)
}
// WrapKey generate and wrap key wtih reciever's uid and system hid
func WrapKey(rand io.Reader, pub *EncryptMasterPublicKey, uid []byte, hid byte, kLen int) (key []byte, cipher *G1, err error) {
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 *big.Int
var ok bool
@ -336,7 +259,7 @@ func WrapKey(rand io.Reader, pub *EncryptMasterPublicKey, uid []byte, hid byte,
return
}
cipher = new(G1).ScalarMult(q, r)
cipher = new(bn256.G1).ScalarMult(q, r)
w := pub.ScalarBaseMult(r)
@ -382,7 +305,7 @@ func (pub *EncryptMasterPublicKey) WrapKeyASN1(rand io.Reader, uid []byte, hid b
}
// UnmarshalSM9KeyPackage is an utility to unmarshal SM9KeyPackage
func UnmarshalSM9KeyPackage(der []byte) ([]byte, *G1, error) {
func UnmarshalSM9KeyPackage(der []byte) ([]byte, *bn256.G1, error) {
input := cryptobyte.String(der)
var (
key []byte
@ -404,12 +327,12 @@ func UnmarshalSM9KeyPackage(der []byte) ([]byte, *G1, error) {
}
// UnwrapKey unwrap key from cipher, user id and aligned key length
func UnwrapKey(priv *EncryptPrivateKey, uid []byte, cipher *G1, kLen int) ([]byte, error) {
if !cipher.p.IsOnCurve() {
func UnwrapKey(priv *EncryptPrivateKey, uid []byte, cipher *bn256.G1, kLen int) ([]byte, error) {
if !cipher.IsOnCurve() {
return nil, errors.New("sm9: invalid cipher, it's NOT on curve")
}
w := Pair(cipher, priv.PrivateKey)
w := bn256.Pair(cipher, priv.PrivateKey)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
@ -486,7 +409,7 @@ func (pub *EncryptMasterPublicKey) Encrypt(rand io.Reader, uid []byte, hid byte,
// Decrypt decrypt chipher, ciphertext should be with format C1||C3||C2
func Decrypt(priv *EncryptPrivateKey, uid, ciphertext []byte) ([]byte, error) {
c := &G1{}
c := &bn256.G1{}
c3, err := c.Unmarshal(ciphertext)
if err != nil {
return nil, err

View File

@ -6,6 +6,7 @@ import (
"math/big"
"sync"
"github.com/emmansun/gmsm/sm9/bn256"
"golang.org/x/crypto/cryptobyte"
)
@ -17,17 +18,17 @@ type SignMasterPrivateKey struct {
// SignMasterPublicKey master public key for sign, generated by KGC
type SignMasterPublicKey struct {
MasterPublicKey *G2 // master public key
MasterPublicKey *bn256.G2 // master public key
pairOnce sync.Once
basePoint *GT // the result of Pair(Gen1, pub.MasterPublicKey)
basePoint *bn256.GT // the result of Pair(Gen1, pub.MasterPublicKey)
tableGenOnce sync.Once
table *[32 * 2]gtTable // precomputed basePoint^n
table *[32 * 2]bn256.GTFieldTable // precomputed basePoint^n
}
// SignPrivateKey user private key for sign, generated by KGC
type SignPrivateKey struct {
PrivateKey *G1 // user private key
SignMasterPublicKey // master public key
PrivateKey *bn256.G1 // user private key
SignMasterPublicKey // master public key
}
// EncryptMasterPrivateKey master private key for encryption, generated by KGC
@ -38,17 +39,17 @@ type EncryptMasterPrivateKey struct {
// EncryptMasterPublicKey master private key for encryption, generated by KGC
type EncryptMasterPublicKey struct {
MasterPublicKey *G1 // public key
MasterPublicKey *bn256.G1 // public key
pairOnce sync.Once
basePoint *GT // the result of Pair(pub.MasterPublicKey, Gen2)
basePoint *bn256.GT // the result of Pair(pub.MasterPublicKey, Gen2)
tableGenOnce sync.Once
table *[32 * 2]gtTable // precomputed basePoint^n
table *[32 * 2]bn256.GTFieldTable // precomputed basePoint^n
}
// EncryptPrivateKey user private key for encryption, generated by KGC
type EncryptPrivateKey struct {
PrivateKey *G2 // user private key
EncryptMasterPublicKey // master public key
PrivateKey *bn256.G2 // user private key
EncryptMasterPublicKey // master public key
}
// GenerateSignMasterKey generates a master public and private key pair for DSA usage.
@ -60,7 +61,7 @@ func GenerateSignMasterKey(rand io.Reader) (*SignMasterPrivateKey, error) {
priv := new(SignMasterPrivateKey)
priv.D = k
priv.MasterPublicKey = new(G2).ScalarBaseMult(k)
priv.MasterPublicKey = new(bn256.G2).ScalarBaseMult(k)
return priv, nil
}
@ -80,7 +81,7 @@ func (master *SignMasterPrivateKey) UnmarshalASN1(der []byte) error {
return errors.New("sm9: invalid sign master key asn1 data")
}
master.D = d
master.MasterPublicKey = new(G2).ScalarBaseMult(d)
master.MasterPublicKey = new(bn256.G2).ScalarBaseMult(d)
return nil
}
@ -95,13 +96,13 @@ func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*Sign
if t1.Sign() == 0 {
return nil, errors.New("sm9: need to re-generate sign master private key")
}
t1 = fermatInverse(t1, Order)
t1 = fermatInverse(t1, bn256.Order)
t2 := new(big.Int).Mul(t1, master.D)
t2.Mod(t2, Order)
t2.Mod(t2, bn256.Order)
priv := new(SignPrivateKey)
priv.SignMasterPublicKey = master.SignMasterPublicKey
priv.PrivateKey = new(G1).ScalarBaseMult(t2)
priv.PrivateKey = new(bn256.G1).ScalarBaseMult(t2)
return priv, nil
}
@ -112,12 +113,12 @@ func (master *SignMasterPrivateKey) Public() *SignMasterPublicKey {
}
// GenerateUserPublicKey generate user sign public key
func (pub *SignMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *G2 {
func (pub *SignMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *bn256.G2 {
var buffer []byte
buffer = append(buffer, uid...)
buffer = append(buffer, hid)
h1 := hashH1(buffer)
p := new(G2).ScalarBaseMult(h1)
p := new(bn256.G2).ScalarBaseMult(h1)
p.Add(p, pub.MasterPublicKey)
return p
}
@ -130,8 +131,8 @@ func (pub *SignMasterPublicKey) MarshalASN1() ([]byte, error) {
return b.Bytes()
}
func unmarshalG2(bytes []byte) (*G2, error) {
g2 := new(G2)
func unmarshalG2(bytes []byte) (*bn256.G2, error) {
g2 := new(bn256.G2)
switch bytes[0] {
case 4:
_, err := g2.Unmarshal(bytes[1:])
@ -184,8 +185,8 @@ func (priv *SignPrivateKey) MarshalASN1() ([]byte, error) {
return b.Bytes()
}
func unmarshalG1(bytes []byte) (*G1, error) {
g := new(G1)
func unmarshalG1(bytes []byte) (*bn256.G1, error) {
g := new(bn256.G1)
switch bytes[0] {
case 4:
_, err := g.Unmarshal(bytes[1:])
@ -228,7 +229,7 @@ func GenerateEncryptMasterKey(rand io.Reader) (*EncryptMasterPrivateKey, error)
priv := new(EncryptMasterPrivateKey)
priv.D = k
priv.MasterPublicKey = new(G1).ScalarBaseMult(k)
priv.MasterPublicKey = new(bn256.G1).ScalarBaseMult(k)
return priv, nil
}
@ -243,13 +244,13 @@ func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*E
if t1.Sign() == 0 {
return nil, errors.New("sm9: need to re-generate encrypt master private key")
}
t1 = fermatInverse(t1, Order)
t1 = fermatInverse(t1, bn256.Order)
t2 := new(big.Int).Mul(t1, master.D)
t2.Mod(t2, Order)
t2.Mod(t2, bn256.Order)
priv := new(EncryptPrivateKey)
priv.EncryptMasterPublicKey = master.EncryptMasterPublicKey
priv.PrivateKey = new(G2).ScalarBaseMult(t2)
priv.PrivateKey = new(bn256.G2).ScalarBaseMult(t2)
return priv, nil
}
@ -275,17 +276,17 @@ func (master *EncryptMasterPrivateKey) UnmarshalASN1(der []byte) error {
return errors.New("sm9: invalid encrpt master key asn1 data")
}
master.D = d
master.MasterPublicKey = new(G1).ScalarBaseMult(d)
master.MasterPublicKey = new(bn256.G1).ScalarBaseMult(d)
return nil
}
// GenerateUserPublicKey generate user encrypt public key
func (pub *EncryptMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *G1 {
func (pub *EncryptMasterPublicKey) GenerateUserPublicKey(uid []byte, hid byte) *bn256.G1 {
var buffer []byte
buffer = append(buffer, uid...)
buffer = append(buffer, hid)
h1 := hashH1(buffer)
p := new(G1).ScalarBaseMult(h1)
p := new(bn256.G1).ScalarBaseMult(h1)
p.Add(p, pub.MasterPublicKey)
return p
}

View File

@ -39,9 +39,7 @@ func TestSignMasterPublicKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if masterKey.MasterPublicKey.p.x != pub2.MasterPublicKey.p.x ||
masterKey.MasterPublicKey.p.y != pub2.MasterPublicKey.p.y ||
masterKey.MasterPublicKey.p.z != pub2.MasterPublicKey.p.z {
if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) {
t.Errorf("not same")
}
}
@ -66,8 +64,7 @@ func TestSignUserPrivateKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if userKey.PrivateKey.p.x != userKey2.PrivateKey.p.x ||
userKey.PrivateKey.p.y != userKey2.PrivateKey.p.y {
if !userKey.PrivateKey.Equal(userKey2.PrivateKey) {
t.Errorf("not same")
}
}
@ -105,8 +102,7 @@ func TestEncryptMasterPublicKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if masterKey.MasterPublicKey.p.x != pub2.MasterPublicKey.p.x ||
masterKey.MasterPublicKey.p.y != pub2.MasterPublicKey.p.y {
if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) {
t.Errorf("not same")
}
}
@ -131,9 +127,7 @@ func TestEncryptUserPrivateKeyMarshalASN1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if userKey.PrivateKey.p.x != userKey2.PrivateKey.p.x ||
userKey.PrivateKey.p.y != userKey2.PrivateKey.p.y ||
userKey.PrivateKey.p.z != userKey2.PrivateKey.p.z {
if !userKey.PrivateKey.Equal(userKey2.PrivateKey) {
t.Errorf("not same")
}
}

View File

@ -9,8 +9,17 @@ import (
"github.com/emmansun/gmsm/internal/xor"
"github.com/emmansun/gmsm/sm3"
"github.com/emmansun/gmsm/sm9/bn256"
)
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})
@ -88,7 +97,7 @@ func TestSignSM9Sample(t *testing.T) {
r := bigFromHex("033c8616b06704813203dfd00965022ed15975c662337aed648835dc4b1cbe")
masterKey := new(SignMasterPrivateKey)
masterKey.D = bigFromHex("0130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4")
masterKey.MasterPublicKey = new(G2).ScalarBaseMult(masterKey.D)
masterKey.MasterPublicKey = new(bn256.G2).ScalarBaseMult(masterKey.D)
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
@ -107,10 +116,10 @@ func TestSignSM9Sample(t *testing.T) {
l := new(big.Int).Sub(r, h)
if l.Sign() < 0 {
l.Add(l, Order)
l.Add(l, bn256.Order)
}
s := new(G1).ScalarMult(userKey.PrivateKey, l)
s := new(bn256.G1).ScalarMult(userKey.PrivateKey, l)
if hex.EncodeToString(s.MarshalUncompressed()) != expectedS {
t.Fatal("not same S")
@ -205,7 +214,7 @@ func TestWrapKeySM9Sample(t *testing.T) {
expectedKey := "4ff5cf86d2ad40c8f4bac98d76abdbde0c0e2f0a829d3f911ef5b2bce0695480"
masterKey := new(EncryptMasterPrivateKey)
masterKey.D = bigFromHex("01EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
masterKey.MasterPublicKey = new(G1).ScalarBaseMult(masterKey.D)
masterKey.MasterPublicKey = new(bn256.G1).ScalarBaseMult(masterKey.D)
fmt.Printf("Pub-e=%v\n", hex.EncodeToString(masterKey.MasterPublicKey.Marshal()))
uid := []byte("Bob")
@ -221,11 +230,11 @@ func TestWrapKeySM9Sample(t *testing.T) {
fmt.Printf("Qb=%v\n", hex.EncodeToString(q.Marshal()))
var r *big.Int = bigFromHex("74015F8489C01EF4270456F9E6475BFB602BDE7F33FD482AB4E3684A6722")
cipher := new(G1).ScalarMult(q, r)
cipher := new(bn256.G1).ScalarMult(q, r)
fmt.Printf("C=%v\n", hex.EncodeToString(cipher.Marshal()))
g := Pair(masterKey.Public().MasterPublicKey, Gen2)
w := new(GT).ScalarMult(g, r)
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)
@ -255,7 +264,7 @@ func TestEncryptSM9Sample(t *testing.T) {
expectedCiphertext := "2445471164490618e1ee20528ff1d545b0f14c8bcaa44544f03dab5dac07d8ff42ffca97d57cddc05ea405f2e586feb3a6930715532b8000759f13059ed59ac0ba672387bcd6de5016a158a52bb2e7fc429197bcab70b25afee37a2b9db9f3671b5f5b0e951489682f3e64e1378cdd5da9513b1c"
masterKey := new(EncryptMasterPrivateKey)
masterKey.D = bigFromHex("01EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
masterKey.MasterPublicKey = new(G1).ScalarBaseMult(masterKey.D)
masterKey.MasterPublicKey = new(bn256.G1).ScalarBaseMult(masterKey.D)
fmt.Printf("Pub-e=%v\n", hex.EncodeToString(masterKey.MasterPublicKey.Marshal()))
uid := []byte("Bob")
@ -271,11 +280,11 @@ func TestEncryptSM9Sample(t *testing.T) {
fmt.Printf("Qb=%v\n", hex.EncodeToString(q.Marshal()))
var r *big.Int = bigFromHex("AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE8BB5EE2CBE5EC9E785C")
cipher := new(G1).ScalarMult(q, r)
cipher := new(bn256.G1).ScalarMult(q, r)
fmt.Printf("C=%v\n", hex.EncodeToString(cipher.Marshal()))
g := Pair(masterKey.Public().MasterPublicKey, Gen2)
w := new(GT).ScalarMult(g, r)
g := bn256.Pair(masterKey.Public().MasterPublicKey, bn256.Gen2)
w := new(bn256.GT).ScalarMult(g, r)
var buffer []byte
buffer = append(buffer, cipher.Marshal()...)