diff --git a/sm2/sm2.go b/sm2/sm2.go index 891e5b9..dddb049 100644 --- a/sm2/sm2.go +++ b/sm2/sm2.go @@ -570,7 +570,8 @@ func fermatInverse(k, N *big.Int) *big.Int { // private key's curve order, the hash will be truncated to that length. It // returns the signature as a pair of integers. The security of the private key // depends on the entropy of rand. -// https://crypto.stackexchange.com/questions/60644/what-does-chopmd-refer-to-in-the-default-go-ecdsa-package +// Backgroud: https://github.com/golang/go/commit/a8049f58f9e3336554da1b0a4f8ea3b9c5cd669c +// func Sign(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (r, s *big.Int, err error) { if !strings.EqualFold(priv.Params().Name, P256().Params().Name) { return ecdsa.Sign(rand, priv, hash) diff --git a/sm2/sm2_test.go b/sm2/sm2_test.go index 00bb930..eeee535 100644 --- a/sm2/sm2_test.go +++ b/sm2/sm2_test.go @@ -250,6 +250,58 @@ func Test_signVerify(t *testing.T) { } } +func TestNonceSafety(t *testing.T) { + priv, _ := GenerateKey(rand.Reader) + + hashed := []byte("testing") + r0, s0, err := Sign(zeroReader, &priv.PrivateKey, hashed) + if err != nil { + t.Errorf("SM2: error signing: %s", err) + return + } + + hashed = []byte("testing...") + r1, s1, err := Sign(zeroReader, &priv.PrivateKey, hashed) + if err != nil { + t.Errorf("SM2: error signing: %s", err) + return + } + + if s0.Cmp(s1) == 0 { + // This should never happen. + t.Error("SM2: the signatures on two different messages were the same") + } + + if r0.Cmp(r1) == 0 { + t.Error("SM2: the nonce used for two diferent messages was the same") + } +} + +func TestINDCCA(t *testing.T) { + priv, _ := GenerateKey(rand.Reader) + + hashed := []byte("testing") + r0, s0, err := Sign(rand.Reader, &priv.PrivateKey, hashed) + if err != nil { + t.Errorf("SM2: error signing: %s", err) + return + } + + r1, s1, err := Sign(rand.Reader, &priv.PrivateKey, hashed) + if err != nil { + t.Errorf("SM2: error signing: %s", err) + return + } + + if s0.Cmp(s1) == 0 { + t.Error("SM2: two signatures of the same message produced the same result") + } + + if r0.Cmp(r1) == 0 { + t.Error("SM2: two signatures of the same message produced the same nonce") + } +} + func benchmarkEncrypt(b *testing.B, curve elliptic.Curve, plaintext string) { for i := 0; i < b.N; i++ { priv, _ := ecdsa.GenerateKey(curve, rand.Reader)