init: v1.0.0
This commit is contained in:
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user