Crypto++  8.2
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 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
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:540
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:881
int crypto_sign(byte *sm, word64 *smlen, const byte *m, word64 n, const byte *sk)
Sign a message.
Definition: tweetnacl.cpp:813
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:116
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:153
int crypto_sign_sk2pk(byte *pk, const byte *sk)
Calculate a public key from a secret key.
Definition: tweetnacl.cpp:758
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:273