github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/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.ResetTimer() 52 for i := 0; i < b.N; i++ { 53 _, _, _ = Sign(rand.Reader, priv, hashed) 54 } 55 } 56 57 func BenchmarkVerifyP256(b *testing.B) { 58 b.ResetTimer() 59 p256 := elliptic.P256() 60 hashed := []byte("testing") 61 priv, _ := GenerateKey(p256, rand.Reader) 62 r, s, _ := Sign(rand.Reader, priv, hashed) 63 64 b.ResetTimer() 65 for i := 0; i < b.N; i++ { 66 Verify(&priv.PublicKey, hashed, r, s) 67 } 68 } 69 70 func BenchmarkKeyGeneration(b *testing.B) { 71 b.ResetTimer() 72 p256 := elliptic.P256() 73 74 b.ResetTimer() 75 for i := 0; i < b.N; i++ { 76 GenerateKey(p256, rand.Reader) 77 } 78 } 79 80 func testSignAndVerify(t *testing.T, c elliptic.Curve, tag string) { 81 priv, _ := GenerateKey(c, rand.Reader) 82 83 hashed := []byte("testing") 84 r, s, err := Sign(rand.Reader, priv, hashed) 85 if err != nil { 86 t.Errorf("%s: error signing: %s", tag, err) 87 return 88 } 89 90 if !Verify(&priv.PublicKey, hashed, r, s) { 91 t.Errorf("%s: Verify failed", tag) 92 } 93 94 hashed[0] ^= 0xff 95 if Verify(&priv.PublicKey, hashed, r, s) { 96 t.Errorf("%s: Verify always works!", tag) 97 } 98 } 99 100 func TestSignAndVerify(t *testing.T) { 101 testSignAndVerify(t, elliptic.P224(), "p224") 102 if testing.Short() { 103 return 104 } 105 testSignAndVerify(t, elliptic.P256(), "p256") 106 testSignAndVerify(t, elliptic.P384(), "p384") 107 testSignAndVerify(t, elliptic.P521(), "p521") 108 } 109 110 func testNonceSafety(t *testing.T, c elliptic.Curve, tag string) { 111 priv, _ := GenerateKey(c, rand.Reader) 112 113 hashed := []byte("testing") 114 r0, s0, err := Sign(zeroReader, priv, hashed) 115 if err != nil { 116 t.Errorf("%s: error signing: %s", tag, err) 117 return 118 } 119 120 hashed = []byte("testing...") 121 r1, s1, err := Sign(zeroReader, priv, hashed) 122 if err != nil { 123 t.Errorf("%s: error signing: %s", tag, err) 124 return 125 } 126 127 if s0.Cmp(s1) == 0 { 128 // This should never happen. 129 t.Errorf("%s: the signatures on two different messages were the same", tag) 130 } 131 132 if r0.Cmp(r1) == 0 { 133 t.Errorf("%s: the nonce used for two diferent messages was the same", tag) 134 } 135 } 136 137 func TestNonceSafety(t *testing.T) { 138 testNonceSafety(t, elliptic.P224(), "p224") 139 if testing.Short() { 140 return 141 } 142 testNonceSafety(t, elliptic.P256(), "p256") 143 testNonceSafety(t, elliptic.P384(), "p384") 144 testNonceSafety(t, elliptic.P521(), "p521") 145 } 146 147 func testINDCCA(t *testing.T, c elliptic.Curve, tag string) { 148 priv, _ := GenerateKey(c, rand.Reader) 149 150 hashed := []byte("testing") 151 r0, s0, err := Sign(rand.Reader, priv, hashed) 152 if err != nil { 153 t.Errorf("%s: error signing: %s", tag, err) 154 return 155 } 156 157 r1, s1, err := Sign(rand.Reader, priv, hashed) 158 if err != nil { 159 t.Errorf("%s: error signing: %s", tag, err) 160 return 161 } 162 163 if s0.Cmp(s1) == 0 { 164 t.Errorf("%s: two signatures of the same message produced the same result", tag) 165 } 166 167 if r0.Cmp(r1) == 0 { 168 t.Errorf("%s: two signatures of the same message produced the same nonce", tag) 169 } 170 } 171 172 func TestINDCCA(t *testing.T) { 173 testINDCCA(t, elliptic.P224(), "p224") 174 if testing.Short() { 175 return 176 } 177 testINDCCA(t, elliptic.P256(), "p256") 178 testINDCCA(t, elliptic.P384(), "p384") 179 testINDCCA(t, elliptic.P521(), "p521") 180 } 181 182 func fromHex(s string) *big.Int { 183 r, ok := new(big.Int).SetString(s, 16) 184 if !ok { 185 panic("bad hex") 186 } 187 return r 188 } 189 190 func TestVectors(t *testing.T) { 191 // This test runs the full set of NIST test vectors from 192 // http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip 193 // 194 // The SigVer.rsp file has been edited to remove test vectors for 195 // unsupported algorithms and has been compressed. 196 197 if testing.Short() { 198 return 199 } 200 201 f, err := os.Open("testdata/SigVer.rsp.bz2") 202 if err != nil { 203 t.Fatal(err) 204 } 205 206 buf := bufio.NewReader(bzip2.NewReader(f)) 207 208 lineNo := 1 209 var h hash.Hash 210 var msg []byte 211 var hashed []byte 212 var r, s *big.Int 213 pub := new(PublicKey) 214 215 for { 216 line, err := buf.ReadString('\n') 217 if len(line) == 0 { 218 if err == io.EOF { 219 break 220 } 221 t.Fatalf("error reading from input: %s", err) 222 } 223 lineNo++ 224 // Need to remove \r\n from the end of the line. 225 if !strings.HasSuffix(line, "\r\n") { 226 t.Fatalf("bad line ending (expected \\r\\n) on line %d", lineNo) 227 } 228 line = line[:len(line)-2] 229 230 if len(line) == 0 || line[0] == '#' { 231 continue 232 } 233 234 if line[0] == '[' { 235 line = line[1 : len(line)-1] 236 parts := strings.SplitN(line, ",", 2) 237 238 switch parts[0] { 239 case "P-224": 240 pub.Curve = elliptic.P224() 241 case "P-256": 242 pub.Curve = elliptic.P256() 243 case "P-384": 244 pub.Curve = elliptic.P384() 245 case "P-521": 246 pub.Curve = elliptic.P521() 247 default: 248 pub.Curve = nil 249 } 250 251 switch parts[1] { 252 case "SHA-1": 253 h = sha1.New() 254 case "SHA-224": 255 h = sha256.New224() 256 case "SHA-256": 257 h = sha256.New() 258 case "SHA-384": 259 h = sha512.New384() 260 case "SHA-512": 261 h = sha512.New() 262 default: 263 h = nil 264 } 265 266 continue 267 } 268 269 if h == nil || pub.Curve == nil { 270 continue 271 } 272 273 switch { 274 case strings.HasPrefix(line, "Msg = "): 275 if msg, err = hex.DecodeString(line[6:]); err != nil { 276 t.Fatalf("failed to decode message on line %d: %s", lineNo, err) 277 } 278 case strings.HasPrefix(line, "Qx = "): 279 pub.X = fromHex(line[5:]) 280 case strings.HasPrefix(line, "Qy = "): 281 pub.Y = fromHex(line[5:]) 282 case strings.HasPrefix(line, "R = "): 283 r = fromHex(line[4:]) 284 case strings.HasPrefix(line, "S = "): 285 s = fromHex(line[4:]) 286 case strings.HasPrefix(line, "Result = "): 287 expected := line[9] == 'P' 288 h.Reset() 289 h.Write(msg) 290 hashed := h.Sum(hashed[:0]) 291 if Verify(pub, hashed, r, s) != expected { 292 t.Fatalf("incorrect result on line %d", lineNo) 293 } 294 default: 295 t.Fatalf("unknown variable on line %d: %s", lineNo, line) 296 } 297 } 298 }