FeCombine function

void FeCombine(
  1. FieldElement h,
  2. int h0,
  3. int h1,
  4. int h2,
  5. int h3,
  6. int h4,
  7. int h5,
  8. int h6,
  9. int h7,
  10. int h8,
  11. int h9,
)

Implementation

void FeCombine(FieldElement h, int h0, int h1, int h2, int h3, int h4, int h5,
    int h6, int h7, int h8, int h9) {
  var c0 = 0;
  var c1 = 0;
  var c2 = 0;
  var c3 = 0;
  var c4 = 0;
  var c5 = 0;
  var c6 = 0;
  var c7 = 0;
  var c8 = 0;
  var c9 = 0;

  /*
      |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
        i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
      |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
        i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
    */

  c0 = (h0 + (1 << 25)) >> 26;
  h1 += c0;
  h0 -= c0 << 26;
  c4 = (h4 + (1 << 25)) >> 26;
  h5 += c4;
  h4 -= c4 << 26;
  /* |h0| <= 2^25 */
  /* |h4| <= 2^25 */
  /* |h1| <= 1.51*2^58 */
  /* |h5| <= 1.51*2^58 */

  c1 = (h1 + (1 << 24)) >> 25;
  h2 += c1;
  h1 -= c1 << 25;
  c5 = (h5 + (1 << 24)) >> 25;
  h6 += c5;
  h5 -= c5 << 25;
  /* |h1| <= 2^24; from now on fits into int32 */
  /* |h5| <= 2^24; from now on fits into int32 */
  /* |h2| <= 1.21*2^59 */
  /* |h6| <= 1.21*2^59 */

  c2 = (h2 + (1 << 25)) >> 26;
  h3 += c2;
  h2 -= c2 << 26;
  c6 = (h6 + (1 << 25)) >> 26;
  h7 += c6;
  h6 -= c6 << 26;
  /* |h2| <= 2^25; from now on fits into int32 unchanged */
  /* |h6| <= 2^25; from now on fits into int32 unchanged */
  /* |h3| <= 1.51*2^58 */
  /* |h7| <= 1.51*2^58 */

  c3 = (h3 + (1 << 24)) >> 25;
  h4 += c3;
  h3 -= c3 << 25;
  c7 = (h7 + (1 << 24)) >> 25;
  h8 += c7;
  h7 -= c7 << 25;
  /* |h3| <= 2^24; from now on fits into int32 unchanged */
  /* |h7| <= 2^24; from now on fits into int32 unchanged */
  /* |h4| <= 1.52*2^33 */
  /* |h8| <= 1.52*2^33 */

  c4 = (h4 + (1 << 25)) >> 26;
  h5 += c4;
  h4 -= c4 << 26;
  c8 = (h8 + (1 << 25)) >> 26;
  h9 += c8;
  h8 -= c8 << 26;
  /* |h4| <= 2^25; from now on fits into int32 unchanged */
  /* |h8| <= 2^25; from now on fits into int32 unchanged */
  /* |h5| <= 1.01*2^24 */
  /* |h9| <= 1.51*2^58 */

  c9 = (h9 + (1 << 24)) >> 25;
  h0 += c9 * 19;
  h9 -= c9 << 25;
  /* |h9| <= 2^24; from now on fits into int32 unchanged */
  /* |h0| <= 1.8*2^37 */

  c0 = (h0 + (1 << 25)) >> 26;
  h1 += c0;
  h0 -= c0 << 26;
  /* |h0| <= 2^25; from now on fits into int32 unchanged */
  /* |h1| <= 1.01*2^24 */

  h[0] = h0;
  h[1] = h1;
  h[2] = h2;
  h[3] = h3;
  h[4] = h4;
  h[5] = h5;
  h[6] = h6;
  h[7] = h7;
  h[8] = h8;
  h[9] = h9;
}