ScReduce function
Input:
s0
+256s1
+...+256^63s63
= s
Output:
s0
+256s1
+...+256^31s31
= s mod l
where l = 2^252 + 27742317777372353535851937790883648493.
Implementation
void ScReduce(Uint8List out, Uint8List s) {
var s0 = 2097151 & load3(s.sublist(0, s.length));
var s1 = 2097151 & (load4(s.sublist(2, s.length)) >> 5);
var s2 = 2097151 & (load3(s.sublist(5, s.length)) >> 2);
var s3 = 2097151 & (load4(s.sublist(7, s.length)) >> 7);
var s4 = 2097151 & (load4(s.sublist(10, s.length)) >> 4);
var s5 = 2097151 & (load3(s.sublist(13, s.length)) >> 1);
var s6 = 2097151 & (load4(s.sublist(15, s.length)) >> 6);
var s7 = 2097151 & (load3(s.sublist(18, s.length)) >> 3);
var s8 = 2097151 & load3(s.sublist(21, s.length));
var s9 = 2097151 & (load4(s.sublist(23, s.length)) >> 5);
var s10 = 2097151 & (load3(s.sublist(26, s.length)) >> 2);
var s11 = 2097151 & (load4(s.sublist(28, s.length)) >> 7);
var s12 = 2097151 & (load4(s.sublist(31, s.length)) >> 4);
var s13 = 2097151 & (load3(s.sublist(34, s.length)) >> 1);
var s14 = 2097151 & (load4(s.sublist(36, s.length)) >> 6);
var s15 = 2097151 & (load3(s.sublist(39, s.length)) >> 3);
var s16 = 2097151 & load3(s.sublist(42, s.length));
var s17 = 2097151 & (load4(s.sublist(44, s.length)) >> 5);
var s18 = 2097151 & (load3(s.sublist(47, s.length)) >> 2);
var s19 = 2097151 & (load4(s.sublist(49, s.length)) >> 7);
var s20 = 2097151 & (load4(s.sublist(52, s.length)) >> 4);
var s21 = 2097151 & (load3(s.sublist(55, s.length)) >> 1);
var s22 = 2097151 & (load4(s.sublist(57, s.length)) >> 6);
var s23 = (load4(s.sublist(60, s.length)) >> 3);
s11 += s23 * 666643;
s12 += s23 * 470296;
s13 += s23 * 654183;
s14 -= s23 * 997805;
s15 += s23 * 136657;
s16 -= s23 * 683901;
s23 = 0;
s10 += s22 * 666643;
s11 += s22 * 470296;
s12 += s22 * 654183;
s13 -= s22 * 997805;
s14 += s22 * 136657;
s15 -= s22 * 683901;
s22 = 0;
s9 += s21 * 666643;
s10 += s21 * 470296;
s11 += s21 * 654183;
s12 -= s21 * 997805;
s13 += s21 * 136657;
s14 -= s21 * 683901;
s21 = 0;
s8 += s20 * 666643;
s9 += s20 * 470296;
s10 += s20 * 654183;
s11 -= s20 * 997805;
s12 += s20 * 136657;
s13 -= s20 * 683901;
s20 = 0;
s7 += s19 * 666643;
s8 += s19 * 470296;
s9 += s19 * 654183;
s10 -= s19 * 997805;
s11 += s19 * 136657;
s12 -= s19 * 683901;
s19 = 0;
s6 += s18 * 666643;
s7 += s18 * 470296;
s8 += s18 * 654183;
s9 -= s18 * 997805;
s10 += s18 * 136657;
s11 -= s18 * 683901;
s18 = 0;
var carry = List<int>.filled(64, 0);
carry[6] = (s6 + (1 << 20)) >> 21;
s7 += carry[6];
s6 -= carry[6] << 21;
carry[8] = (s8 + (1 << 20)) >> 21;
s9 += carry[8];
s8 -= carry[8] << 21;
carry[10] = (s10 + (1 << 20)) >> 21;
s11 += carry[10];
s10 -= carry[10] << 21;
carry[12] = (s12 + (1 << 20)) >> 21;
s13 += carry[12];
s12 -= carry[12] << 21;
carry[14] = (s14 + (1 << 20)) >> 21;
s15 += carry[14];
s14 -= carry[14] << 21;
carry[16] = (s16 + (1 << 20)) >> 21;
s17 += carry[16];
s16 -= carry[16] << 21;
carry[7] = (s7 + (1 << 20)) >> 21;
s8 += carry[7];
s7 -= carry[7] << 21;
carry[9] = (s9 + (1 << 20)) >> 21;
s10 += carry[9];
s9 -= carry[9] << 21;
carry[11] = (s11 + (1 << 20)) >> 21;
s12 += carry[11];
s11 -= carry[11] << 21;
carry[13] = (s13 + (1 << 20)) >> 21;
s14 += carry[13];
s13 -= carry[13] << 21;
carry[15] = (s15 + (1 << 20)) >> 21;
s16 += carry[15];
s15 -= carry[15] << 21;
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
s8 -= s17 * 997805;
s9 += s17 * 136657;
s10 -= s17 * 683901;
s17 = 0;
s4 += s16 * 666643;
s5 += s16 * 470296;
s6 += s16 * 654183;
s7 -= s16 * 997805;
s8 += s16 * 136657;
s9 -= s16 * 683901;
s16 = 0;
s3 += s15 * 666643;
s4 += s15 * 470296;
s5 += s15 * 654183;
s6 -= s15 * 997805;
s7 += s15 * 136657;
s8 -= s15 * 683901;
s15 = 0;
s2 += s14 * 666643;
s3 += s14 * 470296;
s4 += s14 * 654183;
s5 -= s14 * 997805;
s6 += s14 * 136657;
s7 -= s14 * 683901;
s14 = 0;
s1 += s13 * 666643;
s2 += s13 * 470296;
s3 += s13 * 654183;
s4 -= s13 * 997805;
s5 += s13 * 136657;
s6 -= s13 * 683901;
s13 = 0;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry[0] = (s0 + (1 << 20)) >> 21;
s1 += carry[0];
s0 -= carry[0] << 21;
carry[2] = (s2 + (1 << 20)) >> 21;
s3 += carry[2];
s2 -= carry[2] << 21;
carry[4] = (s4 + (1 << 20)) >> 21;
s5 += carry[4];
s4 -= carry[4] << 21;
carry[6] = (s6 + (1 << 20)) >> 21;
s7 += carry[6];
s6 -= carry[6] << 21;
carry[8] = (s8 + (1 << 20)) >> 21;
s9 += carry[8];
s8 -= carry[8] << 21;
carry[10] = (s10 + (1 << 20)) >> 21;
s11 += carry[10];
s10 -= carry[10] << 21;
carry[1] = (s1 + (1 << 20)) >> 21;
s2 += carry[1];
s1 -= carry[1] << 21;
carry[3] = (s3 + (1 << 20)) >> 21;
s4 += carry[3];
s3 -= carry[3] << 21;
carry[5] = (s5 + (1 << 20)) >> 21;
s6 += carry[5];
s5 -= carry[5] << 21;
carry[7] = (s7 + (1 << 20)) >> 21;
s8 += carry[7];
s7 -= carry[7] << 21;
carry[9] = (s9 + (1 << 20)) >> 21;
s10 += carry[9];
s9 -= carry[9] << 21;
carry[11] = (s11 + (1 << 20)) >> 21;
s12 += carry[11];
s11 -= carry[11] << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry[0] = s0 >> 21;
s1 += carry[0];
s0 -= carry[0] << 21;
carry[1] = s1 >> 21;
s2 += carry[1];
s1 -= carry[1] << 21;
carry[2] = s2 >> 21;
s3 += carry[2];
s2 -= carry[2] << 21;
carry[3] = s3 >> 21;
s4 += carry[3];
s3 -= carry[3] << 21;
carry[4] = s4 >> 21;
s5 += carry[4];
s4 -= carry[4] << 21;
carry[5] = s5 >> 21;
s6 += carry[5];
s5 -= carry[5] << 21;
carry[6] = s6 >> 21;
s7 += carry[6];
s6 -= carry[6] << 21;
carry[7] = s7 >> 21;
s8 += carry[7];
s7 -= carry[7] << 21;
carry[8] = s8 >> 21;
s9 += carry[8];
s8 -= carry[8] << 21;
carry[9] = s9 >> 21;
s10 += carry[9];
s9 -= carry[9] << 21;
carry[10] = s10 >> 21;
s11 += carry[10];
s10 -= carry[10] << 21;
carry[11] = s11 >> 21;
s12 += carry[11];
s11 -= carry[11] << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry[0] = s0 >> 21;
s1 += carry[0];
s0 -= carry[0] << 21;
carry[1] = s1 >> 21;
s2 += carry[1];
s1 -= carry[1] << 21;
carry[2] = s2 >> 21;
s3 += carry[2];
s2 -= carry[2] << 21;
carry[3] = s3 >> 21;
s4 += carry[3];
s3 -= carry[3] << 21;
carry[4] = s4 >> 21;
s5 += carry[4];
s4 -= carry[4] << 21;
carry[5] = s5 >> 21;
s6 += carry[5];
s5 -= carry[5] << 21;
carry[6] = s6 >> 21;
s7 += carry[6];
s6 -= carry[6] << 21;
carry[7] = s7 >> 21;
s8 += carry[7];
s7 -= carry[7] << 21;
carry[8] = s8 >> 21;
s9 += carry[8];
s8 -= carry[8] << 21;
carry[9] = s9 >> 21;
s10 += carry[9];
s9 -= carry[9] << 21;
carry[10] = s10 >> 21;
s11 += carry[10];
s10 -= carry[10] << 21;
out[0] = s0 >> 0;
out[1] = s0 >> 8;
out[2] = (s0 >> 16) | (s1 << 5);
out[3] = s1 >> 3;
out[4] = s1 >> 11;
out[5] = (s1 >> 19) | (s2 << 2);
out[6] = s2 >> 6;
out[7] = (s2 >> 14) | (s3 << 7);
out[8] = s3 >> 1;
out[9] = s3 >> 9;
out[10] = (s3 >> 17) | (s4 << 4);
out[11] = s4 >> 4;
out[12] = s4 >> 12;
out[13] = (s4 >> 20) | (s5 << 1);
out[14] = s5 >> 7;
out[15] = (s5 >> 15) | (s6 << 6);
out[16] = s6 >> 2;
out[17] = s6 >> 10;
out[18] = (s6 >> 18) | (s7 << 3);
out[19] = s7 >> 5;
out[20] = s7 >> 13;
out[21] = s8 >> 0;
out[22] = s8 >> 8;
out[23] = (s8 >> 16) | (s9 << 5);
out[24] = s9 >> 3;
out[25] = s9 >> 11;
out[26] = (s9 >> 19) | (s10 << 2);
out[27] = s10 >> 6;
out[28] = (s10 >> 14) | (s11 << 7);
out[29] = s11 >> 1;
out[30] = s11 >> 9;
out[31] = s11 >> 17;
}