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