init: v1.0.0
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
package sm2a
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"xdx.jelly/xgcl/gmath"
|
||||
"xdx.jelly/xgcl/grand/drng"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
)
|
||||
|
||||
type ClientSignKeyGenContext struct {
|
||||
X [SecureParam]*big.Int
|
||||
Y [SecureParam]*big.Int
|
||||
K [SecureParam]byte
|
||||
ClientKey *sm2.PrivateKey // 客户端私钥,与sm2私钥是同样的形式
|
||||
PubKey *sm2.PublicKey // 公钥
|
||||
ClientSubKey *sm2.PrivateKey
|
||||
Rand io.Reader
|
||||
|
||||
isClientKeyReady bool
|
||||
}
|
||||
|
||||
func NewClientSignKeyGenContext(r io.Reader) *ClientSignKeyGenContext {
|
||||
c := new(ClientSignKeyGenContext)
|
||||
for i := 0; i < SecureParam; i++ {
|
||||
c.X[i] = new(big.Int)
|
||||
c.Y[i] = new(big.Int)
|
||||
}
|
||||
c.ClientKey = sm2.NewPrivateKey()
|
||||
c.ClientSubKey = sm2.NewPrivateKey()
|
||||
c.PubKey = sm2.NewPublicKey()
|
||||
c.Rand = r
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *ClientSignKeyGenContext) GetClientKey() (*sm2.PrivateKey, error) {
|
||||
if c.isClientKeyReady {
|
||||
return c.ClientKey, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Key agreement not finished")
|
||||
}
|
||||
|
||||
func (c *ClientSignKeyGenContext) GetClientSubKey() (*sm2.PrivateKey, error) {
|
||||
if c.isClientKeyReady {
|
||||
return c.ClientSubKey, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Key agreement not finished")
|
||||
}
|
||||
|
||||
func (c *ClientSignKeyGenContext) GetPublicKey() (*sm2.PublicKey, error) {
|
||||
if c.isClientKeyReady {
|
||||
return c.PubKey, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Key agreement not finished")
|
||||
}
|
||||
|
||||
// ClientKeyGen_one 客户端第一步,根据服务端第一步计算数据计算客户端的中间数据
|
||||
// in = X_1||Y_1||X_2||Y_2||....||X_128||Y_128
|
||||
// out = (h_i0, h_i1, F_ix, F_iy), ... , for i = 1...128
|
||||
func (c *ClientSignKeyGenContext) ClientKeyGen_one(in []byte) (out []byte, err error) {
|
||||
c.isClientKeyReady = false
|
||||
buf := make([]byte, ((SecureParam + 7) >> 3))
|
||||
if n, err := c.Rand.Read(buf); n != len(buf) || err != nil {
|
||||
return nil, fmt.Errorf("Generate random number error")
|
||||
}
|
||||
for i := 0; i < SecureParam; i++ {
|
||||
c.K[i] = (buf[i>>3] >> uint(i&7)) & 1
|
||||
}
|
||||
var fx, fy *big.Int
|
||||
xx := new(big.Int)
|
||||
xy := new(big.Int)
|
||||
r := new(big.Int)
|
||||
a := new(big.Int)
|
||||
buf = make([]byte, sm2.ByteSize())
|
||||
out = make([]byte, sm2.ByteSize()*4*SecureParam)
|
||||
outPos := 0
|
||||
|
||||
// 使用基于SM3的随机比特生成器生成客户端签名密钥分量
|
||||
c.ClientKey.D, err = rand.Int(drng.SM3Rng, sm2.OrderN())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var n int
|
||||
var i int
|
||||
d := c.ClientKey.Get()
|
||||
d.SetInt64(0)
|
||||
// 计算给协同签名服务端的的中间数据
|
||||
for i = 0; i < SecureParam; i++ {
|
||||
if n, err = c.Rand.Read(buf); n != len(buf) || err != nil {
|
||||
fmt.Printf("%d,%d, %x\n", i, n, len(buf))
|
||||
return nil, fmt.Errorf("Generate random number error1")
|
||||
}
|
||||
r.SetBytes(buf)
|
||||
if n, err = c.Rand.Read(buf); n != len(buf) || err != nil {
|
||||
fmt.Printf("%d,%d, %x, %v\n", i, n, buf, err)
|
||||
return nil, fmt.Errorf("Generate random number error2")
|
||||
}
|
||||
a.SetBytes(buf)
|
||||
d.Add(d, a)
|
||||
if n, err = c.Rand.Read(buf); n != len(buf) || err != nil {
|
||||
fmt.Printf("%d,%d, %x, %v\n", i, n, buf, err)
|
||||
return nil, fmt.Errorf("Generate random number error3")
|
||||
}
|
||||
fx, fy = sm2.Curve256.ScalarBaseMult(buf)
|
||||
xbuf := in[2*i*sm2.ByteSize():]
|
||||
xx.SetBytes(xbuf[:sm2.ByteSize()])
|
||||
xy.SetBytes(xbuf[sm2.ByteSize() : 2*sm2.ByteSize()])
|
||||
c.X[i], c.Y[i] = sm2.Curve256.ScalarMult(xx, xy, buf)
|
||||
if c.K[i] == 1 {
|
||||
fx, fy = sm2.Curve().Add(fx, fy, xx, xy)
|
||||
outPos += marshal(out[outPos:], r, a, fx, fy, sm2.ByteSize())
|
||||
} else {
|
||||
outPos += marshal(out[outPos:], a, r, fx, fy, sm2.ByteSize())
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ClientKeyGen_two 客户端第二步,根据服务端第二步计算数据计算公钥和中间数据并发送给服务端
|
||||
// in = (C_i0, C_i1), ...., for i = 1..128, 服务端计算的中间数据
|
||||
// out = [u^{-1}]·G, 给服务端的中间数据
|
||||
func (c *ClientSignKeyGenContext) ClientKeyGen_two(in []byte) (out []byte, err error) {
|
||||
|
||||
out = make([]byte, 2*sm2.ByteSize())
|
||||
u := new(big.Int)
|
||||
tmp1 := new(big.Int)
|
||||
tmp2 := new(big.Int)
|
||||
u.SetInt64(0)
|
||||
for i := 0; i < SecureParam; i++ {
|
||||
pos := (i*2 + int(c.K[i])) * sm2.ByteSize()
|
||||
tmp1.SetBytes(in[pos : pos+sm2.ByteSize()])
|
||||
pointToInt(tmp2, c.X[i], c.Y[i])
|
||||
tmp1.Sub(tmp1, tmp2)
|
||||
u.Add(u, tmp1)
|
||||
u.Mod(u, sm2.Curve().Params().N)
|
||||
}
|
||||
|
||||
u.ModInverse(u, sm2.Curve().Params().N)
|
||||
|
||||
tmp1, tmp2 = sm2.Curve256.ScalarBaseMult(u.Bytes())
|
||||
copy(out, gmath.BigIntToNByte(tmp1, sm2.ByteSize()))
|
||||
copy(out[sm2.ByteSize():], gmath.BigIntToNByte(tmp2, sm2.ByteSize()))
|
||||
|
||||
tmp1.SetBytes(in[2*SecureParam*sm2.ByteSize() : (2*SecureParam+1)*sm2.ByteSize()])
|
||||
tmp2.SetBytes(in[(2*SecureParam+1)*sm2.ByteSize() : (2*SecureParam+2)*sm2.ByteSize()])
|
||||
x, y := sm2.Curve256.ScalarMult(tmp1, tmp2, u.Bytes())
|
||||
y.Sub(sm2.Curve().Params().P, y)
|
||||
// 客户端计算公钥
|
||||
x, y = sm2.Curve().Add(x, y, sm2.Curve().Params().Gx, sm2.Curve().Params().Gy)
|
||||
y.Sub(sm2.Curve().Params().P, y)
|
||||
c.PubKey.X.Set(x)
|
||||
c.PubKey.Y.Set(y)
|
||||
|
||||
c.ClientSubKey.SetBigInt(u)
|
||||
c.isClientKeyReady = true
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func marshal(out []byte, a, b, c, d *big.Int, n int) int {
|
||||
outPos := 0
|
||||
outPos += copy(out[outPos:], gmath.BigIntToNByte(a, n))
|
||||
outPos += copy(out[outPos:], gmath.BigIntToNByte(b, n))
|
||||
outPos += copy(out[outPos:], gmath.BigIntToNByte(c, n))
|
||||
outPos += copy(out[outPos:], gmath.BigIntToNByte(d, n))
|
||||
return outPos
|
||||
}
|
||||
Reference in New Issue
Block a user