172 lines
5.1 KiB
Go
172 lines
5.1 KiB
Go
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
|
|
}
|