1/*
2 Copyright (c) 2016-2017 Contributors as noted in the AUTHORS file
3
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30/*
31 The precompiled header is not used for c files so this is required here.
32*/
33#include "platform.hpp"
34
35#if defined(ZMQ_USE_TWEETNACL)
36
37/*
38 Disable warnings for this source only, rather than for the whole
39 codebase when building with C99 (gcc >= 4.2) or with Microsoft's compiler
40*/
41#if defined __GNUC__ \
42 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) \
43 && __STDC_VERSION__ < 201112L
44#pragma GCC diagnostic ignored "-Wsign-compare"
45#elif defined _MSC_VER
46#pragma warning(disable : 4018 4244 4146)
47#endif
48
49/* clang-format off */
50
51#include "tweetnacl.h"
52
53#define FOR(i,n) for (i = 0;i < n;++i)
54#define sv static void
55
56static const u8
57 _0[16],
58 _9[32] = {9};
59static const gf
60 gf0,
61 gf1 = {1},
62 _121665 = {0xDB41,1},
63 D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
64 D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
65 X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
66 Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
67 I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
68
69static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
70
71static u32 ld32(const u8 *x)
72{
73 u32 u = x[3];
74 u = (u<<8)|x[2];
75 u = (u<<8)|x[1];
76 return (u<<8)|x[0];
77}
78
79static u64 dl64(const u8 *x)
80{
81 u64 i,u=0;
82 FOR(i,8) u=(u<<8)|x[i];
83 return u;
84}
85
86sv st32(u8 *x,u32 u)
87{
88 int i;
89 FOR(i,4) { x[i] = u; u >>= 8; }
90}
91
92sv ts64(u8 *x,u64 u)
93{
94 int i;
95 for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
96}
97
98static int vn(const u8 *x,const u8 *y,int n)
99{
100 u32 i,d = 0;
101 FOR(i,n) d |= x[i]^y[i];
102 return (1 & ((d - 1) >> 8)) - 1;
103}
104
105int crypto_verify_16(const u8 *x,const u8 *y)
106{
107 return vn(x,y,16);
108}
109
110int crypto_verify_32(const u8 *x,const u8 *y)
111{
112 return vn(x,y,32);
113}
114
115sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
116{
117 u32 w[16],x[16],y[16],t[4];
118 int i,j,m;
119
120 FOR(i,4) {
121 x[5*i] = ld32(c+4*i);
122 x[1+i] = ld32(k+4*i);
123 x[6+i] = ld32(in+4*i);
124 x[11+i] = ld32(k+16+4*i);
125 }
126
127 FOR(i,16) y[i] = x[i];
128
129 FOR(i,20) {
130 FOR(j,4) {
131 FOR(m,4) t[m] = x[(5*j+4*m)%16];
132 t[1] ^= L32(t[0]+t[3], 7);
133 t[2] ^= L32(t[1]+t[0], 9);
134 t[3] ^= L32(t[2]+t[1],13);
135 t[0] ^= L32(t[3]+t[2],18);
136 FOR(m,4) w[4*j+(j+m)%4] = t[m];
137 }
138 FOR(m,16) x[m] = w[m];
139 }
140
141 if (h) {
142 FOR(i,16) x[i] += y[i];
143 FOR(i,4) {
144 x[5*i] -= ld32(c+4*i);
145 x[6+i] -= ld32(in+4*i);
146 }
147 FOR(i,4) {
148 st32(out+4*i,x[5*i]);
149 st32(out+16+4*i,x[6+i]);
150 }
151 } else
152 FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
153}
154
155int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
156{
157 core(out,in,k,c,0);
158 return 0;
159}
160
161int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
162{
163 core(out,in,k,c,1);
164 return 0;
165}
166
167static const u8 sigma[16] = "expand 32-byte k";
168
169int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
170{
171 u8 z[16],x[64];
172 u32 u,i;
173 if (!b) return 0;
174 FOR(i,16) z[i] = 0;
175 FOR(i,8) z[i] = n[i];
176 while (b >= 64) {
177 crypto_core_salsa20(x,z,k,sigma);
178 FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
179 u = 1;
180 for (i = 8;i < 16;++i) {
181 u += (u32) z[i];
182 z[i] = u;
183 u >>= 8;
184 }
185 b -= 64;
186 c += 64;
187 if (m) m += 64;
188 }
189 if (b) {
190 crypto_core_salsa20(x,z,k,sigma);
191 FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
192 }
193 return 0;
194}
195
196int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
197{
198 return crypto_stream_salsa20_xor(c,0,d,n,k);
199}
200
201int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
202{
203 u8 s[32];
204 crypto_core_hsalsa20(s,n,k,sigma);
205 return crypto_stream_salsa20(c,d,n+16,s);
206}
207
208int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
209{
210 u8 s[32];
211 crypto_core_hsalsa20(s,n,k,sigma);
212 return crypto_stream_salsa20_xor(c,m,d,n+16,s);
213}
214
215sv add1305(u32 *h,const u32 *c)
216{
217 u32 j,u = 0;
218 FOR(j,17) {
219 u += h[j] + c[j];
220 h[j] = u & 255;
221 u >>= 8;
222 }
223}
224
225static const u32 minusp[17] = {
226 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
227} ;
228
229int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k)
230{
231 u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
232
233 FOR(j,17) r[j]=h[j]=0;
234 FOR(j,16) r[j]=k[j];
235 r[3]&=15;
236 r[4]&=252;
237 r[7]&=15;
238 r[8]&=252;
239 r[11]&=15;
240 r[12]&=252;
241 r[15]&=15;
242
243 while (n > 0) {
244 FOR(j,17) c[j] = 0;
245 for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
246 c[j] = 1;
247 m += j; n -= j;
248 add1305(h,c);
249 FOR(i,17) {
250 x[i] = 0;
251 FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
252 }
253 FOR(i,17) h[i] = x[i];
254 u = 0;
255 FOR(j,16) {
256 u += h[j];
257 h[j] = u & 255;
258 u >>= 8;
259 }
260 u += h[16]; h[16] = u & 3;
261 u = 5 * (u >> 2);
262 FOR(j,16) {
263 u += h[j];
264 h[j] = u & 255;
265 u >>= 8;
266 }
267 u += h[16]; h[16] = u;
268 }
269
270 FOR(j,17) g[j] = h[j];
271 add1305(h,minusp);
272 s = -(h[16] >> 7);
273 FOR(j,17) h[j] ^= s & (g[j] ^ h[j]);
274
275 FOR(j,16) c[j] = k[j + 16];
276 c[16] = 0;
277 add1305(h,c);
278 FOR(j,16) out[j] = h[j];
279 return 0;
280}
281
282int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k)
283{
284 u8 x[16];
285 crypto_onetimeauth(x,m,n,k);
286 return crypto_verify_16(h,x);
287}
288
289int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
290{
291 int i;
292 if (d < 32) return -1;
293 crypto_stream_xor(c,m,d,n,k);
294 crypto_onetimeauth(c + 16,c + 32,d - 32,c);
295 FOR(i,16) c[i] = 0;
296 return 0;
297}
298
299int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
300{
301 int i;
302 u8 x[32];
303 if (d < 32) return -1;
304 crypto_stream(x,32,n,k);
305 if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
306 crypto_stream_xor(m,c,d,n,k);
307 FOR(i,32) m[i] = 0;
308 return 0;
309}
310
311sv set25519(gf r, const gf a)
312{
313 int i;
314 FOR(i,16) r[i]=a[i];
315}
316
317sv car25519(gf o)
318{
319 int i;
320 i64 c;
321 FOR(i,16) {
322 o[i]+=(1LL<<16);
323 c=o[i]>>16;
324 o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
325 o[i]-=c<<16;
326 }
327}
328
329sv sel25519(gf p,gf q,int b)
330{
331 i64 t,i,c=~(b-1);
332 FOR(i,16) {
333 t= c&(p[i]^q[i]);
334 p[i]^=t;
335 q[i]^=t;
336 }
337}
338
339sv pack25519(u8 *o,const gf n)
340{
341 int i,j,b;
342 gf m,t;
343 FOR(i,16) t[i]=n[i];
344 car25519(t);
345 car25519(t);
346 car25519(t);
347 FOR(j,2) {
348 m[0]=t[0]-0xffed;
349 for(i=1;i<15;i++) {
350 m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
351 m[i-1]&=0xffff;
352 }
353 m[15]=t[15]-0x7fff-((m[14]>>16)&1);
354 b=(m[15]>>16)&1;
355 m[14]&=0xffff;
356 sel25519(t,m,1-b);
357 }
358 FOR(i,16) {
359 o[2*i]=t[i]&0xff;
360 o[2*i+1]=t[i]>>8;
361 }
362}
363
364static int neq25519(const gf a, const gf b)
365{
366 u8 c[32],d[32];
367 pack25519(c,a);
368 pack25519(d,b);
369 return crypto_verify_32(c,d);
370}
371
372static u8 par25519(const gf a)
373{
374 u8 d[32];
375 pack25519(d,a);
376 return d[0]&1;
377}
378
379sv unpack25519(gf o, const u8 *n)
380{
381 int i;
382 FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
383 o[15]&=0x7fff;
384}
385
386sv A(gf o,const gf a,const gf b)
387{
388 int i;
389 FOR(i,16) o[i]=a[i]+b[i];
390}
391
392sv Z(gf o,const gf a,const gf b)
393{
394 int i;
395 FOR(i,16) o[i]=a[i]-b[i];
396}
397
398sv M(gf o,const gf a,const gf b)
399{
400 i64 i,j,t[31];
401 FOR(i,31) t[i]=0;
402 FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
403 FOR(i,15) t[i]+=38*t[i+16];
404 FOR(i,16) o[i]=t[i];
405 car25519(o);
406 car25519(o);
407}
408
409sv S(gf o,const gf a)
410{
411 M(o,a,a);
412}
413
414sv inv25519(gf o,const gf i)
415{
416 gf c;
417 int a;
418 FOR(a,16) c[a]=i[a];
419 for(a=253;a>=0;a--) {
420 S(c,c);
421 if(a!=2&&a!=4) M(c,c,i);
422 }
423 FOR(a,16) o[a]=c[a];
424}
425
426sv pow2523(gf o,const gf i)
427{
428 gf c;
429 int a;
430 FOR(a,16) c[a]=i[a];
431 for(a=250;a>=0;a--) {
432 S(c,c);
433 if(a!=1) M(c,c,i);
434 }
435 FOR(a,16) o[a]=c[a];
436}
437
438int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
439{
440 u8 z[32];
441 i64 x[80],r,i;
442 gf a,b,c,d,e,f;
443 FOR(i,31) z[i]=n[i];
444 z[31]=(n[31]&127)|64;
445 z[0]&=248;
446 unpack25519(x,p);
447 FOR(i,16) {
448 b[i]=x[i];
449 d[i]=a[i]=c[i]=0;
450 }
451 a[0]=d[0]=1;
452 for(i=254;i>=0;--i) {
453 r=(z[i>>3]>>(i&7))&1;
454 sel25519(a,b,r);
455 sel25519(c,d,r);
456 A(e,a,c);
457 Z(a,a,c);
458 A(c,b,d);
459 Z(b,b,d);
460 S(d,e);
461 S(f,a);
462 M(a,c,a);
463 M(c,b,e);
464 A(e,a,c);
465 Z(a,a,c);
466 S(b,a);
467 Z(c,d,f);
468 M(a,c,_121665);
469 A(a,a,d);
470 M(c,c,a);
471 M(a,d,f);
472 M(d,b,x);
473 S(b,e);
474 sel25519(a,b,r);
475 sel25519(c,d,r);
476 }
477 FOR(i,16) {
478 x[i+16]=a[i];
479 x[i+32]=c[i];
480 x[i+48]=b[i];
481 x[i+64]=d[i];
482 }
483 inv25519(x+32,x+32);
484 M(x+16,x+16,x+32);
485 pack25519(q,x+16);
486 return 0;
487}
488
489int crypto_scalarmult_base(u8 *q,const u8 *n)
490{
491 return crypto_scalarmult(q,n,_9);
492}
493
494int crypto_box_keypair(u8 *y,u8 *x)
495{
496 randombytes(x,32);
497 return crypto_scalarmult_base(y,x);
498}
499
500int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x)
501{
502 u8 s[32];
503 crypto_scalarmult(s,x,y);
504 return crypto_core_hsalsa20(k,_0,s,sigma);
505}
506
507int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
508{
509 return crypto_secretbox(c,m,d,n,k);
510}
511
512int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
513{
514 return crypto_secretbox_open(m,c,d,n,k);
515}
516
517int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x)
518{
519 u8 k[32];
520 crypto_box_beforenm(k,y,x);
521 return crypto_box_afternm(c,m,d,n,k);
522}
523
524int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x)
525{
526 u8 k[32];
527 crypto_box_beforenm(k,y,x);
528 return crypto_box_open_afternm(m,c,d,n,k);
529}
530
531static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); }
532static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); }
533static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
534static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
535static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
536static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
537static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
538
539static const u64 K[80] =
540{
541 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
542 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
543 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
544 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
545 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
546 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
547 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
548 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
549 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
550 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
551 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
552 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
553 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
554 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
555 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
556 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
557 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
558 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
559 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
560 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
561};
562
563int crypto_hashblocks(u8 *x,const u8 *m,u64 n)
564{
565 u64 z[8],b[8],a[8],w[16],t;
566 int i,j;
567
568 FOR(i,8) z[i] = a[i] = dl64(x + 8 * i);
569
570 while (n >= 128) {
571 FOR(i,16) w[i] = dl64(m + 8 * i);
572
573 FOR(i,80) {
574 FOR(j,8) b[j] = a[j];
575 t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
576 b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
577 b[3] += t;
578 FOR(j,8) a[(j+1)%8] = b[j];
579 if (i%16 == 15)
580 FOR(j,16)
581 w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
582 }
583
584 FOR(i,8) { a[i] += z[i]; z[i] = a[i]; }
585
586 m += 128;
587 n -= 128;
588 }
589
590 FOR(i,8) ts64(x+8*i,z[i]);
591
592 return n;
593}
594
595static const u8 iv[64] = {
596 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
597 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
598 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
599 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
600 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
601 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
602 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
603 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
604} ;
605
606int crypto_hash(u8 *out,const u8 *m,u64 n)
607{
608 u8 h[64],x[256];
609 u64 i,b = n;
610
611 FOR(i,64) h[i] = iv[i];
612
613 crypto_hashblocks(h,m,n);
614 m += n;
615 n &= 127;
616 m -= n;
617
618 FOR(i,256) x[i] = 0;
619 FOR(i,n) x[i] = m[i];
620 x[n] = 128;
621
622 n = 256-128*(n<112);
623 x[n-9] = b >> 61;
624 ts64(x+n-8,b<<3);
625 crypto_hashblocks(h,x,n);
626
627 FOR(i,64) out[i] = h[i];
628
629 return 0;
630}
631
632sv add(gf p[4],gf q[4])
633{
634 gf a,b,c,d,t,e,f,g,h;
635
636 Z(a, p[1], p[0]);
637 Z(t, q[1], q[0]);
638 M(a, a, t);
639 A(b, p[0], p[1]);
640 A(t, q[0], q[1]);
641 M(b, b, t);
642 M(c, p[3], q[3]);
643 M(c, c, D2);
644 M(d, p[2], q[2]);
645 A(d, d, d);
646 Z(e, b, a);
647 Z(f, d, c);
648 A(g, d, c);
649 A(h, b, a);
650
651 M(p[0], e, f);
652 M(p[1], h, g);
653 M(p[2], g, f);
654 M(p[3], e, h);
655}
656
657sv cswap(gf p[4],gf q[4],u8 b)
658{
659 int i;
660 FOR(i,4)
661 sel25519(p[i],q[i],b);
662}
663
664sv pack(u8 *r,gf p[4])
665{
666 gf tx, ty, zi;
667 inv25519(zi, p[2]);
668 M(tx, p[0], zi);
669 M(ty, p[1], zi);
670 pack25519(r, ty);
671 r[31] ^= par25519(tx) << 7;
672}
673
674sv scalarmult(gf p[4],gf q[4],const u8 *s)
675{
676 int i;
677 set25519(p[0],gf0);
678 set25519(p[1],gf1);
679 set25519(p[2],gf1);
680 set25519(p[3],gf0);
681 for (i = 255;i >= 0;--i) {
682 u8 b = (s[i/8]>>(i&7))&1;
683 cswap(p,q,b);
684 add(q,p);
685 add(p,p);
686 cswap(p,q,b);
687 }
688}
689
690sv scalarbase(gf p[4],const u8 *s)
691{
692 gf q[4];
693 set25519(q[0],X);
694 set25519(q[1],Y);
695 set25519(q[2],gf1);
696 M(q[3],X,Y);
697 scalarmult(p,q,s);
698}
699
700int crypto_sign_keypair(u8 *pk, u8 *sk)
701{
702 u8 d[64];
703 gf p[4];
704 int i;
705
706 randombytes(sk, 32);
707 crypto_hash(d, sk, 32);
708 d[0] &= 248;
709 d[31] &= 127;
710 d[31] |= 64;
711
712 scalarbase(p,d);
713 pack(pk,p);
714
715 FOR(i,32) sk[32 + i] = pk[i];
716 return 0;
717}
718
719static 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};
720
721sv modL(u8 *r,i64 x[64])
722{
723 i64 carry,i,j;
724 for (i = 63;i >= 32;--i) {
725 carry = 0;
726 for (j = i - 32;j < i - 12;++j) {
727 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
728 carry = (x[j] + 128) >> 8;
729 x[j] -= carry << 8;
730 }
731 x[j] += carry;
732 x[i] = 0;
733 }
734 carry = 0;
735 FOR(j,32) {
736 x[j] += carry - (x[31] >> 4) * L[j];
737 carry = x[j] >> 8;
738 x[j] &= 255;
739 }
740 FOR(j,32) x[j] -= carry * L[j];
741 FOR(i,32) {
742 x[i+1] += x[i] >> 8;
743 r[i] = x[i] & 255;
744 }
745}
746
747sv reduce(u8 *r)
748{
749 i64 x[64],i;
750 FOR(i,64) x[i] = (u64) r[i];
751 FOR(i,64) r[i] = 0;
752 modL(r,x);
753}
754
755int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk)
756{
757 u8 d[64],h[64],r[64];
758 i64 i,j,x[64];
759 gf p[4];
760
761 crypto_hash(d, sk, 32);
762 d[0] &= 248;
763 d[31] &= 127;
764 d[31] |= 64;
765
766 *smlen = n+64;
767 FOR(i,n) sm[64 + i] = m[i];
768 FOR(i,32) sm[32 + i] = d[32 + i];
769
770 crypto_hash(r, sm+32, n+32);
771 reduce(r);
772 scalarbase(p,r);
773 pack(sm,p);
774
775 FOR(i,32) sm[i+32] = sk[i+32];
776 crypto_hash(h,sm,n + 64);
777 reduce(h);
778
779 FOR(i,64) x[i] = 0;
780 FOR(i,32) x[i] = (u64) r[i];
781 FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
782 modL(sm + 32,x);
783
784 return 0;
785}
786
787static int unpackneg(gf r[4],const u8 p[32])
788{
789 gf t, chk, num, den, den2, den4, den6;
790 set25519(r[2],gf1);
791 unpack25519(r[1],p);
792 S(num,r[1]);
793 M(den,num,D);
794 Z(num,num,r[2]);
795 A(den,r[2],den);
796
797 S(den2,den);
798 S(den4,den2);
799 M(den6,den4,den2);
800 M(t,den6,num);
801 M(t,t,den);
802
803 pow2523(t,t);
804 M(t,t,num);
805 M(t,t,den);
806 M(t,t,den);
807 M(r[0],t,den);
808
809 S(chk,r[0]);
810 M(chk,chk,den);
811 if (neq25519(chk, num)) M(r[0],r[0],I);
812
813 S(chk,r[0]);
814 M(chk,chk,den);
815 if (neq25519(chk, num)) return -1;
816
817 if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
818
819 M(r[3],r[0],r[1]);
820 return 0;
821}
822
823int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
824{
825 int i;
826 u8 t[32],h[64];
827 gf p[4],q[4];
828
829 *mlen = -1;
830 if (n < 64) return -1;
831
832 if (unpackneg(q,pk)) return -1;
833
834 FOR(i,n) m[i] = sm[i];
835 FOR(i,32) m[i+32] = pk[i];
836 crypto_hash(h,m,n);
837 reduce(h);
838 scalarmult(p,q,h);
839
840 scalarbase(q,sm + 32);
841 add(p,q);
842 pack(t,p);
843
844 n -= 64;
845 if (crypto_verify_32(sm, t)) {
846 FOR(i,n) m[i] = 0;
847 return -1;
848 }
849
850 FOR(i,n) m[i] = sm[i + 64];
851 *mlen = n;
852 return 0;
853}
854
855
856#ifdef ZMQ_HAVE_WINDOWS
857
858#include <windows.h>
859#include <wincrypt.h>
860
861#define NCP ((HCRYPTPROV) 0)
862
863HCRYPTPROV hProvider = NCP;
864
865void randombytes(unsigned char *x,unsigned long long xlen)
866{
867 unsigned i;
868 BOOL ret;
869
870 if (hProvider == NCP) {
871 for (;;) {
872 ret = CryptAcquireContext(&hProvider, NULL, NULL,
873 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
874 if (ret != FALSE)
875 break;
876 Sleep (1);
877 }
878 }
879 while (xlen > 0) {
880 if (xlen < 1048576)
881 i = (unsigned) xlen;
882 else
883 i = 1048576;
884
885 ret = CryptGenRandom(hProvider, i, x);
886 if (ret == FALSE) {
887 Sleep(1);
888 continue;
889 }
890 x += i;
891 xlen -= i;
892 }
893}
894
895int randombytes_close(void)
896{
897 int rc = -1;
898 if ((hProvider != NCP) && (CryptReleaseContext(hProvider, 0) != FALSE)) {
899 hProvider = NCP;
900 rc = 0;
901 }
902 return rc;
903}
904
905int sodium_init (void)
906{
907 return 0;
908}
909
910#else
911
912#include <unistd.h>
913#include <assert.h>
914
915#ifdef ZMQ_HAVE_GETRANDOM
916#include <sys/random.h>
917#else
918#include <sys/types.h>
919#include <sys/stat.h>
920#include <fcntl.h>
921
922static int fd = -1;
923#endif
924
925void randombytes (unsigned char *x,unsigned long long xlen)
926{
927 int i;
928#ifndef ZMQ_HAVE_GETRANDOM
929 /* Require that random_open has already been called, to avoid
930 race conditions. */
931 assert (fd != -1);
932#endif
933 while (xlen > 0) {
934 if (xlen < 1048576)
935 i = xlen;
936 else
937 i = 1048576;
938
939#ifdef ZMQ_HAVE_GETRANDOM
940 i = getrandom (x, i, 0);
941#else
942 i = read(fd,x,i);
943#endif
944 if (i < 1) {
945 sleep (1);
946 continue;
947 }
948 x += i;
949 xlen -= i;
950 }
951}
952
953/* Do not call manually! Use random_close from random.hpp */
954int randombytes_close (void)
955{
956 int rc = -1;
957#ifndef ZMQ_HAVE_GETRANDOM
958 if (fd != -1 && close(fd) == 0) {
959 fd = -1;
960 rc = 0;
961 }
962#endif /* ZMQ_HAVE_GETRANDOM */
963 return rc;
964}
965
966/* Do not call manually! Use random_open from random.hpp */
967int sodium_init (void)
968{
969#ifndef ZMQ_HAVE_GETRANDOM
970 if (fd == -1) {
971 for (;;) {
972 int flags = O_RDONLY;
973#ifdef ZMQ_HAVE_O_CLOEXEC
974 flags |= O_CLOEXEC;
975#endif
976 fd = open ("/dev/urandom", flags);
977 if (fd != -1)
978 break;
979 sleep (1);
980 }
981#if !defined ZMQ_HAVE_O_CLOEXEC && defined FD_CLOEXEC
982 int rc = fcntl (fd, F_SETFD, FD_CLOEXEC);
983 assert (rc != -1);
984#endif
985 }
986#endif /* ZMQ_HAVE_GETRANDOM */
987 return 0;
988}
989
990#endif
991
992#endif
993/* clang-format on */
994