sm2: add comments and refactor

This commit is contained in:
Sun Yimin 2023-12-15 15:11:49 +08:00 committed by GitHub
parent cad90f95ec
commit 515aa31259
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 19 deletions

View File

@ -620,7 +620,7 @@ func (priv *PrivateKey) inverseOfPrivateKeyPlus1(c *sm2Curve) (*bigmod.Nat, erro
} }
func signSM2EC(c *sm2Curve, priv *PrivateKey, rand io.Reader, hash []byte) (sig []byte, err error) { func signSM2EC(c *sm2Curve, priv *PrivateKey, rand io.Reader, hash []byte) (sig []byte, err error) {
// get/compute inv(d+1) // dp1Inv = (d+1)⁻¹
dp1Inv, err := priv.inverseOfPrivateKeyPlus1(c) dp1Inv, err := priv.inverseOfPrivateKeyPlus1(c)
if err != nil { if err != nil {
return nil, err return nil, err
@ -649,21 +649,27 @@ func signSM2EC(c *sm2Curve, priv *PrivateKey, rand io.Reader, hash []byte) (sig
if err != nil { if err != nil {
return nil, err return nil, err
} }
r.Add(e, c.N) // r = (Rx + e) mod N
// r = [Rx + e]
r.Add(e, c.N)
// checks if r is zero or [r+k] is zero
if r.IsZero() == 0 { if r.IsZero() == 0 {
t := bigmod.NewNat().Set(k) t := bigmod.NewNat().Set(k).Add(r, c.N)
t.Add(r, c.N) if t.IsZero() == 0 {
if t.IsZero() == 0 { // if (r + k) != N then ok
break break
} }
} }
} }
// s = [r * d]
s, err = bigmod.NewNat().SetBytes(priv.D.Bytes(), c.N) s, err = bigmod.NewNat().SetBytes(priv.D.Bytes(), c.N)
if err != nil { if err != nil {
return nil, err return nil, err
} }
s.Mul(r, c.N) s.Mul(r, c.N)
// k = [k - s]
k.Sub(s, c.N) k.Sub(s, c.N)
// k = [(d+1)⁻¹ * (k - r * d)]
k.Mul(dp1Inv, c.N) k.Mul(dp1Inv, c.N)
if k.IsZero() == 0 { if k.IsZero() == 0 {
break break
@ -738,21 +744,25 @@ func verifySM2EC(c *sm2Curve, pub *ecdsa.PublicKey, hash, sig []byte) bool {
e := bigmod.NewNat() e := bigmod.NewNat()
hashToNat(c, e, hash) hashToNat(c, e, hash)
// t = [r + s]
t := bigmod.NewNat().Set(r) t := bigmod.NewNat().Set(r)
t.Add(s, c.N) t.Add(s, c.N)
if t.IsZero() == 1 { if t.IsZero() == 1 {
return false return false
} }
// p₁ = [s]G
p1, err := c.newPoint().ScalarBaseMult(s.Bytes(c.N)) p1, err := c.newPoint().ScalarBaseMult(s.Bytes(c.N))
if err != nil { if err != nil {
return false return false
} }
// p₂ = [t]Q
p2, err := Q.ScalarMult(Q, t.Bytes(c.N)) p2, err := Q.ScalarMult(Q, t.Bytes(c.N))
if err != nil { if err != nil {
return false return false
} }
// BytesX returns an error for the point at infinity.
Rx, err := p1.Add(p1, p2).BytesX() Rx, err := p1.Add(p1, p2).BytesX()
if err != nil { if err != nil {
return false return false
@ -762,8 +772,8 @@ func verifySM2EC(c *sm2Curve, pub *ecdsa.PublicKey, hash, sig []byte) bool {
if err != nil { if err != nil {
return false return false
} }
v.Add(e, c.N) v.Add(e, c.N)
return v.Equal(r) == 1 return v.Equal(r) == 1
} }

View File

@ -9,7 +9,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"math/big"
"github.com/emmansun/gmsm/cipher" "github.com/emmansun/gmsm/cipher"
"github.com/emmansun/gmsm/sm4" "github.com/emmansun/gmsm/sm4"
@ -82,9 +81,9 @@ func MarshalEnvelopedPrivateKey(rand io.Reader, pub *ecdsa.PublicKey, tobeEnvelo
func ParseEnvelopedPrivateKey(priv *PrivateKey, enveloped []byte) (*PrivateKey, error) { func ParseEnvelopedPrivateKey(priv *PrivateKey, enveloped []byte) (*PrivateKey, error) {
// unmarshal the asn.1 data // unmarshal the asn.1 data
var ( var (
symAlgId pkix.AlgorithmIdentifier symAlgId pkix.AlgorithmIdentifier
encryptedPrivateKey, pub asn1.BitString encryptedPrivateKey, pub asn1.BitString
inner, symEncryptedKey, symAlgIdBytes cryptobyte.String inner, symEncryptedKey, symAlgIdBytes cryptobyte.String
) )
input := cryptobyte.String(enveloped) input := cryptobyte.String(enveloped)
if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) || if !input.ReadASN1(&inner, cryptobyte_asn1.SEQUENCE) ||
@ -106,9 +105,9 @@ func ParseEnvelopedPrivateKey(priv *PrivateKey, enveloped []byte) (*PrivateKey,
} }
// parse public key // parse public key
x, y := elliptic.Unmarshal(P256(), pub.RightAlign()) pubKey, err := NewPublicKey(pub.RightAlign())
if x == nil || y == nil { if err != nil {
return nil, errors.New("sm2: invald public key in enveloped data") return nil, err
} }
// decrypt symmetric cipher key // decrypt symmetric cipher key
@ -127,12 +126,11 @@ func ParseEnvelopedPrivateKey(priv *PrivateKey, enveloped []byte) (*PrivateKey,
plaintext := make([]byte, len(bytes)) plaintext := make([]byte, len(bytes))
mode.CryptBlocks(plaintext, bytes) mode.CryptBlocks(plaintext, bytes)
// Do we need to check length in order to be compatible with some implementations with padding? // Do we need to check length in order to be compatible with some implementations with padding?
sm2Key := new(PrivateKey) sm2Key, err := NewPrivateKey(plaintext)
sm2Key.D = new(big.Int).SetBytes(plaintext) if err != nil {
sm2Key.Curve = P256() return nil, err
sm2Key.X, sm2Key.Y = sm2Key.ScalarBaseMult(plaintext) }
if !sm2Key.PublicKey.Equal(pubKey) {
if sm2Key.X.Cmp(x) != 0 || sm2Key.Y.Cmp(y) != 0 {
return nil, errors.New("sm2: mismatch key pair in enveloped data") return nil, errors.New("sm2: mismatch key pair in enveloped data")
} }