5 |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
7 Write p=2^255-19; q=floor(h/p).
8 Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
11 Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
12 Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
14 Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
18 Have 0<=r<=p-1=2^255-20.
19 Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
21 Write x=r+19(2^-255)r+y.
22 Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
24 Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
25 so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
28 void fe_tobytes(unsigned char *s, int32_t h[10]) {
51 q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
63 /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
65 /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
67 carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
68 carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
69 carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
70 carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
71 carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
72 carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
73 carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
74 carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
75 carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
76 carry9 = h9 >> 25; h9 -= carry9 << 25;
80 Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
81 Have h0+...+2^230 h9 between 0 and 2^255-1;
82 evidently 2^255 h10-2^255 q = 0.
83 Goal: Output h0+...+2^230 h9.
89 s[3] = (h0 >> 24) | (h1 << 2);
92 s[6] = (h1 >> 22) | (h2 << 3);
95 s[9] = (h2 >> 21) | (h3 << 5);
98 s[12] = (h3 >> 19) | (h4 << 6);
105 s[19] = (h5 >> 24) | (h6 << 1);
108 s[22] = (h6 >> 23) | (h7 << 3);
111 s[25] = (h7 >> 21) | (h8 << 4);
114 s[28] = (h8 >> 20) | (h9 << 6);