sub method
Implementation
JubJubFq sub(JubJubFq rhs) {
// Step 1: Subtract limbs with borrow
var sbbRes = BigintUtils.sbb(limbs[0], rhs.limbs[0], BigInt.zero);
BigInt d0 = sbbRes[0];
BigInt borrow = sbbRes[1];
sbbRes = BigintUtils.sbb(limbs[1], rhs.limbs[1], borrow);
BigInt d1 = sbbRes[0];
borrow = sbbRes[1];
sbbRes = BigintUtils.sbb(limbs[2], rhs.limbs[2], borrow);
BigInt d2 = sbbRes[0];
borrow = sbbRes[1];
sbbRes = BigintUtils.sbb(limbs[3], rhs.limbs[3], borrow);
BigInt d3 = sbbRes[0];
borrow = sbbRes[1];
// Step 2: Conditionally add modulus if underflow occurred
var adcRes = BigintUtils.adc(
d0,
JubJubFqConst.modulus.limbs[0] & borrow,
BigInt.zero,
);
d0 = adcRes[0];
BigInt carry = adcRes[1];
adcRes = BigintUtils.adc(
d1,
JubJubFqConst.modulus.limbs[1] & borrow,
carry,
);
d1 = adcRes[0];
carry = adcRes[1];
adcRes = BigintUtils.adc(
d2,
JubJubFqConst.modulus.limbs[2] & borrow,
carry,
);
d2 = adcRes[0];
carry = adcRes[1];
adcRes = BigintUtils.adc(
d3,
JubJubFqConst.modulus.limbs[3] & borrow,
carry,
);
d3 = adcRes[0];
// final carry ignored
return JubJubFq([d0, d1, d2, d3]);
}