Crypto++  6.1
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 int64_t gf[16];
24 
25 static const uint8_t
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(uint8_t * block, uint64_t size)
41 {
43  prng.GenerateBlock(block, (size_t)size);
44 }
45 
46 static uint32_t L32(uint32_t x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
47 
48 static uint32_t ld32(const uint8_t *x)
49 {
50  uint32_t 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 uint64_t dl64(const uint8_t *x)
57 {
58  uint64_t i,u=0;
59  for(i=0; i<8; ++i) u=(u<<8)|x[i];
60  return u;
61 }
62 
63 static void st32(uint8_t *x,uint32_t u)
64 {
65  int i;
66  for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
67 }
68 
69 static void ts64(uint8_t *x,uint64_t 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 uint8_t *x,const uint8_t *y,uint32_t n)
77 {
78  uint32_t i,d = 0;
79  for(i=0; i<n; ++i) d |= x[i]^y[i];
80  const int32_t v = (int32_t) d;
81  return (1 & ((uint32_t)(v - 1) >> 8)) - 1;
82 }
83 
84 int crypto_verify_16(const uint8_t *x,const uint8_t *y)
85 {
86  return verify_n(x,y,16);
87 }
88 
89 int crypto_verify_32(const uint8_t *x,const uint8_t *y)
90 {
91  return verify_n(x,y,32);
92 }
93 
94 static void core(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c,int h)
95 {
96  uint32_t 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(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c)
135 {
136  core(out,in,k,c,0);
137  return 0;
138 }
139 
140 int crypto_core_hsalsa20(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c)
141 {
142  core(out,in,k,c,1);
143  return 0;
144 }
145 
146 static const uint8_t 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(uint8_t *c,const uint8_t *m,uint64_t b,const uint8_t *n,const uint8_t *k)
149 {
150  uint8_t z[16],x[64];
151  uint32_t 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 += (uint32_t) 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(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
176 {
177  return crypto_stream_salsa20_xor(c,0,d,n,k);
178 }
179 
180 int crypto_stream(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
181 {
182  uint8_t 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(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k)
188 {
189  uint8_t 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(uint32_t *h,const uint32_t *c)
195 {
196  uint32_t 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 uint32_t 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(uint8_t *out,const uint8_t *m,uint64_t n,const uint8_t *k)
209 {
210  uint32_t 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 uint8_t *h,const uint8_t *m,uint64_t n,const uint8_t *k)
262 {
263  uint8_t x[16];
264  crypto_onetimeauth(x,m,n,k);
265  return crypto_verify_16(h,x);
266 }
267 
268 int crypto_secretbox(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *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(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
279 {
280  int i;
281  uint8_t 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  int64_t 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]-=((uint64_t)c)<<16;
305  }
306 }
307 
308 static void sel25519(gf p,gf q,int b)
309 {
310  int64_t 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(uint8_t *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  uint8_t c[32],d[32];
346  pack25519(c,a);
347  pack25519(d,b);
348  return crypto_verify_32(c,d);
349 }
350 
351 static uint8_t par25519(const gf a)
352 {
353  uint8_t d[32];
354  pack25519(d,a);
355  return d[0]&1;
356 }
357 
358 static void unpack25519(gf o, const uint8_t *n)
359 {
360  int i;
361  for(i=0; i<16; ++i) o[i]=n[2*i]+((int64_t)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  int64_t 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 uint8_t s[32])
419 {
420  CRYPTOPP_ALIGN_DATA(16)
421  const uint8_t 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  uint8_t 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(uint8_t *q,const uint8_t *n,const uint8_t *p)
453 {
454  uint8_t z[32];
455  int64_t 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(uint8_t *q,const uint8_t *n)
504 {
505  return crypto_scalarmult(q,n,_9);
506 }
507 
508 int crypto_box_keypair(uint8_t *y,uint8_t *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(uint8_t *k,const uint8_t *y,const uint8_t *x)
517 {
518  uint8_t 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(uint8_t *k,const uint8_t *y,const uint8_t *x)
526 {
527  uint8_t 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(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k)
533 {
534  return crypto_secretbox(c,m,d,n,k);
535 }
536 
537 int crypto_box_open_afternm(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
538 {
539  return crypto_secretbox_open(m,c,d,n,k);
540 }
541 
542 int crypto_box(uint8_t *c, const uint8_t *m, uint64_t d, const uint8_t *n, const uint8_t *y, const uint8_t *x)
543 {
544  uint8_t 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(uint8_t *c, const uint8_t *m, uint64_t d, const uint8_t *n, const uint8_t *y, const uint8_t *x)
550 {
551  uint8_t k[32];
553  return crypto_box_afternm(c, m, d, n, k);
554 }
555 
556 int crypto_box_open(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x)
557 {
558  uint8_t 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(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x)
564 {
565  uint8_t k[32];
567  return crypto_box_open_afternm(m,c,d,n,k);
568 }
569 
570 static uint64_t R(uint64_t x,int c) { return (x >> c) | (x << (64 - c)); }
571 static uint64_t Ch(uint64_t x,uint64_t y,uint64_t z) { return (x & y) ^ (~x & z); }
572 static uint64_t Maj(uint64_t x,uint64_t y,uint64_t z) { return (x & y) ^ (x & z) ^ (y & z); }
573 static uint64_t Sigma0(uint64_t x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
574 static uint64_t Sigma1(uint64_t x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
575 static uint64_t sigma0(uint64_t x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
576 static uint64_t sigma1(uint64_t x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
577 
578 static const uint64_t 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(uint8_t *x,const uint8_t *m,uint64_t n)
603 {
604  uint64_t 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 uint8_t 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(uint8_t *out,const uint8_t *m,uint64_t n)
646 {
647  uint8_t h[64],x[256];
648  uint64_t 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],uint8_t 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(uint8_t *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 uint8_t *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  uint8_t 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 uint8_t *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(uint8_t *pk, uint8_t *sk)
740 {
741  uint8_t 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 uint64_t 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(uint8_t *r,int64_t x[64])
761 {
762  int64_t 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] -= ((uint64_t)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(uint8_t *r)
787 {
788  int64_t x[64],i;
789  for(i=0; i<64; ++i) x[i] = (uint64_t) r[i];
790  for(i=0; i<64; ++i) r[i] = 0;
791  modL(r,x);
792 }
793 
794 int crypto_sign(uint8_t *sm,uint64_t *smlen,const uint8_t *m,uint64_t n,const uint8_t *sk)
795 {
796  uint8_t d[64],h[64],r[64];
797  uint64_t i; int64_t 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] = (uint64_t) r[i];
820  for(i=0; i<32; ++i) for(j=0; j<32; ++j) x[i+j] += h[i] * (uint64_t) d[j];
821  modL(sm + 32,x);
822 
823  return 0;
824 }
825 
826 static int unpackneg(gf r[4],const uint8_t 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(uint8_t *m,uint64_t *mlen,const uint8_t *sm,uint64_t n,const uint8_t *pk)
863 {
864  uint32_t i;
865  uint8_t 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 
Namespace containing NaCl library functions.
Definition: cryptlib.h:544
Utility functions for the Crypto++ library.
int crypto_onetimeauth_verify(const uint8_t *h, const uint8_t *m, uint64_t n, const uint8_t *k)
Verify an authentication tag on a message.
Definition: tweetnacl.cpp:261
int crypto_sign_open(uint8_t *m, uint64_t *mlen, const uint8_t *sm, uint64_t n, const uint8_t *pk)
Verify a message.
Definition: tweetnacl.cpp:862
int crypto_box_keypair(uint8_t *y, uint8_t *x)
Generate a keypair for encryption.
Definition: tweetnacl.cpp:508
int crypto_sign(uint8_t *sm, uint64_t *smlen, const uint8_t *m, uint64_t n, const uint8_t *sk)
Sign a message.
Definition: tweetnacl.cpp:794
int crypto_box_afternm(uint8_t *c, const uint8_t *m, uint64_t d, const uint8_t *n, const uint8_t *k)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:532
int crypto_hash(uint8_t *out, const uint8_t *m, uint64_t n)
Hash a message.
Definition: tweetnacl.cpp:645
Library configuration file.
int crypto_stream_xor(uint8_t *c, const uint8_t *m, uint64_t d, const uint8_t *n, const uint8_t *k)
Encrypt a message using XSalsa20.
Definition: tweetnacl.cpp:187
Common C++ header files.
int crypto_verify_16(const uint8_t *x, const uint8_t *y)
Compare 16-byte buffers.
Definition: tweetnacl.cpp:84
int crypto_stream(uint8_t *c, uint64_t d, const uint8_t *n, const uint8_t *k)
Produce a keystream using XSalsa20.
Definition: tweetnacl.cpp:180
int crypto_box_beforenm(uint8_t *k, const uint8_t *y, const uint8_t *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:516
int crypto_box(uint8_t *c, const uint8_t *m, uint64_t d, const uint8_t *n, const uint8_t *y, const uint8_t *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:542
int crypto_scalarmult(uint8_t *q, const uint8_t *n, const uint8_t *p)
Scalar multiplication of a point.
Definition: tweetnacl.cpp:452
int crypto_box_beforenm_unchecked(uint8_t *k, const uint8_t *y, const uint8_t *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:525
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:144
int crypto_stream_salsa20(uint8_t *c, uint64_t d, const uint8_t *n, const uint8_t *k)
Produce a keystream using Salsa20.
Definition: tweetnacl.cpp:175
int crypto_core_salsa20(uint8_t *out, const uint8_t *in, const uint8_t *k, const uint8_t *c)
TODO.
Definition: tweetnacl.cpp:134
Precompiled header file.
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:181
int crypto_hashblocks(uint8_t *x, const uint8_t *m, uint64_t n)
Hash multiple blocks.
Definition: tweetnacl.cpp:602
Crypto++ interface to TweetNaCl library (20140917)
int crypto_box_open(uint8_t *m, const uint8_t *c, uint64_t d, const uint8_t *n, const uint8_t *y, const uint8_t *x)
Verify and decrypt a message.
Definition: tweetnacl.cpp:556
int crypto_core_hsalsa20(uint8_t *out, const uint8_t *in, const uint8_t *k, const uint8_t *c)
TODO.
Definition: tweetnacl.cpp:140
int crypto_box_open_afternm(uint8_t *m, const uint8_t *c, uint64_t d, const uint8_t *n, const uint8_t *k)
Verify and decrypt a message.
Definition: tweetnacl.cpp:537
int crypto_box_unchecked(uint8_t *c, const uint8_t *m, uint64_t d, const uint8_t *n, const uint8_t *y, const uint8_t *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:549
int crypto_verify_32(const uint8_t *x, const uint8_t *y)
Compare 32-byte buffers.
Definition: tweetnacl.cpp:89
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk)
Generate a keypair for signing.
Definition: tweetnacl.cpp:739
Crypto++ library namespace.
int crypto_secretbox_open(uint8_t *m, const uint8_t *c, uint64_t d, const uint8_t *n, const uint8_t *k)
Verify and decrypt a message.
Definition: tweetnacl.cpp:278
int crypto_onetimeauth(uint8_t *out, const uint8_t *m, uint64_t n, const uint8_t *k)
Create an authentication tag for a message.
Definition: tweetnacl.cpp:208
int crypto_box_open_unchecked(uint8_t *m, const uint8_t *c, uint64_t d, const uint8_t *n, const uint8_t *y, const uint8_t *x)
Verify and decrypt a message.
Definition: tweetnacl.cpp:563
int crypto_scalarmult_base(uint8_t *q, const uint8_t *n)
Scalar multiplication of base point.
Definition: tweetnacl.cpp:503
int crypto_stream_salsa20_xor(uint8_t *c, const uint8_t *m, uint64_t b, const uint8_t *n, const uint8_t *k)
Encrypt a message using Salsa20.
Definition: tweetnacl.cpp:148
Classes for access to the operating system&#39;s random number generators.
int crypto_secretbox(uint8_t *c, const uint8_t *m, uint64_t d, const uint8_t *n, const uint8_t *k)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:268
A typedef providing a default generator.
Definition: osrng.h:263