14 #if CRYPTOPP_MSC_VERSION
15 # pragma warning(disable: 4146 4242 4244 4245)
20 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
21 # define ALIGN_SPEC 16
26 #ifndef CRYPTOPP_DISABLE_NACL
31 typedef sword64 gf[16];
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};
48 static void randombytes(
byte * block, word64 size)
51 prng.GenerateBlock(block, (
size_t)size);
54 static word32 L32(word32 x,
int c) {
return (x << c) | ((x&0xffffffff) >> (32 - c)); }
56 static word32 ld32(
const byte *x)
64 static word64 dl64(
const byte *x)
67 for(i=0; i<8; ++i) u=(u<<8)|x[i];
71 static void st32(
byte *x,word32 u)
74 for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
77 static void ts64(
byte *x,word64 u)
80 for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
84 static int verify_n(
const byte *x,
const byte *y,word32 n)
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;
94 return verify_n(x,y,16);
99 return verify_n(x,y,32);
102 static void core(
byte *out,
const byte *in,
const byte *k,
const byte *c,
int h)
104 word32 w[16],x[16],y[16],t[4];
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);
114 for(i=0; i<16; ++i) y[i] = x[i];
116 for(i=0; i<20; ++i) {
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];
125 for(m=0; m<16; ++m) x[m] = w[m];
129 for(i=0; i<16; ++i) x[i] += y[i];
131 x[5*i] -= ld32(c+4*i);
132 x[6+i] -= ld32(in+4*i);
135 st32(out+4*i,x[5*i]);
136 st32(out+16+4*i,x[6+i]);
139 for(i=0; i<16; ++i) st32(out + 4 * i,x[i] + y[i]);
154 static const byte sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B};
161 for(i=0; i<16; ++i) z[i] = 0;
162 for(i=0; i<8; ++i) z[i] = n[i];
165 for(i=0; i<64; ++i) c[i] = (m?m[i]:0) ^ x[i];
167 for (i = 8;i < 16;++i) {
178 for(i=0; i<b; ++i) c[i] = (m?m[i]:0) ^ x[i];
202 static void add1305(word32 *h,
const word32 *c)
205 for(j=0; j<17; ++j) {
212 static const word32 minusp[17] = {
213 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
218 word32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
220 for(j=0; j<17; ++j) r[j]=h[j]=0;
221 for(j=0; j<16; ++j) r[j]=k[j];
231 for(j=0; j<17; ++j) c[j] = 0;
232 for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
236 for(i=0; i<17; ++i) {
238 for(j=0; j<17; ++j) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
240 for(i=0; i<17; ++i) h[i] = x[i];
242 for(j=0; j<16; ++j) {
247 u += h[16]; h[16] = u & 3;
249 for(j=0; j<16; ++j) {
254 u += h[16]; h[16] = u;
257 for(j=0; j<17; ++j) g[j] = h[j];
260 for(j=0; j<17; ++j) h[j] ^= s & (g[j] ^ h[j]);
262 for(j=0; j<16; ++j) c[j] = k[j + 16];
265 for(j=0; j<16; ++j) out[j] = h[j];
279 if (d < 32)
return -1;
282 for(i=0; i<16; ++i) c[i] = 0;
290 if (d < 32)
return -1;
294 for(i=0; i<32; ++i) m[i] = 0;
298 static void set25519(gf r,
const gf a)
301 for(i=0; i<16; ++i) r[i]=a[i];
304 static void car25519(gf o)
308 for(i=0; i<16; ++i) {
311 o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
312 o[i]-=((word64)c)<<16;
316 static void sel25519(gf p,gf q,
int b)
318 sword64 t,i,c=~(b-1);
319 for(i=0; i<16; ++i) {
326 static void pack25519(
byte *o,
const gf n)
330 for(i=0; i<16; ++i) t[i]=n[i];
337 m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
340 m[15]=t[15]-0x7fff-((m[14]>>16)&1);
345 for(i=0; i<16; ++i) {
351 static int neq25519(
const gf a,
const gf b)
359 static byte par25519(
const gf a)
366 static void unpack25519(gf o,
const byte *n)
369 for(i=0; i<16; ++i) o[i]=n[2*i]+((sword64)n[2*i+1]<<8);
373 static void A(gf o,
const gf a,
const gf b)
376 for(i=0; i<16; ++i) o[i]=a[i]+b[i];
379 static void Z(gf o,
const gf a,
const gf b)
382 for(i=0; i<16; ++i) o[i]=a[i]-b[i];
385 static void M(gf o,
const gf a,
const gf b)
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];
396 static void S(gf o,
const gf a)
401 static void inv25519(gf o,
const gf i)
405 for(a=0; a<16; ++a) c[a]=i[a];
406 for(a=253;a>=0;a--) {
408 if(a!=2&&a!=4) M(c,c,i);
410 for(a=0; a<16; ++a) o[a]=c[a];
413 static void pow2523(gf o,
const gf i)
417 for(a=0; a<16; ++a) c[a]=i[a];
418 for(a=250;a>=0;a--) {
422 for(a=0; a<16; ++a) o[a]=c[a];
426 static int has_small_order(
const byte s[32])
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 }
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];
453 for (
size_t i = 0; i <
COUNTOF(blacklist); i++) {
457 return (
int) ((k >> 8) & 1);
465 for(i=0; i<31; ++i) z[i]=n[i];
466 z[31]=(n[31]&127)|64;
469 for(i=0; i<16; ++i) {
474 for(i=254;i>=0;--i) {
475 r=(z[i>>3]>>(i&7))&1;
499 for(i=0; i<16; ++i) {
528 if(has_small_order(s) != 0)
return -1;
550 int crypto_box(
byte *c,
const byte *m, word64 d,
const byte *n,
const byte *y,
const byte *x)
564 int crypto_box_open(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *y,
const byte *x)
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); }
586 static const word64 K[80] =
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)
612 word64 z[8],b[8],a[8],w[16],t;
615 for(i=0; i<8; ++i) z[i] = a[i] = dl64(x + 8 * i);
618 for(i=0; i<16; ++i) w[i] = dl64(m + 8 * i);
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]);
625 for(j=0; j<8; ++j) a[(j+1)%8] = b[j];
628 w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
631 for(i=0; i<8; ++i) { a[i] += z[i]; z[i] = a[i]; }
637 for(i=0; i<8; ++i) ts64(x+8*i,z[i]);
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
658 for(i=0; i<64; ++i) h[i] = iv[i];
665 for(i=0; i<256; ++i) x[i] = 0;
666 for(i=0; i<n; ++i) x[i] = m[i];
674 for(i=0; i<64; ++i) out[i] = h[i];
679 static void add(gf p[4],gf q[4])
681 gf a,b,c,d,t,e,f,g,h;
704 static void cswap(gf p[4],gf q[4],
byte b)
708 sel25519(p[i],q[i],b);
711 static void pack(
byte *r,gf p[4])
718 r[31] ^= par25519(tx) << 7;
721 static void scalarmult(gf p[4],gf q[4],
const byte *s)
728 for (i = 255;i >= 0;--i) {
729 byte b = (s[i/8]>>(i&7))&1;
737 static void scalarbase(gf p[4],
const byte *s)
762 for(i=0; i<32; ++i) sk[32 + i] = pk[i];
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};
787 static void modL(
byte *r,sword64 x[64])
790 for (i = 63;i >= 32;--i) {
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;
801 for(j=0; j<32; ++j) {
802 x[j] += carry - (x[31] >> 4) * L[j];
806 for(j=0; j<32; ++j) x[j] -= carry * L[j];
807 for(i=0; i<32; ++i) {
813 static void reduce(
byte *r)
816 for(i=0; i<64; ++i) x[i] = (word64) r[i];
817 for(i=0; i<64; ++i) r[i] = 0;
821 int crypto_sign(
byte *sm,word64 *smlen,
const byte *m,word64 n,
const byte *sk)
823 byte d[64],h[64],r[64];
824 word64 i; sword64 j,x[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];
841 for(i=0; i<32; ++i) sm[i+32] = sk[i+32];
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];
853 static int unpackneg(gf r[4],
const byte p[32])
855 gf t, chk, num, den, den2, den4, den6;
877 if (neq25519(chk, num)) M(r[0],r[0],I);
881 if (neq25519(chk, num))
return -1;
883 if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
896 if (n < 64)
return -1;
898 if (unpackneg(q,pk))
return -1;
900 for(i=0; i<n; ++i) m[i] = sm[i];
901 for(i=0; i<32; ++i) m[i+32] = pk[i];
906 scalarbase(q,sm + 32);
912 for(i=0; i<n; ++i) m[i] = 0;
916 for(i=0; i<n; ++i) m[i] = sm[i + 64];
924 #endif // NO_OS_DEPENDENCE