Bls12Fp.montgomeryReduce constructor

Bls12Fp.montgomeryReduce(
  1. BigInt t0,
  2. BigInt t1,
  3. BigInt t2,
  4. BigInt t3,
  5. BigInt t4,
  6. BigInt t5,
  7. BigInt t6,
  8. BigInt t7,
  9. BigInt t8,
  10. BigInt t9,
  11. BigInt t10,
  12. BigInt t11,
)

Montgomery reduction of a 12-limb intermediate into a BLS12-381 field element.

Implementation

factory Bls12Fp.montgomeryReduce(
  BigInt t0,
  BigInt t1,
  BigInt t2,
  BigInt t3,
  BigInt t4,
  BigInt t5,
  BigInt t6,
  BigInt t7,
  BigInt t8,
  BigInt t9,
  BigInt t10,
  BigInt t11,
) {
  final inv = Bls12FpConst.inv;
  // --- 1st iteration --------------------------------------------------------
  BigInt k = (t0 * inv).toU64;
  List<BigInt> tmp = BigintUtils.mac(
    t0,
    k,
    Bls12FpConst.modulus.limbs[0],
    BigInt.zero,
  );
  BigInt carry = tmp[1];

  tmp = BigintUtils.mac(t1, k, Bls12FpConst.modulus.limbs[1], carry);
  BigInt r1 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(t2, k, Bls12FpConst.modulus.limbs[2], carry);
  BigInt r2 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(t3, k, Bls12FpConst.modulus.limbs[3], carry);
  BigInt r3 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(t4, k, Bls12FpConst.modulus.limbs[4], carry);
  BigInt r4 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(t5, k, Bls12FpConst.modulus.limbs[5], carry);
  BigInt r5 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.adc(t6, BigInt.zero, carry);
  BigInt r6 = tmp[0];
  BigInt r7 = tmp[1];

  // --- 2nd iteration --------------------------------------------------------
  k = (r1 * inv).toU64;

  tmp = BigintUtils.mac(r1, k, Bls12FpConst.modulus.limbs[0], BigInt.zero);
  carry = tmp[1];

  tmp = BigintUtils.mac(r2, k, Bls12FpConst.modulus.limbs[1], carry);
  r2 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r3, k, Bls12FpConst.modulus.limbs[2], carry);
  r3 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r4, k, Bls12FpConst.modulus.limbs[3], carry);
  r4 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r5, k, Bls12FpConst.modulus.limbs[4], carry);
  r5 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r6, k, Bls12FpConst.modulus.limbs[5], carry);
  r6 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.adc(t7, r7, carry);
  r7 = tmp[0];
  BigInt r8 = tmp[1];

  // --- 3rd iteration --------------------------------------------------------
  k = (r2 * inv).toU64;

  tmp = BigintUtils.mac(r2, k, Bls12FpConst.modulus.limbs[0], BigInt.zero);
  carry = tmp[1];

  tmp = BigintUtils.mac(r3, k, Bls12FpConst.modulus.limbs[1], carry);
  r3 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r4, k, Bls12FpConst.modulus.limbs[2], carry);
  r4 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r5, k, Bls12FpConst.modulus.limbs[3], carry);
  r5 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r6, k, Bls12FpConst.modulus.limbs[4], carry);
  r6 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r7, k, Bls12FpConst.modulus.limbs[5], carry);
  r7 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.adc(t8, r8, carry);
  r8 = tmp[0];
  BigInt r9 = tmp[1];

  // --- 4th iteration --------------------------------------------------------
  k = (r3 * inv).toU64;

  tmp = BigintUtils.mac(r3, k, Bls12FpConst.modulus.limbs[0], BigInt.zero);
  carry = tmp[1];

  tmp = BigintUtils.mac(r4, k, Bls12FpConst.modulus.limbs[1], carry);
  r4 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r5, k, Bls12FpConst.modulus.limbs[2], carry);
  r5 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r6, k, Bls12FpConst.modulus.limbs[3], carry);
  r6 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r7, k, Bls12FpConst.modulus.limbs[4], carry);
  r7 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r8, k, Bls12FpConst.modulus.limbs[5], carry);
  r8 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.adc(t9, r9, carry);
  r9 = tmp[0];
  BigInt r10 = tmp[1];

  // --- 5th iteration --------------------------------------------------------
  k = (r4 * inv).toU64;

  tmp = BigintUtils.mac(r4, k, Bls12FpConst.modulus.limbs[0], BigInt.zero);
  carry = tmp[1];

  tmp = BigintUtils.mac(r5, k, Bls12FpConst.modulus.limbs[1], carry);
  r5 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r6, k, Bls12FpConst.modulus.limbs[2], carry);
  r6 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r7, k, Bls12FpConst.modulus.limbs[3], carry);
  r7 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r8, k, Bls12FpConst.modulus.limbs[4], carry);
  r8 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r9, k, Bls12FpConst.modulus.limbs[5], carry);
  r9 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.adc(t10, r10, carry);
  r10 = tmp[0];
  BigInt r11 = tmp[1];

  // --- 6th iteration --------------------------------------------------------
  k = (r5 * inv).toU64;

  tmp = BigintUtils.mac(r5, k, Bls12FpConst.modulus.limbs[0], BigInt.zero);
  carry = tmp[1];

  tmp = BigintUtils.mac(r6, k, Bls12FpConst.modulus.limbs[1], carry);
  r6 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r7, k, Bls12FpConst.modulus.limbs[2], carry);
  r7 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r8, k, Bls12FpConst.modulus.limbs[3], carry);
  r8 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r9, k, Bls12FpConst.modulus.limbs[4], carry);
  r9 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(r10, k, Bls12FpConst.modulus.limbs[5], carry);
  r10 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.adc(t11, r11, carry);
  r11 = tmp[0];

  // Final reduce: subtract modulus
  return Bls12Fp([r6, r7, r8, r9, r10, r11])._subtractP();
}