mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-22 02:06:18 +08:00
key exchange refactoring
This commit is contained in:
parent
461f4b6838
commit
b4b9cd07d9
@ -10,12 +10,6 @@ import (
|
|||||||
"github.com/emmansun/gmsm/sm3"
|
"github.com/emmansun/gmsm/sm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Point represent point on curve
|
|
||||||
type Point struct {
|
|
||||||
X *big.Int
|
|
||||||
Y *big.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyExchange key exchange struct, include internal stat in whole key exchange flow.
|
// KeyExchange key exchange struct, include internal stat in whole key exchange flow.
|
||||||
// Initiator's flow will be: NewKeyExchange -> InitKeyExchange -> transmission -> ConfirmResponder
|
// Initiator's flow will be: NewKeyExchange -> InitKeyExchange -> transmission -> ConfirmResponder
|
||||||
// Responder's flow will be: NewKeyExchange -> waiting ... -> RepondKeyExchange -> transmission -> ConfirmInitiator
|
// Responder's flow will be: NewKeyExchange -> waiting ... -> RepondKeyExchange -> transmission -> ConfirmInitiator
|
||||||
@ -26,17 +20,17 @@ type KeyExchange struct {
|
|||||||
z []byte // owner identifiable id
|
z []byte // owner identifiable id
|
||||||
peerPub *ecdsa.PublicKey // peer public key
|
peerPub *ecdsa.PublicKey // peer public key
|
||||||
peerZ []byte // peer identifiable id
|
peerZ []byte // peer identifiable id
|
||||||
r *big.Int // random which will be used to compute secret
|
r *big.Int // Ephemeral Private Key, random which will be used to compute secret
|
||||||
secret Point // generated secret which will be passed to peer
|
secret *ecdsa.PublicKey // Ephemeral Public Key, generated secret which will be passed to peer
|
||||||
peerSecret Point // received peer's secret
|
peerSecret *ecdsa.PublicKey // received peer's secret, Ephemeral Public Key
|
||||||
w2 *big.Int // internal state which will be used when compute the key and signature
|
w2 *big.Int // internal state which will be used when compute the key and signature, 2^w
|
||||||
w2Minus1 *big.Int // internal state which will be used when compute the key and signature
|
w2Minus1 *big.Int // internal state which will be used when compute the key and signature, 2^w – 1
|
||||||
v Point // internal state which will be used when compute the key and signature
|
v *ecdsa.PublicKey // internal state which will be used when compute the key and signature, u/v
|
||||||
key []byte // key will be used after key agreement
|
key []byte // shared key will be used after key agreement
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKey return key after key agreement
|
// GetSharedKey return shared key after key agreement
|
||||||
func (ke *KeyExchange) GetKey() []byte {
|
func (ke *KeyExchange) GetSharedKey() []byte {
|
||||||
return ke.key
|
return ke.key
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +56,13 @@ func NewKeyExchange(priv *PrivateKey, peerPub *ecdsa.PublicKey, uid, peerUID []b
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
ke.secret = &ecdsa.PublicKey{}
|
||||||
|
ke.secret.Curve = priv.PublicKey.Curve
|
||||||
|
ke.peerSecret = &ecdsa.PublicKey{}
|
||||||
|
ke.peerSecret.Curve = peerPub.Curve
|
||||||
|
ke.v = &ecdsa.PublicKey{}
|
||||||
|
ke.v.Curve = priv.PublicKey.Curve
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,13 +72,13 @@ func initKeyExchange(ke *KeyExchange, r *big.Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InitKeyExchange generate random with responder uid, for initiator's step A1-A3
|
// InitKeyExchange generate random with responder uid, for initiator's step A1-A3
|
||||||
func (ke *KeyExchange) InitKeyExchange(rand io.Reader) (*Point, error) {
|
func (ke *KeyExchange) InitKeyExchange(rand io.Reader) (*ecdsa.PublicKey, error) {
|
||||||
r, err := randFieldElement(ke.privateKey, rand)
|
r, err := randFieldElement(ke.privateKey, rand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
initKeyExchange(ke, r)
|
initKeyExchange(ke, r)
|
||||||
return &ke.secret, nil
|
return ke.secret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ke *KeyExchange) sign(isResponder bool, prefix byte) []byte {
|
func (ke *KeyExchange) sign(isResponder bool, prefix byte) []byte {
|
||||||
@ -107,7 +108,7 @@ func (ke *KeyExchange) sign(isResponder bool, prefix byte) []byte {
|
|||||||
return hash.Sum(nil)
|
return hash.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ke *KeyExchange) generateKey(isResponder bool) {
|
func (ke *KeyExchange) generateSharedKey(isResponder bool) {
|
||||||
var buffer []byte
|
var buffer []byte
|
||||||
buffer = append(buffer, toBytes(ke.privateKey, ke.v.X)...)
|
buffer = append(buffer, toBytes(ke.privateKey, ke.v.X)...)
|
||||||
buffer = append(buffer, toBytes(ke.privateKey, ke.v.Y)...)
|
buffer = append(buffer, toBytes(ke.privateKey, ke.v.Y)...)
|
||||||
@ -122,7 +123,7 @@ func (ke *KeyExchange) generateKey(isResponder bool) {
|
|||||||
ke.key = key
|
ke.key = key
|
||||||
}
|
}
|
||||||
|
|
||||||
func respondKeyExchange(ke *KeyExchange, r *big.Int, rA *Point) (*Point, []byte, error) {
|
func respondKeyExchange(ke *KeyExchange, r *big.Int, rA *ecdsa.PublicKey) (*ecdsa.PublicKey, []byte, error) {
|
||||||
ke.secret.X, ke.secret.Y = ke.privateKey.ScalarBaseMult(r.Bytes())
|
ke.secret.X, ke.secret.Y = ke.privateKey.ScalarBaseMult(r.Bytes())
|
||||||
ke.r = r
|
ke.r = r
|
||||||
// Calculate tB
|
// Calculate tB
|
||||||
@ -142,21 +143,21 @@ func respondKeyExchange(ke *KeyExchange, r *big.Int, rA *Point) (*Point, []byte,
|
|||||||
return nil, nil, errors.New("sm2: key exchange fail")
|
return nil, nil, errors.New("sm2: key exchange fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
ke.generateKey(true)
|
ke.generateSharedKey(true)
|
||||||
|
|
||||||
if !ke.genSignature {
|
if !ke.genSignature {
|
||||||
return &ke.secret, nil, nil
|
return ke.secret, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ke.secret, ke.sign(true, 0x02), nil
|
return ke.secret, ke.sign(true, 0x02), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RepondKeyExchange when responder receive rA, for responder's step B1-B8
|
// RepondKeyExchange when responder receive rA, for responder's step B1-B8
|
||||||
func (ke *KeyExchange) RepondKeyExchange(rand io.Reader, rA *Point) (*Point, []byte, error) {
|
func (ke *KeyExchange) RepondKeyExchange(rand io.Reader, rA *ecdsa.PublicKey) (*ecdsa.PublicKey, []byte, error) {
|
||||||
if !ke.privateKey.IsOnCurve(rA.X, rA.Y) {
|
if !ke.privateKey.IsOnCurve(rA.X, rA.Y) {
|
||||||
return nil, nil, errors.New("sm2: received invalid random from initiator")
|
return nil, nil, errors.New("sm2: received invalid random from initiator")
|
||||||
}
|
}
|
||||||
ke.peerSecret = *rA
|
ke.peerSecret = rA
|
||||||
r, err := randFieldElement(ke.privateKey, rand)
|
r, err := randFieldElement(ke.privateKey, rand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -165,11 +166,11 @@ func (ke *KeyExchange) RepondKeyExchange(rand io.Reader, rA *Point) (*Point, []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConfirmResponder for initiator's step A4-A10
|
// ConfirmResponder for initiator's step A4-A10
|
||||||
func (ke *KeyExchange) ConfirmResponder(rB *Point, sB []byte) ([]byte, error) {
|
func (ke *KeyExchange) ConfirmResponder(rB *ecdsa.PublicKey, sB []byte) ([]byte, error) {
|
||||||
if !ke.privateKey.IsOnCurve(rB.X, rB.Y) {
|
if !ke.privateKey.IsOnCurve(rB.X, rB.Y) {
|
||||||
return nil, errors.New("sm2: received invalid random from responder")
|
return nil, errors.New("sm2: received invalid random from responder")
|
||||||
}
|
}
|
||||||
ke.peerSecret = *rB
|
ke.peerSecret = rB
|
||||||
// Calcualte tA
|
// Calcualte tA
|
||||||
t := (&big.Int{}).And(ke.w2Minus1, ke.secret.X)
|
t := (&big.Int{}).And(ke.w2Minus1, ke.secret.X)
|
||||||
t.Add(ke.w2, t)
|
t.Add(ke.w2, t)
|
||||||
@ -187,7 +188,7 @@ func (ke *KeyExchange) ConfirmResponder(rB *Point, sB []byte) ([]byte, error) {
|
|||||||
if ke.v.X.Sign() == 0 && ke.v.Y.Sign() == 0 {
|
if ke.v.X.Sign() == 0 && ke.v.Y.Sign() == 0 {
|
||||||
return nil, errors.New("sm2: key exchange fail")
|
return nil, errors.New("sm2: key exchange fail")
|
||||||
}
|
}
|
||||||
ke.generateKey(false)
|
ke.generateSharedKey(false)
|
||||||
if len(sB) > 0 {
|
if len(sB) > 0 {
|
||||||
buffer := ke.sign(false, 0x02)
|
buffer := ke.sign(false, 0x02)
|
||||||
if goSubtle.ConstantTimeCompare(buffer, sB) != 1 {
|
if goSubtle.ConstantTimeCompare(buffer, sB) != 1 {
|
||||||
|
12
sm9/sm9.go
12
sm9/sm9.go
@ -511,7 +511,7 @@ type KeyExchange struct {
|
|||||||
g1 *bn256.GT // internal state which will be used when compute the key and signature
|
g1 *bn256.GT // internal state which will be used when compute the key and signature
|
||||||
g2 *bn256.GT // internal state which will be used when compute the key and signature
|
g2 *bn256.GT // internal state which will be used when compute the key and signature
|
||||||
g3 *bn256.GT // internal state which will be used when compute the key and signature
|
g3 *bn256.GT // internal state which will be used when compute the key and signature
|
||||||
key []byte // key will be used after key agreement
|
key []byte // shared key will be used after key agreement
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKeyExchange create one new KeyExchange object
|
// NewKeyExchange create one new KeyExchange object
|
||||||
@ -525,8 +525,8 @@ func NewKeyExchange(priv *EncryptPrivateKey, uid, peerUID []byte, keyLen int, ge
|
|||||||
return ke
|
return ke
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKey return key after key agreement
|
// GetSharedKey return key after key agreement
|
||||||
func (ke *KeyExchange) GetKey() []byte {
|
func (ke *KeyExchange) GetSharedKey() []byte {
|
||||||
return ke.key
|
return ke.key
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +571,7 @@ func (ke *KeyExchange) sign(isResponder bool, prefix byte) []byte {
|
|||||||
return hash.Sum(nil)
|
return hash.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ke *KeyExchange) generateKey(isResponder bool) {
|
func (ke *KeyExchange) generateSharedKey(isResponder bool) {
|
||||||
var buffer []byte
|
var buffer []byte
|
||||||
if isResponder {
|
if isResponder {
|
||||||
buffer = append(buffer, ke.peerUID...)
|
buffer = append(buffer, ke.peerUID...)
|
||||||
@ -607,7 +607,7 @@ func respondKeyExchange(ke *KeyExchange, hid byte, r *big.Int, rA *bn256.G1) (*b
|
|||||||
ke.g3.ScalarMult(ke.g1, r)
|
ke.g3.ScalarMult(ke.g1, r)
|
||||||
ke.g2 = ke.privateKey.EncryptMasterPublicKey.ScalarBaseMult(r)
|
ke.g2 = ke.privateKey.EncryptMasterPublicKey.ScalarBaseMult(r)
|
||||||
|
|
||||||
ke.generateKey(true)
|
ke.generateSharedKey(true)
|
||||||
|
|
||||||
if !ke.genSignature {
|
if !ke.genSignature {
|
||||||
return ke.secret, nil, nil
|
return ke.secret, nil, nil
|
||||||
@ -643,7 +643,7 @@ func (ke *KeyExchange) ConfirmResponder(rB *bn256.G1, sB []byte) ([]byte, error)
|
|||||||
return nil, errors.New("sm9: verify responder's signature fail")
|
return nil, errors.New("sm9: verify responder's signature fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ke.generateKey(false)
|
ke.generateSharedKey(false)
|
||||||
|
|
||||||
return ke.sign(false, 0x83), nil
|
return ke.sign(false, 0x83), nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user