square method

  1. @override
PallasFp square()
override

Squares the element.

Implementation

@override
PallasFp square() {
  // Compute cross terms
  var tmp = BigintUtils.mac(BigInt.zero, limbs[0], limbs[1], BigInt.zero);
  var r1 = tmp[0];
  var carry = tmp[1];

  tmp = BigintUtils.mac(BigInt.zero, limbs[0], limbs[2], carry);
  var r2 = tmp[0];
  carry = tmp[1];

  tmp = BigintUtils.mac(BigInt.zero, limbs[0], limbs[3], carry);
  var r3 = tmp[0];
  var r4 = tmp[1];

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

  tmp = BigintUtils.mac(r4, limbs[1], limbs[3], carry);
  r4 = tmp[0];
  var r5 = tmp[1];

  tmp = BigintUtils.mac(r5, limbs[2], limbs[3], BigInt.zero);
  r5 = tmp[0];
  var r6 = tmp[1];

  // Step 2: double the cross terms
  var r7 = (r6 >> 63).toU64;
  r6 = ((r6 << 1) | (r5 >> 63)).toU64;
  r5 = ((r5 << 1) | (r4 >> 63)).toU64;
  r4 = ((r4 << 1) | (r3 >> 63)).toU64;
  r3 = ((r3 << 1) | (r2 >> 63)).toU64;
  r2 = ((r2 << 1) | (r1 >> 63)).toU64;
  r1 = (r1 << 1).toU64;

  // Add squares of individual limbs
  tmp = BigintUtils.mac(BigInt.zero, limbs[0], limbs[0], BigInt.zero);
  var r0 = tmp[0];
  carry = tmp[1];

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

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

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

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

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

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

  tmp = BigintUtils.adc(BigInt.zero, r7, carry);
  r7 = tmp[0];
  // final carry ignored

  // Perform Montgomery reduction
  return PallasFp.montgomeryReduce(r0, r1, r2, r3, r4, r5, r6, r7);
}