arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
ark-curves-cherry-picked/bls12_381/src/fields/tests.rs
bls12_381/src/fields/tests.rsRaw
   1use ark_ff::{
   2    biginteger::{BigInteger, BigInteger384},
   3    fields::{
   4        FftField, FftParameters, Field, Fp12Parameters, Fp2Parameters, Fp6Parameters, FpParameters,
   5        SquareRootField,
   6    },
   7    One, UniformRand, Zero,
   8};
   9use core::{
  10    cmp::Ordering,
  11    ops::{AddAssign, MulAssign, SubAssign},
  12};
  13use rand::SeedableRng;
  14use rand_xorshift::XorShiftRng;
  15
  16use crate::{Fq, Fq12, Fq12Parameters, Fq2, Fq2Parameters, Fq6, Fq6Parameters, FqParameters, Fr};
  17use ark_algebra_test_templates::fields::*;
  18
  19pub(crate) const ITERATIONS: usize = 5;
  20
  21#[test]
  22fn test_fr() {
  23    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
  24    for _ in 0..ITERATIONS {
  25        let a: Fr = UniformRand::rand(&mut rng);
  26        let b: Fr = UniformRand::rand(&mut rng);
  27        field_test(a, b);
  28        primefield_test::<Fr>();
  29        sqrt_field_test(b);
  30    }
  31}
  32
  33#[test]
  34fn test_fq() {
  35    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
  36    for _ in 0..ITERATIONS {
  37        let a: Fq = UniformRand::rand(&mut rng);
  38        let b: Fq = UniformRand::rand(&mut rng);
  39        field_test(a, b);
  40        primefield_test::<Fq>();
  41        sqrt_field_test(a);
  42    }
  43}
  44
  45#[test]
  46fn test_fq2() {
  47    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
  48    for _ in 0..ITERATIONS {
  49        let a: Fq2 = UniformRand::rand(&mut rng);
  50        let b: Fq2 = UniformRand::rand(&mut rng);
  51        field_test(a, b);
  52        sqrt_field_test(a);
  53    }
  54    frobenius_test::<Fq2, _>(Fq::characteristic(), 13);
  55}
  56
  57#[test]
  58fn test_fq6() {
  59    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
  60    for _ in 0..ITERATIONS {
  61        let g: Fq6 = UniformRand::rand(&mut rng);
  62        let h: Fq6 = UniformRand::rand(&mut rng);
  63        field_test(g, h);
  64    }
  65    frobenius_test::<Fq6, _>(Fq::characteristic(), 13);
  66}
  67
  68#[test]
  69fn test_fq12() {
  70    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
  71    for _ in 0..ITERATIONS {
  72        let g: Fq12 = UniformRand::rand(&mut rng);
  73        let h: Fq12 = UniformRand::rand(&mut rng);
  74        field_test(g, h);
  75    }
  76    frobenius_test::<Fq12, _>(Fq::characteristic(), 13);
  77}
  78
  79#[test]
  80fn test_negative_one() {
  81    let neg_one = Fq::new(BigInteger384([
  82        0x43f5fffffffcaaae,
  83        0x32b7fff2ed47fffd,
  84        0x7e83a49a2e99d69,
  85        0xeca8f3318332bb7a,
  86        0xef148d1ea0f4c069,
  87        0x40ab3263eff0206,
  88    ]));
  89    assert_eq!(neg_one, -Fq::one());
  90}
  91
  92#[test]
  93fn test_frob_coeffs() {
  94    let nqr = -Fq::one();
  95
  96    assert_eq!(Fq2Parameters::FROBENIUS_COEFF_FP2_C1[0], Fq::one());
  97    assert_eq!(
  98        Fq2Parameters::FROBENIUS_COEFF_FP2_C1[1],
  99        nqr.pow([
 100            0xdcff7fffffffd555,
 101            0xf55ffff58a9ffff,
 102            0xb39869507b587b12,
 103            0xb23ba5c279c2895f,
 104            0x258dd3db21a5d66b,
 105            0xd0088f51cbff34d,
 106        ])
 107    );
 108
 109    let nqr = Fq2::new(Fq::one(), Fq::one());
 110
 111    assert_eq!(Fq6Parameters::FROBENIUS_COEFF_FP6_C1[0], Fq2::one());
 112    assert_eq!(
 113        Fq6Parameters::FROBENIUS_COEFF_FP6_C1[1],
 114        nqr.pow([
 115            0x9354ffffffffe38e,
 116            0xa395554e5c6aaaa,
 117            0xcd104635a790520c,
 118            0xcc27c3d6fbd7063f,
 119            0x190937e76bc3e447,
 120            0x8ab05f8bdd54cde,
 121        ])
 122    );
 123    assert_eq!(
 124        Fq6Parameters::FROBENIUS_COEFF_FP6_C1[2],
 125        nqr.pow([
 126            0xb78e0000097b2f68,
 127            0xd44f23b47cbd64e3,
 128            0x5cb9668120b069a9,
 129            0xccea85f9bf7b3d16,
 130            0xdba2c8d7adb356d,
 131            0x9cd75ded75d7429,
 132            0xfc65c31103284fab,
 133            0xc58cb9a9b249ee24,
 134            0xccf734c3118a2e9a,
 135            0xa0f4304c5a256ce6,
 136            0xc3f0d2f8e0ba61f8,
 137            0xe167e192ebca97,
 138        ])
 139    );
 140    assert_eq!(
 141        Fq6Parameters::FROBENIUS_COEFF_FP6_C1[3],
 142        nqr.pow([
 143            0xdbc6fcd6f35b9e06,
 144            0x997dead10becd6aa,
 145            0x9dbbd24c17206460,
 146            0x72b97acc6057c45e,
 147            0xf8e9a230bf0c628e,
 148            0x647ccb1885c63a7,
 149            0xce80264fc55bf6ee,
 150            0x94d8d716c3939fc4,
 151            0xad78f0eb77ee6ee1,
 152            0xd6fe49bfe57dc5f9,
 153            0x2656d6c15c63647,
 154            0xdf6282f111fa903,
 155            0x1bdba63e0632b4bb,
 156            0x6883597bcaa505eb,
 157            0xa56d4ec90c34a982,
 158            0x7e4c42823bbe90b2,
 159            0xf64728aa6dcb0f20,
 160            0x16e57e16ef152f,
 161        ])
 162    );
 163    assert_eq!(
 164        Fq6Parameters::FROBENIUS_COEFF_FP6_C1[4],
 165        nqr.pow([
 166            0x4649add3c71c6d90,
 167            0x43caa6528972a865,
 168            0xcda8445bbaaa0fbb,
 169            0xc93dea665662aa66,
 170            0x2863bc891834481d,
 171            0x51a0c3f5d4ccbed8,
 172            0x9210e660f90ccae9,
 173            0xe2bd6836c546d65e,
 174            0xf223abbaa7cf778b,
 175            0xd4f10b222cf11680,
 176            0xd540f5eff4a1962e,
 177            0xa123a1f140b56526,
 178            0x31ace500636a59f6,
 179            0x3a82bc8c8dfa57a9,
 180            0x648c511e217fc1f8,
 181            0x36c17ffd53a4558f,
 182            0x881bef5fd684eefd,
 183            0x5d648dbdc5dbb522,
 184            0x8fd07bf06e5e59b8,
 185            0x8ddec8a9acaa4b51,
 186            0x4cc1f8688e2def26,
 187            0xa74e63cb492c03de,
 188            0x57c968173d1349bb,
 189            0x253674e02a866,
 190        ])
 191    );
 192    assert_eq!(
 193        Fq6Parameters::FROBENIUS_COEFF_FP6_C1[5],
 194        nqr.pow([
 195            0xf896f792732eb2be,
 196            0x49c86a6d1dc593a1,
 197            0xe5b31e94581f91c3,
 198            0xe3da5cc0a6b20d7f,
 199            0x822caef950e0bfed,
 200            0x317ed950b9ee67cd,
 201            0xffd664016ee3f6cd,
 202            0x77d991c88810b122,
 203            0x62e72e635e698264,
 204            0x905e1a1a2d22814a,
 205            0xf5b7ab3a3f33d981,
 206            0x175871b0bc0e25dd,
 207            0x1e2e9a63df5c3772,
 208            0xe888b1f7445b149d,
 209            0x9551c19e5e7e2c24,
 210            0xecf21939a3d2d6be,
 211            0xd830dbfdab72dbd4,
 212            0x7b34af8d622d40c0,
 213            0x3df6d20a45671242,
 214            0xaf86bee30e21d98,
 215            0x41064c1534e5df5d,
 216            0xf5f6cabd3164c609,
 217            0xa5d14bdf2b7ee65,
 218            0xa718c069defc9138,
 219            0xdb1447e770e3110e,
 220            0xc1b164a9e90af491,
 221            0x7180441f9d251602,
 222            0x1fd3a5e6a9a893e,
 223            0x1e17b779d54d5db,
 224            0x3c7afafe3174,
 225        ])
 226    );
 227
 228    assert_eq!(Fq6Parameters::FROBENIUS_COEFF_FP6_C2[0], Fq2::one());
 229    assert_eq!(
 230        Fq6Parameters::FROBENIUS_COEFF_FP6_C2[1],
 231        nqr.pow([
 232            0x26a9ffffffffc71c,
 233            0x1472aaa9cb8d5555,
 234            0x9a208c6b4f20a418,
 235            0x984f87adf7ae0c7f,
 236            0x32126fced787c88f,
 237            0x11560bf17baa99bc,
 238        ])
 239    );
 240    assert_eq!(
 241        Fq6Parameters::FROBENIUS_COEFF_FP6_C2[2],
 242        nqr.pow([
 243            0x6f1c000012f65ed0,
 244            0xa89e4768f97ac9c7,
 245            0xb972cd024160d353,
 246            0x99d50bf37ef67a2c,
 247            0x1b74591af5b66adb,
 248            0x139aebbdaebae852,
 249            0xf8cb862206509f56,
 250            0x8b1973536493dc49,
 251            0x99ee698623145d35,
 252            0x41e86098b44ad9cd,
 253            0x87e1a5f1c174c3f1,
 254            0x1c2cfc325d7952f,
 255        ])
 256    );
 257    assert_eq!(
 258        Fq6Parameters::FROBENIUS_COEFF_FP6_C2[3],
 259        nqr.pow([
 260            0xb78df9ade6b73c0c,
 261            0x32fbd5a217d9ad55,
 262            0x3b77a4982e40c8c1,
 263            0xe572f598c0af88bd,
 264            0xf1d344617e18c51c,
 265            0xc8f996310b8c74f,
 266            0x9d004c9f8ab7eddc,
 267            0x29b1ae2d87273f89,
 268            0x5af1e1d6efdcddc3,
 269            0xadfc937fcafb8bf3,
 270            0x4cadad82b8c6c8f,
 271            0x1bec505e223f5206,
 272            0x37b74c7c0c656976,
 273            0xd106b2f7954a0bd6,
 274            0x4ada9d9218695304,
 275            0xfc988504777d2165,
 276            0xec8e5154db961e40,
 277            0x2dcafc2dde2a5f,
 278        ])
 279    );
 280    assert_eq!(
 281        Fq6Parameters::FROBENIUS_COEFF_FP6_C2[4],
 282        nqr.pow([
 283            0x8c935ba78e38db20,
 284            0x87954ca512e550ca,
 285            0x9b5088b775541f76,
 286            0x927bd4ccacc554cd,
 287            0x50c779123068903b,
 288            0xa34187eba9997db0,
 289            0x2421ccc1f21995d2,
 290            0xc57ad06d8a8dacbd,
 291            0xe44757754f9eef17,
 292            0xa9e2164459e22d01,
 293            0xaa81ebdfe9432c5d,
 294            0x424743e2816aca4d,
 295            0x6359ca00c6d4b3ed,
 296            0x750579191bf4af52,
 297            0xc918a23c42ff83f0,
 298            0x6d82fffaa748ab1e,
 299            0x1037debfad09ddfa,
 300            0xbac91b7b8bb76a45,
 301            0x1fa0f7e0dcbcb370,
 302            0x1bbd9153595496a3,
 303            0x9983f0d11c5bde4d,
 304            0x4e9cc796925807bc,
 305            0xaf92d02e7a269377,
 306            0x4a6ce9c0550cc,
 307        ])
 308    );
 309    assert_eq!(
 310        Fq6Parameters::FROBENIUS_COEFF_FP6_C2[5],
 311        nqr.pow([
 312            0xf12def24e65d657c,
 313            0x9390d4da3b8b2743,
 314            0xcb663d28b03f2386,
 315            0xc7b4b9814d641aff,
 316            0x4595df2a1c17fdb,
 317            0x62fdb2a173dccf9b,
 318            0xffacc802ddc7ed9a,
 319            0xefb3239110216245,
 320            0xc5ce5cc6bcd304c8,
 321            0x20bc34345a450294,
 322            0xeb6f56747e67b303,
 323            0x2eb0e361781c4bbb,
 324            0x3c5d34c7beb86ee4,
 325            0xd11163ee88b6293a,
 326            0x2aa3833cbcfc5849,
 327            0xd9e4327347a5ad7d,
 328            0xb061b7fb56e5b7a9,
 329            0xf6695f1ac45a8181,
 330            0x7beda4148ace2484,
 331            0x15f0d7dc61c43b30,
 332            0x820c982a69cbbeba,
 333            0xebed957a62c98c12,
 334            0x14ba297be56fdccb,
 335            0x4e3180d3bdf92270,
 336            0xb6288fcee1c6221d,
 337            0x8362c953d215e923,
 338            0xe300883f3a4a2c05,
 339            0x3fa74bcd535127c,
 340            0x3c2f6ef3aa9abb6,
 341            0x78f5f5fc62e8,
 342        ])
 343    );
 344
 345    assert_eq!(Fq12Parameters::FROBENIUS_COEFF_FP12_C1[0], Fq2::one());
 346    assert_eq!(
 347        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[1],
 348        nqr.pow([
 349            0x49aa7ffffffff1c7,
 350            0x51caaaa72e35555,
 351            0xe688231ad3c82906,
 352            0xe613e1eb7deb831f,
 353            0xc849bf3b5e1f223,
 354            0x45582fc5eeaa66f,
 355        ])
 356    );
 357    assert_eq!(
 358        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[2],
 359        nqr.pow([
 360            0xdbc7000004bd97b4,
 361            0xea2791da3e5eb271,
 362            0x2e5cb340905834d4,
 363            0xe67542fcdfbd9e8b,
 364            0x86dd1646bd6d9ab6,
 365            0x84e6baef6baeba14,
 366            0x7e32e188819427d5,
 367            0x62c65cd4d924f712,
 368            0x667b9a6188c5174d,
 369            0x507a18262d12b673,
 370            0xe1f8697c705d30fc,
 371            0x70b3f0c975e54b,
 372        ])
 373    );
 374    assert_eq!(
 375        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[3],
 376        nqr.pow(vec![
 377            0x6de37e6b79adcf03,
 378            0x4cbef56885f66b55,
 379            0x4edde9260b903230,
 380            0x395cbd66302be22f,
 381            0xfc74d1185f863147,
 382            0x323e658c42e31d3,
 383            0x67401327e2adfb77,
 384            0xca6c6b8b61c9cfe2,
 385            0xd6bc7875bbf73770,
 386            0xeb7f24dff2bee2fc,
 387            0x8132b6b60ae31b23,
 388            0x86fb1417888fd481,
 389            0x8dedd31f03195a5d,
 390            0x3441acbde55282f5,
 391            0x52b6a764861a54c1,
 392            0x3f2621411ddf4859,
 393            0xfb23945536e58790,
 394            0xb72bf0b778a97,
 395        ])
 396    );
 397    assert_eq!(
 398        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[4],
 399        nqr.pow(vec![
 400            0xa324d6e9e38e36c8,
 401            0xa1e5532944b95432,
 402            0x66d4222ddd5507dd,
 403            0xe49ef5332b315533,
 404            0x1431de448c1a240e,
 405            0xa8d061faea665f6c,
 406            0x490873307c866574,
 407            0xf15eb41b62a36b2f,
 408            0x7911d5dd53e7bbc5,
 409            0x6a78859116788b40,
 410            0x6aa07af7fa50cb17,
 411            0x5091d0f8a05ab293,
 412            0x98d6728031b52cfb,
 413            0x1d415e4646fd2bd4,
 414            0xb246288f10bfe0fc,
 415            0x9b60bffea9d22ac7,
 416            0x440df7afeb42777e,
 417            0x2eb246dee2edda91,
 418            0xc7e83df8372f2cdc,
 419            0x46ef6454d65525a8,
 420            0x2660fc344716f793,
 421            0xd3a731e5a49601ef,
 422            0x2be4b40b9e89a4dd,
 423            0x129b3a7015433,
 424        ])
 425    );
 426    assert_eq!(
 427        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[5],
 428        nqr.pow(vec![
 429            0xfc4b7bc93997595f,
 430            0xa4e435368ee2c9d0,
 431            0xf2d98f4a2c0fc8e1,
 432            0xf1ed2e60535906bf,
 433            0xc116577ca8705ff6,
 434            0x98bf6ca85cf733e6,
 435            0x7feb3200b771fb66,
 436            0x3becc8e444085891,
 437            0x31739731af34c132,
 438            0xc82f0d0d169140a5,
 439            0xfadbd59d1f99ecc0,
 440            0xbac38d85e0712ee,
 441            0x8f174d31efae1bb9,
 442            0x744458fba22d8a4e,
 443            0x4aa8e0cf2f3f1612,
 444            0x76790c9cd1e96b5f,
 445            0x6c186dfed5b96dea,
 446            0x3d9a57c6b116a060,
 447            0x1efb690522b38921,
 448            0x857c35f718710ecc,
 449            0xa083260a9a72efae,
 450            0xfafb655e98b26304,
 451            0x52e8a5ef95bf732,
 452            0x538c6034ef7e489c,
 453            0xed8a23f3b8718887,
 454            0x60d8b254f4857a48,
 455            0x38c0220fce928b01,
 456            0x80fe9d2f354d449f,
 457            0xf0bdbbceaa6aed,
 458            0x1e3d7d7f18ba,
 459        ])
 460    );
 461    assert_eq!(
 462        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[6],
 463        nqr.pow(vec![
 464            0x21219610a012ba3c,
 465            0xa5c19ad35375325,
 466            0x4e9df1e497674396,
 467            0xfb05b717c991c6ef,
 468            0x4a1265bca93a32f2,
 469            0xd875ff2a7bdc1f66,
 470            0xc6d8754736c771b2,
 471            0x2d80c759ba5a2ae7,
 472            0x138a20df4b03cc1a,
 473            0xc22d07fe68e93024,
 474            0xd1dc474d3b433133,
 475            0xc22aa5e75044e5c,
 476            0xf657c6fbf9c17ebf,
 477            0xc591a794a58660d,
 478            0x2261850ee1453281,
 479            0xd17d3bd3b7f5efb4,
 480            0xf00cec8ec507d01,
 481            0x2a6a775657a00ae6,
 482            0x5f098a12ff470719,
 483            0x409d194e7b5c5afa,
 484            0x1d66478e982af5b,
 485            0xda425a5b5e01ca3f,
 486            0xf77e4f78747e903c,
 487            0x177d49f73732c6fc,
 488            0xa9618fecabe0e1f4,
 489            0xba5337eac90bd080,
 490            0x66fececdbc35d4e7,
 491            0xa4cd583203d9206f,
 492            0x98391632ceeca596,
 493            0x4946b76e1236ad3f,
 494            0xa0dec64e60e711a1,
 495            0xfcb41ed3605013,
 496            0x8ca8f9692ae1e3a9,
 497            0xd3078bfc28cc1baf,
 498            0xf0536f764e982f82,
 499            0x3125f1a2656,
 500        ])
 501    );
 502    assert_eq!(
 503        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[7],
 504        nqr.pow(vec![
 505            0x742754a1f22fdb,
 506            0x2a1955c2dec3a702,
 507            0x9747b28c796d134e,
 508            0xc113a0411f59db79,
 509            0x3bb0fa929853bfc1,
 510            0x28c3c25f8f6fb487,
 511            0xbc2b6c99d3045b34,
 512            0x98fb67d6badde1fd,
 513            0x48841d76a24d2073,
 514            0xd49891145fe93ae6,
 515            0xc772b9c8e74d4099,
 516            0xccf4e7b9907755bb,
 517            0x9cf47b25d42fd908,
 518            0x5616a0c347fc445d,
 519            0xff93b7a7ad1b8a6d,
 520            0xac2099256b78a77a,
 521            0x7804a95b02892e1c,
 522            0x5cf59ca7bfd69776,
 523            0xa7023502acd3c866,
 524            0xc76f4982fcf8f37,
 525            0x51862a5a57ac986e,
 526            0x38b80ed72b1b1023,
 527            0x4a291812066a61e1,
 528            0xcd8a685eff45631,
 529            0x3f40f708764e4fa5,
 530            0x8aa0441891285092,
 531            0x9eff60d71cdf0a9,
 532            0x4fdd9d56517e2bfa,
 533            0x1f3c80d74a28bc85,
 534            0x24617417c064b648,
 535            0x7ddda1e4385d5088,
 536            0xf9e132b11dd32a16,
 537            0xcc957cb8ef66ab99,
 538            0xd4f206d37cb752c5,
 539            0x40de343f28ad616b,
 540            0x8d1f24379068f0e3,
 541            0x6f31d7947ea21137,
 542            0x27311f9c32184061,
 543            0x9eea0664cc78ce5f,
 544            0x7d4151f6fea9a0da,
 545            0x454096fa75bd571a,
 546            0x4fe0f20ecb,
 547        ])
 548    );
 549    assert_eq!(
 550        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[8],
 551        nqr.pow(vec![
 552            0x802f5720d0b25710,
 553            0x6714f0a258b85c7c,
 554            0x31394c90afdf16e,
 555            0xe9d2b0c64f957b19,
 556            0xe67c0d9c5e7903ee,
 557            0x3156fdc5443ea8ef,
 558            0x7c4c50524d88c892,
 559            0xc99dc8990c0ad244,
 560            0xd37ababf3649a896,
 561            0x76fe4b838ff7a20c,
 562            0xcf69ee2cec728db3,
 563            0xb83535548e5f41,
 564            0x371147684ccb0c23,
 565            0x194f6f4fa500db52,
 566            0xc4571dc78a4c5374,
 567            0xe4d46d479999ca97,
 568            0x76b6785a615a151c,
 569            0xcceb8bcea7eaf8c1,
 570            0x80d87a6fbe5ae687,
 571            0x6a97ddddb85ce85,
 572            0xd783958f26034204,
 573            0x7144506f2e2e8590,
 574            0x948693d377aef166,
 575            0x8364621ed6f96056,
 576            0xf021777c4c09ee2d,
 577            0xc6cf5e746ecd50b,
 578            0xa2337b7aa22743df,
 579            0xae753f8bbacab39c,
 580            0xfc782a9e34d3c1cc,
 581            0x21b827324fe494d9,
 582            0x5692ce350ed03b38,
 583            0xf323a2b3cd0481b0,
 584            0xe859c97a4ccad2e3,
 585            0x48434b70381e4503,
 586            0x46042d62e4132ed8,
 587            0x48c4d6f56122e2f2,
 588            0xf87711ab9f5c1af7,
 589            0xb14b7a054759b469,
 590            0x8eb0a96993ffa9aa,
 591            0x9b21fb6fc58b760c,
 592            0xf3abdd115d2e7d25,
 593            0xf7beac3d4d12409c,
 594            0x40a5585cce69bf03,
 595            0x697881e1ba22d5a8,
 596            0x3d6c04e6ad373fd9,
 597            0x849871bf627be886,
 598            0x550f4b9b71b28ef9,
 599            0x81d2e0d78,
 600        ])
 601    );
 602    assert_eq!(
 603        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[9],
 604        nqr.pow(vec![
 605            0x4af4accf7de0b977,
 606            0x742485e21805b4ee,
 607            0xee388fbc4ac36dec,
 608            0x1e199da57ad178a,
 609            0xc27c12b292c6726a,
 610            0x162e6ed84505b5e8,
 611            0xe191683f336e09df,
 612            0x17deb7e8d1e0fce6,
 613            0xd944f19ad06f5836,
 614            0x4c5f5e59f6276026,
 615            0xf1ba9c7c148a38a8,
 616            0xd205fe2dba72b326,
 617            0x9a2cf2a4c289824e,
 618            0x4f47ad512c39e24d,
 619            0xc5894d984000ea09,
 620            0x2974c03ff7cf01fa,
 621            0xfcd243b48cb99a22,
 622            0x2b5150c9313ac1e8,
 623            0x9089f37c7fc80eda,
 624            0x989540cc9a7aea56,
 625            0x1ab1d4e337e63018,
 626            0x42b546c30d357e43,
 627            0x1c6abc04f76233d9,
 628            0x78b3b8d88bf73e47,
 629            0x151c4e4c45dc68e6,
 630            0x519a79c4f54397ed,
 631            0x93f5b51535a127c5,
 632            0x5fc51b6f52fa153e,
 633            0x2e0504f2d4a965c3,
 634            0xc85bd3a3da52bffe,
 635            0x98c60957a46a89ef,
 636            0x48c03b5976b91cae,
 637            0xc6598040a0a61438,
 638            0xbf0b49dc255953af,
 639            0xb78dff905b628ab4,
 640            0x68140b797ba74ab8,
 641            0x116cf037991d1143,
 642            0x2f7fe82e58acb0b8,
 643            0xc20bf7a8f7be5d45,
 644            0x86c2905c338d5709,
 645            0xff13a3ae6c8ace3d,
 646            0xb6f95e2282d08337,
 647            0xd49f7b313e9cbf29,
 648            0xf794517193a1ce8c,
 649            0x39641fecb596a874,
 650            0x411c4c4edf462fb3,
 651            0x3f8cd55c10cf25b4,
 652            0x2bdd7ea165e860b6,
 653            0xacd7d2cef4caa193,
 654            0x6558a1d09a05f96,
 655            0x1f52b5f5b546fc20,
 656            0x4ee22a5a8c250c12,
 657            0xd3a63a54a205b6b3,
 658            0xd2ff5be8,
 659        ])
 660    );
 661    assert_eq!(
 662        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[10],
 663        nqr.pow(vec![
 664            0xe5953a4f96cdda44,
 665            0x336b2d734cbc32bb,
 666            0x3f79bfe3cd7410e,
 667            0x267ae19aaa0f0332,
 668            0x85a9c4db78d5c749,
 669            0x90996b046b5dc7d8,
 670            0x8945eae9820afc6a,
 671            0x2644ddea2b036bd,
 672            0x39898e35ac2e3819,
 673            0x2574eab095659ab9,
 674            0x65953d51ac5ea798,
 675            0xc6b8c7afe6752466,
 676            0x40e9e993e9286544,
 677            0x7e0ad34ad9700ea0,
 678            0xac1015eba2c69222,
 679            0x24f057a19239b5d8,
 680            0x2043b48c8a3767eb,
 681            0x1117c124a75d7ff4,
 682            0x433cfd1a09fb3ce7,
 683            0x25b087ce4bcf7fb,
 684            0xbcee0dc53a3e5bdb,
 685            0xbffda040cf028735,
 686            0xf7cf103a25512acc,
 687            0x31d4ecda673130b9,
 688            0xea0906dab18461e6,
 689            0x5a40585a5ac3050d,
 690            0x803358fc14fd0eda,
 691            0x3678ca654eada770,
 692            0x7b91a1293a45e33e,
 693            0xcd5e5b8ea8530e43,
 694            0x21ae563ab34da266,
 695            0xecb00dad60df8894,
 696            0x77fe53e652facfef,
 697            0x9b7d1ad0b00244ec,
 698            0xe695df5ca73f801,
 699            0x23cdb21feeab0149,
 700            0x14de113e7ea810d9,
 701            0x52600cd958dac7e7,
 702            0xc83392c14667e488,
 703            0x9f808444bc1717fc,
 704            0x56facb4bcf7c788f,
 705            0x8bcad53245fc3ca0,
 706            0xdef661e83f27d81c,
 707            0x37d4ebcac9ad87e5,
 708            0x6fe8b24f5cdb9324,
 709            0xee08a26c1197654c,
 710            0xc98b22f65f237e9a,
 711            0xf54873a908ed3401,
 712            0x6e1cb951d41f3f3,
 713            0x290b2250a54e8df6,
 714            0x7f36d51eb1db669e,
 715            0xb08c7ed81a6ee43e,
 716            0x95e1c90fb092f680,
 717            0x429e4afd0e8b820,
 718            0x2c14a83ee87d715c,
 719            0xf37267575cfc8af5,
 720            0xb99e9afeda3c2c30,
 721            0x8f0f69da75792d5a,
 722            0x35074a85a533c73,
 723            0x156ed119,
 724        ])
 725    );
 726    assert_eq!(
 727        Fq12Parameters::FROBENIUS_COEFF_FP12_C1[11],
 728        nqr.pow(vec![
 729            0x107db680942de533,
 730            0x6262b24d2052393b,
 731            0x6136df824159ebc,
 732            0xedb052c9970c5deb,
 733            0xca813aea916c3777,
 734            0xf49dacb9d76c1788,
 735            0x624941bd372933bb,
 736            0xa5e60c2520638331,
 737            0xb38b661683411074,
 738            0x1d2c9af4c43d962b,
 739            0x17d807a0f14aa830,
 740            0x6e6581a51012c108,
 741            0x668a537e5b35e6f5,
 742            0x6c396cf3782dca5d,
 743            0x33b679d1bff536ed,
 744            0x736cce41805d90aa,
 745            0x8a562f369eb680bf,
 746            0x9f61aa208a11ded8,
 747            0x43dd89dd94d20f35,
 748            0xcf84c6610575c10a,
 749            0x9f318d49cf2fe8e6,
 750            0xbbc6e5f25a6e434e,
 751            0x6528c433d11d987b,
 752            0xffced71cc48c0e8a,
 753            0x4cbb1474f4cb2a26,
 754            0x66a035c0b28b7231,
 755            0xa6f2875faa1a82ae,
 756            0xdd1ea3deff818b02,
 757            0xe0cfdf0dcdecf701,
 758            0x9aefa231f2f6d23,
 759            0xfb251297efa06746,
 760            0x5a40d367df985538,
 761            0x1ea31d69ab506fed,
 762            0xc64ea8280e89a73f,
 763            0x969acf9f2d4496f4,
 764            0xe84c9181ee60c52c,
 765            0xc60f27fc19fc6ca4,
 766            0x760b33d850154048,
 767            0x84f69080f66c8457,
 768            0xc0192ba0fabf640e,
 769            0xd2c338765c23a3a8,
 770            0xa7838c20f02cec6c,
 771            0xb7cf01d020572877,
 772            0xd63ffaeba0be200a,
 773            0xf7492baeb5f041ac,
 774            0x8602c5212170d117,
 775            0xad9b2e83a5a42068,
 776            0x2461829b3ba1083e,
 777            0x7c34650da5295273,
 778            0xdc824ba800a8265a,
 779            0xd18d9b47836af7b2,
 780            0x3af78945c58cbf4d,
 781            0x7ed9575b8596906c,
 782            0x6d0c133895009a66,
 783            0x53bc1247ea349fe1,
 784            0x6b3063078d41aa7a,
 785            0x6184acd8cd880b33,
 786            0x76f4d15503fd1b96,
 787            0x7a9afd61eef25746,
 788            0xce974aadece60609,
 789            0x88ca59546a8ceafd,
 790            0x6d29391c41a0ac07,
 791            0x443843a60e0f46a6,
 792            0xa1590f62fd2602c7,
 793            0x536d5b15b514373f,
 794            0x22d582b,
 795        ])
 796    );
 797}
 798
 799#[test]
 800fn test_neg_one() {
 801    let o = -Fq::one();
 802
 803    let thing: [u64; 6] = [
 804        0x43f5fffffffcaaae,
 805        0x32b7fff2ed47fffd,
 806        0x7e83a49a2e99d69,
 807        0xeca8f3318332bb7a,
 808        0xef148d1ea0f4c069,
 809        0x40ab3263eff0206,
 810    ];
 811    println!("{:?}", thing);
 812    let negative_one = Fq::new(BigInteger384(thing));
 813
 814    assert_eq!(negative_one, o);
 815}
 816
 817#[test]
 818fn test_fq_repr_from() {
 819    assert_eq!(
 820        BigInteger384::from(100),
 821        BigInteger384([100, 0, 0, 0, 0, 0])
 822    );
 823}
 824
 825#[test]
 826fn test_fq_repr_is_odd() {
 827    assert!(!BigInteger384::from(0).is_odd());
 828    assert!(BigInteger384::from(0).is_even());
 829    assert!(BigInteger384::from(1).is_odd());
 830    assert!(!BigInteger384::from(1).is_even());
 831    assert!(!BigInteger384::from(324834872).is_odd());
 832    assert!(BigInteger384::from(324834872).is_even());
 833    assert!(BigInteger384::from(324834873).is_odd());
 834    assert!(!BigInteger384::from(324834873).is_even());
 835}
 836
 837#[test]
 838fn test_fq_repr_is_zero() {
 839    assert!(BigInteger384::from(0).is_zero());
 840    assert!(!BigInteger384::from(1).is_zero());
 841    assert!(!BigInteger384([0, 0, 0, 0, 1, 0]).is_zero());
 842}
 843
 844#[test]
 845fn test_fq_repr_div2() {
 846    let mut a = BigInteger384([
 847        0x8b0ad39f8dd7482a,
 848        0x147221c9a7178b69,
 849        0x54764cb08d8a6aa0,
 850        0x8519d708e1d83041,
 851        0x41f82777bd13fdb,
 852        0xf43944578f9b771b,
 853    ]);
 854    a.div2();
 855    assert_eq!(
 856        a,
 857        BigInteger384([
 858            0xc58569cfc6eba415,
 859            0xa3910e4d38bc5b4,
 860            0xaa3b265846c53550,
 861            0xc28ceb8470ec1820,
 862            0x820fc13bbde89fed,
 863            0x7a1ca22bc7cdbb8d,
 864        ])
 865    );
 866    for _ in 0..10 {
 867        a.div2();
 868    }
 869    assert_eq!(
 870        a,
 871        BigInteger384([
 872            0x6d31615a73f1bae9,
 873            0x54028e443934e2f1,
 874            0x82a8ec99611b14d,
 875            0xfb70a33ae11c3b06,
 876            0xe36083f04eef7a27,
 877            0x1e87288af1f36e,
 878        ])
 879    );
 880    for _ in 0..300 {
 881        a.div2();
 882    }
 883    assert_eq!(
 884        a,
 885        BigInteger384([0x7288af1f36ee3608, 0x1e8, 0x0, 0x0, 0x0, 0x0])
 886    );
 887    for _ in 0..50 {
 888        a.div2();
 889    }
 890    assert_eq!(a, BigInteger384([0x7a1ca2, 0x0, 0x0, 0x0, 0x0, 0x0]));
 891    for _ in 0..22 {
 892        a.div2();
 893    }
 894    assert_eq!(a, BigInteger384([0x1, 0x0, 0x0, 0x0, 0x0, 0x0]));
 895    a.div2();
 896    assert!(a.is_zero());
 897}
 898
 899#[test]
 900fn test_fq_repr_divn() {
 901    let mut a = BigInteger384([
 902        0xaa5cdd6172847ffd,
 903        0x43242c06aed55287,
 904        0x9ddd5b312f3dd104,
 905        0xc5541fd48046b7e7,
 906        0x16080cf4071e0b05,
 907        0x1225f2901aea514e,
 908    ]);
 909    a.divn(0);
 910    assert_eq!(
 911        a,
 912        BigInteger384([
 913            0xaa5cdd6172847ffd,
 914            0x43242c06aed55287,
 915            0x9ddd5b312f3dd104,
 916            0xc5541fd48046b7e7,
 917            0x16080cf4071e0b05,
 918            0x1225f2901aea514e,
 919        ])
 920    );
 921    a.divn(1);
 922    assert_eq!(
 923        a,
 924        BigInteger384([
 925            0xd52e6eb0b9423ffe,
 926            0x21921603576aa943,
 927            0xceeead98979ee882,
 928            0xe2aa0fea40235bf3,
 929            0xb04067a038f0582,
 930            0x912f9480d7528a7,
 931        ])
 932    );
 933    a.divn(50);
 934    assert_eq!(
 935        a,
 936        BigInteger384([
 937            0x8580d5daaa50f54b,
 938            0xab6625e7ba208864,
 939            0x83fa9008d6fcf3bb,
 940            0x19e80e3c160b8aa,
 941            0xbe52035d4a29c2c1,
 942            0x244,
 943        ])
 944    );
 945    a.divn(130);
 946    assert_eq!(
 947        a,
 948        BigInteger384([
 949            0xa0fea40235bf3cee,
 950            0x4067a038f0582e2a,
 951            0x2f9480d7528a70b0,
 952            0x91,
 953            0x0,
 954            0x0,
 955        ])
 956    );
 957    a.divn(64);
 958    assert_eq!(
 959        a,
 960        BigInteger384([0x4067a038f0582e2a, 0x2f9480d7528a70b0, 0x91, 0x0, 0x0, 0x0])
 961    );
 962}
 963
 964#[test]
 965fn test_fq_repr_mul2() {
 966    let mut a = BigInteger384::from(23712937547);
 967    a.mul2();
 968    assert_eq!(a, BigInteger384([0xb0acd6c96, 0x0, 0x0, 0x0, 0x0, 0x0]));
 969    for _ in 0..60 {
 970        a.mul2();
 971    }
 972    assert_eq!(
 973        a,
 974        BigInteger384([0x6000000000000000, 0xb0acd6c9, 0x0, 0x0, 0x0, 0x0])
 975    );
 976    for _ in 0..300 {
 977        a.mul2();
 978    }
 979    assert_eq!(
 980        a,
 981        BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0xcd6c960000000000])
 982    );
 983    for _ in 0..17 {
 984        a.mul2();
 985    }
 986    assert_eq!(
 987        a,
 988        BigInteger384([0x0, 0x0, 0x0, 0x0, 0x0, 0x2c00000000000000])
 989    );
 990    for _ in 0..6 {
 991        a.mul2();
 992    }
 993    assert!(a.is_zero());
 994}
 995
 996#[test]
 997fn test_fq_repr_num_bits() {
 998    let mut a = BigInteger384::from(0);
 999    assert_eq!(0, a.num_bits());
1000    a = BigInteger384::from(1);
1001    for i in 1..385 {
1002        assert_eq!(i, a.num_bits());
1003        a.mul2();
1004    }
1005    assert_eq!(0, a.num_bits());
1006}
1007
1008#[test]
1009fn test_fq_repr_sub_noborrow() {
1010    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1011
1012    let mut t = BigInteger384([
1013        0x827a4a08041ebd9,
1014        0x3c239f3dcc8f0d6b,
1015        0x9ab46a912d555364,
1016        0x196936b17b43910b,
1017        0xad0eb3948a5c34fd,
1018        0xd56f7b5ab8b5ce8,
1019    ]);
1020    t.sub_noborrow(&BigInteger384([
1021        0xc7867917187ca02b,
1022        0x5d75679d4911ffef,
1023        0x8c5b3e48b1a71c15,
1024        0x6a427ae846fd66aa,
1025        0x7a37e7265ee1eaf9,
1026        0x7c0577a26f59d5,
1027    ]));
1028    assert!(
1029        t == BigInteger384([
1030            0x40a12b8967c54bae,
1031            0xdeae37a0837d0d7b,
1032            0xe592c487bae374e,
1033            0xaf26bbc934462a61,
1034            0x32d6cc6e2b7a4a03,
1035            0xcdaf23e091c0313,
1036        ])
1037    );
1038
1039    for _ in 0..1000 {
1040        let mut a = BigInteger384::rand(&mut rng);
1041        a.0[5] >>= 30;
1042        let mut b = a;
1043        for _ in 0..10 {
1044            b.mul2();
1045        }
1046        let mut c = b;
1047        for _ in 0..10 {
1048            c.mul2();
1049        }
1050
1051        assert!(a < b);
1052        assert!(b < c);
1053
1054        let mut csub_ba = c;
1055        csub_ba.sub_noborrow(&b);
1056        csub_ba.sub_noborrow(&a);
1057
1058        let mut csub_ab = c;
1059        csub_ab.sub_noborrow(&a);
1060        csub_ab.sub_noborrow(&b);
1061
1062        assert_eq!(csub_ab, csub_ba);
1063    }
1064
1065    // Subtracting q+1 from q should produce -1 (mod 2**384)
1066    let mut qplusone = BigInteger384([
1067        0xb9feffffffffaaab,
1068        0x1eabfffeb153ffff,
1069        0x6730d2a0f6b0f624,
1070        0x64774b84f38512bf,
1071        0x4b1ba7b6434bacd7,
1072        0x1a0111ea397fe69a,
1073    ]);
1074    qplusone.sub_noborrow(&BigInteger384([
1075        0xb9feffffffffaaac,
1076        0x1eabfffeb153ffff,
1077        0x6730d2a0f6b0f624,
1078        0x64774b84f38512bf,
1079        0x4b1ba7b6434bacd7,
1080        0x1a0111ea397fe69a,
1081    ]));
1082    assert_eq!(
1083        qplusone,
1084        BigInteger384([
1085            0xffffffffffffffff,
1086            0xffffffffffffffff,
1087            0xffffffffffffffff,
1088            0xffffffffffffffff,
1089            0xffffffffffffffff,
1090            0xffffffffffffffff,
1091        ])
1092    );
1093}
1094
1095#[test]
1096fn test_fq_repr_add_nocarry() {
1097    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1098
1099    let mut t = BigInteger384([
1100        0x827a4a08041ebd9,
1101        0x3c239f3dcc8f0d6b,
1102        0x9ab46a912d555364,
1103        0x196936b17b43910b,
1104        0xad0eb3948a5c34fd,
1105        0xd56f7b5ab8b5ce8,
1106    ]);
1107    t.add_nocarry(&BigInteger384([
1108        0xc7867917187ca02b,
1109        0x5d75679d4911ffef,
1110        0x8c5b3e48b1a71c15,
1111        0x6a427ae846fd66aa,
1112        0x7a37e7265ee1eaf9,
1113        0x7c0577a26f59d5,
1114    ]));
1115    assert!(
1116        t == BigInteger384([
1117            0xcfae1db798be8c04,
1118            0x999906db15a10d5a,
1119            0x270fa8d9defc6f79,
1120            0x83abb199c240f7b6,
1121            0x27469abae93e1ff6,
1122            0xdd2fd2d4dfab6be,
1123        ])
1124    );
1125
1126    // Test for the associativity of addition.
1127    for _ in 0..1000 {
1128        let mut a = BigInteger384::rand(&mut rng);
1129        let mut b = BigInteger384::rand(&mut rng);
1130        let mut c = BigInteger384::rand(&mut rng);
1131
1132        // Unset the first few bits, so that overflow won't occur.
1133        a.0[5] >>= 3;
1134        b.0[5] >>= 3;
1135        c.0[5] >>= 3;
1136
1137        let mut abc = a;
1138        abc.add_nocarry(&b);
1139        abc.add_nocarry(&c);
1140
1141        let mut acb = a;
1142        acb.add_nocarry(&c);
1143        acb.add_nocarry(&b);
1144
1145        let mut bac = b;
1146        bac.add_nocarry(&a);
1147        bac.add_nocarry(&c);
1148
1149        let mut bca = b;
1150        bca.add_nocarry(&c);
1151        bca.add_nocarry(&a);
1152
1153        let mut cab = c;
1154        cab.add_nocarry(&a);
1155        cab.add_nocarry(&b);
1156
1157        let mut cba = c;
1158        cba.add_nocarry(&b);
1159        cba.add_nocarry(&a);
1160
1161        assert_eq!(abc, acb);
1162        assert_eq!(abc, bac);
1163        assert_eq!(abc, bca);
1164        assert_eq!(abc, cab);
1165        assert_eq!(abc, cba);
1166    }
1167
1168    // Adding 1 to (2^384 - 1) should produce zero
1169    let mut x = BigInteger384([
1170        0xffffffffffffffff,
1171        0xffffffffffffffff,
1172        0xffffffffffffffff,
1173        0xffffffffffffffff,
1174        0xffffffffffffffff,
1175        0xffffffffffffffff,
1176    ]);
1177    x.add_nocarry(&BigInteger384::from(1));
1178    assert!(x.is_zero());
1179}
1180
1181#[test]
1182fn test_fq_add_assign() {
1183    {
1184        // Random number
1185        let mut tmp = Fq::new(BigInteger384([
1186            0x624434821df92b69,
1187            0x503260c04fd2e2ea,
1188            0xd9df726e0d16e8ce,
1189            0xfbcb39adfd5dfaeb,
1190            0x86b8a22b0c88b112,
1191            0x165a2ed809e4201b,
1192        ]));
1193        // Test that adding zero has no effect.
1194        tmp.add_assign(&Fq::new(BigInteger384::from(0)));
1195        assert_eq!(
1196            tmp,
1197            Fq::new(BigInteger384([
1198                0x624434821df92b69,
1199                0x503260c04fd2e2ea,
1200                0xd9df726e0d16e8ce,
1201                0xfbcb39adfd5dfaeb,
1202                0x86b8a22b0c88b112,
1203                0x165a2ed809e4201b,
1204            ]))
1205        );
1206        // Add one and test for the result.
1207        tmp.add_assign(&Fq::new(BigInteger384::from(1)));
1208        assert_eq!(
1209            tmp,
1210            Fq::new(BigInteger384([
1211                0x624434821df92b6a,
1212                0x503260c04fd2e2ea,
1213                0xd9df726e0d16e8ce,
1214                0xfbcb39adfd5dfaeb,
1215                0x86b8a22b0c88b112,
1216                0x165a2ed809e4201b,
1217            ]))
1218        );
1219        // Add another random number that exercises the reduction.
1220        tmp.add_assign(&Fq::new(BigInteger384([
1221            0x374d8f8ea7a648d8,
1222            0xe318bb0ebb8bfa9b,
1223            0x613d996f0a95b400,
1224            0x9fac233cb7e4fef1,
1225            0x67e47552d253c52,
1226            0x5c31b227edf25da,
1227        ])));
1228        assert_eq!(
1229            tmp,
1230            Fq::new(BigInteger384([
1231                0xdf92c410c59fc997,
1232                0x149f1bd05a0add85,
1233                0xd3ec393c20fba6ab,
1234                0x37001165c1bde71d,
1235                0x421b41c9f662408e,
1236                0x21c38104f435f5b,
1237            ]))
1238        );
1239        // Add one to (q - 1) and test for the result.
1240        tmp = Fq::new(BigInteger384([
1241            0xb9feffffffffaaaa,
1242            0x1eabfffeb153ffff,
1243            0x6730d2a0f6b0f624,
1244            0x64774b84f38512bf,
1245            0x4b1ba7b6434bacd7,
1246            0x1a0111ea397fe69a,
1247        ]));
1248        tmp.add_assign(&Fq::new(BigInteger384::from(1)));
1249        assert!(tmp.0.is_zero());
1250        // Add a random number to another one such that the result is q - 1
1251        tmp = Fq::new(BigInteger384([
1252            0x531221a410efc95b,
1253            0x72819306027e9717,
1254            0x5ecefb937068b746,
1255            0x97de59cd6feaefd7,
1256            0xdc35c51158644588,
1257            0xb2d176c04f2100,
1258        ]));
1259        tmp.add_assign(&Fq::new(BigInteger384([
1260            0x66ecde5bef0fe14f,
1261            0xac2a6cf8aed568e8,
1262            0x861d70d86483edd,
1263            0xcc98f1b7839a22e8,
1264            0x6ee5e2a4eae7674e,
1265            0x194e40737930c599,
1266        ])));
1267        assert_eq!(
1268            tmp,
1269            Fq::new(BigInteger384([
1270                0xb9feffffffffaaaa,
1271                0x1eabfffeb153ffff,
1272                0x6730d2a0f6b0f624,
1273                0x64774b84f38512bf,
1274                0x4b1ba7b6434bacd7,
1275                0x1a0111ea397fe69a,
1276            ]))
1277        );
1278        // Add one to the result and test for it.
1279        tmp.add_assign(&Fq::new(BigInteger384::from(1)));
1280        assert!(tmp.0.is_zero());
1281    }
1282
1283    // Test associativity
1284
1285    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1286
1287    for _ in 0..1000 {
1288        // Generate a, b, c and ensure (a + b) + c == a + (b + c).
1289        let a = Fq::rand(&mut rng);
1290        let b = Fq::rand(&mut rng);
1291        let c = Fq::rand(&mut rng);
1292
1293        let mut tmp1 = a;
1294        tmp1.add_assign(&b);
1295        tmp1.add_assign(&c);
1296
1297        let mut tmp2 = b;
1298        tmp2.add_assign(&c);
1299        tmp2.add_assign(&a);
1300
1301        assert_eq!(tmp1, tmp2);
1302    }
1303}
1304
1305#[test]
1306fn test_fq_sub_assign() {
1307    {
1308        // Test arbitrary subtraction that tests reduction.
1309        let mut tmp = Fq::new(BigInteger384([
1310            0x531221a410efc95b,
1311            0x72819306027e9717,
1312            0x5ecefb937068b746,
1313            0x97de59cd6feaefd7,
1314            0xdc35c51158644588,
1315            0xb2d176c04f2100,
1316        ]));
1317        tmp.sub_assign(&Fq::new(BigInteger384([
1318            0x98910d20877e4ada,
1319            0x940c983013f4b8ba,
1320            0xf677dc9b8345ba33,
1321            0xbef2ce6b7f577eba,
1322            0xe1ae288ac3222c44,
1323            0x5968bb602790806,
1324        ])));
1325        assert_eq!(
1326            tmp,
1327            Fq::new(BigInteger384([
1328                0x748014838971292c,
1329                0xfd20fad49fddde5c,
1330                0xcf87f198e3d3f336,
1331                0x3d62d6e6e41883db,
1332                0x45a3443cd88dc61b,
1333                0x151d57aaf755ff94,
1334            ]))
1335        );
1336
1337        // Test the opposite subtraction which doesn't test reduction.
1338        tmp = Fq::new(BigInteger384([
1339            0x98910d20877e4ada,
1340            0x940c983013f4b8ba,
1341            0xf677dc9b8345ba33,
1342            0xbef2ce6b7f577eba,
1343            0xe1ae288ac3222c44,
1344            0x5968bb602790806,
1345        ]));
1346        tmp.sub_assign(&Fq::new(BigInteger384([
1347            0x531221a410efc95b,
1348            0x72819306027e9717,
1349            0x5ecefb937068b746,
1350            0x97de59cd6feaefd7,
1351            0xdc35c51158644588,
1352            0xb2d176c04f2100,
1353        ])));
1354        assert_eq!(
1355            tmp,
1356            Fq::new(BigInteger384([
1357                0x457eeb7c768e817f,
1358                0x218b052a117621a3,
1359                0x97a8e10812dd02ed,
1360                0x2714749e0f6c8ee3,
1361                0x57863796abde6bc,
1362                0x4e3ba3f4229e706,
1363            ]))
1364        );
1365
1366        // Test for sensible results with zero
1367        tmp = Fq::new(BigInteger384::from(0));
1368        tmp.sub_assign(&Fq::new(BigInteger384::from(0)));
1369        assert!(tmp.is_zero());
1370
1371        tmp = Fq::new(BigInteger384([
1372            0x98910d20877e4ada,
1373            0x940c983013f4b8ba,
1374            0xf677dc9b8345ba33,
1375            0xbef2ce6b7f577eba,
1376            0xe1ae288ac3222c44,
1377            0x5968bb602790806,
1378        ]));
1379        tmp.sub_assign(&Fq::new(BigInteger384::from(0)));
1380        assert_eq!(
1381            tmp,
1382            Fq::new(BigInteger384([
1383                0x98910d20877e4ada,
1384                0x940c983013f4b8ba,
1385                0xf677dc9b8345ba33,
1386                0xbef2ce6b7f577eba,
1387                0xe1ae288ac3222c44,
1388                0x5968bb602790806,
1389            ]))
1390        );
1391    }
1392
1393    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1394
1395    for _ in 0..1000 {
1396        // Ensure that (a - b) + (b - a) = 0.
1397        let a = Fq::rand(&mut rng);
1398        let b = Fq::rand(&mut rng);
1399
1400        let mut tmp1 = a;
1401        tmp1.sub_assign(&b);
1402
1403        let mut tmp2 = b;
1404        tmp2.sub_assign(&a);
1405
1406        tmp1.add_assign(&tmp2);
1407        assert!(tmp1.is_zero());
1408    }
1409}
1410
1411#[test]
1412fn test_fq_mul_assign() {
1413    let mut tmp = Fq::new(BigInteger384([
1414        0xcc6200000020aa8a,
1415        0x422800801dd8001a,
1416        0x7f4f5e619041c62c,
1417        0x8a55171ac70ed2ba,
1418        0x3f69cc3a3d07d58b,
1419        0xb972455fd09b8ef,
1420    ]));
1421    tmp.mul_assign(&Fq::new(BigInteger384([
1422        0x329300000030ffcf,
1423        0x633c00c02cc40028,
1424        0xbef70d925862a942,
1425        0x4f7fa2a82a963c17,
1426        0xdf1eb2575b8bc051,
1427        0x1162b680fb8e9566,
1428    ])));
1429    assert!(
1430        tmp == Fq::new(BigInteger384([
1431            0x9dc4000001ebfe14,
1432            0x2850078997b00193,
1433            0xa8197f1abb4d7bf,
1434            0xc0309573f4bfe871,
1435            0xf48d0923ffaf7620,
1436            0x11d4b58c7a926e66,
1437        ]))
1438    );
1439
1440    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1441
1442    for _ in 0..1000000 {
1443        // Ensure that (a * b) * c = a * (b * c)
1444        let a = Fq::rand(&mut rng);
1445        let b = Fq::rand(&mut rng);
1446        let c = Fq::rand(&mut rng);
1447
1448        let mut tmp1 = a;
1449        tmp1.mul_assign(&b);
1450        tmp1.mul_assign(&c);
1451
1452        let mut tmp2 = b;
1453        tmp2.mul_assign(&c);
1454        tmp2.mul_assign(&a);
1455
1456        assert_eq!(tmp1, tmp2);
1457    }
1458
1459    for _ in 0..1000000 {
1460        // Ensure that r * (a + b + c) = r*a + r*b + r*c
1461
1462        let r = Fq::rand(&mut rng);
1463        let mut a = Fq::rand(&mut rng);
1464        let mut b = Fq::rand(&mut rng);
1465        let mut c = Fq::rand(&mut rng);
1466
1467        let mut tmp1 = a;
1468        tmp1.add_assign(&b);
1469        tmp1.add_assign(&c);
1470        tmp1.mul_assign(&r);
1471
1472        a.mul_assign(&r);
1473        b.mul_assign(&r);
1474        c.mul_assign(&r);
1475
1476        a.add_assign(&b);
1477        a.add_assign(&c);
1478
1479        assert_eq!(tmp1, a);
1480    }
1481}
1482
1483#[test]
1484fn test_fq_squaring() {
1485    let mut a = Fq::new(BigInteger384([
1486        0xffffffffffffffff,
1487        0xffffffffffffffff,
1488        0xffffffffffffffff,
1489        0xffffffffffffffff,
1490        0xffffffffffffffff,
1491        0x19ffffffffffffff,
1492    ]));
1493    a.square_in_place();
1494    assert_eq!(
1495        a,
1496        Fq::from(BigInteger384([
1497            0x1cfb28fe7dfbbb86,
1498            0x24cbe1731577a59,
1499            0xcce1d4edc120e66e,
1500            0xdc05c659b4e15b27,
1501            0x79361e5a802c6a23,
1502            0x24bcbe5d51b9a6f,
1503        ]))
1504    );
1505
1506    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1507
1508    for _ in 0..1000000 {
1509        // Ensure that (a * a) = a^2
1510        let a = Fq::rand(&mut rng);
1511
1512        let mut tmp = a;
1513        tmp.square_in_place();
1514
1515        let mut tmp2 = a;
1516        tmp2.mul_assign(&a);
1517
1518        assert_eq!(tmp, tmp2);
1519    }
1520}
1521
1522#[test]
1523fn test_fq_inverse() {
1524    assert!(Fq::zero().inverse().is_none());
1525
1526    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1527
1528    let one = Fq::one();
1529
1530    for _ in 0..1000 {
1531        // Ensure that a * a^-1 = 1
1532        let mut a = Fq::rand(&mut rng);
1533        let ainv = a.inverse().unwrap();
1534        a.mul_assign(&ainv);
1535        assert_eq!(a, one);
1536    }
1537}
1538
1539#[test]
1540fn test_fq_double_in_place() {
1541    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1542
1543    for _ in 0..1000 {
1544        // Ensure doubling a is equivalent to adding a to itself.
1545        let mut a = Fq::rand(&mut rng);
1546        let mut b = a;
1547        b.add_assign(&a);
1548        a.double_in_place();
1549        assert_eq!(a, b);
1550    }
1551}
1552
1553#[test]
1554fn test_fq_negate() {
1555    {
1556        let a = -Fq::zero();
1557
1558        assert!(a.is_zero());
1559    }
1560
1561    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1562
1563    for _ in 0..1000 {
1564        // Ensure (a - (-a)) = 0.
1565        let mut a = Fq::rand(&mut rng);
1566        let b = -a;
1567        a.add_assign(&b);
1568
1569        assert!(a.is_zero());
1570    }
1571}
1572
1573#[test]
1574fn test_fq_pow() {
1575    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1576
1577    for i in 0..1000 {
1578        // Exponentiate by various small numbers and ensure it consists with repeated
1579        // multiplication.
1580        let a = Fq::rand(&mut rng);
1581        let target = a.pow(&[i]);
1582        let mut c = Fq::one();
1583        for _ in 0..i {
1584            c.mul_assign(&a);
1585        }
1586        assert_eq!(c, target);
1587    }
1588
1589    for _ in 0..1000 {
1590        // Exponentiating by the modulus should have no effect in a prime field.
1591        let a = Fq::rand(&mut rng);
1592
1593        assert_eq!(a, a.pow(Fq::characteristic()));
1594    }
1595}
1596
1597#[test]
1598fn test_fq_sqrt() {
1599    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
1600
1601    assert_eq!(Fq::zero().sqrt().unwrap(), Fq::zero());
1602
1603    for _ in 0..1000 {
1604        // Ensure sqrt(a^2) = a or -a
1605        let a = Fq::rand(&mut rng);
1606        let nega = -a;
1607        let mut b = a;
1608        b.square_in_place();
1609
1610        let b = b.sqrt().unwrap();
1611
1612        assert!(a == b || nega == b);
1613    }
1614
1615    for _ in 0..1000 {
1616        // Ensure sqrt(a)^2 = a for random a
1617        let a = Fq::rand(&mut rng);
1618
1619        if let Some(mut tmp) = a.sqrt() {
1620            tmp.square_in_place();
1621
1622            assert_eq!(a, tmp);
1623        }
1624    }
1625}
1626
1627#[test]
1628fn test_fq_num_bits() {
1629    assert_eq!(FqParameters::MODULUS_BITS, 381);
1630    assert_eq!(FqParameters::CAPACITY, 380);
1631}
1632
1633#[test]
1634fn test_fq_root_of_unity() {
1635    assert_eq!(FqParameters::TWO_ADICITY, 1);
1636    assert_eq!(
1637        Fq::multiplicative_generator(),
1638        Fq::from(BigInteger384::from(2))
1639    );
1640    assert_eq!(
1641        Fq::multiplicative_generator().pow([
1642            0xdcff7fffffffd555,
1643            0xf55ffff58a9ffff,
1644            0xb39869507b587b12,
1645            0xb23ba5c279c2895f,
1646            0x258dd3db21a5d66b,
1647            0xd0088f51cbff34d,
1648        ]),
1649        Fq::two_adic_root_of_unity()
1650    );
1651    assert_eq!(
1652        Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
1653        Fq::one()
1654    );
1655    assert!(Fq::multiplicative_generator().sqrt().is_none());
1656}
1657
1658// #[test]
1659// fn fq_field_tests() {
1660//     ::tests::field::random_field_tests::<Fq>();
1661//     ::tests::field::random_sqrt_tests::<Fq>();
1662//     ::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
1663//     ::tests::field::from_str_tests::<Fq>();
1664// }
1665
1666#[test]
1667fn test_fq_ordering() {
1668    // BigInteger384's ordering is well-tested, but we still need to make sure the
1669    // Fq elements aren't being compared in Montgomery form.
1670    for i in 0..100 {
1671        assert!(Fq::from(BigInteger384::from(i + 1)) > Fq::from(BigInteger384::from(i)));
1672    }
1673}
1674
1675// #[test]
1676// fn fq_repr_tests() {
1677//     ::tests::repr::random_repr_tests::<BigInteger384>();
1678// }
1679
1680#[test]
1681fn test_fq_legendre() {
1682    use ark_ff::fields::LegendreSymbol::*;
1683
1684    assert_eq!(QuadraticResidue, Fq::one().legendre());
1685    assert_eq!(Zero, Fq::zero().legendre());
1686
1687    assert_eq!(
1688        QuadraticNonResidue,
1689        Fq::from(BigInteger384::from(2)).legendre()
1690    );
1691    assert_eq!(
1692        QuadraticResidue,
1693        Fq::from(BigInteger384::from(4)).legendre()
1694    );
1695
1696    let e = BigInteger384([
1697        0x52a112f249778642,
1698        0xd0bedb989b7991f,
1699        0xdad3b6681aa63c05,
1700        0xf2efc0bb4721b283,
1701        0x6057a98f18c24733,
1702        0x1022c2fd122889e4,
1703    ]);
1704    assert_eq!(QuadraticNonResidue, Fq::from(e).legendre());
1705    let e = BigInteger384([
1706        0x6dae594e53a96c74,
1707        0x19b16ca9ba64b37b,
1708        0x5c764661a59bfc68,
1709        0xaa346e9b31c60a,
1710        0x346059f9d87a9fa9,
1711        0x1d61ac6bfd5c88b,
1712    ]);
1713    assert_eq!(QuadraticResidue, Fq::from(e).legendre());
1714}
1715
1716#[test]
1717fn test_fq2_ordering() {
1718    let mut a = Fq2::new(Fq::zero(), Fq::zero());
1719
1720    let mut b = a.clone();
1721
1722    assert!(a.cmp(&b) == Ordering::Equal);
1723    b.c0.add_assign(&Fq::one());
1724    assert!(a.cmp(&b) == Ordering::Less);
1725    a.c0.add_assign(&Fq::one());
1726    assert!(a.cmp(&b) == Ordering::Equal);
1727    b.c1.add_assign(&Fq::one());
1728    assert!(a.cmp(&b) == Ordering::Less);
1729    a.c0.add_assign(&Fq::one());
1730    assert!(a.cmp(&b) == Ordering::Less);
1731    a.c1.add_assign(&Fq::one());
1732    assert!(a.cmp(&b) == Ordering::Greater);
1733    b.c0.add_assign(&Fq::one());
1734    assert!(a.cmp(&b) == Ordering::Equal);
1735}
1736
1737#[test]
1738fn test_fq2_basics() {
1739    assert_eq!(Fq2::new(Fq::zero(), Fq::zero(),), Fq2::zero());
1740    assert_eq!(Fq2::new(Fq::one(), Fq::zero(),), Fq2::one());
1741    assert!(Fq2::zero().is_zero());
1742    assert!(!Fq2::one().is_zero());
1743    assert!(!Fq2::new(Fq::zero(), Fq::one(),).is_zero());
1744}
1745
1746#[test]
1747fn test_fq2_squaring() {
1748    let a = Fq2::new(Fq::one(), Fq::one()).square(); // u + 1
1749    assert_eq!(a, Fq2::new(Fq::zero(), Fq::from(BigInteger384::from(2)),)); // 2u
1750
1751    let a = Fq2::new(Fq::zero(), Fq::one()).square(); // u
1752    assert_eq!(a, {
1753        let neg1 = -Fq::one();
1754        Fq2::new(neg1, Fq::zero())
1755    }); // -1
1756
1757    let mut a = Fq2::new(
1758        Fq::from(BigInteger384([
1759            0x9c2c6309bbf8b598,
1760            0x4eef5c946536f602,
1761            0x90e34aab6fb6a6bd,
1762            0xf7f295a94e58ae7c,
1763            0x41b76dcc1c3fbe5e,
1764            0x7080c5fa1d8e042,
1765        ])),
1766        Fq::from(BigInteger384([
1767            0x38f473b3c870a4ab,
1768            0x6ad3291177c8c7e5,
1769            0xdac5a4c911a4353e,
1770            0xbfb99020604137a0,
1771            0xfc58a7b7be815407,
1772            0x10d1615e75250a21,
1773        ])),
1774    );
1775    a.square_in_place();
1776    assert_eq!(
1777        a,
1778        Fq2::new(
1779            Fq::from(BigInteger384([
1780                0xf262c28c538bcf68,
1781                0xb9f2a66eae1073ba,
1782                0xdc46ab8fad67ae0,
1783                0xcb674157618da176,
1784                0x4cf17b5893c3d327,
1785                0x7eac81369c43361,
1786            ])),
1787            Fq::from(BigInteger384([
1788                0xc1579cf58e980cf8,
1789                0xa23eb7e12dd54d98,
1790                0xe75138bce4cec7aa,
1791                0x38d0d7275a9689e1,
1792                0x739c983042779a65,
1793                0x1542a61c8a8db994,
1794            ])),
1795        )
1796    );
1797}
1798
1799#[test]
1800fn test_fq2_mul() {
1801    let mut a = Fq2::new(
1802        Fq::from(BigInteger384([
1803            0x85c9f989e1461f03,
1804            0xa2e33c333449a1d6,
1805            0x41e461154a7354a3,
1806            0x9ee53e7e84d7532e,
1807            0x1c202d8ed97afb45,
1808            0x51d3f9253e2516f,
1809        ])),
1810        Fq::from(BigInteger384([
1811            0xa7348a8b511aedcf,
1812            0x143c215d8176b319,
1813            0x4cc48081c09b8903,
1814            0x9533e4a9a5158be,
1815            0x7a5e1ecb676d65f9,
1816            0x180c3ee46656b008,
1817        ])),
1818    );
1819    a.mul_assign(&Fq2::new(
1820        Fq::from(BigInteger384([
1821            0xe21f9169805f537e,
1822            0xfc87e62e179c285d,
1823            0x27ece175be07a531,
1824            0xcd460f9f0c23e430,
1825            0x6c9110292bfa409,
1826            0x2c93a72eb8af83e,
1827        ])),
1828        Fq::from(BigInteger384([
1829            0x4b1c3f936d8992d4,
1830            0x1d2a72916dba4c8a,
1831            0x8871c508658d1e5f,
1832            0x57a06d3135a752ae,
1833            0x634cd3c6c565096d,
1834            0x19e17334d4e93558,
1835        ])),
1836    ));
1837    assert_eq!(
1838        a,
1839        Fq2::new(
1840            Fq::from(BigInteger384([
1841                0x95b5127e6360c7e4,
1842                0xde29c31a19a6937e,
1843                0xf61a96dacf5a39bc,
1844                0x5511fe4d84ee5f78,
1845                0x5310a202d92f9963,
1846                0x1751afbe166e5399,
1847            ])),
1848            Fq::from(BigInteger384([
1849                0x84af0e1bd630117a,
1850                0x6c63cd4da2c2aa7,
1851                0x5ba6e5430e883d40,
1852                0xc975106579c275ee,
1853                0x33a9ac82ce4c5083,
1854                0x1ef1a36c201589d,
1855            ])),
1856        )
1857    );
1858}
1859
1860#[test]
1861fn test_fq2_inverse() {
1862    assert!(Fq2::zero().inverse().is_none());
1863
1864    let a = Fq2::new(
1865        Fq::from(BigInteger384([
1866            0x85c9f989e1461f03,
1867            0xa2e33c333449a1d6,
1868            0x41e461154a7354a3,
1869            0x9ee53e7e84d7532e,
1870            0x1c202d8ed97afb45,
1871            0x51d3f9253e2516f,
1872        ])),
1873        Fq::from(BigInteger384([
1874            0xa7348a8b511aedcf,
1875            0x143c215d8176b319,
1876            0x4cc48081c09b8903,
1877            0x9533e4a9a5158be,
1878            0x7a5e1ecb676d65f9,
1879            0x180c3ee46656b008,
1880        ])),
1881    );
1882    let a = a.inverse().unwrap();
1883    assert_eq!(
1884        a,
1885        Fq2::new(
1886            Fq::from(BigInteger384([
1887                0x70300f9bcb9e594,
1888                0xe5ecda5fdafddbb2,
1889                0x64bef617d2915a8f,
1890                0xdfba703293941c30,
1891                0xa6c3d8f9586f2636,
1892                0x1351ef01941b70c4,
1893            ])),
1894            Fq::from(BigInteger384([
1895                0x8c39fd76a8312cb4,
1896                0x15d7b6b95defbff0,
1897                0x947143f89faedee9,
1898                0xcbf651a0f367afb2,
1899                0xdf4e54f0d3ef15a6,
1900                0x103bdf241afb0019,
1901            ])),
1902        )
1903    );
1904}
1905
1906#[test]
1907fn test_fq2_addition() {
1908    let mut a = Fq2::new(
1909        Fq::from(BigInteger384([
1910            0x2d0078036923ffc7,
1911            0x11e59ea221a3b6d2,
1912            0x8b1a52e0a90f59ed,
1913            0xb966ce3bc2108b13,
1914            0xccc649c4b9532bf3,
1915            0xf8d295b2ded9dc,
1916        ])),
1917        Fq::from(BigInteger384([
1918            0x977df6efcdaee0db,
1919            0x946ae52d684fa7ed,
1920            0xbe203411c66fb3a5,
1921            0xb3f8afc0ee248cad,
1922            0x4e464dea5bcfd41e,
1923            0x12d1137b8a6a837,
1924        ])),
1925    );
1926    a.add_assign(&Fq2::new(
1927        Fq::from(BigInteger384([
1928            0x619a02d78dc70ef2,
1929            0xb93adfc9119e33e8,
1930            0x4bf0b99a9f0dca12,
1931            0x3b88899a42a6318f,
1932            0x986a4a62fa82a49d,
1933            0x13ce433fa26027f5,
1934        ])),
1935        Fq::from(BigInteger384([
1936            0x66323bf80b58b9b9,
1937            0xa1379b6facf6e596,
1938            0x402aef1fb797e32f,
1939            0x2236f55246d0d44d,
1940            0x4c8c1800eb104566,
1941            0x11d6e20e986c2085,
1942        ])),
1943    ));
1944    assert_eq!(
1945        a,
1946        Fq2::new(
1947            Fq::from(BigInteger384([
1948                0x8e9a7adaf6eb0eb9,
1949                0xcb207e6b3341eaba,
1950                0xd70b0c7b481d23ff,
1951                0xf4ef57d604b6bca2,
1952                0x65309427b3d5d090,
1953                0x14c715d5553f01d2,
1954            ])),
1955            Fq::from(BigInteger384([
1956                0xfdb032e7d9079a94,
1957                0x35a2809d15468d83,
1958                0xfe4b23317e0796d5,
1959                0xd62fa51334f560fa,
1960                0x9ad265eb46e01984,
1961                0x1303f3465112c8bc,
1962            ])),
1963        )
1964    );
1965}
1966
1967#[test]
1968fn test_fq2_subtraction() {
1969    let mut a = Fq2::new(
1970        Fq::from(BigInteger384([
1971            0x2d0078036923ffc7,
1972            0x11e59ea221a3b6d2,
1973            0x8b1a52e0a90f59ed,
1974            0xb966ce3bc2108b13,
1975            0xccc649c4b9532bf3,
1976            0xf8d295b2ded9dc,
1977        ])),
1978        Fq::from(BigInteger384([
1979            0x977df6efcdaee0db,
1980            0x946ae52d684fa7ed,
1981            0xbe203411c66fb3a5,
1982            0xb3f8afc0ee248cad,
1983            0x4e464dea5bcfd41e,
1984            0x12d1137b8a6a837,
1985        ])),
1986    );
1987    a.sub_assign(&Fq2::new(
1988        Fq::from(BigInteger384([
1989            0x619a02d78dc70ef2,
1990            0xb93adfc9119e33e8,
1991            0x4bf0b99a9f0dca12,
1992            0x3b88899a42a6318f,
1993            0x986a4a62fa82a49d,
1994            0x13ce433fa26027f5,
1995        ])),
1996        Fq::from(BigInteger384([
1997            0x66323bf80b58b9b9,
1998            0xa1379b6facf6e596,
1999            0x402aef1fb797e32f,
2000            0x2236f55246d0d44d,
2001            0x4c8c1800eb104566,
2002            0x11d6e20e986c2085,
2003        ])),
2004    ));
2005    assert_eq!(
2006        a,
2007        Fq2::new(
2008            Fq::from(BigInteger384([
2009                0x8565752bdb5c9b80,
2010                0x7756bed7c15982e9,
2011                0xa65a6be700b285fe,
2012                0xe255902672ef6c43,
2013                0x7f77a718021c342d,
2014                0x72ba14049fe9881,
2015            ])),
2016            Fq::from(BigInteger384([
2017                0xeb4abaf7c255d1cd,
2018                0x11df49bc6cacc256,
2019                0xe52617930588c69a,
2020                0xf63905f39ad8cb1f,
2021                0x4cd5dd9fb40b3b8f,
2022                0x957411359ba6e4c,
2023            ])),
2024        )
2025    );
2026}
2027
2028#[test]
2029fn test_fq2_negation() {
2030    let mut a = Fq2::new(
2031        Fq::from(BigInteger384([
2032            0x2d0078036923ffc7,
2033            0x11e59ea221a3b6d2,
2034            0x8b1a52e0a90f59ed,
2035            0xb966ce3bc2108b13,
2036            0xccc649c4b9532bf3,
2037            0xf8d295b2ded9dc,
2038        ])),
2039        Fq::from(BigInteger384([
2040            0x977df6efcdaee0db,
2041            0x946ae52d684fa7ed,
2042            0xbe203411c66fb3a5,
2043            0xb3f8afc0ee248cad,
2044            0x4e464dea5bcfd41e,
2045            0x12d1137b8a6a837,
2046        ])),
2047    );
2048    a = -a;
2049    assert_eq!(
2050        a,
2051        Fq2::new(
2052            Fq::from(BigInteger384([
2053                0x8cfe87fc96dbaae4,
2054                0xcc6615c8fb0492d,
2055                0xdc167fc04da19c37,
2056                0xab107d49317487ab,
2057                0x7e555df189f880e3,
2058                0x19083f5486a10cbd,
2059            ])),
2060            Fq::from(BigInteger384([
2061                0x228109103250c9d0,
2062                0x8a411ad149045812,
2063                0xa9109e8f3041427e,
2064                0xb07e9bc405608611,
2065                0xfcd559cbe77bd8b8,
2066                0x18d400b280d93e62,
2067            ])),
2068        )
2069    );
2070}
2071
2072#[test]
2073fn test_fq2_doubling() {
2074    let mut a = Fq2::new(
2075        Fq::from(BigInteger384([
2076            0x2d0078036923ffc7,
2077            0x11e59ea221a3b6d2,
2078            0x8b1a52e0a90f59ed,
2079            0xb966ce3bc2108b13,
2080            0xccc649c4b9532bf3,
2081            0xf8d295b2ded9dc,
2082        ])),
2083        Fq::from(BigInteger384([
2084            0x977df6efcdaee0db,
2085            0x946ae52d684fa7ed,
2086            0xbe203411c66fb3a5,
2087            0xb3f8afc0ee248cad,
2088            0x4e464dea5bcfd41e,
2089            0x12d1137b8a6a837,
2090        ])),
2091    );
2092    a.double_in_place();
2093    assert_eq!(
2094        a,
2095        Fq2::new(
2096            Fq::from(BigInteger384([
2097                0x5a00f006d247ff8e,
2098                0x23cb3d4443476da4,
2099                0x1634a5c1521eb3da,
2100                0x72cd9c7784211627,
2101                0x998c938972a657e7,
2102                0x1f1a52b65bdb3b9,
2103            ])),
2104            Fq::from(BigInteger384([
2105                0x2efbeddf9b5dc1b6,
2106                0x28d5ca5ad09f4fdb,
2107                0x7c4068238cdf674b,
2108                0x67f15f81dc49195b,
2109                0x9c8c9bd4b79fa83d,
2110                0x25a226f714d506e,
2111            ])),
2112        )
2113    );
2114}
2115
2116#[test]
2117fn test_fq2_frobenius_map() {
2118    let mut a = Fq2::new(
2119        Fq::from(BigInteger384([
2120            0x2d0078036923ffc7,
2121            0x11e59ea221a3b6d2,
2122            0x8b1a52e0a90f59ed,
2123            0xb966ce3bc2108b13,
2124            0xccc649c4b9532bf3,
2125            0xf8d295b2ded9dc,
2126        ])),
2127        Fq::from(BigInteger384([
2128            0x977df6efcdaee0db,
2129            0x946ae52d684fa7ed,
2130            0xbe203411c66fb3a5,
2131            0xb3f8afc0ee248cad,
2132            0x4e464dea5bcfd41e,
2133            0x12d1137b8a6a837,
2134        ])),
2135    );
2136    a.frobenius_map(0);
2137    assert_eq!(
2138        a,
2139        Fq2::new(
2140            Fq::from(BigInteger384([
2141                0x2d0078036923ffc7,
2142                0x11e59ea221a3b6d2,
2143                0x8b1a52e0a90f59ed,
2144                0xb966ce3bc2108b13,
2145                0xccc649c4b9532bf3,
2146                0xf8d295b2ded9dc,
2147            ])),
2148            Fq::from(BigInteger384([
2149                0x977df6efcdaee0db,
2150                0x946ae52d684fa7ed,
2151                0xbe203411c66fb3a5,
2152                0xb3f8afc0ee248cad,
2153                0x4e464dea5bcfd41e,
2154                0x12d1137b8a6a837,
2155            ])),
2156        )
2157    );
2158    a.frobenius_map(1);
2159    assert_eq!(
2160        a,
2161        Fq2::new(
2162            Fq::from(BigInteger384([
2163                0x2d0078036923ffc7,
2164                0x11e59ea221a3b6d2,
2165                0x8b1a52e0a90f59ed,
2166                0xb966ce3bc2108b13,
2167                0xccc649c4b9532bf3,
2168                0xf8d295b2ded9dc,
2169            ])),
2170            Fq::from(BigInteger384([
2171                0x228109103250c9d0,
2172                0x8a411ad149045812,
2173                0xa9109e8f3041427e,
2174                0xb07e9bc405608611,
2175                0xfcd559cbe77bd8b8,
2176                0x18d400b280d93e62,
2177            ])),
2178        )
2179    );
2180    a.frobenius_map(1);
2181    assert_eq!(
2182        a,
2183        Fq2::new(
2184            Fq::from(BigInteger384([
2185                0x2d0078036923ffc7,
2186                0x11e59ea221a3b6d2,
2187                0x8b1a52e0a90f59ed,
2188                0xb966ce3bc2108b13,
2189                0xccc649c4b9532bf3,
2190                0xf8d295b2ded9dc,
2191            ])),
2192            Fq::from(BigInteger384([
2193                0x977df6efcdaee0db,
2194                0x946ae52d684fa7ed,
2195                0xbe203411c66fb3a5,
2196                0xb3f8afc0ee248cad,
2197                0x4e464dea5bcfd41e,
2198                0x12d1137b8a6a837,
2199            ])),
2200        )
2201    );
2202    a.frobenius_map(2);
2203    assert_eq!(
2204        a,
2205        Fq2::new(
2206            Fq::from(BigInteger384([
2207                0x2d0078036923ffc7,
2208                0x11e59ea221a3b6d2,
2209                0x8b1a52e0a90f59ed,
2210                0xb966ce3bc2108b13,
2211                0xccc649c4b9532bf3,
2212                0xf8d295b2ded9dc,
2213            ])),
2214            Fq::from(BigInteger384([
2215                0x977df6efcdaee0db,
2216                0x946ae52d684fa7ed,
2217                0xbe203411c66fb3a5,
2218                0xb3f8afc0ee248cad,
2219                0x4e464dea5bcfd41e,
2220                0x12d1137b8a6a837,
2221            ])),
2222        )
2223    );
2224}
2225
2226#[test]
2227fn test_fq2_legendre() {
2228    use ark_ff::fields::LegendreSymbol::*;
2229
2230    assert_eq!(Zero, Fq2::zero().legendre());
2231    // i^2 = -1
2232    let mut m1 = -Fq2::one();
2233    assert_eq!(QuadraticResidue, m1.legendre());
2234    m1 = Fq6Parameters::mul_fp2_by_nonresidue(&m1);
2235    assert_eq!(QuadraticNonResidue, m1.legendre());
2236}
2237
2238#[test]
2239fn test_fq2_mul_nonresidue() {
2240    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
2241
2242    let nqr = Fq2::new(Fq::one(), Fq::one());
2243
2244    for _ in 0..1000 {
2245        let mut a = Fq2::rand(&mut rng);
2246        let mut b = a;
2247        a = Fq6Parameters::mul_fp2_by_nonresidue(&a);
2248        b.mul_assign(&nqr);
2249
2250        assert_eq!(a, b);
2251    }
2252}
2253
2254#[test]
2255fn test_fq6_mul_nonresidue() {
2256    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
2257
2258    let nqr = Fq6::new(Fq2::zero(), Fq2::one(), Fq2::zero());
2259
2260    for _ in 0..1000 {
2261        let mut a = Fq6::rand(&mut rng);
2262        let mut b = a;
2263        a = Fq12Parameters::mul_fp6_by_nonresidue(&a);
2264        b.mul_assign(&nqr);
2265
2266        assert_eq!(a, b);
2267    }
2268}
2269
2270#[test]
2271fn test_fq6_mul_by_1() {
2272    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
2273
2274    for _ in 0..1000 {
2275        let c1 = Fq2::rand(&mut rng);
2276        let mut a = Fq6::rand(&mut rng);
2277        let mut b = a;
2278
2279        a.mul_by_1(&c1);
2280        b.mul_assign(&Fq6::new(Fq2::zero(), c1, Fq2::zero()));
2281
2282        assert_eq!(a, b);
2283    }
2284}
2285
2286#[test]
2287fn test_fq6_mul_by_01() {
2288    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
2289
2290    for _ in 0..1000 {
2291        let c0 = Fq2::rand(&mut rng);
2292        let c1 = Fq2::rand(&mut rng);
2293        let mut a = Fq6::rand(&mut rng);
2294        let mut b = a;
2295
2296        a.mul_by_01(&c0, &c1);
2297        b.mul_assign(&Fq6::new(c0, c1, Fq2::zero()));
2298
2299        assert_eq!(a, b);
2300    }
2301}
2302
2303#[test]
2304fn test_fq12_mul_by_014() {
2305    let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
2306
2307    for _ in 0..1000 {
2308        let c0 = Fq2::rand(&mut rng);
2309        let c1 = Fq2::rand(&mut rng);
2310        let c5 = Fq2::rand(&mut rng);
2311        let mut a = Fq12::rand(&mut rng);
2312        let mut b = a;
2313
2314        a.mul_by_014(&c0, &c1, &c5);
2315        b.mul_assign(&Fq12::new(
2316            Fq6::new(c0, c1, Fq2::zero()),
2317            Fq6::new(Fq2::zero(), c5, Fq2::zero()),
2318        ));
2319
2320        assert_eq!(a, b);
2321    }
2322}