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 }