Crypto++ 8.7
Free C++ class library of cryptographic schemes
tweetnacl.cpp
1// tweetnacl.cpp - modified tweetnacl.c placed in public domain by Jeffrey Walton.
2// The NaCl library and tweetnacl.c is public domain source code
3// written by Daniel J. Bernstein, Bernard van Gastel, Wesley
4// Janssen, Tanja Lange, Peter Schwabe and Sjaak Smetsers.
5
6#include "pch.h"
7#include "config.h"
8#include "naclite.h"
9#include "misc.h"
10#include "osrng.h"
11#include "stdcpp.h"
12
13// Don't destroy const time properties when squashing warnings.
14#if CRYPTOPP_MSC_VERSION
15# pragma warning(disable: 4146 4242 4244 4245)
16#endif
17
18// Can't use GetAlignmentOf<word32>() because of C++11 and constexpr
19// Can use 'const unsigned int' because of MSVC 2013
20#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
21# define ALIGN_SPEC 16
22#else
23# define ALIGN_SPEC 4
24#endif
25
26#ifndef CRYPTOPP_DISABLE_NACL
27
28NAMESPACE_BEGIN(CryptoPP)
29NAMESPACE_BEGIN(NaCl)
30
31typedef sword64 gf[16];
32
33static const byte
34 _0[32] = {0},
35 _9[32] = {9};
36
37static const gf
38 gf0 = {0},
39 gf1 = {1},
40 _121665 = {0xDB41,1},
41 D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
42 D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
43 X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
44 Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
45 I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
46
47// Added by Crypto++ for TweetNaCl
48static void randombytes(byte * block, word64 size)
49{
51 prng.GenerateBlock(block, (size_t)size);
52}
53
54static word32 L32(word32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
55
56static word32 ld32(const byte *x)
57{
58 word32 u = x[3];
59 u = (u<<8)|x[2];
60 u = (u<<8)|x[1];
61 return (u<<8)|x[0];
62}
63
64static word64 dl64(const byte *x)
65{
66 word64 i,u=0;
67 for(i=0; i<8; ++i) u=(u<<8)|x[i];
68 return u;
69}
70
71static void st32(byte *x,word32 u)
72{
73 int i;
74 for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
75}
76
77static void ts64(byte *x,word64 u)
78{
79 int i;
80 for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
81}
82
83// Extra cast due to Coverity CID 186949
84static int verify_n(const byte *x,const byte *y,word32 n)
85{
86 word32 i,d = 0;
87 for(i=0; i<n; ++i) d |= x[i]^y[i];
88 const sword32 v = (sword32) d;
89 return (1 & ((word32)(v - 1) >> 8)) - 1;
90}
91
92int crypto_verify_16(const byte *x,const byte *y)
93{
94 return verify_n(x,y,16);
95}
96
97int crypto_verify_32(const byte *x,const byte *y)
98{
99 return verify_n(x,y,32);
100}
101
102static void core(byte *out,const byte *in,const byte *k,const byte *c,int h)
103{
104 word32 w[16],x[16],y[16],t[4];
105 int i,j,m;
106
107 for(i=0; i<4; ++i) {
108 x[5*i] = ld32(c+4*i);
109 x[1+i] = ld32(k+4*i);
110 x[6+i] = ld32(in+4*i);
111 x[11+i] = ld32(k+16+4*i);
112 }
113
114 for(i=0; i<16; ++i) y[i] = x[i];
115
116 for(i=0; i<20; ++i) {
117 for(j=0; j<4; ++j) {
118 for(m=0; m<4; ++m) t[m] = x[(5*j+4*m)%16];
119 t[1] ^= L32(t[0]+t[3], 7);
120 t[2] ^= L32(t[1]+t[0], 9);
121 t[3] ^= L32(t[2]+t[1],13);
122 t[0] ^= L32(t[3]+t[2],18);
123 for(m=0; m<4; ++m) w[4*j+(j+m)%4] = t[m];
124 }
125 for(m=0; m<16; ++m) x[m] = w[m];
126 }
127
128 if (h) {
129 for(i=0; i<16; ++i) x[i] += y[i];
130 for(i=0; i<4; ++i) {
131 x[5*i] -= ld32(c+4*i);
132 x[6+i] -= ld32(in+4*i);
133 }
134 for(i=0; i<4; ++i) {
135 st32(out+4*i,x[5*i]);
136 st32(out+16+4*i,x[6+i]);
137 }
138 } else
139 for(i=0; i<16; ++i) st32(out + 4 * i,x[i] + y[i]);
140}
141
142int crypto_core_salsa20(byte *out,const byte *in,const byte *k,const byte *c)
143{
144 core(out,in,k,c,0);
145 return 0;
146}
147
148int crypto_core_hsalsa20(byte *out,const byte *in,const byte *k,const byte *c)
149{
150 core(out,in,k,c,1);
151 return 0;
152}
153
154static const byte sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B};
155
156int crypto_stream_salsa20_xor(byte *c,const byte *m,word64 b,const byte *n,const byte *k)
157{
158 byte z[16],x[64];
159 word32 u,i;
160 if (!b) return 0;
161 for(i=0; i<16; ++i) z[i] = 0;
162 for(i=0; i<8; ++i) z[i] = n[i];
163 while (b >= 64) {
164 crypto_core_salsa20(x,z,k,sigma);
165 for(i=0; i<64; ++i) c[i] = (m?m[i]:0) ^ x[i];
166 u = 1;
167 for (i = 8;i < 16;++i) {
168 u += (word32) z[i];
169 z[i] = u;
170 u >>= 8;
171 }
172 b -= 64;
173 c += 64;
174 if (m) m += 64;
175 }
176 if (b) {
177 crypto_core_salsa20(x,z,k,sigma);
178 for(i=0; i<b; ++i) c[i] = (m?m[i]:0) ^ x[i];
179 }
180 return 0;
181}
182
183int crypto_stream_salsa20(byte *c,word64 d,const byte *n,const byte *k)
184{
185 return crypto_stream_salsa20_xor(c,0,d,n,k);
186}
187
188int crypto_stream(byte *c,word64 d,const byte *n,const byte *k)
189{
190 byte s[32];
191 crypto_core_hsalsa20(s,n,k,sigma);
192 return crypto_stream_salsa20(c,d,n+16,s);
193}
194
195int crypto_stream_xor(byte *c,const byte *m,word64 d,const byte *n,const byte *k)
196{
197 byte s[32];
198 crypto_core_hsalsa20(s,n,k,sigma);
199 return crypto_stream_salsa20_xor(c,m,d,n+16,s);
200}
201
202static void add1305(word32 *h,const word32 *c)
203{
204 word32 j,u = 0;
205 for(j=0; j<17; ++j) {
206 u += h[j] + c[j];
207 h[j] = u & 255;
208 u >>= 8;
209 }
210}
211
212static const word32 minusp[17] = {
213 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
214} ;
215
216int crypto_onetimeauth(byte *out,const byte *m,word64 n,const byte *k)
217{
218 word32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
219
220 for(j=0; j<17; ++j) r[j]=h[j]=0;
221 for(j=0; j<16; ++j) r[j]=k[j];
222 r[3]&=15;
223 r[4]&=252;
224 r[7]&=15;
225 r[8]&=252;
226 r[11]&=15;
227 r[12]&=252;
228 r[15]&=15;
229
230 while (n > 0) {
231 for(j=0; j<17; ++j) c[j] = 0;
232 for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
233 c[j] = 1;
234 m += j; n -= j;
235 add1305(h,c);
236 for(i=0; i<17; ++i) {
237 x[i] = 0;
238 for(j=0; j<17; ++j) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
239 }
240 for(i=0; i<17; ++i) h[i] = x[i];
241 u = 0;
242 for(j=0; j<16; ++j) {
243 u += h[j];
244 h[j] = u & 255;
245 u >>= 8;
246 }
247 u += h[16]; h[16] = u & 3;
248 u = 5 * (u >> 2);
249 for(j=0; j<16; ++j) {
250 u += h[j];
251 h[j] = u & 255;
252 u >>= 8;
253 }
254 u += h[16]; h[16] = u;
255 }
256
257 for(j=0; j<17; ++j) g[j] = h[j];
258 add1305(h,minusp);
259 s = -(h[16] >> 7);
260 for(j=0; j<17; ++j) h[j] ^= s & (g[j] ^ h[j]);
261
262 for(j=0; j<16; ++j) c[j] = k[j + 16];
263 c[16] = 0;
264 add1305(h,c);
265 for(j=0; j<16; ++j) out[j] = h[j];
266 return 0;
267}
268
269int crypto_onetimeauth_verify(const byte *h,const byte *m,word64 n,const byte *k)
270{
271 byte x[16];
272 crypto_onetimeauth(x,m,n,k);
273 return crypto_verify_16(h,x);
274}
275
276int crypto_secretbox(byte *c,const byte *m,word64 d,const byte *n,const byte *k)
277{
278 int i;
279 if (d < 32) return -1;
280 crypto_stream_xor(c,m,d,n,k);
281 crypto_onetimeauth(c + 16,c + 32,d - 32,c);
282 for(i=0; i<16; ++i) c[i] = 0;
283 return 0;
284}
285
286int crypto_secretbox_open(byte *m,const byte *c,word64 d,const byte *n,const byte *k)
287{
288 int i;
289 byte x[32];
290 if (d < 32) return -1;
291 crypto_stream(x,32,n,k);
292 if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
293 crypto_stream_xor(m,c,d,n,k);
294 for(i=0; i<32; ++i) m[i] = 0;
295 return 0;
296}
297
298static void set25519(gf r, const gf a)
299{
300 int i;
301 for(i=0; i<16; ++i) r[i]=a[i];
302}
303
304static void car25519(gf o)
305{
306 int i;
307 sword64 c;
308 for(i=0; i<16; ++i) {
309 o[i]+=(1LL<<16);
310 c=o[i]>>16;
311 o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
312 o[i]-=((word64)c)<<16;
313 }
314}
315
316static void sel25519(gf p,gf q,int b)
317{
318 sword64 t,i,c=~(b-1);
319 for(i=0; i<16; ++i) {
320 t= c&(p[i]^q[i]);
321 p[i]^=t;
322 q[i]^=t;
323 }
324}
325
326static void pack25519(byte *o,const gf n)
327{
328 int i,j,b;
329 gf m,t;
330 for(i=0; i<16; ++i) t[i]=n[i];
331 car25519(t);
332 car25519(t);
333 car25519(t);
334 for(j=0; j<2; ++j) {
335 m[0]=t[0]-0xffed;
336 for(i=1;i<15;i++) {
337 m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
338 m[i-1]&=0xffff;
339 }
340 m[15]=t[15]-0x7fff-((m[14]>>16)&1);
341 b=(m[15]>>16)&1;
342 m[14]&=0xffff;
343 sel25519(t,m,1-b);
344 }
345 for(i=0; i<16; ++i) {
346 o[2*i]=t[i]&0xff;
347 o[2*i+1]=t[i]>>8;
348 }
349}
350
351static int neq25519(const gf a, const gf b)
352{
353 byte c[32],d[32];
354 pack25519(c,a);
355 pack25519(d,b);
356 return crypto_verify_32(c,d);
357}
358
359static byte par25519(const gf a)
360{
361 byte d[32];
362 pack25519(d,a);
363 return d[0]&1;
364}
365
366static void unpack25519(gf o, const byte *n)
367{
368 int i;
369 for(i=0; i<16; ++i) o[i]=n[2*i]+((sword64)n[2*i+1]<<8);
370 o[15]&=0x7fff;
371}
372
373static void A(gf o,const gf a,const gf b)
374{
375 int i;
376 for(i=0; i<16; ++i) o[i]=a[i]+b[i];
377}
378
379static void Z(gf o,const gf a,const gf b)
380{
381 int i;
382 for(i=0; i<16; ++i) o[i]=a[i]-b[i];
383}
384
385static void M(gf o,const gf a,const gf b)
386{
387 sword64 i,j,t[31];
388 for(i=0; i<31; ++i) t[i]=0;
389 for(i=0; i<16; ++i) for(j=0; j<16; ++j) t[i+j]+=a[i]*b[j];
390 for(i=0; i<15; ++i) t[i]+=38*t[i+16];
391 for(i=0; i<16; ++i) o[i]=t[i];
392 car25519(o);
393 car25519(o);
394}
395
396static void S(gf o,const gf a)
397{
398 M(o,a,a);
399}
400
401static void inv25519(gf o,const gf i)
402{
403 gf c;
404 int a;
405 for(a=0; a<16; ++a) c[a]=i[a];
406 for(a=253;a>=0;a--) {
407 S(c,c);
408 if(a!=2&&a!=4) M(c,c,i);
409 }
410 for(a=0; a<16; ++a) o[a]=c[a];
411}
412
413static void pow2523(gf o,const gf i)
414{
415 gf c;
416 int a;
417 for(a=0; a<16; ++a) c[a]=i[a];
418 for(a=250;a>=0;a--) {
419 S(c,c);
420 if(a!=1) M(c,c,i);
421 }
422 for(a=0; a<16; ++a) o[a]=c[a];
423}
424
425// https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c
426static int has_small_order(const byte s[32])
427{
428 CRYPTOPP_ALIGN_DATA(ALIGN_SPEC)
429 const byte blacklist[][32] = {
430 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
431 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
432 { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
433 { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
434 { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
435 { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
436 { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
437 { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 },
438 { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 },
439 { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
440 { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
441 { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
442 };
443 CRYPTOPP_COMPILE_ASSERT(12 == COUNTOF(blacklist));
444
445 byte c[12] = { 0 };
446 for (size_t j = 0; j < 32; j++) {
447 for (size_t i = 0; i < COUNTOF(blacklist); i++) {
448 c[i] |= s[j] ^ blacklist[i][j];
449 }
450 }
451
452 unsigned int k = 0;
453 for (size_t i = 0; i < COUNTOF(blacklist); i++) {
454 k |= (c[i] - 1);
455 }
456
457 return (int) ((k >> 8) & 1);
458}
459
460int crypto_scalarmult(byte *q,const byte *n,const byte *p)
461{
462 byte z[32];
463 sword64 x[80],r,i;
464 gf a,b,c,d,e,f;
465 for(i=0; i<31; ++i) z[i]=n[i];
466 z[31]=(n[31]&127)|64;
467 z[0]&=248;
468 unpack25519(x,p);
469 for(i=0; i<16; ++i) {
470 b[i]=x[i];
471 d[i]=a[i]=c[i]=0;
472 }
473 a[0]=d[0]=1;
474 for(i=254;i>=0;--i) {
475 r=(z[i>>3]>>(i&7))&1;
476 sel25519(a,b,r);
477 sel25519(c,d,r);
478 A(e,a,c);
479 Z(a,a,c);
480 A(c,b,d);
481 Z(b,b,d);
482 S(d,e);
483 S(f,a);
484 M(a,c,a);
485 M(c,b,e);
486 A(e,a,c);
487 Z(a,a,c);
488 S(b,a);
489 Z(c,d,f);
490 M(a,c,_121665);
491 A(a,a,d);
492 M(c,c,a);
493 M(a,d,f);
494 M(d,b,x);
495 S(b,e);
496 sel25519(a,b,r);
497 sel25519(c,d,r);
498 }
499 for(i=0; i<16; ++i) {
500 x[i+16]=a[i];
501 x[i+32]=c[i];
502 x[i+48]=b[i];
503 x[i+64]=d[i];
504 }
505 inv25519(x+32,x+32);
506 M(x+16,x+16,x+32);
507 pack25519(q,x+16);
508 return 0;
509}
510
511int crypto_scalarmult_base(byte *q,const byte *n)
512{
513 return crypto_scalarmult(q,n,_9);
514}
515
516int crypto_box_keypair(byte *y,byte *x)
517{
518 randombytes(x,32);
519 return crypto_scalarmult_base(y,x);
520}
521
522// Avoid small order elements. Also see https://eprint.iacr.org/2017/806.pdf
523// and https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4.
524int crypto_box_beforenm(byte *k,const byte *y,const byte *x)
525{
526 byte s[32];
527 if(crypto_scalarmult(s,x,y) != 0) return -1;
528 if(has_small_order(s) != 0) return -1;
529 return crypto_core_hsalsa20(k,_0,s,sigma);
530}
531
532// Allow small order elements. Also see https://eprint.iacr.org/2017/806.pdf
533int crypto_box_beforenm_unchecked(byte *k,const byte *y,const byte *x)
534{
535 byte s[32];
536 if(crypto_scalarmult(s,x,y) != 0) return -1;
537 return crypto_core_hsalsa20(k,_0,s,sigma);
538}
539
540int crypto_box_afternm(byte *c,const byte *m,word64 d,const byte *n,const byte *k)
541{
542 return crypto_secretbox(c,m,d,n,k);
543}
544
545int crypto_box_open_afternm(byte *m,const byte *c,word64 d,const byte *n,const byte *k)
546{
547 return crypto_secretbox_open(m,c,d,n,k);
548}
549
550int crypto_box(byte *c, const byte *m, word64 d, const byte *n, const byte *y, const byte *x)
551{
552 byte k[32];
553 if (crypto_box_beforenm(k, y, x) != 0) return -1;
554 return crypto_box_afternm(c, m, d, n, k);
555}
556
557int crypto_box_unchecked(byte *c, const byte *m, word64 d, const byte *n, const byte *y, const byte *x)
558{
559 byte k[32];
561 return crypto_box_afternm(c, m, d, n, k);
562}
563
564int crypto_box_open(byte *m,const byte *c,word64 d,const byte *n,const byte *y,const byte *x)
565{
566 byte k[32];
567 if(crypto_box_beforenm(k,y,x) != 0) return -1;
568 return crypto_box_open_afternm(m,c,d,n,k);
569}
570
571int crypto_box_open_unchecked(byte *m,const byte *c,word64 d,const byte *n,const byte *y,const byte *x)
572{
573 byte k[32];
575 return crypto_box_open_afternm(m,c,d,n,k);
576}
577
578static word64 R(word64 x,int c) { return (x >> c) | (x << (64 - c)); }
579static word64 Ch(word64 x,word64 y,word64 z) { return (x & y) ^ (~x & z); }
580static word64 Maj(word64 x,word64 y,word64 z) { return (x & y) ^ (x & z) ^ (y & z); }
581static word64 Sigma0(word64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
582static word64 Sigma1(word64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
583static word64 sigma0(word64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
584static word64 sigma1(word64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
585
586static const word64 K[80] =
587{
588 W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
589 W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
590 W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
591 W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
592 W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
593 W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
594 W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
595 W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
596 W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
597 W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
598 W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
599 W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
600 W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
601 W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
602 W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
603 W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
604 W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
605 W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
606 W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
607 W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
608};
609
610int crypto_hashblocks(byte *x,const byte *m,word64 n)
611{
612 word64 z[8],b[8],a[8],w[16],t;
613 int i,j;
614
615 for(i=0; i<8; ++i) z[i] = a[i] = dl64(x + 8 * i);
616
617 while (n >= 128) {
618 for(i=0; i<16; ++i) w[i] = dl64(m + 8 * i);
619
620 for(i=0; i<80; ++i) {
621 for(j=0; j<8; ++j) b[j] = a[j];
622 t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
623 b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
624 b[3] += t;
625 for(j=0; j<8; ++j) a[(j+1)%8] = b[j];
626 if (i%16 == 15)
627 for(j=0; j<16; ++j)
628 w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
629 }
630
631 for(i=0; i<8; ++i) { a[i] += z[i]; z[i] = a[i]; }
632
633 m += 128;
634 n -= 128;
635 }
636
637 for(i=0; i<8; ++i) ts64(x+8*i,z[i]);
638
639 return n;
640}
641
642static const byte iv[64] = {
643 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
644 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
645 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
646 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
647 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
648 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
649 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
650 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
651} ;
652
653int crypto_hash(byte *out,const byte *m,word64 n)
654{
655 byte h[64],x[256];
656 word64 i,b = n;
657
658 for(i=0; i<64; ++i) h[i] = iv[i];
659
660 crypto_hashblocks(h,m,n);
661 m += n;
662 n &= 127;
663 m -= n;
664
665 for(i=0; i<256; ++i) x[i] = 0;
666 for(i=0; i<n; ++i) x[i] = m[i];
667 x[n] = 128;
668
669 n = 256-128*(n<112);
670 x[n-9] = b >> 61;
671 ts64(x+n-8,b<<3);
672 crypto_hashblocks(h,x,n);
673
674 for(i=0; i<64; ++i) out[i] = h[i];
675
676 return 0;
677}
678
679static void add(gf p[4],gf q[4])
680{
681 gf a,b,c,d,t,e,f,g,h;
682
683 Z(a, p[1], p[0]);
684 Z(t, q[1], q[0]);
685 M(a, a, t);
686 A(b, p[0], p[1]);
687 A(t, q[0], q[1]);
688 M(b, b, t);
689 M(c, p[3], q[3]);
690 M(c, c, D2);
691 M(d, p[2], q[2]);
692 A(d, d, d);
693 Z(e, b, a);
694 Z(f, d, c);
695 A(g, d, c);
696 A(h, b, a);
697
698 M(p[0], e, f);
699 M(p[1], h, g);
700 M(p[2], g, f);
701 M(p[3], e, h);
702}
703
704static void cswap(gf p[4],gf q[4],byte b)
705{
706 int i;
707 for(i=0; i<4; ++i)
708 sel25519(p[i],q[i],b);
709}
710
711static void pack(byte *r,gf p[4])
712{
713 gf tx, ty, zi;
714 inv25519(zi, p[2]);
715 M(tx, p[0], zi);
716 M(ty, p[1], zi);
717 pack25519(r, ty);
718 r[31] ^= par25519(tx) << 7;
719}
720
721static void scalarmult(gf p[4],gf q[4],const byte *s)
722{
723 int i;
724 set25519(p[0],gf0);
725 set25519(p[1],gf1);
726 set25519(p[2],gf1);
727 set25519(p[3],gf0);
728 for (i = 255;i >= 0;--i) {
729 byte b = (s[i/8]>>(i&7))&1;
730 cswap(p,q,b);
731 add(q,p);
732 add(p,p);
733 cswap(p,q,b);
734 }
735}
736
737static void scalarbase(gf p[4],const byte *s)
738{
739 gf q[4];
740 set25519(q[0],X);
741 set25519(q[1],Y);
742 set25519(q[2],gf1);
743 M(q[3],X,Y);
744 scalarmult(p,q,s);
745}
746
747int crypto_sign_keypair(byte *pk, byte *sk)
748{
749 byte d[64];
750 gf p[4];
751 int i;
752
753 randombytes(sk, 32);
754 crypto_hash(d, sk, 32);
755 d[0] &= 248;
756 d[31] &= 127;
757 d[31] |= 64;
758
759 scalarbase(p,d);
760 pack(pk,p);
761
762 for(i=0; i<32; ++i) sk[32 + i] = pk[i];
763 return 0;
764}
765
766int crypto_sign_sk2pk(byte *pk, const byte *sk)
767{
768 byte d[64];
769 gf p[4];
770 // int i;
771
772 // randombytes(sk, 32);
773 crypto_hash(d, sk, 32);
774 d[0] &= 248;
775 d[31] &= 127;
776 d[31] |= 64;
777
778 scalarbase(p,d);
779 pack(pk,p);
780
781 // for(i=0; i<32; ++i) sk[32 + i] = pk[i];
782 return 0;
783}
784
785static const word64 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};
786
787static void modL(byte *r,sword64 x[64])
788{
789 sword64 carry,i,j;
790 for (i = 63;i >= 32;--i) {
791 carry = 0;
792 for (j = i - 32;j < i - 12;++j) {
793 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
794 carry = (x[j] + 128) >> 8;
795 x[j] -= ((word64)carry) << 8;
796 }
797 x[j] += carry;
798 x[i] = 0;
799 }
800 carry = 0;
801 for(j=0; j<32; ++j) {
802 x[j] += carry - (x[31] >> 4) * L[j];
803 carry = x[j] >> 8;
804 x[j] &= 255;
805 }
806 for(j=0; j<32; ++j) x[j] -= carry * L[j];
807 for(i=0; i<32; ++i) {
808 x[i+1] += x[i] >> 8;
809 r[i] = x[i] & 255;
810 }
811}
812
813static void reduce(byte *r)
814{
815 sword64 x[64],i;
816 for(i=0; i<64; ++i) x[i] = (word64) r[i];
817 for(i=0; i<64; ++i) r[i] = 0;
818 modL(r,x);
819}
820
821int crypto_sign(byte *sm,word64 *smlen,const byte *m,word64 n,const byte *sk)
822{
823 byte d[64],h[64],r[64];
824 word64 i; sword64 j,x[64];
825 gf p[4];
826
827 crypto_hash(d, sk, 32);
828 d[0] &= 248;
829 d[31] &= 127;
830 d[31] |= 64;
831
832 *smlen = n+64;
833 for(i=0; i<n; ++i) sm[64 + i] = m[i];
834 for(i=0; i<32; ++i) sm[32 + i] = d[32 + i];
835
836 crypto_hash(r, sm+32, n+32);
837 reduce(r);
838 scalarbase(p,r);
839 pack(sm,p);
840
841 for(i=0; i<32; ++i) sm[i+32] = sk[i+32];
842 crypto_hash(h,sm,n + 64);
843 reduce(h);
844
845 for(i=0; i<64; ++i) x[i] = 0;
846 for(i=0; i<32; ++i) x[i] = (word64) r[i];
847 for(i=0; i<32; ++i) for(j=0; j<32; ++j) x[i+j] += h[i] * (word64) d[j];
848 modL(sm + 32,x);
849
850 return 0;
851}
852
853static int unpackneg(gf r[4],const byte p[32])
854{
855 gf t, chk, num, den, den2, den4, den6;
856 set25519(r[2],gf1);
857 unpack25519(r[1],p);
858 S(num,r[1]);
859 M(den,num,D);
860 Z(num,num,r[2]);
861 A(den,r[2],den);
862
863 S(den2,den);
864 S(den4,den2);
865 M(den6,den4,den2);
866 M(t,den6,num);
867 M(t,t,den);
868
869 pow2523(t,t);
870 M(t,t,num);
871 M(t,t,den);
872 M(t,t,den);
873 M(r[0],t,den);
874
875 S(chk,r[0]);
876 M(chk,chk,den);
877 if (neq25519(chk, num)) M(r[0],r[0],I);
878
879 S(chk,r[0]);
880 M(chk,chk,den);
881 if (neq25519(chk, num)) return -1;
882
883 if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
884
885 M(r[3],r[0],r[1]);
886 return 0;
887}
888
889int crypto_sign_open(byte *m,word64 *mlen,const byte *sm,word64 n,const byte *pk)
890{
891 word32 i;
892 byte t[32],h[64];
893 gf p[4],q[4];
894
895 *mlen = ~W64LIT(0);
896 if (n < 64) return -1;
897
898 if (unpackneg(q,pk)) return -1;
899
900 for(i=0; i<n; ++i) m[i] = sm[i];
901 for(i=0; i<32; ++i) m[i+32] = pk[i];
902 crypto_hash(h,m,n);
903 reduce(h);
904 scalarmult(p,q,h);
905
906 scalarbase(q,sm + 32);
907 add(p,q);
908 pack(t,p);
909
910 n -= 64;
911 if (crypto_verify_32(sm, t)) {
912 for(i=0; i<n; ++i) m[i] = 0;
913 return -1;
914 }
915
916 for(i=0; i<n; ++i) m[i] = sm[i + 64];
917 *mlen = n;
918 return 0;
919}
920
921NAMESPACE_END // CryptoPP
922NAMESPACE_END // NaCl
923
924#endif // NO_OS_DEPENDENCE
A typedef providing a default generator.
Definition: osrng.h:290
Library configuration file.
signed long long sword64
64-bit signed datatype
Definition: config_int.h:99
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:119
signed int sword32
32-bit signed datatype
Definition: config_int.h:81
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
Utility functions for the Crypto++ library.
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:191
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:151
Crypto++ interface to TweetNaCl library (20140917)
int crypto_stream(byte *c, word64 d, const byte *n, const byte *k)
Produce a keystream using XSalsa20.
Definition: tweetnacl.cpp:188
int crypto_stream_salsa20_xor(byte *c, const byte *m, word64 b, const byte *n, const byte *k)
Encrypt a message using Salsa20.
Definition: tweetnacl.cpp:156
int crypto_box_beforenm(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:524
int crypto_box_afternm(byte *c, const byte *m, word64 d, const byte *n, const byte *k)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:540
int crypto_secretbox_open(byte *m, const byte *c, word64 d, const byte *n, const byte *k)
Verify and decrypt a message.
Definition: tweetnacl.cpp:286
int crypto_core_salsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:142
int crypto_verify_32(const byte *x, const byte *y)
Compare 32-byte buffers.
Definition: tweetnacl.cpp:97
int crypto_box_beforenm_unchecked(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:533
int crypto_stream_xor(byte *c, const byte *m, word64 d, const byte *n, const byte *k)
Encrypt a message using XSalsa20.
Definition: tweetnacl.cpp:195
int crypto_core_hsalsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:148
int crypto_box_open(byte *m, const byte *c, word64 d, const byte *n, const byte *y, const byte *x)
Verify and decrypt a message.
Definition: tweetnacl.cpp:564
int crypto_onetimeauth(byte *out, const byte *m, word64 n, const byte *k)
Create an authentication tag for a message.
Definition: tweetnacl.cpp:216
int crypto_box_unchecked(byte *c, const byte *m, word64 d, const byte *n, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:557
int crypto_sign_open(byte *m, word64 *mlen, const byte *sm, word64 n, const byte *pk)
Verify a message.
Definition: tweetnacl.cpp:889
int crypto_scalarmult_base(byte *q, const byte *n)
Scalar multiplication of base point.
Definition: tweetnacl.cpp:511
int crypto_hashblocks(byte *x, const byte *m, word64 n)
Hash multiple blocks.
Definition: tweetnacl.cpp:610
int crypto_stream_salsa20(byte *c, word64 d, const byte *n, const byte *k)
Produce a keystream using Salsa20.
Definition: tweetnacl.cpp:183
int crypto_box_open_unchecked(byte *m, const byte *c, word64 d, const byte *n, const byte *y, const byte *x)
Verify and decrypt a message.
Definition: tweetnacl.cpp:571
int crypto_scalarmult(byte *q, const byte *n, const byte *p)
Scalar multiplication of a point.
Definition: tweetnacl.cpp:460
int crypto_hash(byte *out, const byte *m, word64 n)
Hash a message.
Definition: tweetnacl.cpp:653
int crypto_box(byte *c, const byte *m, word64 d, const byte *n, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:550
int crypto_onetimeauth_verify(const byte *h, const byte *m, word64 n, const byte *k)
Verify an authentication tag on a message.
Definition: tweetnacl.cpp:269
int crypto_box_open_afternm(byte *m, const byte *c, word64 d, const byte *n, const byte *k)
Verify and decrypt a message.
Definition: tweetnacl.cpp:545
int crypto_sign_sk2pk(byte *pk, const byte *sk)
Calculate a public key from a secret key.
Definition: tweetnacl.cpp:766
int crypto_box_keypair(byte *y, byte *x)
Generate a keypair for encryption.
Definition: tweetnacl.cpp:516
int crypto_secretbox(byte *c, const byte *m, word64 d, const byte *n, const byte *k)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:276
int crypto_sign_keypair(byte *pk, byte *sk)
Generate a keypair for signing.
Definition: tweetnacl.cpp:747
int crypto_verify_16(const byte *x, const byte *y)
Compare 16-byte buffers.
Definition: tweetnacl.cpp:92
int crypto_sign(byte *sm, word64 *smlen, const byte *m, word64 n, const byte *sk)
Sign a message.
Definition: tweetnacl.cpp:821
Crypto++ library namespace.
Namespace containing NaCl library functions.
Definition: cryptlib.h:568
Classes for access to the operating system's random number generators.
Precompiled header file.
Common C++ header files.