github.com/lbryio/lbcd@v0.22.119/btcec/btcec_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Copyright 2011 ThePiachu. All rights reserved. 3 // Copyright 2013-2016 The btcsuite developers 4 // Use of this source code is governed by an ISC 5 // license that can be found in the LICENSE file. 6 7 package btcec 8 9 import ( 10 "crypto/rand" 11 "fmt" 12 "math/big" 13 "testing" 14 ) 15 16 // isJacobianOnS256Curve returns boolean if the point (x,y,z) is on the 17 // secp256k1 curve. 18 func isJacobianOnS256Curve(x, y, z *fieldVal) bool { 19 // Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7 20 // In Jacobian coordinates, Y = y/z^3 and X = x/z^2 21 // Thus: 22 // (y/z^3)^2 = (x/z^2)^3 + 7 23 // y^2/z^6 = x^3/z^6 + 7 24 // y^2 = x^3 + 7*z^6 25 var y2, z2, x3, result fieldVal 26 y2.SquareVal(y).Normalize() 27 z2.SquareVal(z) 28 x3.SquareVal(x).Mul(x) 29 result.SquareVal(&z2).Mul(&z2).MulInt(7).Add(&x3).Normalize() 30 return y2.Equals(&result) 31 } 32 33 // TestAddJacobian tests addition of points projected in Jacobian coordinates. 34 func TestAddJacobian(t *testing.T) { 35 tests := []struct { 36 x1, y1, z1 string // Coordinates (in hex) of first point to add 37 x2, y2, z2 string // Coordinates (in hex) of second point to add 38 x3, y3, z3 string // Coordinates (in hex) of expected point 39 }{ 40 // Addition with a point at infinity (left hand side). 41 // ∞ + P = P 42 { 43 "0", 44 "0", 45 "0", 46 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 47 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 48 "1", 49 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 50 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 51 "1", 52 }, 53 // Addition with a point at infinity (right hand side). 54 // P + ∞ = P 55 { 56 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 57 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 58 "1", 59 "0", 60 "0", 61 "0", 62 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 63 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 64 "1", 65 }, 66 // Addition with z1=z2=1 different x values. 67 { 68 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 69 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 70 "1", 71 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 72 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 73 "1", 74 "0cfbc7da1e569b334460788faae0286e68b3af7379d5504efc25e4dba16e46a6", 75 "e205f79361bbe0346b037b4010985dbf4f9e1e955e7d0d14aca876bfa79aad87", 76 "44a5646b446e3877a648d6d381370d9ef55a83b666ebce9df1b1d7d65b817b2f", 77 }, 78 // Addition with z1=z2=1 same x opposite y. 79 // P(x, y, z) + P(x, -y, z) = infinity 80 { 81 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 82 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 83 "1", 84 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 85 "f48e156428cf0276dc092da5856e182288d7569f97934a56fe44be60f0d359fd", 86 "1", 87 "0", 88 "0", 89 "0", 90 }, 91 // Addition with z1=z2=1 same point. 92 // P(x, y, z) + P(x, y, z) = 2P 93 { 94 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 95 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 96 "1", 97 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 98 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 99 "1", 100 "ec9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee64f87c50c27", 101 "b082b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd0755c8f2a", 102 "16e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c1e594464", 103 }, 104 105 // Addition with z1=z2 (!=1) different x values. 106 { 107 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 108 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 109 "2", 110 "5d2fe112c21891d440f65a98473cb626111f8a234d2cd82f22172e369f002147", 111 "98e3386a0a622a35c4561ffb32308d8e1c6758e10ebb1b4ebd3d04b4eb0ecbe8", 112 "2", 113 "cfbc7da1e569b334460788faae0286e68b3af7379d5504efc25e4dba16e46a60", 114 "817de4d86ef80d1ac0ded00426176fd3e787a5579f43452b2a1db021e6ac3778", 115 "129591ad11b8e1de99235b4e04dc367bd56a0ed99baf3a77c6c75f5a6e05f08d", 116 }, 117 // Addition with z1=z2 (!=1) same x opposite y. 118 // P(x, y, z) + P(x, -y, z) = infinity 119 { 120 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 121 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 122 "2", 123 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 124 "a470ab21467813b6e0496d2c2b70c11446bab4fcbc9a52b7f225f30e869aea9f", 125 "2", 126 "0", 127 "0", 128 "0", 129 }, 130 // Addition with z1=z2 (!=1) same point. 131 // P(x, y, z) + P(x, y, z) = 2P 132 { 133 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 134 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 135 "2", 136 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 137 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 138 "2", 139 "9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac", 140 "2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988", 141 "6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11", 142 }, 143 144 // Addition with z1!=z2 and z2=1 different x values. 145 { 146 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 147 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 148 "2", 149 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 150 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 151 "1", 152 "3ef1f68795a6ccd1181e23eab80a1b9a2cebdcde755413bf097936eb5b91b4f3", 153 "0bef26c377c068d606f6802130bb7e9f3c3d2abcfa1a295950ed81133561cb04", 154 "252b235a2371c3bd3246b69c09b86cf7aad41db3375e74ef8d8ebeb4dc0be11a", 155 }, 156 // Addition with z1!=z2 and z2=1 same x opposite y. 157 // P(x, y, z) + P(x, -y, z) = infinity 158 { 159 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 160 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 161 "2", 162 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 163 "f48e156428cf0276dc092da5856e182288d7569f97934a56fe44be60f0d359fd", 164 "1", 165 "0", 166 "0", 167 "0", 168 }, 169 // Addition with z1!=z2 and z2=1 same point. 170 // P(x, y, z) + P(x, y, z) = 2P 171 { 172 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 173 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 174 "2", 175 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 176 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 177 "1", 178 "9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac", 179 "2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988", 180 "6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11", 181 }, 182 183 // Addition with z1!=z2 and z2!=1 different x values. 184 // P(x, y, z) + P(x, y, z) = 2P 185 { 186 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 187 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 188 "2", 189 "91abba6a34b7481d922a4bd6a04899d5a686f6cf6da4e66a0cb427fb25c04bd4", 190 "03fede65e30b4e7576a2abefc963ddbf9fdccbf791b77c29beadefe49951f7d1", 191 "3", 192 "3f07081927fd3f6dadd4476614c89a09eba7f57c1c6c3b01fa2d64eac1eef31e", 193 "949166e04ebc7fd95a9d77e5dfd88d1492ecffd189792e3944eb2b765e09e031", 194 "eb8cba81bcffa4f44d75427506737e1f045f21e6d6f65543ee0e1d163540c931", 195 }, // Addition with z1!=z2 and z2!=1 same x opposite y. 196 // P(x, y, z) + P(x, -y, z) = infinity 197 { 198 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 199 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 200 "2", 201 "dcc3768780c74a0325e2851edad0dc8a566fa61a9e7fc4a34d13dcb509f99bc7", 202 "cafc41904dd5428934f7d075129c8ba46eb622d4fc88d72cd1401452664add18", 203 "3", 204 "0", 205 "0", 206 "0", 207 }, 208 // Addition with z1!=z2 and z2!=1 same point. 209 // P(x, y, z) + P(x, y, z) = 2P 210 { 211 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 212 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 213 "2", 214 "dcc3768780c74a0325e2851edad0dc8a566fa61a9e7fc4a34d13dcb509f99bc7", 215 "3503be6fb22abd76cb082f8aed63745b9149dd2b037728d32ebfebac99b51f17", 216 "3", 217 "9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac", 218 "2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988", 219 "6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11", 220 }, 221 } 222 223 t.Logf("Running %d tests", len(tests)) 224 for i, test := range tests { 225 // Convert hex to field values. 226 x1 := new(fieldVal).SetHex(test.x1) 227 y1 := new(fieldVal).SetHex(test.y1) 228 z1 := new(fieldVal).SetHex(test.z1) 229 x2 := new(fieldVal).SetHex(test.x2) 230 y2 := new(fieldVal).SetHex(test.y2) 231 z2 := new(fieldVal).SetHex(test.z2) 232 x3 := new(fieldVal).SetHex(test.x3) 233 y3 := new(fieldVal).SetHex(test.y3) 234 z3 := new(fieldVal).SetHex(test.z3) 235 236 // Ensure the test data is using points that are actually on 237 // the curve (or the point at infinity). 238 if !z1.IsZero() && !isJacobianOnS256Curve(x1, y1, z1) { 239 t.Errorf("#%d first point is not on the curve -- "+ 240 "invalid test data", i) 241 continue 242 } 243 if !z2.IsZero() && !isJacobianOnS256Curve(x2, y2, z2) { 244 t.Errorf("#%d second point is not on the curve -- "+ 245 "invalid test data", i) 246 continue 247 } 248 if !z3.IsZero() && !isJacobianOnS256Curve(x3, y3, z3) { 249 t.Errorf("#%d expected point is not on the curve -- "+ 250 "invalid test data", i) 251 continue 252 } 253 254 // Add the two points. 255 rx, ry, rz := new(fieldVal), new(fieldVal), new(fieldVal) 256 S256().addJacobian(x1, y1, z1, x2, y2, z2, rx, ry, rz) 257 258 // Ensure result matches expected. 259 if !rx.Equals(x3) || !ry.Equals(y3) || !rz.Equals(z3) { 260 t.Errorf("#%d wrong result\ngot: (%v, %v, %v)\n"+ 261 "want: (%v, %v, %v)", i, rx, ry, rz, x3, y3, z3) 262 continue 263 } 264 } 265 } 266 267 // TestAddAffine tests addition of points in affine coordinates. 268 func TestAddAffine(t *testing.T) { 269 tests := []struct { 270 x1, y1 string // Coordinates (in hex) of first point to add 271 x2, y2 string // Coordinates (in hex) of second point to add 272 x3, y3 string // Coordinates (in hex) of expected point 273 }{ 274 // Addition with a point at infinity (left hand side). 275 // ∞ + P = P 276 { 277 "0", 278 "0", 279 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 280 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 281 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 282 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 283 }, 284 // Addition with a point at infinity (right hand side). 285 // P + ∞ = P 286 { 287 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 288 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 289 "0", 290 "0", 291 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 292 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 293 }, 294 295 // Addition with different x values. 296 { 297 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 298 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 299 "d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575", 300 "131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d", 301 "fd5b88c21d3143518d522cd2796f3d726793c88b3e05636bc829448e053fed69", 302 "21cf4f6a5be5ff6380234c50424a970b1f7e718f5eb58f68198c108d642a137f", 303 }, 304 // Addition with same x opposite y. 305 // P(x, y) + P(x, -y) = infinity 306 { 307 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 308 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 309 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 310 "f48e156428cf0276dc092da5856e182288d7569f97934a56fe44be60f0d359fd", 311 "0", 312 "0", 313 }, 314 // Addition with same point. 315 // P(x, y) + P(x, y) = 2P 316 { 317 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 318 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 319 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 320 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 321 "59477d88ae64a104dbb8d31ec4ce2d91b2fe50fa628fb6a064e22582196b365b", 322 "938dc8c0f13d1e75c987cb1a220501bd614b0d3dd9eb5c639847e1240216e3b6", 323 }, 324 } 325 326 t.Logf("Running %d tests", len(tests)) 327 for i, test := range tests { 328 // Convert hex to field values. 329 x1, y1 := fromHex(test.x1), fromHex(test.y1) 330 x2, y2 := fromHex(test.x2), fromHex(test.y2) 331 x3, y3 := fromHex(test.x3), fromHex(test.y3) 332 333 // Ensure the test data is using points that are actually on 334 // the curve (or the point at infinity). 335 if !(x1.Sign() == 0 && y1.Sign() == 0) && !S256().IsOnCurve(x1, y1) { 336 t.Errorf("#%d first point is not on the curve -- "+ 337 "invalid test data", i) 338 continue 339 } 340 if !(x2.Sign() == 0 && y2.Sign() == 0) && !S256().IsOnCurve(x2, y2) { 341 t.Errorf("#%d second point is not on the curve -- "+ 342 "invalid test data", i) 343 continue 344 } 345 if !(x3.Sign() == 0 && y3.Sign() == 0) && !S256().IsOnCurve(x3, y3) { 346 t.Errorf("#%d expected point is not on the curve -- "+ 347 "invalid test data", i) 348 continue 349 } 350 351 // Add the two points. 352 rx, ry := S256().Add(x1, y1, x2, y2) 353 354 // Ensure result matches expected. 355 if rx.Cmp(x3) != 00 || ry.Cmp(y3) != 0 { 356 t.Errorf("#%d wrong result\ngot: (%x, %x)\n"+ 357 "want: (%x, %x)", i, rx, ry, x3, y3) 358 continue 359 } 360 } 361 } 362 363 // TestDoubleJacobian tests doubling of points projected in Jacobian 364 // coordinates. 365 func TestDoubleJacobian(t *testing.T) { 366 tests := []struct { 367 x1, y1, z1 string // Coordinates (in hex) of point to double 368 x3, y3, z3 string // Coordinates (in hex) of expected point 369 }{ 370 // Doubling a point at infinity is still infinity. 371 { 372 "0", 373 "0", 374 "0", 375 "0", 376 "0", 377 "0", 378 }, 379 // Doubling with z1=1. 380 { 381 "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", 382 "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", 383 "1", 384 "ec9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee64f87c50c27", 385 "b082b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd0755c8f2a", 386 "16e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c1e594464", 387 }, 388 // Doubling with z1!=1. 389 { 390 "d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718", 391 "5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190", 392 "2", 393 "9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac", 394 "2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988", 395 "6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11", 396 }, 397 // From btcd issue #709. 398 { 399 "201e3f75715136d2f93c4f4598f91826f94ca01f4233a5bd35de9708859ca50d", 400 "bdf18566445e7562c6ada68aef02d498d7301503de5b18c6aef6e2b1722412e1", 401 "0000000000000000000000000000000000000000000000000000000000000001", 402 "4a5e0559863ebb4e9ed85f5c4fa76003d05d9a7626616e614a1f738621e3c220", 403 "00000000000000000000000000000000000000000000000000000001b1388778", 404 "7be30acc88bceac58d5b4d15de05a931ae602a07bcb6318d5dedc563e4482993", 405 }, 406 } 407 408 t.Logf("Running %d tests", len(tests)) 409 for i, test := range tests { 410 // Convert hex to field values. 411 x1 := new(fieldVal).SetHex(test.x1) 412 y1 := new(fieldVal).SetHex(test.y1) 413 z1 := new(fieldVal).SetHex(test.z1) 414 x3 := new(fieldVal).SetHex(test.x3) 415 y3 := new(fieldVal).SetHex(test.y3) 416 z3 := new(fieldVal).SetHex(test.z3) 417 418 // Ensure the test data is using points that are actually on 419 // the curve (or the point at infinity). 420 if !z1.IsZero() && !isJacobianOnS256Curve(x1, y1, z1) { 421 t.Errorf("#%d first point is not on the curve -- "+ 422 "invalid test data", i) 423 continue 424 } 425 if !z3.IsZero() && !isJacobianOnS256Curve(x3, y3, z3) { 426 t.Errorf("#%d expected point is not on the curve -- "+ 427 "invalid test data", i) 428 continue 429 } 430 431 // Double the point. 432 rx, ry, rz := new(fieldVal), new(fieldVal), new(fieldVal) 433 S256().doubleJacobian(x1, y1, z1, rx, ry, rz) 434 435 // Ensure result matches expected. 436 if !rx.Equals(x3) || !ry.Equals(y3) || !rz.Equals(z3) { 437 t.Errorf("#%d wrong result\ngot: (%v, %v, %v)\n"+ 438 "want: (%v, %v, %v)", i, rx, ry, rz, x3, y3, z3) 439 continue 440 } 441 } 442 } 443 444 // TestDoubleAffine tests doubling of points in affine coordinates. 445 func TestDoubleAffine(t *testing.T) { 446 tests := []struct { 447 x1, y1 string // Coordinates (in hex) of point to double 448 x3, y3 string // Coordinates (in hex) of expected point 449 }{ 450 // Doubling a point at infinity is still infinity. 451 // 2*∞ = ∞ (point at infinity) 452 453 { 454 "0", 455 "0", 456 "0", 457 "0", 458 }, 459 460 // Random points. 461 { 462 "e41387ffd8baaeeb43c2faa44e141b19790e8ac1f7ff43d480dc132230536f86", 463 "1b88191d430f559896149c86cbcb703193105e3cf3213c0c3556399836a2b899", 464 "88da47a089d333371bd798c548ef7caae76e737c1980b452d367b3cfe3082c19", 465 "3b6f659b09a362821dfcfefdbfbc2e59b935ba081b6c249eb147b3c2100b1bc1", 466 }, 467 { 468 "b3589b5d984f03ef7c80aeae444f919374799edf18d375cab10489a3009cff0c", 469 "c26cf343875b3630e15bccc61202815b5d8f1fd11308934a584a5babe69db36a", 470 "e193860172998751e527bb12563855602a227fc1f612523394da53b746bb2fb1", 471 "2bfcf13d2f5ab8bb5c611fab5ebbed3dc2f057062b39a335224c22f090c04789", 472 }, 473 { 474 "2b31a40fbebe3440d43ac28dba23eee71c62762c3fe3dbd88b4ab82dc6a82340", 475 "9ba7deb02f5c010e217607fd49d58db78ec273371ea828b49891ce2fd74959a1", 476 "2c8d5ef0d343b1a1a48aa336078eadda8481cb048d9305dc4fdf7ee5f65973a2", 477 "bb4914ac729e26d3cd8f8dc8f702f3f4bb7e0e9c5ae43335f6e94c2de6c3dc95", 478 }, 479 { 480 "61c64b760b51981fab54716d5078ab7dffc93730b1d1823477e27c51f6904c7a", 481 "ef6eb16ea1a36af69d7f66524c75a3a5e84c13be8fbc2e811e0563c5405e49bd", 482 "5f0dcdd2595f5ad83318a0f9da481039e36f135005420393e72dfca985b482f4", 483 "a01c849b0837065c1cb481b0932c441f49d1cab1b4b9f355c35173d93f110ae0", 484 }, 485 } 486 487 t.Logf("Running %d tests", len(tests)) 488 for i, test := range tests { 489 // Convert hex to field values. 490 x1, y1 := fromHex(test.x1), fromHex(test.y1) 491 x3, y3 := fromHex(test.x3), fromHex(test.y3) 492 493 // Ensure the test data is using points that are actually on 494 // the curve (or the point at infinity). 495 if !(x1.Sign() == 0 && y1.Sign() == 0) && !S256().IsOnCurve(x1, y1) { 496 t.Errorf("#%d first point is not on the curve -- "+ 497 "invalid test data", i) 498 continue 499 } 500 if !(x3.Sign() == 0 && y3.Sign() == 0) && !S256().IsOnCurve(x3, y3) { 501 t.Errorf("#%d expected point is not on the curve -- "+ 502 "invalid test data", i) 503 continue 504 } 505 506 // Double the point. 507 rx, ry := S256().Double(x1, y1) 508 509 // Ensure result matches expected. 510 if rx.Cmp(x3) != 00 || ry.Cmp(y3) != 0 { 511 t.Errorf("#%d wrong result\ngot: (%x, %x)\n"+ 512 "want: (%x, %x)", i, rx, ry, x3, y3) 513 continue 514 } 515 } 516 } 517 518 func TestOnCurve(t *testing.T) { 519 s256 := S256() 520 if !s256.IsOnCurve(s256.Params().Gx, s256.Params().Gy) { 521 t.Errorf("FAIL S256") 522 } 523 } 524 525 type baseMultTest struct { 526 k string 527 x, y string 528 } 529 530 // TODO: add more test vectors 531 var s256BaseMultTests = []baseMultTest{ 532 { 533 "AA5E28D6A97A2479A65527F7290311A3624D4CC0FA1578598EE3C2613BF99522", 534 "34F9460F0E4F08393D192B3C5133A6BA099AA0AD9FD54EBCCFACDFA239FF49C6", 535 "B71EA9BD730FD8923F6D25A7A91E7DD7728A960686CB5A901BB419E0F2CA232", 536 }, 537 { 538 "7E2B897B8CEBC6361663AD410835639826D590F393D90A9538881735256DFAE3", 539 "D74BF844B0862475103D96A611CF2D898447E288D34B360BC885CB8CE7C00575", 540 "131C670D414C4546B88AC3FF664611B1C38CEB1C21D76369D7A7A0969D61D97D", 541 }, 542 { 543 "6461E6DF0FE7DFD05329F41BF771B86578143D4DD1F7866FB4CA7E97C5FA945D", 544 "E8AECC370AEDD953483719A116711963CE201AC3EB21D3F3257BB48668C6A72F", 545 "C25CAF2F0EBA1DDB2F0F3F47866299EF907867B7D27E95B3873BF98397B24EE1", 546 }, 547 { 548 "376A3A2CDCD12581EFFF13EE4AD44C4044B8A0524C42422A7E1E181E4DEECCEC", 549 "14890E61FCD4B0BD92E5B36C81372CA6FED471EF3AA60A3E415EE4FE987DABA1", 550 "297B858D9F752AB42D3BCA67EE0EB6DCD1C2B7B0DBE23397E66ADC272263F982", 551 }, 552 { 553 "1B22644A7BE026548810C378D0B2994EEFA6D2B9881803CB02CEFF865287D1B9", 554 "F73C65EAD01C5126F28F442D087689BFA08E12763E0CEC1D35B01751FD735ED3", 555 "F449A8376906482A84ED01479BD18882B919C140D638307F0C0934BA12590BDE", 556 }, 557 } 558 559 // TODO: test different curves as well? 560 func TestBaseMult(t *testing.T) { 561 s256 := S256() 562 for i, e := range s256BaseMultTests { 563 k, ok := new(big.Int).SetString(e.k, 16) 564 if !ok { 565 t.Errorf("%d: bad value for k: %s", i, e.k) 566 } 567 x, y := s256.ScalarBaseMult(k.Bytes()) 568 if fmt.Sprintf("%X", x) != e.x || fmt.Sprintf("%X", y) != e.y { 569 t.Errorf("%d: bad output for k=%s: got (%X, %X), want (%s, %s)", i, e.k, x, y, e.x, e.y) 570 } 571 if testing.Short() && i > 5 { 572 break 573 } 574 } 575 } 576 577 func TestBaseMultVerify(t *testing.T) { 578 s256 := S256() 579 for bytes := 1; bytes < 40; bytes++ { 580 for i := 0; i < 30; i++ { 581 data := make([]byte, bytes) 582 _, err := rand.Read(data) 583 if err != nil { 584 t.Errorf("failed to read random data for %d", i) 585 continue 586 } 587 x, y := s256.ScalarBaseMult(data) 588 xWant, yWant := s256.ScalarMult(s256.Gx, s256.Gy, data) 589 if x.Cmp(xWant) != 0 || y.Cmp(yWant) != 0 { 590 t.Errorf("%d: bad output for %X: got (%X, %X), want (%X, %X)", i, data, x, y, xWant, yWant) 591 } 592 if testing.Short() && i > 2 { 593 break 594 } 595 } 596 } 597 } 598 599 func TestScalarMult(t *testing.T) { 600 tests := []struct { 601 x string 602 y string 603 k string 604 rx string 605 ry string 606 }{ 607 // base mult, essentially. 608 { 609 "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", 610 "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 611 "18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725", 612 "50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352", 613 "2cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6", 614 }, 615 // From btcd issue #709. 616 { 617 "000000000000000000000000000000000000000000000000000000000000002c", 618 "420e7a99bba18a9d3952597510fd2b6728cfeafc21a4e73951091d4d8ddbe94e", 619 "a2e8ba2e8ba2e8ba2e8ba2e8ba2e8ba219b51835b55cc30ebfe2f6599bc56f58", 620 "a2112dcdfbcd10ae1133a358de7b82db68e0a3eb4b492cc8268d1e7118c98788", 621 "27fc7463b7bb3c5f98ecf2c84a6272bb1681ed553d92c69f2dfe25a9f9fd3836", 622 }, 623 } 624 625 s256 := S256() 626 for i, test := range tests { 627 x, _ := new(big.Int).SetString(test.x, 16) 628 y, _ := new(big.Int).SetString(test.y, 16) 629 k, _ := new(big.Int).SetString(test.k, 16) 630 xWant, _ := new(big.Int).SetString(test.rx, 16) 631 yWant, _ := new(big.Int).SetString(test.ry, 16) 632 xGot, yGot := s256.ScalarMult(x, y, k.Bytes()) 633 if xGot.Cmp(xWant) != 0 || yGot.Cmp(yWant) != 0 { 634 t.Fatalf("%d: bad output: got (%X, %X), want (%X, %X)", i, xGot, yGot, xWant, yWant) 635 } 636 } 637 } 638 639 func TestScalarMultRand(t *testing.T) { 640 // Strategy for this test: 641 // Get a random exponent from the generator point at first 642 // This creates a new point which is used in the next iteration 643 // Use another random exponent on the new point. 644 // We use BaseMult to verify by multiplying the previous exponent 645 // and the new random exponent together (mod N) 646 s256 := S256() 647 x, y := s256.Gx, s256.Gy 648 exponent := big.NewInt(1) 649 for i := 0; i < 1024; i++ { 650 data := make([]byte, 32) 651 _, err := rand.Read(data) 652 if err != nil { 653 t.Fatalf("failed to read random data at %d", i) 654 break 655 } 656 x, y = s256.ScalarMult(x, y, data) 657 exponent.Mul(exponent, new(big.Int).SetBytes(data)) 658 xWant, yWant := s256.ScalarBaseMult(exponent.Bytes()) 659 if x.Cmp(xWant) != 0 || y.Cmp(yWant) != 0 { 660 t.Fatalf("%d: bad output for %X: got (%X, %X), want (%X, %X)", i, data, x, y, xWant, yWant) 661 break 662 } 663 } 664 } 665 666 func TestSplitK(t *testing.T) { 667 tests := []struct { 668 k string 669 k1, k2 string 670 s1, s2 int 671 }{ 672 { 673 "6df2b5d30854069ccdec40ae022f5c948936324a4e9ebed8eb82cfd5a6b6d766", 674 "00000000000000000000000000000000b776e53fb55f6b006a270d42d64ec2b1", 675 "00000000000000000000000000000000d6cc32c857f1174b604eefc544f0c7f7", 676 -1, -1, 677 }, 678 { 679 "6ca00a8f10632170accc1b3baf2a118fa5725f41473f8959f34b8f860c47d88d", 680 "0000000000000000000000000000000007b21976c1795723c1bfbfa511e95b84", 681 "00000000000000000000000000000000d8d2d5f9d20fc64fd2cf9bda09a5bf90", 682 1, -1, 683 }, 684 { 685 "b2eda8ab31b259032d39cbc2a234af17fcee89c863a8917b2740b67568166289", 686 "00000000000000000000000000000000507d930fecda7414fc4a523b95ef3c8c", 687 "00000000000000000000000000000000f65ffb179df189675338c6185cb839be", 688 -1, -1, 689 }, 690 { 691 "f6f00e44f179936f2befc7442721b0633f6bafdf7161c167ffc6f7751980e3a0", 692 "0000000000000000000000000000000008d0264f10bcdcd97da3faa38f85308d", 693 "0000000000000000000000000000000065fed1506eb6605a899a54e155665f79", 694 -1, -1, 695 }, 696 { 697 "8679085ab081dc92cdd23091ce3ee998f6b320e419c3475fae6b5b7d3081996e", 698 "0000000000000000000000000000000089fbf24fbaa5c3c137b4f1cedc51d975", 699 "00000000000000000000000000000000d38aa615bd6754d6f4d51ccdaf529fea", 700 -1, -1, 701 }, 702 { 703 "6b1247bb7931dfcae5b5603c8b5ae22ce94d670138c51872225beae6bba8cdb3", 704 "000000000000000000000000000000008acc2a521b21b17cfb002c83be62f55d", 705 "0000000000000000000000000000000035f0eff4d7430950ecb2d94193dedc79", 706 -1, -1, 707 }, 708 { 709 "a2e8ba2e8ba2e8ba2e8ba2e8ba2e8ba219b51835b55cc30ebfe2f6599bc56f58", 710 "0000000000000000000000000000000045c53aa1bb56fcd68c011e2dad6758e4", 711 "00000000000000000000000000000000a2e79d200f27f2360fba57619936159b", 712 -1, -1, 713 }, 714 } 715 716 s256 := S256() 717 for i, test := range tests { 718 k, ok := new(big.Int).SetString(test.k, 16) 719 if !ok { 720 t.Errorf("%d: bad value for k: %s", i, test.k) 721 } 722 k1, k2, k1Sign, k2Sign := s256.splitK(k.Bytes()) 723 k1str := fmt.Sprintf("%064x", k1) 724 if test.k1 != k1str { 725 t.Errorf("%d: bad k1: got %v, want %v", i, k1str, test.k1) 726 } 727 k2str := fmt.Sprintf("%064x", k2) 728 if test.k2 != k2str { 729 t.Errorf("%d: bad k2: got %v, want %v", i, k2str, test.k2) 730 } 731 if test.s1 != k1Sign { 732 t.Errorf("%d: bad k1 sign: got %d, want %d", i, k1Sign, test.s1) 733 } 734 if test.s2 != k2Sign { 735 t.Errorf("%d: bad k2 sign: got %d, want %d", i, k2Sign, test.s2) 736 } 737 k1Int := new(big.Int).SetBytes(k1) 738 k1SignInt := new(big.Int).SetInt64(int64(k1Sign)) 739 k1Int.Mul(k1Int, k1SignInt) 740 k2Int := new(big.Int).SetBytes(k2) 741 k2SignInt := new(big.Int).SetInt64(int64(k2Sign)) 742 k2Int.Mul(k2Int, k2SignInt) 743 gotK := new(big.Int).Mul(k2Int, s256.lambda) 744 gotK.Add(k1Int, gotK) 745 gotK.Mod(gotK, s256.N) 746 if k.Cmp(gotK) != 0 { 747 t.Errorf("%d: bad k: got %X, want %X", i, gotK.Bytes(), k.Bytes()) 748 } 749 } 750 } 751 752 func TestSplitKRand(t *testing.T) { 753 s256 := S256() 754 for i := 0; i < 1024; i++ { 755 bytesK := make([]byte, 32) 756 _, err := rand.Read(bytesK) 757 if err != nil { 758 t.Fatalf("failed to read random data at %d", i) 759 break 760 } 761 k := new(big.Int).SetBytes(bytesK) 762 k1, k2, k1Sign, k2Sign := s256.splitK(bytesK) 763 k1Int := new(big.Int).SetBytes(k1) 764 k1SignInt := new(big.Int).SetInt64(int64(k1Sign)) 765 k1Int.Mul(k1Int, k1SignInt) 766 k2Int := new(big.Int).SetBytes(k2) 767 k2SignInt := new(big.Int).SetInt64(int64(k2Sign)) 768 k2Int.Mul(k2Int, k2SignInt) 769 gotK := new(big.Int).Mul(k2Int, s256.lambda) 770 gotK.Add(k1Int, gotK) 771 gotK.Mod(gotK, s256.N) 772 if k.Cmp(gotK) != 0 { 773 t.Errorf("%d: bad k: got %X, want %X", i, gotK.Bytes(), k.Bytes()) 774 } 775 } 776 } 777 778 // Test this curve's usage with the ecdsa package. 779 780 func testKeyGeneration(t *testing.T, c *KoblitzCurve, tag string) { 781 priv, err := NewPrivateKey(c) 782 if err != nil { 783 t.Errorf("%s: error: %s", tag, err) 784 return 785 } 786 if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) { 787 t.Errorf("%s: public key invalid: %s", tag, err) 788 } 789 } 790 791 func TestKeyGeneration(t *testing.T) { 792 testKeyGeneration(t, S256(), "S256") 793 } 794 795 func testSignAndVerify(t *testing.T, c *KoblitzCurve, tag string) { 796 priv, _ := NewPrivateKey(c) 797 pub := priv.PubKey() 798 799 hashed := []byte("testing") 800 sig, err := priv.Sign(hashed) 801 if err != nil { 802 t.Errorf("%s: error signing: %s", tag, err) 803 return 804 } 805 806 if !sig.Verify(hashed, pub) { 807 t.Errorf("%s: Verify failed", tag) 808 } 809 810 hashed[0] ^= 0xff 811 if sig.Verify(hashed, pub) { 812 t.Errorf("%s: Verify always works!", tag) 813 } 814 } 815 816 func TestSignAndVerify(t *testing.T) { 817 testSignAndVerify(t, S256(), "S256") 818 } 819 820 func TestNAF(t *testing.T) { 821 tests := []string{ 822 "6df2b5d30854069ccdec40ae022f5c948936324a4e9ebed8eb82cfd5a6b6d766", 823 "b776e53fb55f6b006a270d42d64ec2b1", 824 "d6cc32c857f1174b604eefc544f0c7f7", 825 "45c53aa1bb56fcd68c011e2dad6758e4", 826 "a2e79d200f27f2360fba57619936159b", 827 } 828 negOne := big.NewInt(-1) 829 one := big.NewInt(1) 830 two := big.NewInt(2) 831 for i, test := range tests { 832 want, _ := new(big.Int).SetString(test, 16) 833 nafPos, nafNeg := NAF(want.Bytes()) 834 got := big.NewInt(0) 835 // Check that the NAF representation comes up with the right number 836 for i := 0; i < len(nafPos); i++ { 837 bytePos := nafPos[i] 838 byteNeg := nafNeg[i] 839 for j := 7; j >= 0; j-- { 840 got.Mul(got, two) 841 if bytePos&0x80 == 0x80 { 842 got.Add(got, one) 843 } else if byteNeg&0x80 == 0x80 { 844 got.Add(got, negOne) 845 } 846 bytePos <<= 1 847 byteNeg <<= 1 848 } 849 } 850 if got.Cmp(want) != 0 { 851 t.Errorf("%d: Failed NAF got %X want %X", i, got, want) 852 } 853 } 854 } 855 856 func TestNAFRand(t *testing.T) { 857 negOne := big.NewInt(-1) 858 one := big.NewInt(1) 859 two := big.NewInt(2) 860 for i := 0; i < 1024; i++ { 861 data := make([]byte, 32) 862 _, err := rand.Read(data) 863 if err != nil { 864 t.Fatalf("failed to read random data at %d", i) 865 break 866 } 867 nafPos, nafNeg := NAF(data) 868 want := new(big.Int).SetBytes(data) 869 got := big.NewInt(0) 870 // Check that the NAF representation comes up with the right number 871 for i := 0; i < len(nafPos); i++ { 872 bytePos := nafPos[i] 873 byteNeg := nafNeg[i] 874 for j := 7; j >= 0; j-- { 875 got.Mul(got, two) 876 if bytePos&0x80 == 0x80 { 877 got.Add(got, one) 878 } else if byteNeg&0x80 == 0x80 { 879 got.Add(got, negOne) 880 } 881 bytePos <<= 1 882 byteNeg <<= 1 883 } 884 } 885 if got.Cmp(want) != 0 { 886 t.Errorf("%d: Failed NAF got %X want %X", i, got, want) 887 } 888 } 889 }