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