1 /* Since TweetNacl doesn't come with a `randombytes` implementation,
2 we're using the one from PHP.*/
3 #include "php_snuffleupagus.h"
4 #include "ext/standard/php_random.h"
5 
randombytes(unsigned char * x,unsigned long long xlen)6 void randombytes(unsigned char *x, unsigned long long xlen) {
7   assert(SIZE_MAX >= ULLONG_MAX);  // max(size_t) > max(ull) ?
8   php_random_bytes(x, xlen, 1);
9 }
10 
11 // And now, the original code of tweetnacl - https://tweetnacl.cr.yp.to/
12 
13 #include "tweetnacl.h"
14 #define FOR(i,n) for (i = 0;i < n;++i)
15 #define sv static void
16 
17 typedef unsigned char u8;
18 typedef unsigned long u32;
19 typedef unsigned long long u64;
20 typedef long long i64;
21 typedef i64 gf[16];
22 
23 static const u8
24   _0[16],
25   _9[32] = {9};
26 static const gf
27   gf0,
28   gf1 = {1},
29   _121665 = {0xDB41,1},
30   D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
31   D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
32   X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
33   Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
34   I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
35 
L32(u32 x,int c)36 static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
37 
ld32(const u8 * x)38 static u32 ld32(const u8 *x)
39 {
40   u32 u = x[3];
41   u = (u<<8)|x[2];
42   u = (u<<8)|x[1];
43   return (u<<8)|x[0];
44 }
45 
dl64(const u8 * x)46 static u64 dl64(const u8 *x)
47 {
48   u64 i,u=0;
49   FOR(i,8) u=(u<<8)|x[i];
50   return u;
51 }
52 
st32(u8 * x,u32 u)53 sv st32(u8 *x,u32 u)
54 {
55   int i;
56   FOR(i,4) { x[i] = u; u >>= 8; }
57 }
58 
ts64(u8 * x,u64 u)59 sv ts64(u8 *x,u64 u)
60 {
61   int i;
62   for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
63 }
64 
vn(const u8 * x,const u8 * y,int n)65 static int vn(const u8 *x,const u8 *y,int n)
66 {
67   int i = 0;
68   u32 d = 0;
69   FOR(i,n) d |= x[i]^y[i];
70   return (1 & ((d - 1) >> 8)) - 1;
71 }
72 
crypto_verify_16(const u8 * x,const u8 * y)73 int crypto_verify_16(const u8 *x,const u8 *y)
74 {
75   return vn(x,y,16);
76 }
77 
crypto_verify_32(const u8 * x,const u8 * y)78 int crypto_verify_32(const u8 *x,const u8 *y)
79 {
80   return vn(x,y,32);
81 }
82 
core(u8 * out,const u8 * in,const u8 * k,const u8 * c,int h)83 sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
84 {
85   u32 w[16],x[16],y[16],t[4];
86   int i,j,m;
87 
88   FOR(i,4) {
89     x[5*i] = ld32(c+4*i);
90     x[1+i] = ld32(k+4*i);
91     x[6+i] = ld32(in+4*i);
92     x[11+i] = ld32(k+16+4*i);
93   }
94 
95   FOR(i,16) y[i] = x[i];
96 
97   FOR(i,20) {
98     FOR(j,4) {
99       FOR(m,4) t[m] = x[(5*j+4*m)%16];
100       t[1] ^= L32(t[0]+t[3], 7);
101       t[2] ^= L32(t[1]+t[0], 9);
102       t[3] ^= L32(t[2]+t[1],13);
103       t[0] ^= L32(t[3]+t[2],18);
104       FOR(m,4) w[4*j+(j+m)%4] = t[m];
105     }
106     FOR(m,16) x[m] = w[m];
107   }
108 
109   if (h) {
110     FOR(i,16) x[i] += y[i];
111     FOR(i,4) {
112       x[5*i] -= ld32(c+4*i);
113       x[6+i] -= ld32(in+4*i);
114     }
115     FOR(i,4) {
116       st32(out+4*i,x[5*i]);
117       st32(out+16+4*i,x[6+i]);
118     }
119   } else
120     FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
121 }
122 
crypto_core_salsa20(u8 * out,const u8 * in,const u8 * k,const u8 * c)123 int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
124 {
125   core(out,in,k,c,0);
126   return 0;
127 }
128 
crypto_core_hsalsa20(u8 * out,const u8 * in,const u8 * k,const u8 * c)129 int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
130 {
131   core(out,in,k,c,1);
132   return 0;
133 }
134 
135 static const u8 sigma[16] = "expand 32-byte k";
136 
crypto_stream_salsa20_xor(u8 * c,const u8 * m,u64 b,const u8 * n,const u8 * k)137 int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
138 {
139   u8 z[16],x[64];
140   u32 u,i;
141   if (!b) return 0;
142   FOR(i,16) z[i] = 0;
143   FOR(i,8) z[i] = n[i];
144   while (b >= 64) {
145     crypto_core_salsa20(x,z,k,sigma);
146     FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
147     u = 1;
148     for (i = 8;i < 16;++i) {
149       u += (u32) z[i];
150       z[i] = u;
151       u >>= 8;
152     }
153     b -= 64;
154     c += 64;
155     if (m) m += 64;
156   }
157   if (b) {
158     crypto_core_salsa20(x,z,k,sigma);
159     FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
160   }
161   return 0;
162 }
163 
crypto_stream_salsa20(u8 * c,u64 d,const u8 * n,const u8 * k)164 int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
165 {
166   return crypto_stream_salsa20_xor(c,0,d,n,k);
167 }
168 
crypto_stream(u8 * c,u64 d,const u8 * n,const u8 * k)169 int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
170 {
171   u8 s[32];
172   crypto_core_hsalsa20(s,n,k,sigma);
173   return crypto_stream_salsa20(c,d,n+16,s);
174 }
175 
crypto_stream_xor(u8 * c,const u8 * m,u64 d,const u8 * n,const u8 * k)176 int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
177 {
178   u8 s[32];
179   crypto_core_hsalsa20(s,n,k,sigma);
180   return crypto_stream_salsa20_xor(c,m,d,n+16,s);
181 }
182 
add1305(u32 * h,const u32 * c)183 sv add1305(u32 *h,const u32 *c)
184 {
185   u32 j,u = 0;
186   FOR(j,17) {
187     u += h[j] + c[j];
188     h[j] = u & 255;
189     u >>= 8;
190   }
191 }
192 
193 static const u32 minusp[17] = {
194   5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
195 } ;
196 
crypto_onetimeauth(u8 * out,const u8 * m,u64 n,const u8 * k)197 int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k)
198 {
199   u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
200 
201   FOR(j,17) r[j]=h[j]=0;
202   FOR(j,16) r[j]=k[j];
203   r[3]&=15;
204   r[4]&=252;
205   r[7]&=15;
206   r[8]&=252;
207   r[11]&=15;
208   r[12]&=252;
209   r[15]&=15;
210 
211   while (n > 0) {
212     FOR(j,17) c[j] = 0;
213     for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
214     c[j] = 1;
215     m += j; n -= j;
216     add1305(h,c);
217     FOR(i,17) {
218       x[i] = 0;
219       FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
220     }
221     FOR(i,17) h[i] = x[i];
222     u = 0;
223     FOR(j,16) {
224       u += h[j];
225       h[j] = u & 255;
226       u >>= 8;
227     }
228     u += h[16]; h[16] = u & 3;
229     u = 5 * (u >> 2);
230     FOR(j,16) {
231       u += h[j];
232       h[j] = u & 255;
233       u >>= 8;
234     }
235     u += h[16]; h[16] = u;
236   }
237 
238   FOR(j,17) g[j] = h[j];
239   add1305(h,minusp);
240   s = -(h[16] >> 7);
241   FOR(j,17) h[j] ^= s & (g[j] ^ h[j]);
242 
243   FOR(j,16) c[j] = k[j + 16];
244   c[16] = 0;
245   add1305(h,c);
246   FOR(j,16) out[j] = h[j];
247   return 0;
248 }
249 
crypto_onetimeauth_verify(const u8 * h,const u8 * m,u64 n,const u8 * k)250 int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k)
251 {
252   u8 x[16];
253   crypto_onetimeauth(x,m,n,k);
254   return crypto_verify_16(h,x);
255 }
256 
crypto_secretbox(u8 * c,const u8 * m,u64 d,const u8 * n,const u8 * k)257 int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
258 {
259   int i;
260   if (d < 32) return -1;
261   crypto_stream_xor(c,m,d,n,k);
262   crypto_onetimeauth(c + 16,c + 32,d - 32,c);
263   FOR(i,16) c[i] = 0;
264   return 0;
265 }
266 
crypto_secretbox_open(u8 * m,const u8 * c,u64 d,const u8 * n,const u8 * k)267 int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
268 {
269   int i;
270   u8 x[32];
271   if (d < 32) return -1;
272   crypto_stream(x,32,n,k);
273   if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
274   crypto_stream_xor(m,c,d,n,k);
275   FOR(i,32) m[i] = 0;
276   return 0;
277 }
278 
set25519(gf r,const gf a)279 sv set25519(gf r, const gf a)
280 {
281   int i;
282   FOR(i,16) r[i]=a[i];
283 }
284 
car25519(gf o)285 sv car25519(gf o)
286 {
287   int i;
288   i64 c;
289   FOR(i,16) {
290     o[i]+=(1LL<<16);
291     c=o[i]>>16;
292     o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
293     o[i]-=c<<16;
294   }
295 }
296 
sel25519(gf p,gf q,int b)297 sv sel25519(gf p,gf q,int b)
298 {
299   i64 t,i,c=~(b-1);
300   FOR(i,16) {
301     t= c&(p[i]^q[i]);
302     p[i]^=t;
303     q[i]^=t;
304   }
305 }
306 
pack25519(u8 * o,const gf n)307 sv pack25519(u8 *o,const gf n)
308 {
309   int i,j,b;
310   gf m,t;
311   FOR(i,16) t[i]=n[i];
312   car25519(t);
313   car25519(t);
314   car25519(t);
315   FOR(j,2) {
316     m[0]=t[0]-0xffed;
317     for(i=1;i<15;i++) {
318       m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
319       m[i-1]&=0xffff;
320     }
321     m[15]=t[15]-0x7fff-((m[14]>>16)&1);
322     b=(m[15]>>16)&1;
323     m[14]&=0xffff;
324     sel25519(t,m,1-b);
325   }
326   FOR(i,16) {
327     o[2*i]=t[i]&0xff;
328     o[2*i+1]=t[i]>>8;
329   }
330 }
331 
neq25519(const gf a,const gf b)332 static int neq25519(const gf a, const gf b)
333 {
334   u8 c[32],d[32];
335   pack25519(c,a);
336   pack25519(d,b);
337   return crypto_verify_32(c,d);
338 }
339 
par25519(const gf a)340 static u8 par25519(const gf a)
341 {
342   u8 d[32];
343   pack25519(d,a);
344   return d[0]&1;
345 }
346 
unpack25519(gf o,const u8 * n)347 sv unpack25519(gf o, const u8 *n)
348 {
349   int i;
350   FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
351   o[15]&=0x7fff;
352 }
353 
A(gf o,const gf a,const gf b)354 sv A(gf o,const gf a,const gf b)
355 {
356   int i;
357   FOR(i,16) o[i]=a[i]+b[i];
358 }
359 
Z(gf o,const gf a,const gf b)360 sv Z(gf o,const gf a,const gf b)
361 {
362   int i;
363   FOR(i,16) o[i]=a[i]-b[i];
364 }
365 
M(gf o,const gf a,const gf b)366 sv M(gf o,const gf a,const gf b)
367 {
368   i64 i,j,t[31];
369   FOR(i,31) t[i]=0;
370   FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
371   FOR(i,15) t[i]+=38*t[i+16];
372   FOR(i,16) o[i]=t[i];
373   car25519(o);
374   car25519(o);
375 }
376 
S(gf o,const gf a)377 sv S(gf o,const gf a)
378 {
379   M(o,a,a);
380 }
381 
inv25519(gf o,const gf i)382 sv inv25519(gf o,const gf i)
383 {
384   gf c;
385   int a;
386   FOR(a,16) c[a]=i[a];
387   for(a=253;a>=0;a--) {
388     S(c,c);
389     if(a!=2&&a!=4) M(c,c,i);
390   }
391   FOR(a,16) o[a]=c[a];
392 }
393 
pow2523(gf o,const gf i)394 sv pow2523(gf o,const gf i)
395 {
396   gf c;
397   int a;
398   FOR(a,16) c[a]=i[a];
399   for(a=250;a>=0;a--) {
400     S(c,c);
401     if(a!=1) M(c,c,i);
402   }
403   FOR(a,16) o[a]=c[a];
404 }
405 
crypto_scalarmult(u8 * q,const u8 * n,const u8 * p)406 int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
407 {
408   u8 z[32];
409   i64 x[80],r,i;
410   gf a,b,c,d,e,f;
411   FOR(i,31) z[i]=n[i];
412   z[31]=(n[31]&127)|64;
413   z[0]&=248;
414   unpack25519(x,p);
415   FOR(i,16) {
416     b[i]=x[i];
417     d[i]=a[i]=c[i]=0;
418   }
419   a[0]=d[0]=1;
420   for(i=254;i>=0;--i) {
421     r=(z[i>>3]>>(i&7))&1;
422     sel25519(a,b,r);
423     sel25519(c,d,r);
424     A(e,a,c);
425     Z(a,a,c);
426     A(c,b,d);
427     Z(b,b,d);
428     S(d,e);
429     S(f,a);
430     M(a,c,a);
431     M(c,b,e);
432     A(e,a,c);
433     Z(a,a,c);
434     S(b,a);
435     Z(c,d,f);
436     M(a,c,_121665);
437     A(a,a,d);
438     M(c,c,a);
439     M(a,d,f);
440     M(d,b,x);
441     S(b,e);
442     sel25519(a,b,r);
443     sel25519(c,d,r);
444   }
445   FOR(i,16) {
446     x[i+16]=a[i];
447     x[i+32]=c[i];
448     x[i+48]=b[i];
449     x[i+64]=d[i];
450   }
451   inv25519(x+32,x+32);
452   M(x+16,x+16,x+32);
453   pack25519(q,x+16);
454   return 0;
455 }
456 
crypto_scalarmult_base(u8 * q,const u8 * n)457 int crypto_scalarmult_base(u8 *q,const u8 *n)
458 {
459   return crypto_scalarmult(q,n,_9);
460 }
461 
crypto_box_keypair(u8 * y,u8 * x)462 int crypto_box_keypair(u8 *y,u8 *x)
463 {
464   randombytes(x,32);
465   return crypto_scalarmult_base(y,x);
466 }
467 
crypto_box_beforenm(u8 * k,const u8 * y,const u8 * x)468 int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x)
469 {
470   u8 s[32];
471   crypto_scalarmult(s,x,y);
472   return crypto_core_hsalsa20(k,_0,s,sigma);
473 }
474 
crypto_box_afternm(u8 * c,const u8 * m,u64 d,const u8 * n,const u8 * k)475 int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
476 {
477   return crypto_secretbox(c,m,d,n,k);
478 }
479 
crypto_box_open_afternm(u8 * m,const u8 * c,u64 d,const u8 * n,const u8 * k)480 int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
481 {
482   return crypto_secretbox_open(m,c,d,n,k);
483 }
484 
crypto_box(u8 * c,const u8 * m,u64 d,const u8 * n,const u8 * y,const u8 * x)485 int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x)
486 {
487   u8 k[32];
488   crypto_box_beforenm(k,y,x);
489   return crypto_box_afternm(c,m,d,n,k);
490 }
491 
crypto_box_open(u8 * m,const u8 * c,u64 d,const u8 * n,const u8 * y,const u8 * x)492 int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x)
493 {
494   u8 k[32];
495   crypto_box_beforenm(k,y,x);
496   return crypto_box_open_afternm(m,c,d,n,k);
497 }
498 
R(u64 x,int c)499 static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); }
Ch(u64 x,u64 y,u64 z)500 static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); }
Maj(u64 x,u64 y,u64 z)501 static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
Sigma0(u64 x)502 static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
Sigma1(u64 x)503 static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
sigma0(u64 x)504 static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
sigma1(u64 x)505 static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
506 
507 static const u64 K[80] =
508 {
509   0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
510   0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
511   0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
512   0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
513   0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
514   0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
515   0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
516   0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
517   0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
518   0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
519   0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
520   0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
521   0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
522   0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
523   0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
524   0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
525   0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
526   0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
527   0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
528   0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
529 };
530 
crypto_hashblocks(u8 * x,const u8 * m,u64 n)531 int crypto_hashblocks(u8 *x,const u8 *m,u64 n)
532 {
533   u64 z[8],b[8],a[8],w[16],t;
534   int i,j;
535 
536   FOR(i,8) z[i] = a[i] = dl64(x + 8 * i);
537 
538   while (n >= 128) {
539     FOR(i,16) w[i] = dl64(m + 8 * i);
540 
541     FOR(i,80) {
542       FOR(j,8) b[j] = a[j];
543       t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
544       b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
545       b[3] += t;
546       FOR(j,8) a[(j+1)%8] = b[j];
547       if (i%16 == 15)
548 	FOR(j,16)
549 	  w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
550     }
551 
552     FOR(i,8) { a[i] += z[i]; z[i] = a[i]; }
553 
554     m += 128;
555     n -= 128;
556   }
557 
558   FOR(i,8) ts64(x+8*i,z[i]);
559 
560   return n;
561 }
562 
563 static const u8 iv[64] = {
564   0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
565   0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
566   0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
567   0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
568   0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
569   0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
570   0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
571   0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
572 } ;
573 
crypto_hash(u8 * out,const u8 * m,u64 n)574 int crypto_hash(u8 *out,const u8 *m,u64 n)
575 {
576   u8 h[64],x[256];
577   u64 i,b = n;
578 
579   FOR(i,64) h[i] = iv[i];
580 
581   crypto_hashblocks(h,m,n);
582   m += n;
583   n &= 127;
584   m -= n;
585 
586   FOR(i,256) x[i] = 0;
587   FOR(i,n) x[i] = m[i];
588   x[n] = 128;
589 
590   n = 256-128*(n<112);
591   x[n-9] = b >> 61;
592   ts64(x+n-8,b<<3);
593   crypto_hashblocks(h,x,n);
594 
595   FOR(i,64) out[i] = h[i];
596 
597   return 0;
598 }
599 
add(gf p[4],gf q[4])600 sv add(gf p[4],gf q[4])
601 {
602   gf a,b,c,d,t,e,f,g,h;
603 
604   Z(a, p[1], p[0]);
605   Z(t, q[1], q[0]);
606   M(a, a, t);
607   A(b, p[0], p[1]);
608   A(t, q[0], q[1]);
609   M(b, b, t);
610   M(c, p[3], q[3]);
611   M(c, c, D2);
612   M(d, p[2], q[2]);
613   A(d, d, d);
614   Z(e, b, a);
615   Z(f, d, c);
616   A(g, d, c);
617   A(h, b, a);
618 
619   M(p[0], e, f);
620   M(p[1], h, g);
621   M(p[2], g, f);
622   M(p[3], e, h);
623 }
624 
cswap(gf p[4],gf q[4],u8 b)625 sv cswap(gf p[4],gf q[4],u8 b)
626 {
627   int i;
628   FOR(i,4)
629     sel25519(p[i],q[i],b);
630 }
631 
pack(u8 * r,gf p[4])632 sv pack(u8 *r,gf p[4])
633 {
634   gf tx, ty, zi;
635   inv25519(zi, p[2]);
636   M(tx, p[0], zi);
637   M(ty, p[1], zi);
638   pack25519(r, ty);
639   r[31] ^= par25519(tx) << 7;
640 }
641 
scalarmult(gf p[4],gf q[4],const u8 * s)642 sv scalarmult(gf p[4],gf q[4],const u8 *s)
643 {
644   int i;
645   set25519(p[0],gf0);
646   set25519(p[1],gf1);
647   set25519(p[2],gf1);
648   set25519(p[3],gf0);
649   for (i = 255;i >= 0;--i) {
650     u8 b = (s[i/8]>>(i&7))&1;
651     cswap(p,q,b);
652     add(q,p);
653     add(p,p);
654     cswap(p,q,b);
655   }
656 }
657 
scalarbase(gf p[4],const u8 * s)658 sv scalarbase(gf p[4],const u8 *s)
659 {
660   gf q[4];
661   set25519(q[0],X);
662   set25519(q[1],Y);
663   set25519(q[2],gf1);
664   M(q[3],X,Y);
665   scalarmult(p,q,s);
666 }
667 
crypto_sign_keypair(u8 * pk,u8 * sk)668 int crypto_sign_keypair(u8 *pk, u8 *sk)
669 {
670   u8 d[64];
671   gf p[4];
672   int i;
673 
674   randombytes(sk, 32);
675   crypto_hash(d, sk, 32);
676   d[0] &= 248;
677   d[31] &= 127;
678   d[31] |= 64;
679 
680   scalarbase(p,d);
681   pack(pk,p);
682 
683   FOR(i,32) sk[32 + i] = pk[i];
684   return 0;
685 }
686 
687 static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
688 
modL(u8 * r,i64 x[64])689 sv modL(u8 *r,i64 x[64])
690 {
691   i64 carry,i,j;
692   for (i = 63;i >= 32;--i) {
693     carry = 0;
694     for (j = i - 32;j < i - 12;++j) {
695       x[j] += carry - 16 * x[i] * L[j - (i - 32)];
696       carry = (x[j] + 128) >> 8;
697       x[j] -= carry << 8;
698     }
699     x[j] += carry;
700     x[i] = 0;
701   }
702   carry = 0;
703   FOR(j,32) {
704     x[j] += carry - (x[31] >> 4) * L[j];
705     carry = x[j] >> 8;
706     x[j] &= 255;
707   }
708   FOR(j,32) x[j] -= carry * L[j];
709   FOR(i,32) {
710     x[i+1] += x[i] >> 8;
711     r[i] = x[i] & 255;
712   }
713 }
714 
reduce(u8 * r)715 sv reduce(u8 *r)
716 {
717   i64 x[64],i;
718   FOR(i,64) x[i] = (u64) r[i];
719   FOR(i,64) r[i] = 0;
720   modL(r,x);
721 }
722 
crypto_sign(u8 * sm,u64 * smlen,const u8 * m,u64 n,const u8 * sk)723 int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk)
724 {
725   u8 d[64],h[64],r[64];
726   u64 i;
727   i64 j,x[64];
728   gf p[4];
729 
730   crypto_hash(d, sk, 32);
731   d[0] &= 248;
732   d[31] &= 127;
733   d[31] |= 64;
734 
735   *smlen = n+64;
736   FOR(i,n) sm[64 + i] = m[i];
737   FOR(i,32) sm[32 + i] = d[32 + i];
738 
739   crypto_hash(r, sm+32, n+32);
740   reduce(r);
741   scalarbase(p,r);
742   pack(sm,p);
743 
744   FOR(i,32) sm[i+32] = sk[i+32];
745   crypto_hash(h,sm,n + 64);
746   reduce(h);
747 
748   FOR(i,64) x[i] = 0;
749   FOR(i,32) x[i] = (u64) r[i];
750   FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
751   modL(sm + 32,x);
752 
753   return 0;
754 }
755 
unpackneg(gf r[4],const u8 p[32])756 static int unpackneg(gf r[4],const u8 p[32])
757 {
758   gf t, chk, num, den, den2, den4, den6;
759   set25519(r[2],gf1);
760   unpack25519(r[1],p);
761   S(num,r[1]);
762   M(den,num,D);
763   Z(num,num,r[2]);
764   A(den,r[2],den);
765 
766   S(den2,den);
767   S(den4,den2);
768   M(den6,den4,den2);
769   M(t,den6,num);
770   M(t,t,den);
771 
772   pow2523(t,t);
773   M(t,t,num);
774   M(t,t,den);
775   M(t,t,den);
776   M(r[0],t,den);
777 
778   S(chk,r[0]);
779   M(chk,chk,den);
780   if (neq25519(chk, num)) M(r[0],r[0],I);
781 
782   S(chk,r[0]);
783   M(chk,chk,den);
784   if (neq25519(chk, num)) return -1;
785 
786   if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
787 
788   M(r[3],r[0],r[1]);
789   return 0;
790 }
791 
crypto_sign_open(u8 * m,u64 * mlen,const u8 * sm,u64 n,const u8 * pk)792 int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
793 {
794   u64 i;
795   u8 t[32],h[64];
796   gf p[4],q[4];
797 
798   *mlen = -1;
799   if (n < 64) return -1;
800 
801   if (unpackneg(q,pk)) return -1;
802 
803   FOR(i,n) m[i] = sm[i];
804   FOR(i,32) m[i+32] = pk[i];
805   crypto_hash(h,m,n);
806   reduce(h);
807   scalarmult(p,q,h);
808 
809   scalarbase(q,sm + 32);
810   add(p,q);
811   pack(t,p);
812 
813   n -= 64;
814   if (crypto_verify_32(sm, t)) {
815     FOR(i,n) m[i] = 0;
816     return -1;
817   }
818 
819   FOR(i,n) m[i] = sm[i + 64];
820   *mlen = n;
821   return 0;
822 }
823