feTobytes static method
Implementation
static void feTobytes(List<int> s, FieldElement h) {
s.asMin32("feTobytes");
BigInt h0 = h.h[0].toBig;
BigInt h1 = h.h[1].toBig;
BigInt h2 = h.h[2].toBig;
BigInt h3 = h.h[3].toBig;
BigInt h4 = h.h[4].toBig;
BigInt h5 = h.h[5].toBig;
BigInt h6 = h.h[6].toBig;
BigInt h7 = h.h[7].toBig;
BigInt h8 = h.h[8].toBig;
BigInt h9 = h.h[9].toBig;
BigInt q;
BigInt carry0;
BigInt carry1;
BigInt carry2;
BigInt carry3;
BigInt carry4;
BigInt carry5;
BigInt carry6;
BigInt carry7;
BigInt carry8;
BigInt carry9;
q = (BigInt.from(19) * h9 + ((1) << 24).toBig) >> 25;
q = (h0 + q) >> 26;
q = (h1 + q) >> 25;
q = (h2 + q) >> 26;
q = (h3 + q) >> 25;
q = (h4 + q) >> 26;
q = (h5 + q) >> 25;
q = (h6 + q) >> 26;
q = (h7 + q) >> 25;
q = (h8 + q) >> 26;
q = (h9 + q) >> 25;
/* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
h0 += BigInt.from(19) * q;
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
carry0 = (h0 >> 26);
h1 += carry0;
h0 -= carry0 << 26;
carry1 = h1 >> 25;
h2 += carry1;
h1 -= carry1 << 25;
carry2 = h2 >> 26;
h3 += carry2;
h2 -= carry2 << 26;
carry3 = h3 >> 25;
h4 += carry3;
h3 -= carry3 << 25;
carry4 = h4 >> 26;
h5 += carry4;
h4 -= carry4 << 26;
carry5 = h5 >> 25;
h6 += carry5;
h5 -= carry5 << 25;
carry6 = h6 >> 26;
h7 += carry6;
h6 -= carry6 << 26;
carry7 = h7 >> 25;
h8 += carry7;
h7 -= carry7 << 25;
carry8 = h8 >> 26;
h9 += carry8;
h8 -= carry8 << 26;
carry9 = h9 >> 25;
h9 -= carry9 << 25;
/* h10 = carry9 */
/*
Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
Have h0+...+2^230 h9 between 0 and 2^255-1;
evidently 2^255 h10-2^255 q = 0.
Goal: Output h0+...+2^230 h9.
*/
final List<BigInt> sBig = List<BigInt>.filled(32, BigInt.zero);
sBig[0] = h0 >> 0;
sBig[1] = h0 >> 8;
sBig[2] = h0 >> 16;
sBig[3] = (h0 >> 24) | (h1 << 2);
sBig[4] = h1 >> 6;
sBig[5] = h1 >> 14;
sBig[6] = (h1 >> 22) | (h2 << 3);
sBig[7] = h2 >> 5;
sBig[8] = h2 >> 13;
sBig[9] = (h2 >> 21) | (h3 << 5);
sBig[10] = h3 >> 3;
sBig[11] = h3 >> 11;
sBig[12] = (h3 >> 19) | (h4 << 6);
sBig[13] = h4 >> 2;
sBig[14] = h4 >> 10;
sBig[15] = h4 >> 18;
sBig[16] = h5 >> 0;
sBig[17] = h5 >> 8;
sBig[18] = h5 >> 16;
sBig[19] = (h5 >> 24) | (h6 << 1);
sBig[20] = h6 >> 7;
sBig[21] = h6 >> 15;
sBig[22] = (h6 >> 23) | (h7 << 3);
sBig[23] = h7 >> 5;
sBig[24] = h7 >> 13;
sBig[25] = (h7 >> 21) | (h8 << 4);
sBig[26] = h8 >> 4;
sBig[27] = h8 >> 12;
sBig[28] = (h8 >> 20) | (h9 << 6);
sBig[29] = h9 >> 2;
sBig[30] = h9 >> 10;
sBig[31] = h9 >> 18;
for (int i = 0; i < s.length; i++) {
s[i] = sBig[i].toUnsigned8;
}
}