14#if CRYPTOPP_MSC_VERSION
15# pragma warning(disable: 4146 4242 4244 4245)
18#ifndef CRYPTOPP_DISABLE_NACL
23typedef sword64 gf[16];
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};
40static void randombytes(
byte * block, word64 size)
43 prng.GenerateBlock(block, (
size_t)size);
46static word32 L32(word32 x,
int c) {
return (x << c) | ((x&0xffffffff) >> (32 - c)); }
48static word32 ld32(
const byte *x)
56static word64 dl64(
const byte *x)
59 for(i=0; i<8; ++i) u=(u<<8)|x[i];
63static void st32(
byte *x,word32 u)
66 for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
69static void ts64(
byte *x,word64 u)
72 for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
76static int verify_n(
const byte *x,
const byte *y,word32 n)
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;
84int crypto_verify_16(
const byte *x,
const byte *y)
86 return verify_n(x,y,16);
89int crypto_verify_32(
const byte *x,
const byte *y)
91 return verify_n(x,y,32);
94static void core(
byte *out,
const byte *in,
const byte *k,
const byte *c,
int h)
96 word32 w[16],x[16],y[16],t[4];
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);
106 for(i=0; i<16; ++i) y[i] = x[i];
108 for(i=0; i<20; ++i) {
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];
117 for(m=0; m<16; ++m) x[m] = w[m];
121 for(i=0; i<16; ++i) x[i] += y[i];
123 x[5*i] -= ld32(c+4*i);
124 x[6+i] -= ld32(in+4*i);
127 st32(out+4*i,x[5*i]);
128 st32(out+16+4*i,x[6+i]);
131 for(i=0; i<16; ++i) st32(out + 4 * i,x[i] + y[i]);
134int crypto_core_salsa20(
byte *out,
const byte *in,
const byte *k,
const byte *c)
140int crypto_core_hsalsa20(
byte *out,
const byte *in,
const byte *k,
const byte *c)
146static const byte sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B};
148int crypto_stream_salsa20_xor(
byte *c,
const byte *m,word64 b,
const byte *n,
const byte *k)
153 for(i=0; i<16; ++i) z[i] = 0;
154 for(i=0; i<8; ++i) z[i] = n[i];
156 crypto_core_salsa20(x,z,k,sigma);
157 for(i=0; i<64; ++i) c[i] = (m?m[i]:0) ^ x[i];
159 for (i = 8;i < 16;++i) {
169 crypto_core_salsa20(x,z,k,sigma);
170 for(i=0; i<b; ++i) c[i] = (m?m[i]:0) ^ x[i];
175int crypto_stream_salsa20(
byte *c,word64 d,
const byte *n,
const byte *k)
177 return crypto_stream_salsa20_xor(c,0,d,n,k);
180int crypto_stream(
byte *c,word64 d,
const byte *n,
const byte *k)
183 crypto_core_hsalsa20(s,n,k,sigma);
184 return crypto_stream_salsa20(c,d,n+16,s);
187int crypto_stream_xor(
byte *c,
const byte *m,word64 d,
const byte *n,
const byte *k)
190 crypto_core_hsalsa20(s,n,k,sigma);
191 return crypto_stream_salsa20_xor(c,m,d,n+16,s);
194static void add1305(word32 *h,
const word32 *c)
197 for(j=0; j<17; ++j) {
204static const word32 minusp[17] = {
205 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
208int crypto_onetimeauth(
byte *out,
const byte *m,word64 n,
const byte *k)
210 word32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
212 for(j=0; j<17; ++j) r[j]=h[j]=0;
213 for(j=0; j<16; ++j) r[j]=k[j];
223 for(j=0; j<17; ++j) c[j] = 0;
224 for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
228 for(i=0; i<17; ++i) {
230 for(j=0; j<17; ++j) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
232 for(i=0; i<17; ++i) h[i] = x[i];
234 for(j=0; j<16; ++j) {
239 u += h[16]; h[16] = u & 3;
241 for(j=0; j<16; ++j) {
246 u += h[16]; h[16] = u;
249 for(j=0; j<17; ++j) g[j] = h[j];
252 for(j=0; j<17; ++j) h[j] ^= s & (g[j] ^ h[j]);
254 for(j=0; j<16; ++j) c[j] = k[j + 16];
257 for(j=0; j<16; ++j) out[j] = h[j];
261int crypto_onetimeauth_verify(
const byte *h,
const byte *m,word64 n,
const byte *k)
264 crypto_onetimeauth(x,m,n,k);
265 return crypto_verify_16(h,x);
268int crypto_secretbox(
byte *c,
const byte *m,word64 d,
const byte *n,
const byte *k)
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;
278int crypto_secretbox_open(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *k)
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;
290static void set25519(gf r,
const gf a)
293 for(i=0; i<16; ++i) r[i]=a[i];
296static void car25519(gf o)
300 for(i=0; i<16; ++i) {
303 o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
304 o[i]-=((word64)c)<<16;
308static void sel25519(gf p,gf q,
int b)
310 sword64 t,i,c=~(b-1);
311 for(i=0; i<16; ++i) {
318static void pack25519(
byte *o,
const gf n)
322 for(i=0; i<16; ++i) t[i]=n[i];
329 m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
332 m[15]=t[15]-0x7fff-((m[14]>>16)&1);
337 for(i=0; i<16; ++i) {
343static int neq25519(
const gf a,
const gf b)
348 return crypto_verify_32(c,d);
351static byte par25519(
const gf a)
358static void unpack25519(gf o,
const byte *n)
361 for(i=0; i<16; ++i) o[i]=n[2*i]+((sword64)n[2*i+1]<<8);
365static void A(gf o,
const gf a,
const gf b)
368 for(i=0; i<16; ++i) o[i]=a[i]+b[i];
371static void Z(gf o,
const gf a,
const gf b)
374 for(i=0; i<16; ++i) o[i]=a[i]-b[i];
377static void M(gf o,
const gf a,
const gf b)
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];
388static void S(gf o,
const gf a)
393static void inv25519(gf o,
const gf i)
397 for(a=0; a<16; ++a) c[a]=i[a];
398 for(a=253;a>=0;a--) {
400 if(a!=2&&a!=4) M(c,c,i);
402 for(a=0; a<16; ++a) o[a]=c[a];
405static void pow2523(gf o,
const gf i)
409 for(a=0; a<16; ++a) c[a]=i[a];
410 for(a=250;a>=0;a--) {
414 for(a=0; a<16; ++a) o[a]=c[a];
418static int has_small_order(
const byte s[32])
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 }
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];
445 for (
size_t i = 0; i <
COUNTOF(blacklist); i++) {
449 return (
int) ((k >> 8) & 1);
452int crypto_scalarmult(
byte *q,
const byte *n,
const byte *p)
457 for(i=0; i<31; ++i) z[i]=n[i];
458 z[31]=(n[31]&127)|64;
461 for(i=0; i<16; ++i) {
466 for(i=254;i>=0;--i) {
467 r=(z[i>>3]>>(i&7))&1;
491 for(i=0; i<16; ++i) {
503int crypto_scalarmult_base(
byte *q,
const byte *n)
505 return crypto_scalarmult(q,n,_9);
508int crypto_box_keypair(
byte *y,
byte *x)
511 return crypto_scalarmult_base(y,x);
516int crypto_box_beforenm(
byte *k,
const byte *y,
const byte *x)
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);
528 if(crypto_scalarmult(s,x,y) != 0)
return -1;
529 return crypto_core_hsalsa20(k,_0,s,sigma);
532int crypto_box_afternm(
byte *c,
const byte *m,word64 d,
const byte *n,
const byte *k)
534 return crypto_secretbox(c,m,d,n,k);
537int crypto_box_open_afternm(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *k)
539 return crypto_secretbox_open(m,c,d,n,k);
542int crypto_box(
byte *c,
const byte *m, word64 d,
const byte *n,
const byte *y,
const byte *x)
545 if (crypto_box_beforenm(k, y, x) != 0)
return -1;
546 return crypto_box_afternm(c, m, d, n, k);
553 return crypto_box_afternm(c, m, d, n, k);
556int crypto_box_open(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *y,
const byte *x)
559 if(crypto_box_beforenm(k,y,x) != 0)
return -1;
560 return crypto_box_open_afternm(m,c,d,n,k);
567 return crypto_box_open_afternm(m,c,d,n,k);
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); }
578static const word64 K[80] =
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)
602int crypto_hashblocks(
byte *x,
const byte *m,word64 n)
604 word64 z[8],b[8],a[8],w[16],t;
607 for(i=0; i<8; ++i) z[i] = a[i] = dl64(x + 8 * i);
610 for(i=0; i<16; ++i) w[i] = dl64(m + 8 * i);
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]);
617 for(j=0; j<8; ++j) a[(j+1)%8] = b[j];
620 w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
623 for(i=0; i<8; ++i) { a[i] += z[i]; z[i] = a[i]; }
629 for(i=0; i<8; ++i) ts64(x+8*i,z[i]);
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
645int crypto_hash(
byte *out,
const byte *m,word64 n)
650 for(i=0; i<64; ++i) h[i] = iv[i];
652 crypto_hashblocks(h,m,n);
657 for(i=0; i<256; ++i) x[i] = 0;
658 for(i=0; i<n; ++i) x[i] = m[i];
664 crypto_hashblocks(h,x,n);
666 for(i=0; i<64; ++i) out[i] = h[i];
671static void add(gf p[4],gf q[4])
673 gf a,b,c,d,t,e,f,g,h;
696static void cswap(gf p[4],gf q[4],
byte b)
700 sel25519(p[i],q[i],b);
703static void pack(
byte *r,gf p[4])
710 r[31] ^= par25519(tx) << 7;
713static void scalarmult(gf p[4],gf q[4],
const byte *s)
720 for (i = 255;i >= 0;--i) {
721 byte b = (s[i/8]>>(i&7))&1;
729static void scalarbase(gf p[4],
const byte *s)
739int crypto_sign_keypair(
byte *pk,
byte *sk)
746 crypto_hash(d, sk, 32);
754 for(i=0; i<32; ++i) sk[32 + i] = pk[i];
765 crypto_hash(d, sk, 32);
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};
779static void modL(
byte *r,sword64 x[64])
782 for (i = 63;i >= 32;--i) {
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;
793 for(j=0; j<32; ++j) {
794 x[j] += carry - (x[31] >> 4) * L[j];
798 for(j=0; j<32; ++j) x[j] -= carry * L[j];
799 for(i=0; i<32; ++i) {
805static void reduce(
byte *r)
808 for(i=0; i<64; ++i) x[i] = (word64) r[i];
809 for(i=0; i<64; ++i) r[i] = 0;
813int crypto_sign(
byte *sm,word64 *smlen,
const byte *m,word64 n,
const byte *sk)
815 byte d[64],h[64],r[64];
816 word64 i; sword64 j,x[64];
819 crypto_hash(d, sk, 32);
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];
828 crypto_hash(r, sm+32, n+32);
833 for(i=0; i<32; ++i) sm[i+32] = sk[i+32];
834 crypto_hash(h,sm,n + 64);
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];
845static int unpackneg(gf r[4],
const byte p[32])
847 gf t, chk, num, den, den2, den4, den6;
869 if (neq25519(chk, num)) M(r[0],r[0],I);
873 if (neq25519(chk, num))
return -1;
875 if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
881int crypto_sign_open(
byte *m,word64 *mlen,
const byte *sm,word64 n,
const byte *pk)
888 if (n < 64)
return -1;
890 if (unpackneg(q,pk))
return -1;
892 for(i=0; i<n; ++i) m[i] = sm[i];
893 for(i=0; i<32; ++i) m[i+32] = pk[i];
898 scalarbase(q,sm + 32);
903 if (crypto_verify_32(sm, t)) {
904 for(i=0; i<n; ++i) m[i] = 0;
908 for(i=0; i<n; ++i) m[i] = sm[i + 64];
A typedef providing a default generator.
Library configuration file.
Utility functions for the Crypto++ library.
#define COUNTOF(arr)
Counts elements in an array.
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Crypto++ interface to TweetNaCl library (20140917)
int crypto_box_beforenm_unchecked(byte *k, const byte *y, const byte *x)
Encrypt and authenticate a message.
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.
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.
int crypto_sign_sk2pk(byte *pk, const byte *sk)
Calculate a public key from a secret key.
Crypto++ library namespace.
Namespace containing NaCl library functions.
Classes for access to the operating system's random number generators.