diff --git a/go.mod b/go.mod index d0d472a..4e0e76e 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module github.com/emmansun/gmsm go 1.16 require ( - golang.org/x/crypto v0.2.0 + golang.org/x/crypto v0.3.0 golang.org/x/sys v0.2.0 ) diff --git a/go.sum b/go.sum index 05c024e..2f77b42 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= -golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -28,3 +28,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/sm2/sm2_test.go b/sm2/sm2_test.go index e4dc287..891e9c4 100644 --- a/sm2/sm2_test.go +++ b/sm2/sm2_test.go @@ -1,6 +1,7 @@ package sm2 import ( + "bufio" "bytes" "crypto" "crypto/ecdsa" @@ -19,7 +20,7 @@ import ( "golang.org/x/crypto/cryptobyte/asn1" ) -func Test_SplicingOrder(t *testing.T) { +func TestSplicingOrder(t *testing.T) { priv, _ := GenerateKey(rand.Reader) tests := []struct { name string @@ -65,7 +66,7 @@ func Test_SplicingOrder(t *testing.T) { } } -func Test_encryptDecrypt_ASN1(t *testing.T) { +func TestEncryptDecryptASN1(t *testing.T) { priv, _ := GenerateKey(rand.Reader) priv2, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) key2 := new(PrivateKey) @@ -142,7 +143,7 @@ func TestAdjustCiphertextSplicingOrder(t *testing.T) { } } -func Test_Ciphertext2ASN1(t *testing.T) { +func TestCiphertext2ASN1(t *testing.T) { priv, _ := GenerateKey(rand.Reader) tests := []struct { name string @@ -191,7 +192,7 @@ func Test_Ciphertext2ASN1(t *testing.T) { } } -func Test_ASN1Ciphertext2Plain(t *testing.T) { +func TestCiphertextASN12Plain(t *testing.T) { priv, _ := GenerateKey(rand.Reader) tests := []struct { name string @@ -223,7 +224,7 @@ func Test_ASN1Ciphertext2Plain(t *testing.T) { } } -func Test_encryptDecrypt(t *testing.T) { +func TestEncryptDecrypt(t *testing.T) { priv, _ := GenerateKey(rand.Reader) priv2, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) key2 := new(PrivateKey) @@ -292,7 +293,7 @@ func Test_encryptDecrypt(t *testing.T) { } } -func Test_signVerify(t *testing.T) { +func TestSignVerify(t *testing.T) { priv, _ := GenerateKey(rand.Reader) tests := []struct { name string @@ -305,20 +306,24 @@ func Test_signVerify(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - hash := sm3.Sum([]byte(tt.plainText)) - signature, err := priv.Sign(rand.Reader, hash[:], nil) + hashed := sm3.Sum([]byte(tt.plainText)) + signature, err := priv.Sign(rand.Reader, hashed[:], nil) if err != nil { t.Fatalf("sign failed %v", err) } - result := VerifyASN1(&priv.PublicKey, hash[:], signature) + result := VerifyASN1(&priv.PublicKey, hashed[:], signature) if !result { t.Fatal("verify failed") } + hashed[0] ^= 0xff + if VerifyASN1(&priv.PublicKey, hashed[:], signature) { + t.Errorf("VerifyASN1 always works!") + } }) } } -func Test_signVerifyLegacy(t *testing.T) { +func TestSignVerifyLegacy(t *testing.T) { priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) tests := []struct { name string @@ -331,22 +336,29 @@ func Test_signVerifyLegacy(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - hash := sm3.Sum([]byte(tt.plainText)) - r, s, err := Sign(rand.Reader, priv, hash[:]) + hashed := sm3.Sum([]byte(tt.plainText)) + r, s, err := Sign(rand.Reader, priv, hashed[:]) if err != nil { t.Fatalf("sign failed %v", err) } - result := Verify(&priv.PublicKey, hash[:], r, s) + result := Verify(&priv.PublicKey, hashed[:], r, s) if !result { t.Fatal("verify failed") } + hashed[0] ^= 0xff + if Verify(&priv.PublicKey, hashed[:], r, s) { + t.Errorf("VerifyASN1 always works!") + } }) } } // Check that signatures are safe even with a broken entropy source. func TestNonceSafety(t *testing.T) { - priv, _ := GenerateKey(rand.Reader) + priv, err := GenerateKey(rand.Reader) + if err != nil { + t.Errorf("failed to generate key") + } hashed := []byte("testing") r0, s0, err := Sign(zeroReader, &priv.PrivateKey, hashed) @@ -374,7 +386,10 @@ func TestNonceSafety(t *testing.T) { // Check that signatures remain non-deterministic with a functional entropy source. func TestINDCCA(t *testing.T) { - priv, _ := GenerateKey(rand.Reader) + priv, err := GenerateKey(rand.Reader) + if err != nil { + t.Errorf("failed to generate key") + } hashed := []byte("testing") r0, s0, err := Sign(rand.Reader, &priv.PrivateKey, hashed) @@ -398,6 +413,42 @@ func TestINDCCA(t *testing.T) { } } +func TestNegativeInputs(t *testing.T) { + key, err := GenerateKey(rand.Reader) + if err != nil { + t.Errorf("failed to generate key") + } + + var hash [32]byte + r := new(big.Int).SetInt64(1) + r.Lsh(r, 550 /* larger than any supported curve */) + r.Neg(r) + + if Verify(&key.PublicKey, hash[:], r, r) { + t.Errorf("bogus signature accepted") + } +} + +func TestZeroHashSignature(t *testing.T) { + zeroHash := make([]byte, 64) + + privKey, err := GenerateKey(rand.Reader) + if err != nil { + panic(err) + } + + // Sign a hash consisting of all zeros. + r, s, err := Sign(rand.Reader, &privKey.PrivateKey, zeroHash) + if err != nil { + panic(err) + } + + // Confirm that it can be verified. + if !Verify(&privKey.PublicKey, zeroHash, r, s) { + t.Errorf("zero hash signature verify failed") + } +} + func TestEqual(t *testing.T) { private, _ := GenerateKey(rand.Reader) public := &private.PublicKey @@ -516,27 +567,30 @@ func TestRandomPoint(t *testing.T) { } func BenchmarkGenerateKey_SM2(b *testing.B) { + r := bufio.NewReaderSize(rand.Reader, 1<<15) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - if _, err := GenerateKey(rand.Reader); err != nil { + if _, err := GenerateKey(r); err != nil { b.Fatal(err) } } } func BenchmarkGenerateKey_P256(b *testing.B) { + r := bufio.NewReaderSize(rand.Reader, 1<<15) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - if _, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil { + if _, err := ecdsa.GenerateKey(elliptic.P256(), r); err != nil { b.Fatal(err) } } } func BenchmarkSign_SM2(b *testing.B) { - priv, err := GenerateKey(rand.Reader) + r := bufio.NewReaderSize(rand.Reader, 1<<15) + priv, err := GenerateKey(r) if err != nil { b.Fatal(err) } @@ -555,7 +609,8 @@ func BenchmarkSign_SM2(b *testing.B) { } func BenchmarkSign_SM2Specific(b *testing.B) { - priv, err := GenerateKey(rand.Reader) + r := bufio.NewReaderSize(rand.Reader, 1<<15) + priv, err := GenerateKey(r) if err != nil { b.Fatal(err) } @@ -571,7 +626,8 @@ func BenchmarkSign_SM2Specific(b *testing.B) { } func BenchmarkSign_P256(b *testing.B) { - priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + r := bufio.NewReaderSize(rand.Reader, 1<<15) + priv, err := ecdsa.GenerateKey(elliptic.P256(), r) if err != nil { b.Fatal(err) } @@ -590,7 +646,8 @@ func BenchmarkSign_P256(b *testing.B) { } func BenchmarkVerify_P256(b *testing.B) { - priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + rd := bufio.NewReaderSize(rand.Reader, 1<<15) + priv, err := ecdsa.GenerateKey(elliptic.P256(), rd) if err != nil { b.Fatal(err) } @@ -610,7 +667,8 @@ func BenchmarkVerify_P256(b *testing.B) { } func BenchmarkVerify_SM2(b *testing.B) { - priv, err := GenerateKey(rand.Reader) + rd := bufio.NewReaderSize(rand.Reader, 1<<15) + priv, err := GenerateKey(rd) if err != nil { b.Fatal(err) } @@ -630,7 +688,8 @@ func BenchmarkVerify_SM2(b *testing.B) { } func benchmarkEncrypt(b *testing.B, curve elliptic.Curve, plaintext string) { - priv, err := ecdsa.GenerateKey(curve, rand.Reader) + r := bufio.NewReaderSize(rand.Reader, 1<<15) + priv, err := ecdsa.GenerateKey(curve, r) if err != nil { b.Fatal(err) }