Crypto++  7.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 {
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];
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];
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 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};
759 
760 static void modL(byte *r,sword64 x[64])
761 {
762  sword64 carry,i,j;
763  for (i = 63;i >= 32;--i) {
764  carry = 0;
765  for (j = i - 32;j < i - 12;++j) {
766  x[j] += carry - 16 * x[i] * L[j - (i - 32)];
767  carry = (x[j] + 128) >> 8;
768  x[j] -= ((word64)carry) << 8;
769  }
770  x[j] += carry;
771  x[i] = 0;
772  }
773  carry = 0;
774  for(j=0; j<32; ++j) {
775  x[j] += carry - (x[31] >> 4) * L[j];
776  carry = x[j] >> 8;
777  x[j] &= 255;
778  }
779  for(j=0; j<32; ++j) x[j] -= carry * L[j];
780  for(i=0; i<32; ++i) {
781  x[i+1] += x[i] >> 8;
782  r[i] = x[i] & 255;
783  }
784 }
785 
786 static void reduce(byte *r)
787 {
788  sword64 x[64],i;
789  for(i=0; i<64; ++i) x[i] = (word64) r[i];
790  for(i=0; i<64; ++i) r[i] = 0;
791  modL(r,x);
792 }
793 
794 int crypto_sign(byte *sm,word64 *smlen,const byte *m,word64 n,const byte *sk)
795 {
796  byte d[64],h[64],r[64];
797  word64 i; sword64 j,x[64];
798  gf p[4];
799 
800  crypto_hash(d, sk, 32);
801  d[0] &= 248;
802  d[31] &= 127;
803  d[31] |= 64;
804 
805  *smlen = n+64;
806  for(i=0; i<n; ++i) sm[64 + i] = m[i];
807  for(i=0; i<32; ++i) sm[32 + i] = d[32 + i];
808 
809  crypto_hash(r, sm+32, n+32);
810  reduce(r);
811  scalarbase(p,r);
812  pack(sm,p);
813 
814  for(i=0; i<32; ++i) sm[i+32] = sk[i+32];
815  crypto_hash(h,sm,n + 64);
816  reduce(h);
817 
818  for(i=0; i<64; ++i) x[i] = 0;
819  for(i=0; i<32; ++i) x[i] = (word64) r[i];
820  for(i=0; i<32; ++i) for(j=0; j<32; ++j) x[i+j] += h[i] * (word64) d[j];
821  modL(sm + 32,x);
822 
823  return 0;
824 }
825 
826 static int unpackneg(gf r[4],const byte p[32])
827 {
828  gf t, chk, num, den, den2, den4, den6;
829  set25519(r[2],gf1);
830  unpack25519(r[1],p);
831  S(num,r[1]);
832  M(den,num,D);
833  Z(num,num,r[2]);
834  A(den,r[2],den);
835 
836  S(den2,den);
837  S(den4,den2);
838  M(den6,den4,den2);
839  M(t,den6,num);
840  M(t,t,den);
841 
842  pow2523(t,t);
843  M(t,t,num);
844  M(t,t,den);
845  M(t,t,den);
846  M(r[0],t,den);
847 
848  S(chk,r[0]);
849  M(chk,chk,den);
850  if (neq25519(chk, num)) M(r[0],r[0],I);
851 
852  S(chk,r[0]);
853  M(chk,chk,den);
854  if (neq25519(chk, num)) return -1;
855 
856  if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
857 
858  M(r[3],r[0],r[1]);
859  return 0;
860 }
861 
862 int crypto_sign_open(byte *m,word64 *mlen,const byte *sm,word64 n,const byte *pk)
863 {
864  word32 i;
865  byte t[32],h[64];
866  gf p[4],q[4];
867 
868  *mlen = -1;
869  if (n < 64) return -1;
870 
871  if (unpackneg(q,pk)) return -1;
872 
873  for(i=0; i<n; ++i) m[i] = sm[i];
874  for(i=0; i<32; ++i) m[i+32] = pk[i];
875  crypto_hash(h,m,n);
876  reduce(h);
877  scalarmult(p,q,h);
878 
879  scalarbase(q,sm + 32);
880  add(p,q);
881  pack(t,p);
882 
883  n -= 64;
884  if (crypto_verify_32(sm, t)) {
885  for(i=0; i<n; ++i) m[i] = 0;
886  return -1;
887  }
888 
889  for(i=0; i<n; ++i) m[i] = sm[i + 64];
890  *mlen = n;
891  return 0;
892 }
893 
894 NAMESPACE_END // CryptoPP
895 NAMESPACE_END // NaCl
896 
897 #endif // NO_OS_DEPENDENCE
898 
899 
900 
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
int crypto_box_keypair(byte *y, byte *x)
Generate a keypair for encryption.
Definition: tweetnacl.cpp:508
Namespace containing NaCl library functions.
Definition: cryptlib.h:543
Utility functions for the Crypto++ library.
int crypto_hash(byte *out, const byte *m, word64 n)
Hash a message.
Definition: tweetnacl.cpp:645
int crypto_box_beforenm_unchecked(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:525
int crypto_hashblocks(byte *x, const byte *m, word64 n)
Hash multiple blocks.
Definition: tweetnacl.cpp:602
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
int crypto_core_salsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:134
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
Library configuration file.
Common C++ header files.
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
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
int crypto_sign_open(byte *m, word64 *mlen, const byte *sm, word64 n, const byte *pk)
Verify a message.
Definition: tweetnacl.cpp:862
int crypto_sign(byte *sm, word64 *smlen, const byte *m, word64 n, const byte *sk)
Sign a message.
Definition: tweetnacl.cpp:794
int crypto_sign_keypair(byte *pk, byte *sk)
Generate a keypair for signing.
Definition: tweetnacl.cpp:739
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
int crypto_onetimeauth(byte *out, const byte *m, word64 n, const byte *k)
Create an authentication tag for a message.
Definition: tweetnacl.cpp:208
int crypto_verify_16(const byte *x, const byte *y)
Compare 16-byte buffers.
Definition: tweetnacl.cpp:84
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:144
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
Precompiled header file.
int crypto_verify_32(const byte *x, const byte *y)
Compare 32-byte buffers.
Definition: tweetnacl.cpp:89
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:181
int crypto_stream(byte *c, word64 d, const byte *n, const byte *k)
Produce a keystream using XSalsa20.
Definition: tweetnacl.cpp:180
Crypto++ interface to TweetNaCl library (20140917)
int crypto_core_hsalsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:140
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
int crypto_scalarmult_base(byte *q, const byte *n)
Scalar multiplication of base point.
Definition: tweetnacl.cpp:503
Crypto++ library namespace.
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
int crypto_scalarmult(byte *q, const byte *n, const byte *p)
Scalar multiplication of a point.
Definition: tweetnacl.cpp:452
int crypto_box_beforenm(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
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:268
int crypto_stream_salsa20(byte *c, word64 d, const byte *n, const byte *k)
Produce a keystream using Salsa20.
Definition: tweetnacl.cpp:175
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
Classes for access to the operating system&#39;s random number generators.
A typedef providing a default generator.
Definition: osrng.h:263