github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/crypto/ecdsa/ecdsa_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ecdsa 6 7 import ( 8 "bufio" 9 "compress/bzip2" 10 "crypto/elliptic" 11 "crypto/rand" 12 "crypto/sha1" 13 "crypto/sha256" 14 "crypto/sha512" 15 "encoding/hex" 16 "hash" 17 "io" 18 "math/big" 19 "os" 20 "strings" 21 "testing" 22 ) 23 24 func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) { 25 tests := []struct { 26 name string 27 curve elliptic.Curve 28 }{ 29 {"P256", elliptic.P256()}, 30 {"P224", elliptic.P224()}, 31 {"P384", elliptic.P384()}, 32 {"P521", elliptic.P521()}, 33 } 34 if testing.Short() { 35 tests = tests[:1] 36 } 37 for _, test := range tests { 38 curve := test.curve 39 t.Run(test.name, func(t *testing.T) { 40 t.Parallel() 41 f(t, curve) 42 }) 43 } 44 } 45 46 func TestKeyGeneration(t *testing.T) { 47 testAllCurves(t, testKeyGeneration) 48 } 49 50 func testKeyGeneration(t *testing.T, c elliptic.Curve) { 51 priv, err := GenerateKey(c, rand.Reader) 52 if err != nil { 53 t.Fatal(err) 54 } 55 if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) { 56 t.Errorf("public key invalid: %s", err) 57 } 58 } 59 60 func TestSignAndVerify(t *testing.T) { 61 testAllCurves(t, testSignAndVerify) 62 } 63 64 func testSignAndVerify(t *testing.T, c elliptic.Curve) { 65 priv, _ := GenerateKey(c, rand.Reader) 66 67 hashed := []byte("testing") 68 r, s, err := Sign(rand.Reader, priv, hashed) 69 if err != nil { 70 t.Errorf("error signing: %s", err) 71 return 72 } 73 74 if !Verify(&priv.PublicKey, hashed, r, s) { 75 t.Errorf("Verify failed") 76 } 77 78 hashed[0] ^= 0xff 79 if Verify(&priv.PublicKey, hashed, r, s) { 80 t.Errorf("Verify always works!") 81 } 82 } 83 84 func TestSignAndVerifyASN1(t *testing.T) { 85 testAllCurves(t, testSignAndVerifyASN1) 86 } 87 88 func testSignAndVerifyASN1(t *testing.T, c elliptic.Curve) { 89 priv, _ := GenerateKey(c, rand.Reader) 90 91 hashed := []byte("testing") 92 sig, err := SignASN1(rand.Reader, priv, hashed) 93 if err != nil { 94 t.Errorf("error signing: %s", err) 95 return 96 } 97 98 if !VerifyASN1(&priv.PublicKey, hashed, sig) { 99 t.Errorf("VerifyASN1 failed") 100 } 101 102 hashed[0] ^= 0xff 103 if VerifyASN1(&priv.PublicKey, hashed, sig) { 104 t.Errorf("VerifyASN1 always works!") 105 } 106 } 107 108 func TestNonceSafety(t *testing.T) { 109 testAllCurves(t, testNonceSafety) 110 } 111 112 func testNonceSafety(t *testing.T, c elliptic.Curve) { 113 priv, _ := GenerateKey(c, rand.Reader) 114 115 hashed := []byte("testing") 116 r0, s0, err := Sign(zeroReader, priv, hashed) 117 if err != nil { 118 t.Errorf("error signing: %s", err) 119 return 120 } 121 122 hashed = []byte("testing...") 123 r1, s1, err := Sign(zeroReader, priv, hashed) 124 if err != nil { 125 t.Errorf("error signing: %s", err) 126 return 127 } 128 129 if s0.Cmp(s1) == 0 { 130 // This should never happen. 131 t.Errorf("the signatures on two different messages were the same") 132 } 133 134 if r0.Cmp(r1) == 0 { 135 t.Errorf("the nonce used for two different messages was the same") 136 } 137 } 138 139 func TestINDCCA(t *testing.T) { 140 testAllCurves(t, testINDCCA) 141 } 142 143 func testINDCCA(t *testing.T, c elliptic.Curve) { 144 priv, _ := GenerateKey(c, rand.Reader) 145 146 hashed := []byte("testing") 147 r0, s0, err := Sign(rand.Reader, priv, hashed) 148 if err != nil { 149 t.Errorf("error signing: %s", err) 150 return 151 } 152 153 r1, s1, err := Sign(rand.Reader, priv, hashed) 154 if err != nil { 155 t.Errorf("error signing: %s", err) 156 return 157 } 158 159 if s0.Cmp(s1) == 0 { 160 t.Errorf("two signatures of the same message produced the same result") 161 } 162 163 if r0.Cmp(r1) == 0 { 164 t.Errorf("two signatures of the same message produced the same nonce") 165 } 166 } 167 168 func fromHex(s string) *big.Int { 169 r, ok := new(big.Int).SetString(s, 16) 170 if !ok { 171 panic("bad hex") 172 } 173 return r 174 } 175 176 func TestVectors(t *testing.T) { 177 // This test runs the full set of NIST test vectors from 178 // https://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip 179 // 180 // The SigVer.rsp file has been edited to remove test vectors for 181 // unsupported algorithms and has been compressed. 182 183 if testing.Short() { 184 return 185 } 186 187 f, err := os.Open("testdata/SigVer.rsp.bz2") 188 if err != nil { 189 t.Fatal(err) 190 } 191 192 buf := bufio.NewReader(bzip2.NewReader(f)) 193 194 lineNo := 1 195 var h hash.Hash 196 var msg []byte 197 var hashed []byte 198 var r, s *big.Int 199 pub := new(PublicKey) 200 201 for { 202 line, err := buf.ReadString('\n') 203 if len(line) == 0 { 204 if err == io.EOF { 205 break 206 } 207 t.Fatalf("error reading from input: %s", err) 208 } 209 lineNo++ 210 // Need to remove \r\n from the end of the line. 211 if !strings.HasSuffix(line, "\r\n") { 212 t.Fatalf("bad line ending (expected \\r\\n) on line %d", lineNo) 213 } 214 line = line[:len(line)-2] 215 216 if len(line) == 0 || line[0] == '#' { 217 continue 218 } 219 220 if line[0] == '[' { 221 line = line[1 : len(line)-1] 222 parts := strings.SplitN(line, ",", 2) 223 224 switch parts[0] { 225 case "P-224": 226 pub.Curve = elliptic.P224() 227 case "P-256": 228 pub.Curve = elliptic.P256() 229 case "P-384": 230 pub.Curve = elliptic.P384() 231 case "P-521": 232 pub.Curve = elliptic.P521() 233 default: 234 pub.Curve = nil 235 } 236 237 switch parts[1] { 238 case "SHA-1": 239 h = sha1.New() 240 case "SHA-224": 241 h = sha256.New224() 242 case "SHA-256": 243 h = sha256.New() 244 case "SHA-384": 245 h = sha512.New384() 246 case "SHA-512": 247 h = sha512.New() 248 default: 249 h = nil 250 } 251 252 continue 253 } 254 255 if h == nil || pub.Curve == nil { 256 continue 257 } 258 259 switch { 260 case strings.HasPrefix(line, "Msg = "): 261 if msg, err = hex.DecodeString(line[6:]); err != nil { 262 t.Fatalf("failed to decode message on line %d: %s", lineNo, err) 263 } 264 case strings.HasPrefix(line, "Qx = "): 265 pub.X = fromHex(line[5:]) 266 case strings.HasPrefix(line, "Qy = "): 267 pub.Y = fromHex(line[5:]) 268 case strings.HasPrefix(line, "R = "): 269 r = fromHex(line[4:]) 270 case strings.HasPrefix(line, "S = "): 271 s = fromHex(line[4:]) 272 case strings.HasPrefix(line, "Result = "): 273 expected := line[9] == 'P' 274 h.Reset() 275 h.Write(msg) 276 hashed := h.Sum(hashed[:0]) 277 if Verify(pub, hashed, r, s) != expected { 278 t.Fatalf("incorrect result on line %d", lineNo) 279 } 280 default: 281 t.Fatalf("unknown variable on line %d: %s", lineNo, line) 282 } 283 } 284 } 285 286 func TestNegativeInputs(t *testing.T) { 287 testAllCurves(t, testNegativeInputs) 288 } 289 290 func testNegativeInputs(t *testing.T, curve elliptic.Curve) { 291 key, err := GenerateKey(curve, rand.Reader) 292 if err != nil { 293 t.Errorf("failed to generate key") 294 } 295 296 var hash [32]byte 297 r := new(big.Int).SetInt64(1) 298 r.Lsh(r, 550 /* larger than any supported curve */) 299 r.Neg(r) 300 301 if Verify(&key.PublicKey, hash[:], r, r) { 302 t.Errorf("bogus signature accepted") 303 } 304 } 305 306 func TestZeroHashSignature(t *testing.T) { 307 testAllCurves(t, testZeroHashSignature) 308 } 309 310 func testZeroHashSignature(t *testing.T, curve elliptic.Curve) { 311 zeroHash := make([]byte, 64) 312 313 privKey, err := GenerateKey(curve, rand.Reader) 314 if err != nil { 315 panic(err) 316 } 317 318 // Sign a hash consisting of all zeros. 319 r, s, err := Sign(rand.Reader, privKey, zeroHash) 320 if err != nil { 321 panic(err) 322 } 323 324 // Confirm that it can be verified. 325 if !Verify(&privKey.PublicKey, zeroHash, r, s) { 326 t.Errorf("zero hash signature verify failed for %T", curve) 327 } 328 } 329 330 func benchmarkAllCurves(t *testing.B, f func(*testing.B, elliptic.Curve)) { 331 tests := []struct { 332 name string 333 curve elliptic.Curve 334 }{ 335 {"P256", elliptic.P256()}, 336 {"P224", elliptic.P224()}, 337 {"P384", elliptic.P384()}, 338 {"P521", elliptic.P521()}, 339 } 340 for _, test := range tests { 341 curve := test.curve 342 t.Run(test.name, func(t *testing.B) { 343 f(t, curve) 344 }) 345 } 346 } 347 348 func BenchmarkSign(b *testing.B) { 349 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) { 350 priv, err := GenerateKey(curve, rand.Reader) 351 if err != nil { 352 b.Fatal(err) 353 } 354 hashed := []byte("testing") 355 356 b.ReportAllocs() 357 b.ResetTimer() 358 for i := 0; i < b.N; i++ { 359 sig, err := SignASN1(rand.Reader, priv, hashed) 360 if err != nil { 361 b.Fatal(err) 362 } 363 // Prevent the compiler from optimizing out the operation. 364 hashed[0] = sig[0] 365 } 366 }) 367 } 368 369 func BenchmarkVerify(b *testing.B) { 370 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) { 371 priv, err := GenerateKey(curve, rand.Reader) 372 if err != nil { 373 b.Fatal(err) 374 } 375 hashed := []byte("testing") 376 r, s, err := Sign(rand.Reader, priv, hashed) 377 if err != nil { 378 b.Fatal(err) 379 } 380 381 b.ReportAllocs() 382 b.ResetTimer() 383 for i := 0; i < b.N; i++ { 384 if !Verify(&priv.PublicKey, hashed, r, s) { 385 b.Fatal("verify failed") 386 } 387 } 388 }) 389 } 390 391 func BenchmarkGenerateKey(b *testing.B) { 392 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) { 393 b.ReportAllocs() 394 b.ResetTimer() 395 for i := 0; i < b.N; i++ { 396 if _, err := GenerateKey(curve, rand.Reader); err != nil { 397 b.Fatal(err) 398 } 399 } 400 }) 401 }