Crypto++ 8.2
Free C&
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
20NAMESPACE_BEGIN(CryptoPP)
21NAMESPACE_BEGIN(NaCl)
22
23typedef sword64 gf[16];
24
25static const byte
26 _0[32] = {0},
27 _9[32] = {9};
28
29static 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
40static void randombytes(byte * block, word64 size)
41{
43 prng.GenerateBlock(block, (size_t)size);
44}
45
46static word32 L32(word32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
47
48static 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
56static 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
63static void st32(byte *x,word32 u)
64{
65 int i;
66 for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
67}
68
69static 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
76static 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
84int crypto_verify_16(const byte *x,const byte *y)
85{
86 return verify_n(x,y,16);
87}
88
89int crypto_verify_32(const byte *x,const byte *y)
90{
91 return verify_n(x,y,32);
92}
93
94static 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
134int 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
140int 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
146static const byte sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B};
147
148int 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
175int 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
180int 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
187int 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
194static 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
204static const word32 minusp[17] = {
205 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
206} ;
207
208int 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
261int 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
268int 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
278int 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
290static void set25519(gf r, const gf a)
291{
292 int i;
293 for(i=0; i<16; ++i) r[i]=a[i];
294}
295
296static 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
308static 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
318static 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
343static 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
351static byte par25519(const gf a)
352{
353 byte d[32];
354 pack25519(d,a);
355 return d[0]&1;
356}
357
358static 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
365static 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
371static 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
377static 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
388static void S(gf o,const gf a)
389{
390 M(o,a,a);
391}
392
393static 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
405static 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
418static 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
452int 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
503int crypto_scalarmult_base(byte *q,const byte *n)
504{
505 return crypto_scalarmult(q,n,_9);
506}
507
508int 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.
516int 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
525int 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
532int 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
537int 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
542int 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
549int 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
556int 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
563int 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
570static word64 R(word64 x,int c) { return (x >> c) | (x << (64 - c)); }
571static word64 Ch(word64 x,word64 y,word64 z) { return (x & y) ^ (~x & z); }
572static word64 Maj(word64 x,word64 y,word64 z) { return (x & y) ^ (x & z) ^ (y & z); }
573static word64 Sigma0(word64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
574static word64 Sigma1(word64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
575static word64 sigma0(word64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
576static word64 sigma1(word64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
577
578static 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
602int 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
634static 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
645int 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
671static 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
696static 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
703static 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
713static 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
729static 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
739int 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
758int 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
777static 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
779static 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
805static 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
813int 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
845static 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
881int 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
913NAMESPACE_END // CryptoPP
914NAMESPACE_END // NaCl
915
916#endif // NO_OS_DEPENDENCE
A typedef providing a default generator.
Definition: osrng.h:273
Library configuration file.
Utility functions for the Crypto++ library.
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:153
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:116
Crypto++ interface to TweetNaCl library (20140917)
int crypto_box_beforenm_unchecked(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
Definition: tweetnacl.cpp:525
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_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_sk2pk(byte *pk, const byte *sk)
Calculate a public key from a secret key.
Definition: tweetnacl.cpp:758
Crypto++ library namespace.
Namespace containing NaCl library functions.
Definition: cryptlib.h:540
Classes for access to the operating system's random number generators.
Precompiled header file.
Common C++ header files.