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