comparison src/tweetnacl.c @ 64:fa53d1c54886

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