xref: /aosp_15_r20/external/libwebsockets/plugins/ssh-base/crypto/sc25519.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /* $OpenBSD: sc25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
2*1c60b9acSAndroid Build Coastguard Worker 
3*1c60b9acSAndroid Build Coastguard Worker /*
4*1c60b9acSAndroid Build Coastguard Worker  * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
5*1c60b9acSAndroid Build Coastguard Worker  * Peter Schwabe, Bo-Yin Yang.
6*1c60b9acSAndroid Build Coastguard Worker  * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c
7*1c60b9acSAndroid Build Coastguard Worker  */
8*1c60b9acSAndroid Build Coastguard Worker 
9*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
10*1c60b9acSAndroid Build Coastguard Worker 
11*1c60b9acSAndroid Build Coastguard Worker #include "sc25519.h"
12*1c60b9acSAndroid Build Coastguard Worker 
13*1c60b9acSAndroid Build Coastguard Worker /*Arithmetic modulo the group order m = 2^252 +  27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
14*1c60b9acSAndroid Build Coastguard Worker 
15*1c60b9acSAndroid Build Coastguard Worker static const uint32_t m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
16*1c60b9acSAndroid Build Coastguard Worker                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
17*1c60b9acSAndroid Build Coastguard Worker 
18*1c60b9acSAndroid Build Coastguard Worker static const uint32_t mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
19*1c60b9acSAndroid Build Coastguard Worker                                      0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
20*1c60b9acSAndroid Build Coastguard Worker 
lt(uint32_t a,uint32_t b)21*1c60b9acSAndroid Build Coastguard Worker static uint32_t lt(uint32_t a,uint32_t b) /* 16-bit inputs */
22*1c60b9acSAndroid Build Coastguard Worker {
23*1c60b9acSAndroid Build Coastguard Worker   unsigned int x = a;
24*1c60b9acSAndroid Build Coastguard Worker   x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
25*1c60b9acSAndroid Build Coastguard Worker   x >>= 31; /* 0: no; 1: yes */
26*1c60b9acSAndroid Build Coastguard Worker   return x;
27*1c60b9acSAndroid Build Coastguard Worker }
28*1c60b9acSAndroid Build Coastguard Worker 
29*1c60b9acSAndroid Build Coastguard Worker /* Reduce coefficients of r before calling sc_reduce_add_sub */
sc_reduce_add_sub(sc25519 * r)30*1c60b9acSAndroid Build Coastguard Worker static void sc_reduce_add_sub(sc25519 *r)
31*1c60b9acSAndroid Build Coastguard Worker {
32*1c60b9acSAndroid Build Coastguard Worker   uint32_t pb = 0;
33*1c60b9acSAndroid Build Coastguard Worker   uint32_t b;
34*1c60b9acSAndroid Build Coastguard Worker   uint32_t mask;
35*1c60b9acSAndroid Build Coastguard Worker   int i;
36*1c60b9acSAndroid Build Coastguard Worker   unsigned char t[32];
37*1c60b9acSAndroid Build Coastguard Worker 
38*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
39*1c60b9acSAndroid Build Coastguard Worker   {
40*1c60b9acSAndroid Build Coastguard Worker     pb += m[i];
41*1c60b9acSAndroid Build Coastguard Worker     b = lt(r->v[i],pb);
42*1c60b9acSAndroid Build Coastguard Worker     t[i] = (unsigned char)(r->v[i]-pb+(b<<8));
43*1c60b9acSAndroid Build Coastguard Worker     pb = b;
44*1c60b9acSAndroid Build Coastguard Worker   }
45*1c60b9acSAndroid Build Coastguard Worker   mask = b - 1;
46*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
47*1c60b9acSAndroid Build Coastguard Worker     r->v[i] ^= mask & (r->v[i] ^ t[i]);
48*1c60b9acSAndroid Build Coastguard Worker }
49*1c60b9acSAndroid Build Coastguard Worker 
50*1c60b9acSAndroid Build Coastguard Worker /* Reduce coefficients of x before calling barrett_reduce */
barrett_reduce(sc25519 * r,const uint32_t x[64])51*1c60b9acSAndroid Build Coastguard Worker static void barrett_reduce(sc25519 *r, const uint32_t x[64])
52*1c60b9acSAndroid Build Coastguard Worker {
53*1c60b9acSAndroid Build Coastguard Worker   /* See HAC, Alg. 14.42 */
54*1c60b9acSAndroid Build Coastguard Worker   int i,j;
55*1c60b9acSAndroid Build Coastguard Worker   uint32_t q2[66];
56*1c60b9acSAndroid Build Coastguard Worker   uint32_t *q3 = q2 + 33;
57*1c60b9acSAndroid Build Coastguard Worker   uint32_t r1[33];
58*1c60b9acSAndroid Build Coastguard Worker   uint32_t r2[33];
59*1c60b9acSAndroid Build Coastguard Worker   uint32_t carry;
60*1c60b9acSAndroid Build Coastguard Worker   uint32_t pb = 0;
61*1c60b9acSAndroid Build Coastguard Worker   uint32_t b;
62*1c60b9acSAndroid Build Coastguard Worker 
63*1c60b9acSAndroid Build Coastguard Worker   for (i = 0;i < 66;++i) q2[i] = 0;
64*1c60b9acSAndroid Build Coastguard Worker   for (i = 0;i < 33;++i) r2[i] = 0;
65*1c60b9acSAndroid Build Coastguard Worker 
66*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<33;i++)
67*1c60b9acSAndroid Build Coastguard Worker     for(j=0;j<33;j++)
68*1c60b9acSAndroid Build Coastguard Worker       if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
69*1c60b9acSAndroid Build Coastguard Worker   carry = q2[31] >> 8;
70*1c60b9acSAndroid Build Coastguard Worker   q2[32] += carry;
71*1c60b9acSAndroid Build Coastguard Worker   carry = q2[32] >> 8;
72*1c60b9acSAndroid Build Coastguard Worker   q2[33] += carry;
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<33;i++)r1[i] = x[i];
75*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
76*1c60b9acSAndroid Build Coastguard Worker     for(j=0;j<33;j++)
77*1c60b9acSAndroid Build Coastguard Worker       if(i+j < 33) r2[i+j] += m[i]*q3[j];
78*1c60b9acSAndroid Build Coastguard Worker 
79*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
80*1c60b9acSAndroid Build Coastguard Worker   {
81*1c60b9acSAndroid Build Coastguard Worker     carry = r2[i] >> 8;
82*1c60b9acSAndroid Build Coastguard Worker     r2[i+1] += carry;
83*1c60b9acSAndroid Build Coastguard Worker     r2[i] &= 0xff;
84*1c60b9acSAndroid Build Coastguard Worker   }
85*1c60b9acSAndroid Build Coastguard Worker 
86*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
87*1c60b9acSAndroid Build Coastguard Worker   {
88*1c60b9acSAndroid Build Coastguard Worker     pb += r2[i];
89*1c60b9acSAndroid Build Coastguard Worker     b = lt(r1[i],pb);
90*1c60b9acSAndroid Build Coastguard Worker     r->v[i] = r1[i]-pb+(b<<8);
91*1c60b9acSAndroid Build Coastguard Worker     pb = b;
92*1c60b9acSAndroid Build Coastguard Worker   }
93*1c60b9acSAndroid Build Coastguard Worker 
94*1c60b9acSAndroid Build Coastguard Worker   /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
95*1c60b9acSAndroid Build Coastguard Worker    * If so: Handle  it here!
96*1c60b9acSAndroid Build Coastguard Worker    */
97*1c60b9acSAndroid Build Coastguard Worker 
98*1c60b9acSAndroid Build Coastguard Worker   sc_reduce_add_sub(r);
99*1c60b9acSAndroid Build Coastguard Worker   sc_reduce_add_sub(r);
100*1c60b9acSAndroid Build Coastguard Worker }
101*1c60b9acSAndroid Build Coastguard Worker 
sc25519_from32bytes(sc25519 * r,const unsigned char x[32])102*1c60b9acSAndroid Build Coastguard Worker void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
103*1c60b9acSAndroid Build Coastguard Worker {
104*1c60b9acSAndroid Build Coastguard Worker   int i;
105*1c60b9acSAndroid Build Coastguard Worker   uint32_t t[64];
106*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++) t[i] = x[i];
107*1c60b9acSAndroid Build Coastguard Worker   for(i=32;i<64;++i) t[i] = 0;
108*1c60b9acSAndroid Build Coastguard Worker   barrett_reduce(r, t);
109*1c60b9acSAndroid Build Coastguard Worker }
110*1c60b9acSAndroid Build Coastguard Worker 
shortsc25519_from16bytes(shortsc25519 * r,const unsigned char x[16])111*1c60b9acSAndroid Build Coastguard Worker void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16])
112*1c60b9acSAndroid Build Coastguard Worker {
113*1c60b9acSAndroid Build Coastguard Worker   int i;
114*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<16;i++) r->v[i] = x[i];
115*1c60b9acSAndroid Build Coastguard Worker }
116*1c60b9acSAndroid Build Coastguard Worker 
sc25519_from64bytes(sc25519 * r,const unsigned char x[64])117*1c60b9acSAndroid Build Coastguard Worker void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
118*1c60b9acSAndroid Build Coastguard Worker {
119*1c60b9acSAndroid Build Coastguard Worker   int i;
120*1c60b9acSAndroid Build Coastguard Worker   uint32_t t[64];
121*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<64;i++) t[i] = x[i];
122*1c60b9acSAndroid Build Coastguard Worker   barrett_reduce(r, t);
123*1c60b9acSAndroid Build Coastguard Worker }
124*1c60b9acSAndroid Build Coastguard Worker 
sc25519_from_shortsc(sc25519 * r,const shortsc25519 * x)125*1c60b9acSAndroid Build Coastguard Worker void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x)
126*1c60b9acSAndroid Build Coastguard Worker {
127*1c60b9acSAndroid Build Coastguard Worker   int i;
128*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<16;i++)
129*1c60b9acSAndroid Build Coastguard Worker     r->v[i] = x->v[i];
130*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<16;i++)
131*1c60b9acSAndroid Build Coastguard Worker     r->v[16+i] = 0;
132*1c60b9acSAndroid Build Coastguard Worker }
133*1c60b9acSAndroid Build Coastguard Worker 
sc25519_to32bytes(unsigned char r[32],const sc25519 * x)134*1c60b9acSAndroid Build Coastguard Worker void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
135*1c60b9acSAndroid Build Coastguard Worker {
136*1c60b9acSAndroid Build Coastguard Worker   int i;
137*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++) r[i] = (unsigned char)x->v[i];
138*1c60b9acSAndroid Build Coastguard Worker }
139*1c60b9acSAndroid Build Coastguard Worker 
sc25519_iszero_vartime(const sc25519 * x)140*1c60b9acSAndroid Build Coastguard Worker int sc25519_iszero_vartime(const sc25519 *x)
141*1c60b9acSAndroid Build Coastguard Worker {
142*1c60b9acSAndroid Build Coastguard Worker   int i;
143*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
144*1c60b9acSAndroid Build Coastguard Worker     if(x->v[i] != 0) return 0;
145*1c60b9acSAndroid Build Coastguard Worker   return 1;
146*1c60b9acSAndroid Build Coastguard Worker }
147*1c60b9acSAndroid Build Coastguard Worker 
sc25519_isshort_vartime(const sc25519 * x)148*1c60b9acSAndroid Build Coastguard Worker int sc25519_isshort_vartime(const sc25519 *x)
149*1c60b9acSAndroid Build Coastguard Worker {
150*1c60b9acSAndroid Build Coastguard Worker   int i;
151*1c60b9acSAndroid Build Coastguard Worker   for(i=31;i>15;i--)
152*1c60b9acSAndroid Build Coastguard Worker     if(x->v[i] != 0) return 0;
153*1c60b9acSAndroid Build Coastguard Worker   return 1;
154*1c60b9acSAndroid Build Coastguard Worker }
155*1c60b9acSAndroid Build Coastguard Worker 
sc25519_lt_vartime(const sc25519 * x,const sc25519 * y)156*1c60b9acSAndroid Build Coastguard Worker int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)
157*1c60b9acSAndroid Build Coastguard Worker {
158*1c60b9acSAndroid Build Coastguard Worker   int i;
159*1c60b9acSAndroid Build Coastguard Worker   for(i=31;i>=0;i--)
160*1c60b9acSAndroid Build Coastguard Worker   {
161*1c60b9acSAndroid Build Coastguard Worker     if(x->v[i] < y->v[i]) return 1;
162*1c60b9acSAndroid Build Coastguard Worker     if(x->v[i] > y->v[i]) return 0;
163*1c60b9acSAndroid Build Coastguard Worker   }
164*1c60b9acSAndroid Build Coastguard Worker   return 0;
165*1c60b9acSAndroid Build Coastguard Worker }
166*1c60b9acSAndroid Build Coastguard Worker 
sc25519_add(sc25519 * r,const sc25519 * x,const sc25519 * y)167*1c60b9acSAndroid Build Coastguard Worker void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
168*1c60b9acSAndroid Build Coastguard Worker {
169*1c60b9acSAndroid Build Coastguard Worker   int i, carry;
170*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
171*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<31;i++)
172*1c60b9acSAndroid Build Coastguard Worker   {
173*1c60b9acSAndroid Build Coastguard Worker     carry = (int)r->v[i] >> 8;
174*1c60b9acSAndroid Build Coastguard Worker     r->v[i+1] += (uint32_t)carry;
175*1c60b9acSAndroid Build Coastguard Worker     r->v[i] &= 0xff;
176*1c60b9acSAndroid Build Coastguard Worker   }
177*1c60b9acSAndroid Build Coastguard Worker   sc_reduce_add_sub(r);
178*1c60b9acSAndroid Build Coastguard Worker }
179*1c60b9acSAndroid Build Coastguard Worker 
sc25519_sub_nored(sc25519 * r,const sc25519 * x,const sc25519 * y)180*1c60b9acSAndroid Build Coastguard Worker void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)
181*1c60b9acSAndroid Build Coastguard Worker {
182*1c60b9acSAndroid Build Coastguard Worker   uint32_t b = 0;
183*1c60b9acSAndroid Build Coastguard Worker   int i;
184*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
185*1c60b9acSAndroid Build Coastguard Worker   {
186*1c60b9acSAndroid Build Coastguard Worker     uint32_t t = x->v[i] - y->v[i] - b;
187*1c60b9acSAndroid Build Coastguard Worker     r->v[i] = t & 255;
188*1c60b9acSAndroid Build Coastguard Worker     b = (t >> 8) & 1;
189*1c60b9acSAndroid Build Coastguard Worker   }
190*1c60b9acSAndroid Build Coastguard Worker }
191*1c60b9acSAndroid Build Coastguard Worker 
sc25519_mul(sc25519 * r,const sc25519 * x,const sc25519 * y)192*1c60b9acSAndroid Build Coastguard Worker void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
193*1c60b9acSAndroid Build Coastguard Worker {
194*1c60b9acSAndroid Build Coastguard Worker   int i,j,carry;
195*1c60b9acSAndroid Build Coastguard Worker   uint32_t t[64];
196*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<64;i++)t[i] = 0;
197*1c60b9acSAndroid Build Coastguard Worker 
198*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
199*1c60b9acSAndroid Build Coastguard Worker     for(j=0;j<32;j++)
200*1c60b9acSAndroid Build Coastguard Worker       t[i+j] += x->v[i] * y->v[j];
201*1c60b9acSAndroid Build Coastguard Worker 
202*1c60b9acSAndroid Build Coastguard Worker   /* Reduce coefficients */
203*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<63;i++)
204*1c60b9acSAndroid Build Coastguard Worker   {
205*1c60b9acSAndroid Build Coastguard Worker     carry = (int)t[i] >> 8;
206*1c60b9acSAndroid Build Coastguard Worker     t[i+1] += (uint32_t)carry;
207*1c60b9acSAndroid Build Coastguard Worker     t[i] &= 0xff;
208*1c60b9acSAndroid Build Coastguard Worker   }
209*1c60b9acSAndroid Build Coastguard Worker 
210*1c60b9acSAndroid Build Coastguard Worker   barrett_reduce(r, t);
211*1c60b9acSAndroid Build Coastguard Worker }
212*1c60b9acSAndroid Build Coastguard Worker 
sc25519_mul_shortsc(sc25519 * r,const sc25519 * x,const shortsc25519 * y)213*1c60b9acSAndroid Build Coastguard Worker void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y)
214*1c60b9acSAndroid Build Coastguard Worker {
215*1c60b9acSAndroid Build Coastguard Worker   sc25519 t;
216*1c60b9acSAndroid Build Coastguard Worker   sc25519_from_shortsc(&t, y);
217*1c60b9acSAndroid Build Coastguard Worker   sc25519_mul(r, x, &t);
218*1c60b9acSAndroid Build Coastguard Worker }
219*1c60b9acSAndroid Build Coastguard Worker 
sc25519_window3(signed char r[85],const sc25519 * s)220*1c60b9acSAndroid Build Coastguard Worker void sc25519_window3(signed char r[85], const sc25519 *s)
221*1c60b9acSAndroid Build Coastguard Worker {
222*1c60b9acSAndroid Build Coastguard Worker   char carry;
223*1c60b9acSAndroid Build Coastguard Worker   int i;
224*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<10;i++)
225*1c60b9acSAndroid Build Coastguard Worker   {
226*1c60b9acSAndroid Build Coastguard Worker     r[8*i+0]  =  s->v[3*i+0]       & 7;
227*1c60b9acSAndroid Build Coastguard Worker     r[8*i+1]  = (s->v[3*i+0] >> 3) & 7;
228*1c60b9acSAndroid Build Coastguard Worker     r[8*i+2]  = (s->v[3*i+0] >> 6) & 7;
229*1c60b9acSAndroid Build Coastguard Worker     r[8*i+2] =  (signed char)(r[8*i+2] ^ (int)((s->v[3*i+1] << 2) & 7));
230*1c60b9acSAndroid Build Coastguard Worker     r[8*i+3]  = (s->v[3*i+1] >> 1) & 7;
231*1c60b9acSAndroid Build Coastguard Worker     r[8*i+4]  = (s->v[3*i+1] >> 4) & 7;
232*1c60b9acSAndroid Build Coastguard Worker     r[8*i+5]  = (s->v[3*i+1] >> 7) & 7;
233*1c60b9acSAndroid Build Coastguard Worker     r[8*i+5] =  (signed char)(r[8*i+5] ^ (int)((s->v[3*i+2] << 1) & 7));
234*1c60b9acSAndroid Build Coastguard Worker     r[8*i+6]  = (s->v[3*i+2] >> 2) & 7;
235*1c60b9acSAndroid Build Coastguard Worker     r[8*i+7]  = (s->v[3*i+2] >> 5) & 7;
236*1c60b9acSAndroid Build Coastguard Worker   }
237*1c60b9acSAndroid Build Coastguard Worker   r[8*i+0]  =  s->v[3*i+0]       & 7;
238*1c60b9acSAndroid Build Coastguard Worker   r[8*i+1]  = (s->v[3*i+0] >> 3) & 7;
239*1c60b9acSAndroid Build Coastguard Worker   r[8*i+2]  = (s->v[3*i+0] >> 6) & 7;
240*1c60b9acSAndroid Build Coastguard Worker   r[8*i+2]  = (signed char)(r[8*i+2] ^ (int)((s->v[3*i+1] << 2) & 7));
241*1c60b9acSAndroid Build Coastguard Worker   r[8*i+3]  = (s->v[3*i+1] >> 1) & 7;
242*1c60b9acSAndroid Build Coastguard Worker   r[8*i+4]  = (s->v[3*i+1] >> 4) & 7;
243*1c60b9acSAndroid Build Coastguard Worker 
244*1c60b9acSAndroid Build Coastguard Worker   /* Making it signed */
245*1c60b9acSAndroid Build Coastguard Worker   carry = 0;
246*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<84;i++)
247*1c60b9acSAndroid Build Coastguard Worker   {
248*1c60b9acSAndroid Build Coastguard Worker     r[i] = (signed char)(r[i] + carry);
249*1c60b9acSAndroid Build Coastguard Worker     r[i+1] = (signed char)(r[i + 1] + (r[i] >> 3));
250*1c60b9acSAndroid Build Coastguard Worker     r[i] &= 7;
251*1c60b9acSAndroid Build Coastguard Worker     carry = (char)(r[i] >> 2);
252*1c60b9acSAndroid Build Coastguard Worker     r[i] = (signed char)(r[i] - (carry<<3));
253*1c60b9acSAndroid Build Coastguard Worker   }
254*1c60b9acSAndroid Build Coastguard Worker   r[84] = (signed char)(r[84] + (signed char)carry);
255*1c60b9acSAndroid Build Coastguard Worker }
256*1c60b9acSAndroid Build Coastguard Worker 
sc25519_window5(signed char r[51],const sc25519 * s)257*1c60b9acSAndroid Build Coastguard Worker void sc25519_window5(signed char r[51], const sc25519 *s)
258*1c60b9acSAndroid Build Coastguard Worker {
259*1c60b9acSAndroid Build Coastguard Worker   char carry;
260*1c60b9acSAndroid Build Coastguard Worker   int i;
261*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<6;i++)
262*1c60b9acSAndroid Build Coastguard Worker   {
263*1c60b9acSAndroid Build Coastguard Worker     r[8*i+0]  =  s->v[5*i+0]       & 31;
264*1c60b9acSAndroid Build Coastguard Worker     r[8*i+1]  = (s->v[5*i+0] >> 5) & 31;
265*1c60b9acSAndroid Build Coastguard Worker     r[8*i+1] = (signed char)(r[8*i+1] ^ (int)((s->v[5*i+1] << 3) & 31));
266*1c60b9acSAndroid Build Coastguard Worker     r[8*i+2]  = (s->v[5*i+1] >> 2) & 31;
267*1c60b9acSAndroid Build Coastguard Worker     r[8*i+3]  = (s->v[5*i+1] >> 7) & 31;
268*1c60b9acSAndroid Build Coastguard Worker     r[8*i+3] = (signed char)(r[8*i+3] ^ (int)((s->v[5*i+2] << 1) & 31));
269*1c60b9acSAndroid Build Coastguard Worker     r[8*i+4]  = (s->v[5*i+2] >> 4) & 31;
270*1c60b9acSAndroid Build Coastguard Worker     r[8*i+4] = (signed char)(r[8*i+4] ^ (int)((s->v[5*i+3] << 4) & 31));
271*1c60b9acSAndroid Build Coastguard Worker     r[8*i+5]  = (s->v[5*i+3] >> 1) & 31;
272*1c60b9acSAndroid Build Coastguard Worker     r[8*i+6]  = (s->v[5*i+3] >> 6) & 31;
273*1c60b9acSAndroid Build Coastguard Worker     r[8*i+6] = (signed char)(r[8*i+6] ^ (int)((s->v[5*i+4] << 2) & 31));
274*1c60b9acSAndroid Build Coastguard Worker     r[8*i+7]  = (s->v[5*i+4] >> 3) & 31;
275*1c60b9acSAndroid Build Coastguard Worker   }
276*1c60b9acSAndroid Build Coastguard Worker   r[8*i+0]  =  s->v[5*i+0]       & 31;
277*1c60b9acSAndroid Build Coastguard Worker   r[8*i+1]  = (s->v[5*i+0] >> 5) & 31;
278*1c60b9acSAndroid Build Coastguard Worker   r[8*i+1] = (signed char)(r[8*i+1] ^ (int)((s->v[5*i+1] << 3) & 31));
279*1c60b9acSAndroid Build Coastguard Worker   r[8*i+2]  = (s->v[5*i+1] >> 2) & 31;
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker   /* Making it signed */
282*1c60b9acSAndroid Build Coastguard Worker   carry = 0;
283*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<50;i++)
284*1c60b9acSAndroid Build Coastguard Worker   {
285*1c60b9acSAndroid Build Coastguard Worker     r[i] = (signed char)(r[i] + (signed char)carry);
286*1c60b9acSAndroid Build Coastguard Worker     r[i+1] = (signed char)(r[i + 1] + (r[i] >> 5));
287*1c60b9acSAndroid Build Coastguard Worker     r[i] &= 31;
288*1c60b9acSAndroid Build Coastguard Worker     carry = (char)(r[i] >> 4);
289*1c60b9acSAndroid Build Coastguard Worker     r[i] = (signed char)(r[i] - (carry<<5));
290*1c60b9acSAndroid Build Coastguard Worker   }
291*1c60b9acSAndroid Build Coastguard Worker   r[50] = (signed char)(r[50] + carry);
292*1c60b9acSAndroid Build Coastguard Worker }
293*1c60b9acSAndroid Build Coastguard Worker 
sc25519_2interleave2(unsigned char r[127],const sc25519 * s1,const sc25519 * s2)294*1c60b9acSAndroid Build Coastguard Worker void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
295*1c60b9acSAndroid Build Coastguard Worker {
296*1c60b9acSAndroid Build Coastguard Worker   int i;
297*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<31;i++)
298*1c60b9acSAndroid Build Coastguard Worker   {
299*1c60b9acSAndroid Build Coastguard Worker     r[4*i]   = (unsigned char)(( s1->v[i]       & 3) ^ (( s2->v[i]       & 3) << 2));
300*1c60b9acSAndroid Build Coastguard Worker     r[4*i+1] = (unsigned char)(((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2));
301*1c60b9acSAndroid Build Coastguard Worker     r[4*i+2] = (unsigned char)(((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2));
302*1c60b9acSAndroid Build Coastguard Worker     r[4*i+3] = (unsigned char)(((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2));
303*1c60b9acSAndroid Build Coastguard Worker   }
304*1c60b9acSAndroid Build Coastguard Worker   r[124] = (unsigned char)(( s1->v[31]       & 3) ^ (( s2->v[31]       & 3) << 2));
305*1c60b9acSAndroid Build Coastguard Worker   r[125] = (unsigned char)(((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2));
306*1c60b9acSAndroid Build Coastguard Worker   r[126] = (unsigned char)(((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2));
307*1c60b9acSAndroid Build Coastguard Worker }
308