Crypto++  8.8
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 {
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];
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];
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
A typedef providing a default generator.
Definition: osrng.h:290
Library configuration file.
signed long long sword64
64-bit signed datatype
Definition: config_int.h:109
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:129
signed int sword32
32-bit signed datatype
Definition: config_int.h:91
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:101
Utility functions for the Crypto++ library.
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:193
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:153
Crypto++ interface to TweetNaCl library (20140917)
int crypto_stream(byte *c, word64 d, const byte *n, const byte *k)
Produce a keystream using XSalsa20.
Definition: tweetnacl.cpp:188
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
int crypto_box_beforenm(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:524
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
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
int crypto_core_salsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:142
int crypto_verify_32(const byte *x, const byte *y)
Compare 32-byte buffers.
Definition: tweetnacl.cpp:97
int crypto_box_beforenm_unchecked(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:533
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
int crypto_core_hsalsa20(byte *out, const byte *in, const byte *k, const byte *c)
TODO.
Definition: tweetnacl.cpp:148
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
int crypto_onetimeauth(byte *out, const byte *m, word64 n, const byte *k)
Create an authentication tag for a message.
Definition: tweetnacl.cpp:216
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
int crypto_sign_open(byte *m, word64 *mlen, const byte *sm, word64 n, const byte *pk)
Verify a message.
Definition: tweetnacl.cpp:889
int crypto_scalarmult_base(byte *q, const byte *n)
Scalar multiplication of base point.
Definition: tweetnacl.cpp:511
int crypto_hashblocks(byte *x, const byte *m, word64 n)
Hash multiple blocks.
Definition: tweetnacl.cpp:610
int crypto_stream_salsa20(byte *c, word64 d, const byte *n, const byte *k)
Produce a keystream using Salsa20.
Definition: tweetnacl.cpp:183
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
int crypto_scalarmult(byte *q, const byte *n, const byte *p)
Scalar multiplication of a point.
Definition: tweetnacl.cpp:460
int crypto_hash(byte *out, const byte *m, word64 n)
Hash a message.
Definition: tweetnacl.cpp:653
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
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
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
int crypto_sign_sk2pk(byte *pk, const byte *sk)
Calculate a public key from a secret key.
Definition: tweetnacl.cpp:766
int crypto_box_keypair(byte *y, byte *x)
Generate a keypair for encryption.
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:276
int crypto_sign_keypair(byte *pk, byte *sk)
Generate a keypair for signing.
Definition: tweetnacl.cpp:747
int crypto_verify_16(const byte *x, const byte *y)
Compare 16-byte buffers.
Definition: tweetnacl.cpp:92
int crypto_sign(byte *sm, word64 *smlen, const byte *m, word64 n, const byte *sk)
Sign a message.
Definition: tweetnacl.cpp:821
Crypto++ library namespace.
Namespace containing NaCl library functions.
Definition: cryptlib.h:573
Classes for access to the operating system's random number generators.
Precompiled header file.
Common C++ header files.