square method
Squares the element.
Implementation
@override
VestaFq square() {
// Step 1: cross products
var r1Carry = BigintUtils.mac(BigInt.zero, limbs[0], limbs[1], BigInt.zero);
var r1 = r1Carry[0];
var carry = r1Carry[1];
var r2Carry = BigintUtils.mac(BigInt.zero, limbs[0], limbs[2], carry);
var r2 = r2Carry[0];
carry = r2Carry[1];
var r3Carry = BigintUtils.mac(BigInt.zero, limbs[0], limbs[3], carry);
var r3 = r3Carry[0];
var r4 = r3Carry[1];
var r3Carry2 = BigintUtils.mac(r3, limbs[1], limbs[2], BigInt.zero);
r3 = r3Carry2[0];
var r4Carry = BigintUtils.mac(r4, limbs[1], limbs[3], r3Carry2[1]);
r4 = r4Carry[0];
var r5 = r4Carry[1];
var r5Carry = BigintUtils.mac(r5, limbs[2], limbs[3], BigInt.zero);
r5 = r5Carry[0];
var r6 = r5Carry[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;
// Step 3: add squares of limbs
var r0Carry = BigintUtils.mac(BigInt.zero, limbs[0], limbs[0], BigInt.zero);
var r0 = r0Carry[0];
carry = r0Carry[1];
var r1Adc = BigintUtils.adc(BigInt.zero, r1, carry);
r1 = r1Adc[0];
carry = r1Adc[1];
r2Carry = BigintUtils.mac(r2, limbs[1], limbs[1], carry);
r2 = r2Carry[0];
carry = r2Carry[1];
var r3Adc = BigintUtils.adc(BigInt.zero, r3, carry);
r3 = r3Adc[0];
carry = r3Adc[1];
r4Carry = BigintUtils.mac(r4, limbs[2], limbs[2], carry);
r4 = r4Carry[0];
carry = r4Carry[1];
var r5Adc = BigintUtils.adc(BigInt.zero, r5, carry);
r5 = r5Adc[0];
carry = r5Adc[1];
var r6Carry = BigintUtils.mac(r6, limbs[3], limbs[3], carry);
r6 = r6Carry[0];
carry = r6Carry[1];
var r7Adc = BigintUtils.adc(BigInt.zero, r7, carry);
r7 = r7Adc[0];
// final carry ignored
return VestaFq.montgomeryReduce(r0, r1, r2, r3, r4, r5, r6, r7);
}