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