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

267 lines
7.0 KiB
Go

package sm2a
import (
"crypto/rand"
"encoding/binary"
"fmt"
"io"
"math/big"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/grand/drng"
"xdx.jelly/xgcl/sm/sm2"
)
type ServerSignKeyGenContext struct {
B [SecureParam]*big.Int
X [SecureParam]*big.Int
ServerKey *sm2.PrivateKey
PubKey *sm2.PublicKey
ServerSubKey *sm2.PrivateKey // ServerSubKey * ClientSubKey = 1+d
isServerKeyReady bool
}
func NewServerSignKeyGenContext() *ServerSignKeyGenContext {
s := new(ServerSignKeyGenContext)
for i := 0; i < SecureParam; i++ {
s.B[i] = new(big.Int)
s.X[i] = new(big.Int)
}
s.ServerKey = sm2.NewPrivateKey()
s.PubKey = sm2.NewPublicKey()
s.ServerSubKey = sm2.NewPrivateKey()
return s
}
func (s *ServerSignKeyGenContext) GetServerKey() (*sm2.PrivateKey, error) {
if s.isServerKeyReady {
return s.ServerKey, nil
}
return nil, fmt.Errorf("Key agreement not finished")
}
func (s *ServerSignKeyGenContext) GetServerSubKey() (*sm2.PrivateKey, error) {
if s.isServerKeyReady {
return s.ServerSubKey, nil
}
return nil, fmt.Errorf("Key agreement not finished")
}
func (s *ServerSignKeyGenContext) GetPublicKey() (*sm2.PublicKey, error) {
if s.isServerKeyReady {
return s.PubKey, nil
}
return nil, fmt.Errorf("Key agreement not finished")
}
// MarshalBinary 保存ServerSignKeyGenContext
func (s *ServerSignKeyGenContext) MarshalBinary() ([]byte, error) {
out := make([]byte, 0, 8432)
size := sm2.ByteSize()
N := sm2.OrderN()
// binary.BigEndian.PutUint32(out[:4], uint32(SecureParam))
for i := 0; i < SecureParam; i++ {
s.B[i].Mod(s.B[i], N)
out = append(out, gmath.BigIntToNByte(s.B[i], size)...)
s.X[i].Mod(s.X[i], N)
out = append(out, gmath.BigIntToNByte(s.X[i], size)...)
}
// s.ServerSubKey.Mod(s.ServerSubKey, N)
// out = append(out, gmath.BigIntToNByte(s.ServerSubKey, size)...)
var buf4 [4]byte
buf, err := s.ServerSubKey.MarshalBinary()
if err != nil {
return nil, err
}
binary.BigEndian.PutUint32(buf4[:], uint32(len(buf)))
out = append(out, buf4[:]...)
out = append(out, buf...)
buf, err = s.ServerKey.MarshalBinary()
if err != nil {
return nil, err
}
binary.BigEndian.PutUint32(buf4[:], uint32(len(buf)))
out = append(out, buf4[:]...)
out = append(out, buf...)
buf, err = s.PubKey.MarshalBinary()
if err != nil {
return nil, err
}
binary.BigEndian.PutUint32(buf4[:], uint32(len(buf)))
out = append(out, buf4[:]...)
out = append(out, buf...)
if s.isServerKeyReady {
out = append(out, 1)
} else {
out = append(out, 0)
}
return out, nil
}
// UnmarshalBinary 恢复ServerSignKeyGenContext
func (s *ServerSignKeyGenContext) UnmarshalBinary(b []byte) error {
size := sm2.ByteSize()
for i := 0; i < SecureParam; i++ {
s.B[i].SetBytes(b[:size])
b = b[size:]
s.X[i].SetBytes(b[:size])
b = b[size:]
}
// s.ServerSubKey.SetBytes(b[:size])
// b = b[size:]
len := binary.BigEndian.Uint32(b)
b = b[4:]
if err := s.ServerSubKey.UnmarshalBinary(b[:len]); err != nil {
return err
}
b = b[len:]
len = binary.BigEndian.Uint32(b)
b = b[4:]
if err := s.ServerKey.UnmarshalBinary(b[:len]); err != nil {
return err
}
b = b[len:]
len = binary.BigEndian.Uint32(b)
b = b[4:]
if err := s.PubKey.UnmarshalBinary(b[:len]); err != nil {
return err
}
b = b[len:]
if b[0] != 0 {
s.isServerKeyReady = true
} else {
s.isServerKeyReady = false
}
return nil
}
// ServerGenKey_one 服务端第一步,生成协同密钥中间数据给客户端
// 计算(X_i,Y_i) = [x_i]·G
// 输出 X_1||Y_1||X_2||Y_2||....||X_128||Y_128
func (s *ServerSignKeyGenContext) ServerGenKey_one(rnd io.Reader) ([]byte, error) {
var err error
s.isServerKeyReady = false
buf := make([]byte, sm2.ByteSize())
out := make([]byte, 2*SecureParam*sm2.ByteSize())
defer func() {
for i := range buf {
buf[i] = 0 // 清除临时使用的内存数据
}
}()
// 使用基于SM3的随机比特生成器生成服务端签名密钥分量
s.ServerKey.D, err = rand.Int(drng.SM3Rng, sm2.OrderN())
if err != nil {
return nil, err
}
d := s.ServerKey.Get()
d.SetInt64(0)
// 服务端计算中间数据
for i := 0; i < SecureParam; i++ {
if n, err := rnd.Read(buf); n != len(buf) || err != nil {
return nil, fmt.Errorf("Generate random number error")
}
s.B[i].SetBytes(buf)
d.Add(d, s.B[i])
if n, err := rnd.Read(buf); n != len(buf) || err != nil {
return nil, fmt.Errorf("Generate random number error")
}
s.X[i].SetBytes(buf)
x, y := sm2.Curve256.ScalarBaseMult(buf)
copy(out[(i*2+1)*sm2.ByteSize()-len(x.Bytes()):], x.Bytes())
copy(out[(i*2+2)*sm2.ByteSize()-len(y.Bytes()):], y.Bytes())
}
d.Mod(d, sm2.OrderN())
return out, nil
}
// ServerGenKey_two 服务端第二步,收到客户端数据in,计算中间数据并返回给客户端
// 其中in = (h_i0, h_i1, F_ix, F_iy), ... , for i = 1...128
// 输出 (C_i0, C_i1), ...., for i = 1..128
func (s *ServerSignKeyGenContext) ServerGenKey_two(in []byte, rand io.Reader) ([]byte, error) {
tmp := new(big.Int)
h0 := new(big.Int)
h1 := new(big.Int)
fx := new(big.Int)
fy := new(big.Int)
out := make([]byte, 2*sm2.ByteSize()*SecureParam+2*sm2.ByteSize())
v := new(big.Int)
buf := make([]byte, sm2.ByteSize())
if n, err := rand.Read(buf); n != len(buf) || err != nil {
return nil, fmt.Errorf("Generate random number error")
}
v.SetBytes(buf)
v.Mod(v, sm2.Curve().Params().P)
pos := 0
for i := 0; i < SecureParam; i++ {
h0.SetBytes(in[pos : pos+sm2.ByteSize()])
pos += sm2.ByteSize()
h1.SetBytes(in[pos : pos+sm2.ByteSize()])
pos += sm2.ByteSize()
fx.SetBytes(in[pos : pos+sm2.ByteSize()])
pos += sm2.ByteSize()
fy.SetBytes(in[pos : pos+sm2.ByteSize()])
pos += sm2.ByteSize()
x, y := sm2.Curve256.ScalarMult(fx, fy, s.X[i].Bytes())
h0.Add(h0, s.B[i])
h0.Mul(h0, v)
pointToInt(tmp, x, y)
h0.Add(h0, tmp)
h0.Mod(h0, sm2.Curve().Params().N)
x, y = sm2.Curve256.ScalarBaseMult(s.X[i].Bytes())
y.Sub(sm2.Curve().Params().P, y)
fx, fy = sm2.Curve().Add(fx, fy, x, y)
x, y = sm2.Curve256.ScalarMult(fx, fy, s.X[i].Bytes())
h1.Add(h1, s.B[i])
h1.Mul(h1, v)
pointToInt(tmp, x, y)
h1.Add(h1, tmp)
h1.Mod(h1, sm2.Curve().Params().N)
copy(out[i*2*sm2.ByteSize():], gmath.BigIntToNByte(h0, sm2.ByteSize()))
copy(out[(i*2+1)*sm2.ByteSize():], gmath.BigIntToNByte(h1, sm2.ByteSize()))
}
fx, fy = sm2.Curve256.ScalarBaseMult(v.Bytes())
copy(out[SecureParam*2*sm2.ByteSize():], gmath.BigIntToNByte(fx, sm2.ByteSize()))
copy(out[(SecureParam*2+1)*sm2.ByteSize():], gmath.BigIntToNByte(fy, sm2.ByteSize()))
s.ServerSubKey.SetBigInt(v)
return out, nil
}
// ServerGenKey_three 服务端第三步,服务端计算公钥
// in = [u^{-1}]·G
func (s *ServerSignKeyGenContext) ServerGenKey_three(in []byte) (err error) {
x := new(big.Int)
y := new(big.Int)
x.SetBytes(in[:sm2.ByteSize()])
y.SetBytes(in[sm2.ByteSize() : 2*sm2.ByteSize()])
x, y = sm2.Curve256.ScalarMult(x, y, s.ServerSubKey.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)
s.PubKey.X.Set(x)
s.PubKey.Y.Set(y)
s.isServerKeyReady = true
return nil
}