Files
xgcl/tpc/sm2/sm2a/gen_sign_key_client.go
2026-05-27 23:03:00 +08:00

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
}