init: v1.0.0

This commit is contained in:
yaole
2026-05-27 23:03:00 +08:00
commit 8d97f750eb
466 changed files with 80067 additions and 0 deletions
+107
View File
@@ -0,0 +1,107 @@
package concentration
import (
"encoding/binary"
"fmt"
"hash/crc32"
"math/big"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/sm/sm2"
"xdx.jelly/xgcl/sm/sm3"
)
var (
ErrClientGenerateAgreementData = fmt.Errorf("client GenerateAgreementData error")
)
type ClientKeyGenContext struct {
ks *sm2.PrivateKey
ppub *sm2.PublicKey
clientPub *sm2.PublicKey
}
func NewClientKeyGenContext() *ClientKeyGenContext {
return &ClientKeyGenContext{}
}
// GenerateTempKGC output data, and send to server
// in: serverData, server临时公钥U
// out: []byte, ppub_x || ppub_y || W_x || W_y || t || check
func (c *ClientKeyGenContext) GenerateAgreementData(serverData []byte, clientID []byte) ([]byte, *sm2.PublicKey, error) {
var data []byte
var err error
serverTempPubkey := sm2.NewPublicKey()
if err = serverTempPubkey.UnmarshalBinary(serverData); err != nil {
return []byte{}, nil, ErrClientGenerateAgreementData
}
if c.ks, err = sm2.GenPrivateKey(grand.GetRandom(sm2.ByteSize())); err != nil {
return []byte{}, nil, ErrClientGenerateAgreementData
}
c.ppub = sm2.GenPublicKey(c.ks)
data = make([]byte, 0, 128+32+4)
data = append(data, gmath.BigIntToNByte(c.ppub.X, 32)...)
data = append(data, gmath.BigIntToNByte(c.ppub.Y, 32)...)
w, err := sm2.GenPrivateKey(grand.GetRandom(sm2.ByteSize()))
if err != nil {
return []byte{}, nil, ErrClientGenerateAgreementData
}
W := sm2.GenPublicKey(w)
data = append(data, gmath.BigIntToNByte(W.X, 32)...)
data = append(data, gmath.BigIntToNByte(W.Y, 32)...)
// FIXME: W.X.Bytes() may not 32-bytes
digest := sm3.Sum(W.Bytes(), sm2.PreComputeWithIdAndPubkey(clientID, c.ppub))
// digest := sm3.Sum(W.X.Bytes(), W.Y.Bytes(), sm2.PreComputeWithIdAndPubkey(clientID, c.ppub))
t := new(big.Int)
t.SetBytes(digest[:])
t.Mul(t, c.ks.D)
t.Add(t, w.D)
t.Mod(t, sm2.OrderN())
data = append(data, gmath.BigIntToNByte(t, sm2.ByteSize())...)
checkSum := crc32.ChecksumIEEE(data)
buf := make([]byte, 4)
binary.BigEndian.PutUint32(buf, checkSum)
data = append(data, buf...)
x, y := sm2.Curve256.ScalarBaseMult(t.Bytes())
x, y = sm2.Curve().Add(x, y, serverTempPubkey.X, serverTempPubkey.Y)
pk := &sm2.PublicKey{
X: x,
Y: y,
}
c.clientPub = sm2.NewPublicKey()
c.clientPub.X.Set(x)
c.clientPub.Y.Set(y)
return data, pk, nil
}
type ClientSignContext struct {
k *sm2.PrivateKey
r *big.Int
}
func NewClientSignContext() *ClientSignContext {
return &ClientSignContext{}
}
// GenerateSignData 生成签名中间数据和r
func (c *ClientSignContext) GenerateSignData(serverData []byte, e []byte) (dataToServer []byte, r []byte, err error) {
c.k = sm2.NewPrivateKey()
c.k.Random(grand.Reader)
c.r = new(big.Int)
c.r.SetBytes(e)
tempPK := sm2.NewPublicKey()
tempPK.X.SetBytes(serverData[:32])
tempPK.Y.SetBytes(serverData[32:])
x, _ := sm2.Curve256.ScalarMult(tempPK.X, tempPK.Y, c.k.Bytes())
c.r.Add(c.r, x)
c.r.Mod(c.r, sm2.OrderN())
return gmath.BigIntToNByte(c.k.D, 32), gmath.BigIntToNByte(c.r, 32), nil
}
+7
View File
@@ -0,0 +1,7 @@
# 合并签名
## 密钥生成流程
## 签名流程
+114
View File
@@ -0,0 +1,114 @@
package concentration
import (
"bytes"
"fmt"
"testing"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/sm/sm2"
)
func TestSign(t *testing.T) {
fmt.Println("============= 生成密钥 =============")
clientID := []byte("Teacher Tony")
serverKeyGenCTX := NewServerKeyGenContext()
clientKeyGenCTX := NewClientKeyGenContext()
// 1 server调用密码机获取32字节随机数。 GenerateAgreementData传出数据发送给客户端。
data, err := serverKeyGenCTX.GenerateAgreementData(grand.GetRandom(sm2.ByteSize()))
if err != nil {
panic(err)
}
//2 client 调用生成数据和公钥
data, clientPK, err := clientKeyGenCTX.GenerateAgreementData(data, clientID)
if err != nil {
panic(err)
}
// 3 server 计算密钥对
sk, serverPK, err := serverKeyGenCTX.ComputeKeyPair(data, clientID)
if err != nil {
panic(err)
}
// 服务端清除敏感信息
serverKeyGenCTX.Clear()
if !serverPK.Equals(clientPK) {
panic("clientPK != serverPK")
}
fmt.Println("server pubkey: ", serverPK)
fmt.Println("client pubkey: ", clientPK)
fmt.Printf("sk: %02x\n", sk)
fmt.Println()
fmt.Println("============= 签名 =============")
e := grand.GetRandom(32)
serverSignCTX := NewServerSignContext()
clientSignCTX := NewClientSignContext()
data, err = serverSignCTX.GenerateSignData(grand.GetRandom(32))
if err != nil {
panic(err)
}
data, clientR, err := clientSignCTX.GenerateSignData(data, e)
if err != nil {
panic(err)
}
sig, err := serverSignCTX.Sign(data, e, sk)
if err != nil {
panic(err)
}
sk.Clear()
fmt.Println("sig: ", sig)
fmt.Printf("client's r: %02x\n", clientR)
fmt.Println("serverPK verify: ", sm2.Verify(e, serverPK, sig))
fmt.Println("clientPK verify: ", sm2.Verify(e, clientPK, sig))
if (bytes.Compare(clientR, gmath.BigIntToNByte(sig.R, 32))) != 0 {
panic("client r != server r")
}
}
func TestMarshal(t *testing.T) {
ctx := NewServerSignContext()
ctx.k1 = sm2.NewPrivateKey().Random(grand.Reader)
ctx.u = sm2.NewPublicKey().Generate(ctx.k1)
ctx.clientPPub = sm2.NewPublicKey().Generate(sm2.NewPrivateKey().Random(grand.Reader))
buf, err := ctx.MarshalBinary()
if err != nil {
fmt.Println(err)
}
fmt.Printf("%x\n\n", buf)
ctx1 := NewServerSignContext()
err = ctx1.UnmarshalBinary(buf)
if err != nil {
fmt.Println(err)
}
buf, err = ctx1.MarshalBinary()
if err != nil {
fmt.Println(err)
}
fmt.Printf("%x\n\n", buf)
if ctx1.k1.D.Cmp(ctx.k1.D) != 0 {
t.Log()
t.Fail()
}
if !ctx1.u.Equals(ctx.u) {
t.Log()
t.Fail()
}
if !ctx1.clientPPub.Equals(ctx.clientPPub) {
t.Log()
t.Fail()
}
}
+245
View File
@@ -0,0 +1,245 @@
package concentration
import (
"encoding/binary"
"fmt"
"hash/crc32"
"math/big"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/sm/sm2"
)
var (
ErrServerKeyGen = fmt.Errorf("GenerateAgreementData error")
ErrInputDataInvalid = fmt.Errorf("input data invalid")
ErrServerSignError = fmt.Errorf("server sign error")
)
type ServerKeyGenContext struct {
d *sm2.PrivateKey
u *sm2.PublicKey
clientPPub *sm2.PublicKey
//sk *sm2.PrivateKey
//pk *sm2.PublicKey
}
func NewServerKeyGenContext() *ServerKeyGenContext {
return &ServerKeyGenContext{
d: sm2.NewPrivateKey(),
u: sm2.NewPublicKey(),
}
}
// GenerateAgreementData 根据客户端发送的数据生成临时数据并发送给客户度
func (s *ServerKeyGenContext) GenerateAgreementData(rnd32 []byte) ([]byte, error) {
var data []byte
var err error
if len(rnd32) < sm2.ByteSize() {
rnd32 = grand.GetRandom(sm2.ByteSize())
}
if s.d, err = sm2.GenPrivateKey(rnd32); err != nil {
return []byte{}, err
}
s.u = sm2.GenPublicKey(s.d)
if data, err = s.u.MarshalBinary(); err != nil {
return []byte{}, ErrServerKeyGen
}
return data, nil
}
// ComputeKeyPair clientData = ppub_x || ppub_y || W_x || W_y || t || check
// out key pair
func (s *ServerKeyGenContext) ComputeKeyPair(clientData []byte, clientID []byte) (*sm2.PrivateKey, *sm2.PublicKey, error) {
if len(clientData) < 64+64+32+4 {
return nil, nil, ErrInputDataInvalid
}
checkSumShouldBe := crc32.ChecksumIEEE(clientData[:64+64+32])
checkSum := binary.BigEndian.Uint32(clientData[128+32:])
if checkSum != checkSumShouldBe {
return nil, nil, ErrInputDataInvalid
}
sk := sm2.NewPrivateKey()
sk.SetBytes(clientData[128 : 128+32])
sk.D.Add(sk.D, s.d.D)
sk.D.Mod(sk.D, sm2.OrderN())
if gmath.IsBigInt0(sk.D) {
return nil, nil, ErrServerKeyGen
}
pk := sm2.GenPublicKey(sk)
//
//ppub := sm2.NewPublicKey()
//if err := ppub.UnmarshalBinary(clientData); err != nil{
// return nil, nil, ErrServerKeyGen
//}
//
//digest := sm3.Sum(clientData[64:128],sm2.PreComputeWithIdAndPubkey(clientID, ppub))
//PublicKey := sm2.Curve256.ScalarMult(ppub.X, ppub.Y, digest[:])
return sk, pk, nil
}
func (s *ServerKeyGenContext) Clear() {
s.d.Clear()
}
type ServerSignContext struct {
k1 *sm2.PrivateKey
u *sm2.PublicKey
clientPPub *sm2.PublicKey
}
func NewServerSignContext() *ServerSignContext {
return &ServerSignContext{
sm2.NewPrivateKey(),
sm2.NewPublicKey(),
sm2.NewPublicKey(),
}
}
func (s *ServerSignContext) MarshalBinary() ([]byte, error) {
if s.k1 == nil {
s.k1 = sm2.NewPrivateKey()
}
if s.u == nil {
s.u = sm2.NewPublicKey()
}
if s.clientPPub == nil {
s.clientPPub = sm2.NewPublicKey()
}
r := make([]byte, 0, 3*4+(4+sm2.ECCRefMaxLen)+(4+2*sm2.ECCRefMaxLen)+(4+2*sm2.ECCRefMaxLen))
var buf []byte
var uintBuf = make([]byte, 4)
var err error
if buf, err = s.k1.MarshalBinary(); err != nil {
return nil, err
}
binary.BigEndian.PutUint32(uintBuf, uint32(len(buf)))
r = append(r, uintBuf...)
r = append(r, buf...)
if buf, err = s.u.MarshalBinary(); err != nil {
return nil, err
}
binary.BigEndian.PutUint32(uintBuf, uint32(len(buf)))
r = append(r, uintBuf...)
r = append(r, buf...)
if buf, err = s.clientPPub.MarshalBinary(); err != nil {
return nil, err
}
binary.BigEndian.PutUint32(uintBuf, uint32(len(buf)))
r = append(r, uintBuf...)
r = append(r, buf...)
return r, nil
}
func (s *ServerSignContext) UnmarshalBinary(data []byte) error {
if s.k1 == nil {
s.k1 = sm2.NewPrivateKey()
}
if s.u == nil {
s.u = sm2.NewPublicKey()
}
if s.clientPPub == nil {
s.clientPPub = sm2.NewPublicKey()
}
var err error
if len(data) < 4 {
return fmt.Errorf("invalid input of ServerSignContext.UnmarshalBinary")
}
size := binary.BigEndian.Uint32(data)
data = data[4:]
if uint32(len(data)) < size {
return fmt.Errorf("invalid input of ServerSignContext.UnmarshalBinary")
}
if err = s.k1.UnmarshalBinary(data[:size]); err != nil {
return err
}
data = data[size:]
if len(data) < 4 {
return fmt.Errorf("invalid input of ServerSignContext.UnmarshalBinary")
}
size = binary.BigEndian.Uint32(data)
data = data[4:]
if uint32(len(data)) < size {
return fmt.Errorf("invalid input of ServerSignContext.UnmarshalBinary")
}
if err = s.u.UnmarshalBinary(data[:size]); err != nil {
return err
}
data = data[size:]
if len(data) < 4 {
return fmt.Errorf("invalid input of ServerSignContext.UnmarshalBinary")
}
size = binary.BigEndian.Uint32(data)
data = data[4:]
if uint32(len(data)) < size {
return fmt.Errorf("invalid input of ServerSignContext.UnmarshalBinary")
}
if err = s.clientPPub.UnmarshalBinary(data[:size]); err != nil {
return err
}
return nil
}
func (s *ServerSignContext) GenerateSignData(rnd32 []byte) ([]byte, error) {
var data []byte = make([]byte, 0, 64)
var err error
if len(rnd32) < sm2.ByteSize() {
rnd32 = grand.GetRandom(sm2.ByteSize())
}
if s.k1, err = sm2.GenPrivateKey(rnd32); err != nil {
}
s.u = sm2.GenPublicKey(s.k1)
data = append(data, gmath.BigIntToNByte(s.u.X, 32)...)
data = append(data, gmath.BigIntToNByte(s.u.Y, 32)...)
return data, nil
}
// Sign generate signature
// input: clientData 32 bytes
func (ssc *ServerSignContext) Sign(clientData []byte, e []byte, sk *sm2.PrivateKey) (*sm2.Signature, error) {
k := new(big.Int)
k.SetBytes(clientData)
k.Mul(k, ssc.k1.D)
k.Mod(k, sm2.OrderN())
x, _ := sm2.Curve256.ScalarBaseMult(k.Bytes())
r := new(big.Int)
r.SetBytes(e)
r.Add(x, r)
r.Mod(r, sm2.OrderN())
s := new(big.Int)
s.Set(sk.D)
s.Add(s, gmath.BigInt1)
s.ModInverse(s, sm2.OrderN())
k.Add(k, r)
s.Mul(s, k)
s.Sub(s, r)
s.Mod(s, sm2.OrderN())
sig := &sm2.Signature{
R: r,
S: s,
}
return sig, nil
}
func (ssc *ServerSignContext) Clear() {
ssc.k1.Clear()
}