init: v1.0.0
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
package sm2a
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"xdx.jelly/xgcl/gmath"
|
||||
"xdx.jelly/xgcl/grand"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
)
|
||||
|
||||
type ClientSponsor struct {
|
||||
mixPoint *sm2.PublicKey
|
||||
KeyBits uint32
|
||||
z []byte
|
||||
r *sm2.PrivateKey // sponsor's temp private key
|
||||
clientKey *sm2.PrivateKey
|
||||
publicKey *sm2.PublicKey
|
||||
tempKeyOfSponsor *sm2.PublicKey
|
||||
tempKeyOfResponsor *sm2.PublicKey
|
||||
}
|
||||
|
||||
func NewClientSponsor(id []byte, clientKey *sm2.PrivateKey, publicKey *sm2.PublicKey) *ClientSponsor {
|
||||
return &ClientSponsor{
|
||||
z: sm2.PreComputeWithIdAndPubkey(id, publicKey),
|
||||
clientKey: sm2.NewPrivateKey().Set(clientKey),
|
||||
publicKey: sm2.NewPublicKey().Set(publicKey),
|
||||
tempKeyOfSponsor: sm2.NewPublicKey(),
|
||||
tempKeyOfResponsor: sm2.NewPublicKey(),
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateAgreementData 发起方客户端计算密钥交换数据
|
||||
func (c *ClientSponsor) GenerateAgreementData(rnd []byte) (tempKeyOfSponsor *sm2.PublicKey, err error) {
|
||||
if len(rnd) < sm2.ByteSize() {
|
||||
rnd = make([]byte, sm2.ByteSize())
|
||||
if _, err := grand.GenerateRandom(rnd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c.r, _ = sm2.GenPrivateKey(rnd[:sm2.ByteSize()])
|
||||
tempKeyOfSponsor = sm2.GenPublicKey(c.r)
|
||||
c.tempKeyOfSponsor.Set(tempKeyOfSponsor)
|
||||
return tempKeyOfSponsor, nil
|
||||
}
|
||||
|
||||
// GenerateKey_1of2 发起方客户端计算密钥第一步
|
||||
func (c *ClientSponsor) GenerateKey_1of2(pubkeyOfResponsor, tempKeyOfResponsor *sm2.PublicKey) ([]byte, error) {
|
||||
if !pubkeyOfResponsor.IsValid() || !tempKeyOfResponsor.IsValid() {
|
||||
return nil, fmt.Errorf("Input Public Key are not valid")
|
||||
}
|
||||
c.mixPoint = mixPoint(pubkeyOfResponsor, tempKeyOfResponsor) // P+[x_R]·R
|
||||
return marshalPoint(c.mixPoint), nil
|
||||
}
|
||||
|
||||
// GenerateKey_2of2 发起方客户端计算密钥第二步
|
||||
func (c *ClientSponsor) GenerateKey_2of2(keyLength int, idOfResponsor []byte, fromServer []byte, pubkeyOfResponsor *sm2.PublicKey, clientKey *sm2.PrivateKey) (key []byte, err error) {
|
||||
if len(fromServer) < 2*sm2.ByteSize() {
|
||||
return nil, fmt.Errorf("Input Public Key are not valid")
|
||||
}
|
||||
|
||||
tempKeyOfServer := unmarshalPoint(fromServer)
|
||||
if !tempKeyOfServer.IsValid() || !pubkeyOfResponsor.IsValid() {
|
||||
return nil, fmt.Errorf("Input Public Key are not valid")
|
||||
}
|
||||
|
||||
// U = [d_c + d_s + \bar{x_1} * r_A]*MixPointB
|
||||
// = [d_s]*MixPointB + [d_c + \bar{x_1} * r_A]*MixPointB
|
||||
w := sm2.XBar(c.tempKeyOfSponsor.X)
|
||||
w.Mul(w, c.r.D)
|
||||
w.Add(w, clientKey.D)
|
||||
w.Mod(w, sm2.OrderN())
|
||||
x, y := sm2.Curve256.ScalarMult(c.mixPoint.X, c.mixPoint.Y, w.Bytes())
|
||||
x, y = sm2.Curve().Add(x, y, tempKeyOfServer.X, tempKeyOfServer.Y) // U = (x,y)
|
||||
|
||||
// printLog("U= %x\n", append(append([]byte{}, x.Bytes()...), y.Bytes()...))
|
||||
|
||||
if gmath.IsBigInt0(x) && gmath.IsBigInt0(y) {
|
||||
return nil, fmt.Errorf("U is zero")
|
||||
}
|
||||
|
||||
key = make([]byte, keyLength)
|
||||
sm2.Kdf(key,
|
||||
gmath.BigIntToNByte(x, sm2.ByteSize()),
|
||||
gmath.BigIntToNByte(y, sm2.ByteSize()),
|
||||
c.z,
|
||||
sm2.PreComputeWithIdAndPubkey(idOfResponsor, pubkeyOfResponsor))
|
||||
|
||||
return key, nil
|
||||
|
||||
}
|
||||
|
||||
type ClientResponsor struct {
|
||||
z []byte
|
||||
clientKey *sm2.PrivateKey
|
||||
publicKey *sm2.PublicKey
|
||||
|
||||
mixPoint *sm2.PublicKey
|
||||
}
|
||||
|
||||
// NewResponsor return a responsor's instance
|
||||
func NewClientResponsor(id []byte, clientKey *sm2.PrivateKey, publicKey *sm2.PublicKey) *ClientResponsor {
|
||||
return &ClientResponsor{
|
||||
z: sm2.PreComputeWithIdAndPubkey(id, publicKey),
|
||||
clientKey: sm2.NewPrivateKey().Set(clientKey),
|
||||
publicKey: sm2.NewPublicKey().Set(publicKey),
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateAgreementDataAndKey_1of2 响应方客户端生成数据和密钥第一步
|
||||
func (cr *ClientResponsor) GenerateAgreementDataAndKey_1of2(pubkeyOfSponsor, tempKeyOfSponsor *sm2.PublicKey) (toServer []byte, err error) {
|
||||
if !pubkeyOfSponsor.IsValid() || !tempKeyOfSponsor.IsValid() {
|
||||
return nil, fmt.Errorf("Input Public Key are not valid")
|
||||
}
|
||||
cr.mixPoint = mixPoint(pubkeyOfSponsor, tempKeyOfSponsor)
|
||||
return marshalPoint(cr.mixPoint), nil
|
||||
}
|
||||
|
||||
// GenerateAgreementDataAndKey_1of2 响应方客户端生成数据和密钥第二步
|
||||
func (cr *ClientResponsor) GenerateAgreementDataAndKey_2of2(keyLength int, idOfSponsor []byte, pubkeyOfSponsor *sm2.PublicKey, fromServer []byte, rnd []byte) (key []byte, tempKeyOfResponsor *sm2.PublicKey, err error) {
|
||||
if len(fromServer) < 2*sm2.ByteSize() {
|
||||
return nil, nil, fmt.Errorf("Input Public Key are not valid")
|
||||
}
|
||||
|
||||
tempKeyOfServer := unmarshalPoint(fromServer)
|
||||
if !pubkeyOfSponsor.IsValid() || !tempKeyOfServer.IsValid() {
|
||||
return nil, nil, fmt.Errorf("Input Public Key are not valid")
|
||||
}
|
||||
|
||||
if len(rnd) < sm2.ByteSize() {
|
||||
rnd = make([]byte, sm2.ByteSize())
|
||||
if _, err := grand.GenerateRandom(rnd); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
rb, _ := sm2.GenPrivateKey(rnd[:sm2.ByteSize()])
|
||||
tempKeyOfResponsor = sm2.GenPublicKey(rb)
|
||||
|
||||
w := sm2.XBar(tempKeyOfResponsor.X)
|
||||
w.Mul(w, rb.D)
|
||||
w.Add(w, cr.clientKey.D)
|
||||
w.Mod(w, sm2.OrderN())
|
||||
x, y := sm2.Curve256.ScalarMult(cr.mixPoint.X, cr.mixPoint.Y, w.Bytes())
|
||||
x, y = sm2.Curve().Add(x, y, tempKeyOfServer.X, tempKeyOfServer.Y) // V = (x,y)
|
||||
|
||||
// printLog("V=", append(append([]byte{}, x.Bytes()...), y.Bytes()...))
|
||||
|
||||
if gmath.IsBigInt0(x) && gmath.IsBigInt0(y) {
|
||||
return nil, nil, fmt.Errorf("U is zero")
|
||||
}
|
||||
|
||||
key = make([]byte, keyLength)
|
||||
sm2.Kdf(key,
|
||||
gmath.BigIntToNByte(x, sm2.ByteSize()),
|
||||
gmath.BigIntToNByte(y, sm2.ByteSize()),
|
||||
sm2.PreComputeWithIdAndPubkey(idOfSponsor, pubkeyOfSponsor),
|
||||
cr.z,
|
||||
)
|
||||
|
||||
return key, tempKeyOfResponsor, nil
|
||||
}
|
||||
|
||||
// mixPoint return p+[x_r]·r
|
||||
func mixPoint(p, r *sm2.PublicKey) *sm2.PublicKey {
|
||||
xBar := sm2.XBar(r.X)
|
||||
x, y := sm2.Curve256.ScalarMult(r.X, r.Y, xBar.Bytes())
|
||||
x, y = sm2.Curve().Add(x, y, p.X, p.Y)
|
||||
return &sm2.PublicKey{X: x, Y: y}
|
||||
}
|
||||
|
||||
func marshalPoint(p *sm2.PublicKey) []byte {
|
||||
out := make([]byte, 0, 2*sm2.ByteSize())
|
||||
out = append(out, gmath.BigIntToNByte(p.X, sm2.ByteSize())...)
|
||||
out = append(out, gmath.BigIntToNByte(p.Y, sm2.ByteSize())...)
|
||||
return out
|
||||
}
|
||||
|
||||
func unmarshalPoint(b []byte) *sm2.PublicKey {
|
||||
ret := sm2.NewPublicKey()
|
||||
ret.X.SetBytes(b[:sm2.ByteSize()])
|
||||
ret.Y.SetBytes(b[sm2.ByteSize() : 2*sm2.ByteSize()])
|
||||
return ret
|
||||
}
|
||||
Reference in New Issue
Block a user