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 }