ScReduce function

void ScReduce(
  1. Uint8List out,
  2. Uint8List s
)

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