@@ -704,6 +704,13 @@ var primes = []string{
704
704
"230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593" ,
705
705
"5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993" ,
706
706
"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123" ,
707
+
708
+ // ECC primes: http://tools.ietf.org/html/draft-ladd-safecurves-02
709
+ "3618502788666131106986593281521497120414687020801267626233049500247285301239" , // Curve1174: 2^251-9
710
+ "57896044618658097711785492504343953926634992332820282019728792003956564819949" , // Curve25519: 2^255-19
711
+ "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599" , // E-382: 2^382-105
712
+ "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367" , // Curve41417: 2^414-17
713
+ "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151" , // E-521: 2^521-1
707
714
}
708
715
709
716
var composites = []string {
@@ -1249,6 +1256,136 @@ func TestModInverse(t *testing.T) {
1249
1256
}
1250
1257
}
1251
1258
1259
+ // testModSqrt is a helper for TestModSqrt,
1260
+ // which checks that ModSqrt can compute a square-root of elt^2.
1261
+ func testModSqrt (t * testing.T , elt , mod , sq , sqrt * Int ) bool {
1262
+ var sqChk , sqrtChk , sqrtsq Int
1263
+ sq .Mul (elt , elt )
1264
+ sq .Mod (sq , mod )
1265
+ z := sqrt .ModSqrt (sq , mod )
1266
+ if z != sqrt {
1267
+ t .Errorf ("ModSqrt returned wrong value %s" , z )
1268
+ }
1269
+
1270
+ // test ModSqrt arguments outside the range [0,mod)
1271
+ sqChk .Add (sq , mod )
1272
+ z = sqrtChk .ModSqrt (& sqChk , mod )
1273
+ if z != & sqrtChk || z .Cmp (sqrt ) != 0 {
1274
+ t .Errorf ("ModSqrt returned inconsistent value %s" , z )
1275
+ }
1276
+ sqChk .Sub (sq , mod )
1277
+ z = sqrtChk .ModSqrt (& sqChk , mod )
1278
+ if z != & sqrtChk || z .Cmp (sqrt ) != 0 {
1279
+ t .Errorf ("ModSqrt returned inconsistent value %s" , z )
1280
+ }
1281
+
1282
+ // make sure we actually got a square root
1283
+ if sqrt .Cmp (elt ) == 0 {
1284
+ return true // we found the "desired" square root
1285
+ }
1286
+ sqrtsq .Mul (sqrt , sqrt ) // make sure we found the "other" one
1287
+ sqrtsq .Mod (& sqrtsq , mod )
1288
+ return sq .Cmp (& sqrtsq ) == 0
1289
+ }
1290
+
1291
+ func TestModSqrt (t * testing.T ) {
1292
+ var elt , mod , modx4 , sq , sqrt Int
1293
+ r := rand .New (rand .NewSource (9 ))
1294
+ for i , s := range primes [1 :] { // skip 2, use only odd primes
1295
+ mod .SetString (s , 10 )
1296
+ modx4 .Lsh (& mod , 2 )
1297
+
1298
+ // test a few random elements per prime
1299
+ for x := 1 ; x < 5 ; x ++ {
1300
+ elt .Rand (r , & modx4 )
1301
+ elt .Sub (& elt , & mod ) // test range [-mod, 3*mod)
1302
+ if ! testModSqrt (t , & elt , & mod , & sq , & sqrt ) {
1303
+ t .Errorf ("#%d: failed (sqrt(e) = %s)" , i , & sqrt )
1304
+ }
1305
+ }
1306
+ }
1307
+
1308
+ // exhaustive test for small values
1309
+ for n := 3 ; n < 100 ; n ++ {
1310
+ mod .SetInt64 (int64 (n ))
1311
+ if ! mod .ProbablyPrime (10 ) {
1312
+ continue
1313
+ }
1314
+ isSquare := make ([]bool , n )
1315
+
1316
+ // test all the squares
1317
+ for x := 1 ; x < n ; x ++ {
1318
+ elt .SetInt64 (int64 (x ))
1319
+ if ! testModSqrt (t , & elt , & mod , & sq , & sqrt ) {
1320
+ t .Errorf ("#%d: failed (sqrt(%d,%d) = %s)" , x , & elt , & mod , & sqrt )
1321
+ }
1322
+ isSquare [sq .Uint64 ()] = true
1323
+ }
1324
+
1325
+ // test all non-squares
1326
+ for x := 1 ; x < n ; x ++ {
1327
+ sq .SetInt64 (int64 (x ))
1328
+ z := sqrt .ModSqrt (& sq , & mod )
1329
+ if ! isSquare [x ] && z != nil {
1330
+ t .Errorf ("#%d: failed (sqrt(%d,%d) = nil)" , x , & sqrt , & mod )
1331
+ }
1332
+ }
1333
+ }
1334
+ }
1335
+
1336
+ func TestJacobi (t * testing.T ) {
1337
+ testCases := []struct {
1338
+ x , y int64
1339
+ result int
1340
+ }{
1341
+ {0 , 1 , 1 },
1342
+ {0 , - 1 , 1 },
1343
+ {1 , 1 , 1 },
1344
+ {1 , - 1 , 1 },
1345
+ {0 , 5 , 0 },
1346
+ {1 , 5 , 1 },
1347
+ {2 , 5 , - 1 },
1348
+ {- 2 , 5 , - 1 },
1349
+ {2 , - 5 , - 1 },
1350
+ {- 2 , - 5 , 1 },
1351
+ {3 , 5 , - 1 },
1352
+ {5 , 5 , 0 },
1353
+ {- 5 , 5 , 0 },
1354
+ {6 , 5 , 1 },
1355
+ {6 , - 5 , 1 },
1356
+ {- 6 , 5 , 1 },
1357
+ {- 6 , - 5 , - 1 },
1358
+ }
1359
+
1360
+ var x , y Int
1361
+
1362
+ for i , test := range testCases {
1363
+ x .SetInt64 (test .x )
1364
+ y .SetInt64 (test .y )
1365
+ expected := test .result
1366
+ actual := Jacobi (& x , & y )
1367
+ if actual != expected {
1368
+ t .Errorf ("#%d: Jacobi(%d, %d) = %d, but expected %d" , i , test .x , test .y , actual , expected )
1369
+ }
1370
+ }
1371
+ }
1372
+
1373
+ func TestJacobiPanic (t * testing.T ) {
1374
+ const failureMsg = "test failure"
1375
+ defer func () {
1376
+ msg := recover ()
1377
+ if msg == nil || msg == failureMsg {
1378
+ panic (msg )
1379
+ }
1380
+ t .Log (msg )
1381
+ }()
1382
+ x := NewInt (1 )
1383
+ y := NewInt (2 )
1384
+ // Jacobi should panic when the second argument is even.
1385
+ Jacobi (x , y )
1386
+ panic (failureMsg )
1387
+ }
1388
+
1252
1389
var encodingTests = []string {
1253
1390
"-539345864568634858364538753846587364875430589374589" ,
1254
1391
"-678645873" ,
0 commit comments