Crypto++ 8.4 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
28 NAMESPACE_BEGIN(CryptoPP)
29 NAMESPACE_BEGIN(NaCl)
30
31 typedef sword64 gf[16];
32
33 static const byte
34 _0[32] = {0},
35 _9[32] = {9};
36
37 static 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
48 static void randombytes(byte * block, word64 size)
49 {
50 DefaultAutoSeededRNG prng;
51 prng.GenerateBlock(block, (size_t)size);
52 }
53
54 static word32 L32(word32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
55
56 static 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
64 static 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
71 static void st32(byte *x,word32 u)
72 {
73 int i;
74 for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
75 }
76
77 static 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
84 static 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
92 int crypto_verify_16(const byte *x,const byte *y)
93 {
94 return verify_n(x,y,16);
95 }
96
97 int crypto_verify_32(const byte *x,const byte *y)
98 {
99 return verify_n(x,y,32);
100 }
101
102 static 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
142 int 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
148 int 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
154 static const byte sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B};
155
156 int 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
183 int 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
188 int 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
195 int 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
202 static 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
212 static const word32 minusp[17] = {
213 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
214 } ;
215
216 int 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
269 int 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
276 int 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
286 int 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
298 static void set25519(gf r, const gf a)
299 {
300 int i;
301 for(i=0; i<16; ++i) r[i]=a[i];
302 }
303
304 static 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
316 static 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
326 static 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
351 static 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
359 static byte par25519(const gf a)
360 {
361 byte d[32];
362 pack25519(d,a);
363 return d[0]&1;
364 }
365
366 static 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
373 static 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
379 static 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
385 static 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
396 static void S(gf o,const gf a)
397 {
398 M(o,a,a);
399 }
400
401 static 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
413 static 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
426 static 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
460 int 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
511 int crypto_scalarmult_base(byte *q,const byte *n)
512 {
513 return crypto_scalarmult(q,n,_9);
514 }
515
516 int 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.
524 int 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
533 int 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
540 int 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
545 int 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
550 int 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
557 int crypto_box_unchecked(byte *c, const byte *m, word64 d, const byte *n, const byte *y, const byte *x)
558 {
559 byte k[32];
560 crypto_box_beforenm_unchecked(k, y, x);
561 return crypto_box_afternm(c, m, d, n, k);
562 }
563
564 int 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
571 int 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];
574 crypto_box_beforenm_unchecked(k,y,x);
575 return crypto_box_open_afternm(m,c,d,n,k);
576 }
577
578 static word64 R(word64 x,int c) { return (x >> c) | (x << (64 - c)); }
579 static word64 Ch(word64 x,word64 y,word64 z) { return (x & y) ^ (~x & z); }
580 static word64 Maj(word64 x,word64 y,word64 z) { return (x & y) ^ (x & z) ^ (y & z); }
581 static word64 Sigma0(word64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
582 static word64 Sigma1(word64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
583 static word64 sigma0(word64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
584 static word64 sigma1(word64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
585
586 static 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
610 int 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
642 static 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
653 int 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
679 static 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
704 static 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
711 static 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
721 static 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
737 static 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
747 int 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
766 int 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
785 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};
786
787 static 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
813 static 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
821 int 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
853 static 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
889 int 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
921 NAMESPACE_END // CryptoPP
922 NAMESPACE_END // NaCl
923
924 #endif // NO_OS_DEPENDENCE
crypto_box_keypair
int crypto_box_keypair(byte *y, byte *x)
Generate a keypair for encryption.
Definition: tweetnacl.cpp:516
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:564
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:276
W64LIT
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:119
crypto_hashblocks
int crypto_hashblocks(byte *x, const byte *m, word64 n)
Hash multiple blocks.
Definition: tweetnacl.cpp:610
naclite.h
Crypto++ interface to TweetNaCl library (20140917)
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:533
crypto_hash
int crypto_hash(byte *out, const byte *m, word64 n)
Hash a message.
Definition: tweetnacl.cpp:653
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:156
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:571
DefaultAutoSeededRNG
A typedef providing a default generator.
Definition: osrng.h:290
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:540
word64
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
pch.h
Precompiled header file.
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:545
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:889
COUNTOF
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:189
CRYPTOPP_COMPILE_ASSERT
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:149
crypto_core_salsa20
int crypto_core_salsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:142
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
crypto_sign
int crypto_sign(byte *sm, word64 *smlen, const byte *m, word64 n, const byte *sk)
Sign a message.
Definition: tweetnacl.cpp:821
crypto_sign_keypair
int crypto_sign_keypair(byte *pk, byte *sk)
Generate a keypair for signing.
Definition: tweetnacl.cpp:747
crypto_verify_16
int crypto_verify_16(const byte *x, const byte *y)
Compare 16-byte buffers.
Definition: tweetnacl.cpp:92
misc.h
Utility functions for the Crypto++ library.
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:216
NaCl
Namespace containing NaCl library functions.
Definition: cryptlib.h:568
crypto_core_hsalsa20
int crypto_core_hsalsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:148
stdcpp.h
Common C++ header files.
crypto_scalarmult_base
int crypto_scalarmult_base(byte *q, const byte *n)
Scalar multiplication of base point.
Definition: tweetnacl.cpp:511
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:286
crypto_scalarmult
int crypto_scalarmult(byte *q, const byte *n, const byte *p)
Scalar multiplication of a point.
Definition: tweetnacl.cpp:460
crypto_stream
int crypto_stream(byte *c, word64 d, const byte *n, const byte *k)
Produce a keystream using XSalsa20.
Definition: tweetnacl.cpp:188
crypto_verify_32
int crypto_verify_32(const byte *x, const byte *y)
Compare 32-byte buffers.
Definition: tweetnacl.cpp:97
sword32
signed int sword32
32-bit signed datatype
Definition: config_int.h:81
crypto_sign_sk2pk
int crypto_sign_sk2pk(byte *pk, const byte *sk)
Calculate a public key from a secret key.
Definition: tweetnacl.cpp:766
CryptoPP
Crypto++ library namespace.
sword64
signed long long sword64
64-bit signed datatype
Definition: config_int.h:99
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:269
crypto_box_beforenm
int crypto_box_beforenm(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:524
osrng.h
Classes for access to the operating system's random number generators.
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:183
config.h
Library configuration file.
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:557
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:195
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:550