14#if CRYPTOPP_MSC_VERSION
15# pragma warning(disable: 4146 4242 4244 4245)
20#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
26#ifndef CRYPTOPP_DISABLE_NACL
28NAMESPACE_BEGIN(CryptoPP)
31typedef 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};
48static void randombytes(
byte * block, word64 size)
50 DefaultAutoSeededRNG prng;
51 prng.GenerateBlock(block, (
size_t)size);
54static word32 L32(
word32 x,
int c) {
return (x << c) | ((x&0xffffffff) >> (32 - c)); }
56static word32 ld32(
const byte *x)
64static word64 dl64(
const byte *x)
67 for(i=0; i<8; ++i) u=(u<<8)|x[i];
71static void st32(
byte *x,
word32 u)
74 for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
77static void ts64(
byte *x,word64 u)
80 for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
84static int verify_n(
const byte *x,
const byte *y,
word32 n)
87 for(i=0; i<n; ++i) d |= x[i]^y[i];
89 return (1 & ((
word32)(v - 1) >> 8)) - 1;
92int crypto_verify_16(
const byte *x,
const byte *y)
94 return verify_n(x,y,16);
97int crypto_verify_32(
const byte *x,
const byte *y)
99 return verify_n(x,y,32);
102static 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]);
142int crypto_core_salsa20(
byte *out,
const byte *in,
const byte *k,
const byte *c)
148int crypto_core_hsalsa20(
byte *out,
const byte *in,
const byte *k,
const byte *c)
154static const byte sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B};
156int crypto_stream_salsa20_xor(
byte *c,
const byte *m,word64 b,
const byte *n,
const byte *k)
161 for(i=0; i<16; ++i) z[i] = 0;
162 for(i=0; i<8; ++i) z[i] = n[i];
164 crypto_core_salsa20(x,z,k,sigma);
165 for(i=0; i<64; ++i) c[i] = (m?m[i]:0) ^ x[i];
167 for (i = 8;i < 16;++i) {
177 crypto_core_salsa20(x,z,k,sigma);
178 for(i=0; i<b; ++i) c[i] = (m?m[i]:0) ^ x[i];
183int crypto_stream_salsa20(
byte *c,word64 d,
const byte *n,
const byte *k)
185 return crypto_stream_salsa20_xor(c,0,d,n,k);
188int crypto_stream(
byte *c,word64 d,
const byte *n,
const byte *k)
191 crypto_core_hsalsa20(s,n,k,sigma);
192 return crypto_stream_salsa20(c,d,n+16,s);
195int crypto_stream_xor(
byte *c,
const byte *m,word64 d,
const byte *n,
const byte *k)
198 crypto_core_hsalsa20(s,n,k,sigma);
199 return crypto_stream_salsa20_xor(c,m,d,n+16,s);
205 for(j=0; j<17; ++j) {
212static const word32 minusp[17] = {
213 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
216int crypto_onetimeauth(
byte *out,
const byte *m,word64 n,
const byte *k)
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];
269int crypto_onetimeauth_verify(
const byte *h,
const byte *m,word64 n,
const byte *k)
272 crypto_onetimeauth(x,m,n,k);
273 return crypto_verify_16(h,x);
276int crypto_secretbox(
byte *c,
const byte *m,word64 d,
const byte *n,
const byte *k)
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;
286int crypto_secretbox_open(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *k)
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;
298static void set25519(gf r,
const gf a)
301 for(i=0; i<16; ++i) r[i]=a[i];
304static 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;
316static void sel25519(gf p,gf q,
int b)
318 sword64 t,i,c=~(b-1);
319 for(i=0; i<16; ++i) {
326static 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) {
351static int neq25519(
const gf a,
const gf b)
356 return crypto_verify_32(c,d);
359static byte par25519(
const gf a)
366static 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);
373static void A(gf o,
const gf a,
const gf b)
376 for(i=0; i<16; ++i) o[i]=a[i]+b[i];
379static void Z(gf o,
const gf a,
const gf b)
382 for(i=0; i<16; ++i) o[i]=a[i]-b[i];
385static 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];
396static void S(gf o,
const gf a)
401static 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];
413static 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];
426static 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 }
443 CRYPTOPP_COMPILE_ASSERT(12 == COUNTOF(blacklist));
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);
460int crypto_scalarmult(
byte *q,
const byte *n,
const byte *p)
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) {
511int crypto_scalarmult_base(
byte *q,
const byte *n)
513 return crypto_scalarmult(q,n,_9);
516int crypto_box_keypair(
byte *y,
byte *x)
519 return crypto_scalarmult_base(y,x);
524int crypto_box_beforenm(
byte *k,
const byte *y,
const byte *x)
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);
533int crypto_box_beforenm_unchecked(
byte *k,
const byte *y,
const byte *x)
536 if(crypto_scalarmult(s,x,y) != 0)
return -1;
537 return crypto_core_hsalsa20(k,_0,s,sigma);
540int crypto_box_afternm(
byte *c,
const byte *m,word64 d,
const byte *n,
const byte *k)
542 return crypto_secretbox(c,m,d,n,k);
545int crypto_box_open_afternm(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *k)
547 return crypto_secretbox_open(m,c,d,n,k);
550int crypto_box(
byte *c,
const byte *m, word64 d,
const byte *n,
const byte *y,
const byte *x)
553 if (crypto_box_beforenm(k, y, x) != 0)
return -1;
554 return crypto_box_afternm(c, m, d, n, k);
557int crypto_box_unchecked(
byte *c,
const byte *m, word64 d,
const byte *n,
const byte *y,
const byte *x)
560 crypto_box_beforenm_unchecked(k, y, x);
561 return crypto_box_afternm(c, m, d, n, k);
564int crypto_box_open(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *y,
const byte *x)
567 if(crypto_box_beforenm(k,y,x) != 0)
return -1;
568 return crypto_box_open_afternm(m,c,d,n,k);
571int crypto_box_open_unchecked(
byte *m,
const byte *c,word64 d,
const byte *n,
const byte *y,
const byte *x)
574 crypto_box_beforenm_unchecked(k,y,x);
575 return crypto_box_open_afternm(m,c,d,n,k);
578static word64 R(word64 x,
int c) {
return (x >> c) | (x << (64 - c)); }
579static word64 Ch(word64 x,word64 y,word64 z) {
return (x & y) ^ (~x & z); }
580static word64 Maj(word64 x,word64 y,word64 z) {
return (x & y) ^ (x & z) ^ (y & z); }
581static word64 Sigma0(word64 x) {
return R(x,28) ^ R(x,34) ^ R(x,39); }
582static word64 Sigma1(word64 x) {
return R(x,14) ^ R(x,18) ^ R(x,41); }
583static word64 sigma0(word64 x) {
return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
584static word64 sigma1(word64 x) {
return R(x,19) ^ R(x,61) ^ (x >> 6); }
586static 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)
610int crypto_hashblocks(
byte *x,
const byte *m,word64 n)
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]);
642static 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
653int crypto_hash(
byte *out,
const byte *m,word64 n)
658 for(i=0; i<64; ++i) h[i] = iv[i];
660 crypto_hashblocks(h,m,n);
665 for(i=0; i<256; ++i) x[i] = 0;
666 for(i=0; i<n; ++i) x[i] = m[i];
672 crypto_hashblocks(h,x,n);
674 for(i=0; i<64; ++i) out[i] = h[i];
679static void add(gf p[4],gf q[4])
681 gf a,b,c,d,t,e,f,g,h;
704static void cswap(gf p[4],gf q[4],
byte b)
708 sel25519(p[i],q[i],b);
711static void pack(
byte *r,gf p[4])
718 r[31] ^= par25519(tx) << 7;
721static 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;
737static void scalarbase(gf p[4],
const byte *s)
747int crypto_sign_keypair(
byte *pk,
byte *sk)
754 crypto_hash(d, sk, 32);
762 for(i=0; i<32; ++i) sk[32 + i] = pk[i];
766int crypto_sign_sk2pk(
byte *pk,
const byte *sk)
773 crypto_hash(d, sk, 32);
785static 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};
787static 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) {
813static 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;
821int 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];
827 crypto_hash(d, sk, 32);
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];
836 crypto_hash(r, sm+32, n+32);
841 for(i=0; i<32; ++i) sm[i+32] = sk[i+32];
842 crypto_hash(h,sm,n + 64);
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];
853static 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]);
889int crypto_sign_open(
byte *m,word64 *mlen,
const byte *sm,word64 n,
const byte *pk)
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);
911 if (crypto_verify_32(sm, t)) {
912 for(i=0; i<n; ++i) m[i] = 0;
916 for(i=0; i<n; ++i) m[i] = sm[i + 64];
Library configuration file.
signed int sword32
32-bit signed datatype
unsigned int word32
32-bit unsigned datatype
Utility functions for the Crypto++ library.
Crypto++ interface to TweetNaCl library (20140917)
Classes for access to the operating system's random number generators.