mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-27 12:46:18 +08:00
SM9: refactoring, move separate SM9 & bn256
This commit is contained in:
parent
3320de17b8
commit
81c0dbb0fa
@ -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
4
sm9/bn256/README.md
Normal 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等
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"math/big"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"math/big"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
// u is the BN parameter that determines the prime: 600000000058f98a.
|
||||
var u = bigFromHex("600000000058f98a")
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"io"
|
@ -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
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
@ -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()
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"bytes"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import "math/big"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"math/big"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"math/big"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"math/big"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import "math/big"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"math/big"
|
@ -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.
|
@ -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{}
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
@ -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 := >{}
|
||||
base.Set(basePoint)
|
||||
for i := 0; i < 32*2; i++ {
|
||||
table[i][0] = >{}
|
||||
table[i][0].Set(base)
|
||||
for j := 1; j < 15; j += 2 {
|
||||
table[i][j] = >{}
|
||||
table[i][j].p = &gfP12{}
|
||||
table[i][j].p.Square(table[i][j/2].p)
|
||||
table[i][j+1] = >{}
|
||||
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 := >{}, >{}
|
||||
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
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"bytes"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import "math/big"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
@ -1,4 +1,4 @@
|
||||
package sm9
|
||||
package bn256
|
||||
|
||||
import (
|
||||
"testing"
|
139
sm9/sm9.go
139
sm9/sm9.go
@ -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 := >{}
|
||||
base.Set(pub.Pair())
|
||||
for i := 0; i < 32*2; i++ {
|
||||
pub.table[i][0] = >{}
|
||||
pub.table[i][0].Set(base)
|
||||
for j := 1; j < 15; j += 2 {
|
||||
pub.table[i][j] = >{}
|
||||
pub.table[i][j].p = &gfP12{}
|
||||
pub.table[i][j].p.Square(pub.table[i][j/2].p)
|
||||
pub.table[i][j+1] = >{}
|
||||
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 := >{}, >{}
|
||||
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 := >{}
|
||||
base.Set(pub.Pair())
|
||||
for i := 0; i < 32*2; i++ {
|
||||
pub.table[i][0] = >{}
|
||||
pub.table[i][0].Set(base)
|
||||
for j := 1; j < 15; j += 2 {
|
||||
pub.table[i][j] = >{}
|
||||
pub.table[i][j].p = &gfP12{}
|
||||
pub.table[i][j].p.Square(pub.table[i][j/2].p)
|
||||
pub.table[i][j+1] = >{}
|
||||
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 := >{}, >{}
|
||||
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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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()...)
|
||||
|
Loading…
x
Reference in New Issue
Block a user