sub method

JubJubFq sub(
  1. JubJubFq rhs
)

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]);
}