diff options
author | Jeffrey Walton <noloader@gmail.com> | 2018-01-17 22:02:09 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-17 22:02:09 -0500 |
commit | 13ea8f374f82aef22b31ba8db712c67625e39e8b (patch) | |
tree | 68b1dd131441512e2f838368ce39d7917080ba65 | |
parent | 4e86f42d78b82e7a8c56f3810c27fca35afc257b (diff) | |
download | cryptopp-git-13ea8f374f82aef22b31ba8db712c67625e39e8b.tar.gz |
Add interface to TweetNaCl library (#566)
TweetNaCl is a compact reimplementation of the NaCl library by Daniel J. Bernstein, Bernard van Gastel, Wesley Janssen, Tanja Lange, Peter Schwabe and Sjaak Smetsers. The library is less than 20 KB in size and provides 25 of the NaCl library functions.
The compact library uses curve25519, XSalsa20, Poly1305 and SHA-512 as default primitives, and includes both x25519 key exchange and ed25519 signatures. The complete list of functions can be found in TweetNaCl: A crypto library in 100 tweets (20140917), Table 1, page 5.
Crypto++ retained the function names and signatures but switched to data types provided by <stdint.h> to promote interoperability with Crypto++ and avoid size problems on platforms like Cygwin. For example, NaCl typdef'd u64 as an unsigned long long, but Cygwin, MinGW and MSYS are LP64 systems (not LLP64 systems). In addition, Crypto++ was missing NaCl's signed 64-bit integer i64.
Crypto++ enforces the 0-key restriction due to small points. The TweetNaCl library allowed the 0-keys to small points. Also see RFC 7748, Elliptic Curves for Security, Section 6.
TweetNaCl is well written but not well optimized. It runs 2x to 3x slower than optimized routines from libsodium. However, the library is still 2x to 4x faster than the algorithms NaCl was designed to replace.
The Crypto++ wrapper for TweetNaCl requires OS features. That is, NO_OS_DEPENDENCE cannot be defined. It is due to TweetNaCl's internal function randombytes. Crypto++ used DefaultAutoSeededRNG within randombytes, so OS integration must be enabled. You can use another generator like RDRAND to avoid the restriction.
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | Filelist.txt | 4 | ||||
-rwxr-xr-x | GNUmakefile | 4 | ||||
-rwxr-xr-x | GNUmakefile-cross | 2 | ||||
-rw-r--r-- | TestScripts/tweetnacl.patch | 968 | ||||
-rwxr-xr-x | TestScripts/tweetnacl.sh | 47 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | cryptest.nmake | 8 | ||||
-rw-r--r-- | cryptest.vcxproj | 1 | ||||
-rw-r--r-- | cryptest.vcxproj.filters | 3 | ||||
-rw-r--r-- | cryptlib.h | 6 | ||||
-rw-r--r-- | cryptlib.vcxproj | 3 | ||||
-rw-r--r-- | cryptlib.vcxproj.filters | 9 | ||||
-rw-r--r-- | nacl.h | 341 | ||||
-rw-r--r-- | test.cpp | 1 | ||||
-rw-r--r-- | tweetnacl.cpp | 837 | ||||
-rw-r--r-- | tweetnacl.h | 272 | ||||
-rw-r--r-- | validat1.cpp | 2 | ||||
-rw-r--r-- | validat4.cpp | 488 | ||||
-rw-r--r-- | validate.h | 2 |
20 files changed, 2993 insertions, 8 deletions
diff --git a/.travis.yml b/.travis.yml index 2b0b61a8..9cda9a7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ dist: trusty sudo: false
# OS X only supports one image. Use the latest.
-osx_image: xcode8.2
+osx_image: xcode8.3
git:
depth: 3
diff --git a/Filelist.txt b/Filelist.txt index dca7df64..7bfd69b0 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -183,6 +183,7 @@ mqueue.cpp mqueue.h
mqv.cpp
mqv.h
+nacl.h
nbtheory.cpp
nbtheory.h
neon-simd.cpp
@@ -314,12 +315,15 @@ trdlocal.h trunhash.h
ttmac.cpp
ttmac.h
+tweetnacl.cpp
+tweetnacl.h
twofish.cpp
twofish.h
validat0.cpp
validat1.cpp
validat2.cpp
validat3.cpp
+validat4.cpp
validate.h
vmac.cpp
vmac.h
diff --git a/GNUmakefile b/GNUmakefile index 605e45d3..23b118af 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -715,7 +715,7 @@ endif endif # Nasm # List test.cpp first to tame C++ static initialization problems. -TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp dlltest.cpp fipsalgt.cpp +TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp dlltest.cpp fipsalgt.cpp TESTINCL := bench.h factory.h validate.h # Test objects TESTOBJS := $(TESTSRCS:.cpp=.o) @@ -972,7 +972,7 @@ convert: @-$(CHMOD) 0700 $(EXEC_FILES) *.sh *.cmd TestScripts/*.sh TestScripts/*.cmd @-$(CHMOD) 0700 *.cmd *.sh GNUmakefile GNUmakefile-cross TestScripts/*.sh -unix2dos --keepdate --quiet $(TEXT_FILES) .*.yml *.asm *.cmd TestScripts/*.* - -dos2unix --keepdate --quiet GNUmakefile GNUmakefile-cross *.supp *.s *.sh *.mapfile TestScripts/*.sh + -dos2unix --keepdate --quiet GNUmakefile GNUmakefile-cross *.supp *.s *.sh *.mapfile TestScripts/*.sh TestScripts/*.patch ifneq ($(IS_DARWIN),0) @-xattr -c * endif diff --git a/GNUmakefile-cross b/GNUmakefile-cross index 70fea6ca..3b4cba2e 100755 --- a/GNUmakefile-cross +++ b/GNUmakefile-cross @@ -283,7 +283,7 @@ INCL := $(filter-out resource.h,$(sort $(wildcard *.h))) OBJS := $(SRCS:.cpp=.o) # List test.cpp first to tame C++ static initialization problems. -TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp fipsalgt.cpp dlltest.cpp +TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp fipsalgt.cpp dlltest.cpp TESTINCL := bench.h factory.h validate.h TESTOBJS := $(TESTSRCS:.cpp=.o) LIBOBJS := $(filter-out $(TESTOBJS),$(OBJS)) diff --git a/TestScripts/tweetnacl.patch b/TestScripts/tweetnacl.patch new file mode 100644 index 00000000..6f9e782f --- /dev/null +++ b/TestScripts/tweetnacl.patch @@ -0,0 +1,968 @@ +--- tweetnacl.c 2018-01-17 21:26:25.086390308 -0500 ++++ tweetnacl.cpp 2018-01-17 21:26:25.088390282 -0500 +@@ -1,19 +1,33 @@ +-#include "tweetnacl.h" +-#define FOR(i,n) for (i = 0;i < n;++i) +-#define sv static void +- +-typedef unsigned char u8; +-typedef unsigned long u32; +-typedef unsigned long long u64; +-typedef long long i64; +-typedef i64 gf[16]; +-extern void randombytes(u8 *,u64); ++// tweetnacl.cpp - modified tweetnacl.c placed in public domain by Jeffrey Walton. ++// The NaCl library and tweetnacl.c is public domain source code ++// written by Daniel J. Bernstein, Bernard van Gastel, Wesley ++// Janssen, Tanja Lange, Peter Schwabe and Sjaak Smetsers. ++ ++#include "pch.h" ++#include "config.h" ++#include "nacl.h" ++#include "misc.h" ++#include "osrng.h" ++#include "stdcpp.h" ++ ++// Don't destroy const time properties when squashing warnings. ++#if CRYPTOPP_MSC_VERSION ++# pragma warning(disable: 4242 4244 4245) ++#endif ++ ++#ifndef CRYPTOPP_DISABLE_NACL + +-static const u8 +- _0[16], ++NAMESPACE_BEGIN(CryptoPP) ++NAMESPACE_BEGIN(NaCl) ++ ++typedef int64_t gf[16]; ++ ++static const uint8_t ++ _0[32] = {0}, + _9[32] = {9}; ++ + static const gf +- gf0, ++ gf0 = {0}, + gf1 = {1}, + _121665 = {0xDB41,1}, + D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203}, +@@ -22,119 +36,126 @@ + Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666}, + I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83}; + +-static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); } ++// Added by Crypto++ for TweetNaCl ++static void randombytes(uint8_t * block, uint64_t size) ++{ ++ DefaultAutoSeededRNG prng; ++ prng.GenerateBlock(block, (size_t)size); ++} ++ ++static uint32_t L32(uint32_t x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); } + +-static u32 ld32(const u8 *x) ++static uint32_t ld32(const uint8_t *x) + { +- u32 u = x[3]; ++ uint32_t u = x[3]; + u = (u<<8)|x[2]; + u = (u<<8)|x[1]; + return (u<<8)|x[0]; + } + +-static u64 dl64(const u8 *x) ++static uint64_t dl64(const uint8_t *x) + { +- u64 i,u=0; +- FOR(i,8) u=(u<<8)|x[i]; ++ uint64_t i,u=0; ++ for(i=0; i<8; ++i) u=(u<<8)|x[i]; + return u; + } + +-sv st32(u8 *x,u32 u) ++static void st32(uint8_t *x,uint32_t u) + { + int i; +- FOR(i,4) { x[i] = u; u >>= 8; } ++ for(i=0; i<4; ++i) { x[i] = u; u >>= 8; } + } + +-sv ts64(u8 *x,u64 u) ++static void ts64(uint8_t *x,uint64_t u) + { + int i; + for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; } + } + +-static int vn(const u8 *x,const u8 *y,int n) ++static int verify_n(const uint8_t *x,const uint8_t *y,uint32_t n) + { +- u32 i,d = 0; +- FOR(i,n) d |= x[i]^y[i]; ++ uint32_t i,d = 0; ++ for(i=0; i<n; ++i) d |= x[i]^y[i]; + return (1 & ((d - 1) >> 8)) - 1; + } + +-int crypto_verify_16(const u8 *x,const u8 *y) ++int crypto_verify_16(const uint8_t *x,const uint8_t *y) + { +- return vn(x,y,16); ++ return verify_n(x,y,16); + } + +-int crypto_verify_32(const u8 *x,const u8 *y) ++int crypto_verify_32(const uint8_t *x,const uint8_t *y) + { +- return vn(x,y,32); ++ return verify_n(x,y,32); + } + +-sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h) ++static void core(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c,int h) + { +- u32 w[16],x[16],y[16],t[4]; ++ uint32_t w[16],x[16],y[16],t[4]; + int i,j,m; + +- FOR(i,4) { ++ for(i=0; i<4; ++i) { + x[5*i] = ld32(c+4*i); + x[1+i] = ld32(k+4*i); + x[6+i] = ld32(in+4*i); + x[11+i] = ld32(k+16+4*i); + } + +- FOR(i,16) y[i] = x[i]; ++ for(i=0; i<16; ++i) y[i] = x[i]; + +- FOR(i,20) { +- FOR(j,4) { +- FOR(m,4) t[m] = x[(5*j+4*m)%16]; ++ for(i=0; i<20; ++i) { ++ for(j=0; j<4; ++j) { ++ for(m=0; m<4; ++m) t[m] = x[(5*j+4*m)%16]; + t[1] ^= L32(t[0]+t[3], 7); + t[2] ^= L32(t[1]+t[0], 9); + t[3] ^= L32(t[2]+t[1],13); + t[0] ^= L32(t[3]+t[2],18); +- FOR(m,4) w[4*j+(j+m)%4] = t[m]; ++ for(m=0; m<4; ++m) w[4*j+(j+m)%4] = t[m]; + } +- FOR(m,16) x[m] = w[m]; ++ for(m=0; m<16; ++m) x[m] = w[m]; + } + + if (h) { +- FOR(i,16) x[i] += y[i]; +- FOR(i,4) { ++ for(i=0; i<16; ++i) x[i] += y[i]; ++ for(i=0; i<4; ++i) { + x[5*i] -= ld32(c+4*i); + x[6+i] -= ld32(in+4*i); + } +- FOR(i,4) { ++ for(i=0; i<4; ++i) { + st32(out+4*i,x[5*i]); + st32(out+16+4*i,x[6+i]); + } + } else +- FOR(i,16) st32(out + 4 * i,x[i] + y[i]); ++ for(i=0; i<16; ++i) st32(out + 4 * i,x[i] + y[i]); + } + +-int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) ++int crypto_core_salsa20(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c) + { + core(out,in,k,c,0); + return 0; + } + +-int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) ++int crypto_core_hsalsa20(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c) + { + core(out,in,k,c,1); + return 0; + } + +-static const u8 sigma[16] = "expand 32-byte k"; ++static const uint8_t sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B}; + +-int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k) ++int crypto_stream_salsa20_xor(uint8_t *c,const uint8_t *m,uint64_t b,const uint8_t *n,const uint8_t *k) + { +- u8 z[16],x[64]; +- u32 u,i; ++ uint8_t z[16],x[64]; ++ uint32_t u,i; + if (!b) return 0; +- FOR(i,16) z[i] = 0; +- FOR(i,8) z[i] = n[i]; ++ for(i=0; i<16; ++i) z[i] = 0; ++ for(i=0; i<8; ++i) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); +- FOR(i,64) c[i] = (m?m[i]:0) ^ x[i]; ++ for(i=0; i<64; ++i) c[i] = (m?m[i]:0) ^ x[i]; + u = 1; + for (i = 8;i < 16;++i) { +- u += (u32) z[i]; ++ u += (uint32_t) z[i]; + z[i] = u; + u >>= 8; + } +@@ -144,50 +165,50 @@ + } + if (b) { + crypto_core_salsa20(x,z,k,sigma); +- FOR(i,b) c[i] = (m?m[i]:0) ^ x[i]; ++ for(i=0; i<b; ++i) c[i] = (m?m[i]:0) ^ x[i]; + } + return 0; + } + +-int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k) ++int crypto_stream_salsa20(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k) + { + return crypto_stream_salsa20_xor(c,0,d,n,k); + } + +-int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k) ++int crypto_stream(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k) + { +- u8 s[32]; ++ uint8_t s[32]; + crypto_core_hsalsa20(s,n,k,sigma); + return crypto_stream_salsa20(c,d,n+16,s); + } + +-int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) ++int crypto_stream_xor(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k) + { +- u8 s[32]; ++ uint8_t s[32]; + crypto_core_hsalsa20(s,n,k,sigma); + return crypto_stream_salsa20_xor(c,m,d,n+16,s); + } + +-sv add1305(u32 *h,const u32 *c) ++static void add1305(uint32_t *h,const uint32_t *c) + { +- u32 j,u = 0; +- FOR(j,17) { ++ uint32_t j,u = 0; ++ for(j=0; j<17; ++j) { + u += h[j] + c[j]; + h[j] = u & 255; + u >>= 8; + } + } + +-static const u32 minusp[17] = { ++static const uint32_t minusp[17] = { + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 + } ; + +-int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k) ++int crypto_onetimeauth(uint8_t *out,const uint8_t *m,uint64_t n,const uint8_t *k) + { +- u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17]; ++ uint32_t s,i,j,u,x[17],r[17],h[17],c[17],g[17]; + +- FOR(j,17) r[j]=h[j]=0; +- FOR(j,16) r[j]=k[j]; ++ for(j=0; j<17; ++j) r[j]=h[j]=0; ++ for(j=0; j<16; ++j) r[j]=k[j]; + r[3]&=15; + r[4]&=252; + r[7]&=15; +@@ -197,25 +218,25 @@ + r[15]&=15; + + while (n > 0) { +- FOR(j,17) c[j] = 0; ++ for(j=0; j<17; ++j) c[j] = 0; + for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j]; + c[j] = 1; + m += j; n -= j; + add1305(h,c); +- FOR(i,17) { ++ for(i=0; i<17; ++i) { + x[i] = 0; +- FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]); ++ for(j=0; j<17; ++j) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]); + } +- FOR(i,17) h[i] = x[i]; ++ for(i=0; i<17; ++i) h[i] = x[i]; + u = 0; +- FOR(j,16) { ++ for(j=0; j<16; ++j) { + u += h[j]; + h[j] = u & 255; + u >>= 8; + } + u += h[16]; h[16] = u & 3; + u = 5 * (u >> 2); +- FOR(j,16) { ++ for(j=0; j<16; ++j) { + u += h[j]; + h[j] = u & 255; + u >>= 8; +@@ -223,84 +244,84 @@ + u += h[16]; h[16] = u; + } + +- FOR(j,17) g[j] = h[j]; ++ for(j=0; j<17; ++j) g[j] = h[j]; + add1305(h,minusp); + s = -(h[16] >> 7); +- FOR(j,17) h[j] ^= s & (g[j] ^ h[j]); ++ for(j=0; j<17; ++j) h[j] ^= s & (g[j] ^ h[j]); + +- FOR(j,16) c[j] = k[j + 16]; ++ for(j=0; j<16; ++j) c[j] = k[j + 16]; + c[16] = 0; + add1305(h,c); +- FOR(j,16) out[j] = h[j]; ++ for(j=0; j<16; ++j) out[j] = h[j]; + return 0; + } + +-int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k) ++int crypto_onetimeauth_verify(const uint8_t *h,const uint8_t *m,uint64_t n,const uint8_t *k) + { +- u8 x[16]; ++ uint8_t x[16]; + crypto_onetimeauth(x,m,n,k); + return crypto_verify_16(h,x); + } + +-int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) ++int crypto_secretbox(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k) + { + int i; + if (d < 32) return -1; + crypto_stream_xor(c,m,d,n,k); + crypto_onetimeauth(c + 16,c + 32,d - 32,c); +- FOR(i,16) c[i] = 0; ++ for(i=0; i<16; ++i) c[i] = 0; + return 0; + } + +-int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) ++int crypto_secretbox_open(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k) + { + int i; +- u8 x[32]; ++ uint8_t x[32]; + if (d < 32) return -1; + crypto_stream(x,32,n,k); + if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1; + crypto_stream_xor(m,c,d,n,k); +- FOR(i,32) m[i] = 0; ++ for(i=0; i<32; ++i) m[i] = 0; + return 0; + } + +-sv set25519(gf r, const gf a) ++static void set25519(gf r, const gf a) + { + int i; +- FOR(i,16) r[i]=a[i]; ++ for(i=0; i<16; ++i) r[i]=a[i]; + } + +-sv car25519(gf o) ++static void car25519(gf o) + { + int i; +- i64 c; +- FOR(i,16) { ++ int64_t c; ++ for(i=0; i<16; ++i) { + o[i]+=(1LL<<16); + c=o[i]>>16; + o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15); +- o[i]-=c<<16; ++ o[i]-=((uint64_t)c)<<16; + } + } + +-sv sel25519(gf p,gf q,int b) ++static void sel25519(gf p,gf q,int b) + { +- i64 t,i,c=~(b-1); +- FOR(i,16) { ++ int64_t t,i,c=~(b-1); ++ for(i=0; i<16; ++i) { + t= c&(p[i]^q[i]); + p[i]^=t; + q[i]^=t; + } + } + +-sv pack25519(u8 *o,const gf n) ++static void pack25519(uint8_t *o,const gf n) + { + int i,j,b; + gf m,t; +- FOR(i,16) t[i]=n[i]; ++ for(i=0; i<16; ++i) t[i]=n[i]; + car25519(t); + car25519(t); + car25519(t); +- FOR(j,2) { ++ for(j=0; j<2; ++j) { + m[0]=t[0]-0xffed; + for(i=1;i<15;i++) { + m[i]=t[i]-0xffff-((m[i-1]>>16)&1); +@@ -311,7 +332,7 @@ + m[14]&=0xffff; + sel25519(t,m,1-b); + } +- FOR(i,16) { ++ for(i=0; i<16; ++i) { + o[2*i]=t[i]&0xff; + o[2*i+1]=t[i]>>8; + } +@@ -319,88 +340,88 @@ + + static int neq25519(const gf a, const gf b) + { +- u8 c[32],d[32]; ++ uint8_t c[32],d[32]; + pack25519(c,a); + pack25519(d,b); + return crypto_verify_32(c,d); + } + +-static u8 par25519(const gf a) ++static uint8_t par25519(const gf a) + { +- u8 d[32]; ++ uint8_t d[32]; + pack25519(d,a); + return d[0]&1; + } + +-sv unpack25519(gf o, const u8 *n) ++static void unpack25519(gf o, const uint8_t *n) + { + int i; +- FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8); ++ for(i=0; i<16; ++i) o[i]=n[2*i]+((int64_t)n[2*i+1]<<8); + o[15]&=0x7fff; + } + +-sv A(gf o,const gf a,const gf b) ++static void A(gf o,const gf a,const gf b) + { + int i; +- FOR(i,16) o[i]=a[i]+b[i]; ++ for(i=0; i<16; ++i) o[i]=a[i]+b[i]; + } + +-sv Z(gf o,const gf a,const gf b) ++static void Z(gf o,const gf a,const gf b) + { + int i; +- FOR(i,16) o[i]=a[i]-b[i]; ++ for(i=0; i<16; ++i) o[i]=a[i]-b[i]; + } + +-sv M(gf o,const gf a,const gf b) ++static void M(gf o,const gf a,const gf b) + { +- i64 i,j,t[31]; +- FOR(i,31) t[i]=0; +- FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j]; +- FOR(i,15) t[i]+=38*t[i+16]; +- FOR(i,16) o[i]=t[i]; ++ int64_t i,j,t[31]; ++ for(i=0; i<31; ++i) t[i]=0; ++ for(i=0; i<16; ++i) for(j=0; j<16; ++j) t[i+j]+=a[i]*b[j]; ++ for(i=0; i<15; ++i) t[i]+=38*t[i+16]; ++ for(i=0; i<16; ++i) o[i]=t[i]; + car25519(o); + car25519(o); + } + +-sv S(gf o,const gf a) ++static void S(gf o,const gf a) + { + M(o,a,a); + } + +-sv inv25519(gf o,const gf i) ++static void inv25519(gf o,const gf i) + { + gf c; + int a; +- FOR(a,16) c[a]=i[a]; ++ for(a=0; a<16; ++a) c[a]=i[a]; + for(a=253;a>=0;a--) { + S(c,c); + if(a!=2&&a!=4) M(c,c,i); + } +- FOR(a,16) o[a]=c[a]; ++ for(a=0; a<16; ++a) o[a]=c[a]; + } + +-sv pow2523(gf o,const gf i) ++static void pow2523(gf o,const gf i) + { + gf c; + int a; +- FOR(a,16) c[a]=i[a]; ++ for(a=0; a<16; ++a) c[a]=i[a]; + for(a=250;a>=0;a--) { + S(c,c); + if(a!=1) M(c,c,i); + } +- FOR(a,16) o[a]=c[a]; ++ for(a=0; a<16; ++a) o[a]=c[a]; + } + +-int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p) ++int crypto_scalarmult(uint8_t *q,const uint8_t *n,const uint8_t *p) + { +- u8 z[32]; +- i64 x[80],r,i; ++ uint8_t z[32]; ++ int64_t x[80],r,i; + gf a,b,c,d,e,f; +- FOR(i,31) z[i]=n[i]; ++ for(i=0; i<31; ++i) z[i]=n[i]; + z[31]=(n[31]&127)|64; + z[0]&=248; + unpack25519(x,p); +- FOR(i,16) { ++ for(i=0; i<16; ++i) { + b[i]=x[i]; + d[i]=a[i]=c[i]=0; + } +@@ -430,7 +451,7 @@ + sel25519(a,b,r); + sel25519(c,d,r); + } +- FOR(i,16) { ++ for(i=0; i<16; ++i) { + x[i+16]=a[i]; + x[i+32]=c[i]; + x[i+48]=b[i]; +@@ -442,113 +463,115 @@ + return 0; + } + +-int crypto_scalarmult_base(u8 *q,const u8 *n) ++int crypto_scalarmult_base(uint8_t *q,const uint8_t *n) + { + return crypto_scalarmult(q,n,_9); + } + +-int crypto_box_keypair(u8 *y,u8 *x) ++int crypto_box_keypair(uint8_t *y,uint8_t *x) + { + randombytes(x,32); + return crypto_scalarmult_base(y,x); + } + +-int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x) ++// S must not be all 0's ++int crypto_box_beforenm(uint8_t *k,const uint8_t *y,const uint8_t *x) + { +- u8 s[32]; +- crypto_scalarmult(s,x,y); ++ uint8_t s[32]; ++ if(crypto_scalarmult(s,x,y) != 0) return -1; ++ if(verify_n(s,_0,32) != -1) return -1; + return crypto_core_hsalsa20(k,_0,s,sigma); + } + +-int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) ++int crypto_box_afternm(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k) + { + return crypto_secretbox(c,m,d,n,k); + } + +-int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) ++int crypto_box_open_afternm(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k) + { + return crypto_secretbox_open(m,c,d,n,k); + } + +-int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x) ++int crypto_box(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x) + { +- u8 k[32]; +- crypto_box_beforenm(k,y,x); ++ uint8_t k[32]; ++ if(crypto_box_beforenm(k,y,x) != 0) return -1; + return crypto_box_afternm(c,m,d,n,k); + } + +-int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x) ++int crypto_box_open(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x) + { +- u8 k[32]; +- crypto_box_beforenm(k,y,x); ++ uint8_t k[32]; ++ if(crypto_box_beforenm(k,y,x) != 0) return -1; + return crypto_box_open_afternm(m,c,d,n,k); + } + +-static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); } +-static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); } +-static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); } +-static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); } +-static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); } +-static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); } +-static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); } +- +-static const u64 K[80] = +-{ +- 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, +- 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, +- 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, +- 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, +- 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, +- 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, +- 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, +- 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, +- 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, +- 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, +- 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, +- 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, +- 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, +- 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, +- 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, +- 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, +- 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, +- 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, +- 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, +- 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL ++static uint64_t R(uint64_t x,int c) { return (x >> c) | (x << (64 - c)); } ++static uint64_t Ch(uint64_t x,uint64_t y,uint64_t z) { return (x & y) ^ (~x & z); } ++static uint64_t Maj(uint64_t x,uint64_t y,uint64_t z) { return (x & y) ^ (x & z) ^ (y & z); } ++static uint64_t Sigma0(uint64_t x) { return R(x,28) ^ R(x,34) ^ R(x,39); } ++static uint64_t Sigma1(uint64_t x) { return R(x,14) ^ R(x,18) ^ R(x,41); } ++static uint64_t sigma0(uint64_t x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); } ++static uint64_t sigma1(uint64_t x) { return R(x,19) ^ R(x,61) ^ (x >> 6); } ++ ++static const uint64_t K[80] = ++{ ++ W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), ++ W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), ++ W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), ++ W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), ++ W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), ++ W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), ++ W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), ++ W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), ++ W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), ++ W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), ++ W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), ++ W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), ++ W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), ++ W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), ++ W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), ++ W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), ++ W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), ++ W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), ++ W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), ++ W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) + }; + +-int crypto_hashblocks(u8 *x,const u8 *m,u64 n) ++int crypto_hashblocks(uint8_t *x,const uint8_t *m,uint64_t n) + { +- u64 z[8],b[8],a[8],w[16],t; ++ uint64_t z[8],b[8],a[8],w[16],t; + int i,j; + +- FOR(i,8) z[i] = a[i] = dl64(x + 8 * i); ++ for(i=0; i<8; ++i) z[i] = a[i] = dl64(x + 8 * i); + + while (n >= 128) { +- FOR(i,16) w[i] = dl64(m + 8 * i); ++ for(i=0; i<16; ++i) w[i] = dl64(m + 8 * i); + +- FOR(i,80) { +- FOR(j,8) b[j] = a[j]; ++ for(i=0; i<80; ++i) { ++ for(j=0; j<8; ++j) b[j] = a[j]; + t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16]; + b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]); + b[3] += t; +- FOR(j,8) a[(j+1)%8] = b[j]; ++ for(j=0; j<8; ++j) a[(j+1)%8] = b[j]; + if (i%16 == 15) +- FOR(j,16) ++ for(j=0; j<16; ++j) + w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]); + } + +- FOR(i,8) { a[i] += z[i]; z[i] = a[i]; } ++ for(i=0; i<8; ++i) { a[i] += z[i]; z[i] = a[i]; } + + m += 128; + n -= 128; + } + +- FOR(i,8) ts64(x+8*i,z[i]); ++ for(i=0; i<8; ++i) ts64(x+8*i,z[i]); + + return n; + } + +-static const u8 iv[64] = { ++static const uint8_t iv[64] = { + 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, + 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, + 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, +@@ -559,20 +582,20 @@ + 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 + } ; + +-int crypto_hash(u8 *out,const u8 *m,u64 n) ++int crypto_hash(uint8_t *out,const uint8_t *m,uint64_t n) + { +- u8 h[64],x[256]; +- u64 i,b = n; ++ uint8_t h[64],x[256]; ++ uint64_t i,b = n; + +- FOR(i,64) h[i] = iv[i]; ++ for(i=0; i<64; ++i) h[i] = iv[i]; + + crypto_hashblocks(h,m,n); + m += n; + n &= 127; + m -= n; + +- FOR(i,256) x[i] = 0; +- FOR(i,n) x[i] = m[i]; ++ for(i=0; i<256; ++i) x[i] = 0; ++ for(i=0; i<n; ++i) x[i] = m[i]; + x[n] = 128; + + n = 256-128*(n<112); +@@ -580,12 +603,12 @@ + ts64(x+n-8,b<<3); + crypto_hashblocks(h,x,n); + +- FOR(i,64) out[i] = h[i]; ++ for(i=0; i<64; ++i) out[i] = h[i]; + + return 0; + } + +-sv add(gf p[4],gf q[4]) ++static void add(gf p[4],gf q[4]) + { + gf a,b,c,d,t,e,f,g,h; + +@@ -610,14 +633,14 @@ + M(p[3], e, h); + } + +-sv cswap(gf p[4],gf q[4],u8 b) ++static void cswap(gf p[4],gf q[4],uint8_t b) + { + int i; +- FOR(i,4) ++ for(i=0; i<4; ++i) + sel25519(p[i],q[i],b); + } + +-sv pack(u8 *r,gf p[4]) ++static void pack(uint8_t *r,gf p[4]) + { + gf tx, ty, zi; + inv25519(zi, p[2]); +@@ -627,7 +650,7 @@ + r[31] ^= par25519(tx) << 7; + } + +-sv scalarmult(gf p[4],gf q[4],const u8 *s) ++static void scalarmult(gf p[4],gf q[4],const uint8_t *s) + { + int i; + set25519(p[0],gf0); +@@ -635,7 +658,7 @@ + set25519(p[2],gf1); + set25519(p[3],gf0); + for (i = 255;i >= 0;--i) { +- u8 b = (s[i/8]>>(i&7))&1; ++ uint8_t b = (s[i/8]>>(i&7))&1; + cswap(p,q,b); + add(q,p); + add(p,p); +@@ -643,7 +666,7 @@ + } + } + +-sv scalarbase(gf p[4],const u8 *s) ++static void scalarbase(gf p[4],const uint8_t *s) + { + gf q[4]; + set25519(q[0],X); +@@ -653,9 +676,9 @@ + scalarmult(p,q,s); + } + +-int crypto_sign_keypair(u8 *pk, u8 *sk) ++int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) + { +- u8 d[64]; ++ uint8_t d[64]; + gf p[4]; + int i; + +@@ -668,50 +691,50 @@ + scalarbase(p,d); + pack(pk,p); + +- FOR(i,32) sk[32 + i] = pk[i]; ++ for(i=0; i<32; ++i) sk[32 + i] = pk[i]; + return 0; + } + +-static const u64 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}; ++static const uint64_t 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}; + +-sv modL(u8 *r,i64 x[64]) ++static void modL(uint8_t *r,int64_t x[64]) + { +- i64 carry,i,j; ++ int64_t carry,i,j; + for (i = 63;i >= 32;--i) { + carry = 0; + for (j = i - 32;j < i - 12;++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; +- x[j] -= carry << 8; ++ x[j] -= ((uint64_t)carry) << 8; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; +- FOR(j,32) { ++ for(j=0; j<32; ++j) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } +- FOR(j,32) x[j] -= carry * L[j]; +- FOR(i,32) { ++ for(j=0; j<32; ++j) x[j] -= carry * L[j]; ++ for(i=0; i<32; ++i) { + x[i+1] += x[i] >> 8; + r[i] = x[i] & 255; + } + } + +-sv reduce(u8 *r) ++static void reduce(uint8_t *r) + { +- i64 x[64],i; +- FOR(i,64) x[i] = (u64) r[i]; +- FOR(i,64) r[i] = 0; ++ int64_t x[64],i; ++ for(i=0; i<64; ++i) x[i] = (uint64_t) r[i]; ++ for(i=0; i<64; ++i) r[i] = 0; + modL(r,x); + } + +-int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk) ++int crypto_sign(uint8_t *sm,uint64_t *smlen,const uint8_t *m,uint64_t n,const uint8_t *sk) + { +- u8 d[64],h[64],r[64]; +- i64 i,j,x[64]; ++ uint8_t d[64],h[64],r[64]; ++ uint64_t i; int64_t j,x[64]; + gf p[4]; + + crypto_hash(d, sk, 32); +@@ -720,27 +743,27 @@ + d[31] |= 64; + + *smlen = n+64; +- FOR(i,n) sm[64 + i] = m[i]; +- FOR(i,32) sm[32 + i] = d[32 + i]; ++ for(i=0; i<n; ++i) sm[64 + i] = m[i]; ++ for(i=0; i<32; ++i) sm[32 + i] = d[32 + i]; + + crypto_hash(r, sm+32, n+32); + reduce(r); + scalarbase(p,r); + pack(sm,p); + +- FOR(i,32) sm[i+32] = sk[i+32]; ++ for(i=0; i<32; ++i) sm[i+32] = sk[i+32]; + crypto_hash(h,sm,n + 64); + reduce(h); + +- FOR(i,64) x[i] = 0; +- FOR(i,32) x[i] = (u64) r[i]; +- FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j]; ++ for(i=0; i<64; ++i) x[i] = 0; ++ for(i=0; i<32; ++i) x[i] = (uint64_t) r[i]; ++ for(i=0; i<32; ++i) for(j=0; j<32; ++j) x[i+j] += h[i] * (uint64_t) d[j]; + modL(sm + 32,x); + + return 0; + } + +-static int unpackneg(gf r[4],const u8 p[32]) ++static int unpackneg(gf r[4],const uint8_t p[32]) + { + gf t, chk, num, den, den2, den4, den6; + set25519(r[2],gf1); +@@ -776,10 +799,10 @@ + return 0; + } + +-int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk) ++int crypto_sign_open(uint8_t *m,uint64_t *mlen,const uint8_t *sm,uint64_t n,const uint8_t *pk) + { + int i; +- u8 t[32],h[64]; ++ uint8_t t[32],h[64]; + gf p[4],q[4]; + + *mlen = -1; +@@ -787,8 +810,8 @@ + + if (unpackneg(q,pk)) return -1; + +- FOR(i,n) m[i] = sm[i]; +- FOR(i,32) m[i+32] = pk[i]; ++ for(i=0; i<n; ++i) m[i] = sm[i]; ++ for(i=0; i<32; ++i) m[i+32] = pk[i]; + crypto_hash(h,m,n); + reduce(h); + scalarmult(p,q,h); +@@ -799,11 +822,16 @@ + + n -= 64; + if (crypto_verify_32(sm, t)) { +- FOR(i,n) m[i] = 0; ++ for(i=0; i<n; ++i) m[i] = 0; + return -1; + } + +- FOR(i,n) m[i] = sm[i + 64]; ++ for(i=0; i<n; ++i) m[i] = sm[i + 64]; + *mlen = n; + return 0; + } ++ ++NAMESPACE_END // CryptoPP ++NAMESPACE_END // NaCl ++ ++#endif // NO_OS_DEPENDENCE +\ No newline at end of file diff --git a/TestScripts/tweetnacl.sh b/TestScripts/tweetnacl.sh new file mode 100755 index 00000000..824ed214 --- /dev/null +++ b/TestScripts/tweetnacl.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# Written and placed in public domain by Jeffrey Walton +# +# This script fetches TweetNaCl from Bernstein's site, and then +# prepares it for use in Crypto++ by applying tweetnacl.patch. +# The script should be run from the Crypto++ root directory on a +# Unix machine because of the use of Unix tools like wget. + +curl https://tweetnacl.cr.yp.to/20140427/tweetnacl.h > tweetnacl.h +curl https://tweetnacl.cr.yp.to/20140427/tweetnacl.c > tweetnacl.c + +# Fix whitespace +sed -e 's/[[:space:]]*$//' tweetnacl.h > tweetnacl.h.fixed +mv tweetnacl.h.fixed tweetnacl.h +sed -e 's/[[:space:]]*$//' tweetnacl.c > tweetnacl.c.fixed +mv tweetnacl.c.fixed tweetnacl.c + +if [[ -e "TestScripts/tweetnacl.patch" ]]; then + cp "TestScripts/tweetnacl.patch" . +fi + +if [[ ! -e "tweetnacl.patch" ]]; then + echo "Cannot find tweetnacl.patch. Please make sure it exists in the root directory." + echo "It can be created with 'diff -u tweetnacl.c tweetnacl.cpp > tweetnacl.patch'" + [[ "$0" = "$BASH_SOURCE" ]] && exit 0 || return 0 +fi + +# Normalize line endings +dos2unix tweetnacl.h tweetnacl.cpp tweetnacl.patch + +# Apply patch +patch --unified --binary -p0 < tweetnacl.patch +mv tweetnacl.c tweetnacl.cpp + +# Place things where they belong in source control +cp tweetnacl.sh TestScripts/ +cp tweetnacl.patch TestScripts/ + +# Fix whitespace +sed -e 's/[[:space:]]*$//' tweetnacl.h > tweetnacl.h.fixed +mv tweetnacl.h.fixed tweetnacl.h +sed -e 's/[[:space:]]*$//' tweetnacl.cpp > tweetnacl.cpp.fixed +mv tweetnacl.cpp.fixed tweetnacl.cpp + +# Convert to MS DOS for source control +unix2dos tweetnacl.h tweetnacl.cpp @@ -169,6 +169,7 @@ /// the namespace, there are two additional namespaces.
/// <ul>
/// <li>Name - namespace for names used with \p NameValuePairs and documented in argnames.h
+/// <li>NaCl - namespace for NaCl library functions like crypto_box, crypto_box_open, crypto_sign, and crypto_sign_open
/// <li>Test - namespace for testing and benchmarks classes
/// <li>Weak - namespace for weak and wounded algorithms, like ARC4, MD5 and Pananma
/// </ul>
diff --git a/cryptest.nmake b/cryptest.nmake index 985a4b4c..f329d3fd 100644 --- a/cryptest.nmake +++ b/cryptest.nmake @@ -47,13 +47,13 @@ # If you use 'make sources' from Linux makefile, then add 'winpipes.cpp' to the list below.
-LIB_SRCS = cryptlib.cpp cpu.cpp integer.cpp 3way.cpp adler32.cpp algebra.cpp algparam.cpp arc4.cpp aria-simd.cpp aria.cpp ariatab.cpp asn.cpp authenc.cpp base32.cpp base64.cpp basecode.cpp bfinit.cpp blake2-simd.cpp blake2.cpp blowfish.cpp blumshub.cpp camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp channels.cpp cmac.cpp crc-simd.cpp crc.cpp default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp dll.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gcm-simd.cpp gcm.cpp gf256.cpp gf2_32.cpp gf2n.cpp gfpcrypt.cpp gost.cpp gzip.cpp hex.cpp hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp keccak.cpp luc.cpp mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp neon-simd.cpp network.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp pssr.cpp pubkey.cpp queue.cpp rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp rijndael-simd.cpp rijndael.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp seal.cpp seed.cpp serpent.cpp sha-simd.cpp sha.cpp sha3.cpp shacal2-simd.cpp shacal2.cpp shark.cpp sharkbox.cpp simon.cpp simon-simd.cpp skipjack.cpp sm3.cpp sm4.cpp socketft.cpp sosemanuk.cpp speck.cpp speck-simd.cpp square.cpp squaretb.cpp sse-simd.cpp strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp trdlocal.cpp ttmac.cpp twofish.cpp vmac.cpp wait.cpp wake.cpp whrlpool.cpp winpipes.cpp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp
+LIB_SRCS = cryptlib.cpp cpu.cpp integer.cpp 3way.cpp adler32.cpp algebra.cpp algparam.cpp arc4.cpp aria-simd.cpp aria.cpp ariatab.cpp asn.cpp authenc.cpp base32.cpp base64.cpp basecode.cpp bfinit.cpp blake2-simd.cpp blake2.cpp blowfish.cpp blumshub.cpp camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp channels.cpp cmac.cpp crc-simd.cpp crc.cpp default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp dll.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gcm-simd.cpp gcm.cpp gf256.cpp gf2_32.cpp gf2n.cpp gfpcrypt.cpp gost.cpp gzip.cpp hex.cpp hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp keccak.cpp luc.cpp mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp neon-simd.cpp network.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp pssr.cpp pubkey.cpp queue.cpp rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp rijndael-simd.cpp rijndael.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp seal.cpp seed.cpp serpent.cpp sha-simd.cpp sha.cpp sha3.cpp shacal2-simd.cpp shacal2.cpp shark.cpp sharkbox.cpp simon.cpp simon-simd.cpp skipjack.cpp sm3.cpp sm4.cpp socketft.cpp sosemanuk.cpp speck.cpp speck-simd.cpp square.cpp squaretb.cpp sse-simd.cpp strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp trdlocal.cpp ttmac.cpp tweetnacl.cpp twofish.cpp vmac.cpp wait.cpp wake.cpp whrlpool.cpp winpipes.cpp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp
-LIB_OBJS = cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj algparam.obj arc4.obj aria-simd.obj aria.obj ariatab.obj asn.obj authenc.obj base32.obj base64.obj basecode.obj bfinit.obj blake2-simd.obj blake2.obj blowfish.obj blumshub.obj camellia.obj cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj channels.obj cmac.obj crc-simd.obj crc.obj default.obj des.obj dessp.obj dh.obj dh2.obj dll.obj dsa.obj eax.obj ec2n.obj eccrypto.obj ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj filters.obj fips140.obj fipstest.obj gcm-simd.obj gcm.obj gf256.obj gf2_32.obj gf2n.obj gfpcrypt.obj gost.obj gzip.obj hex.obj hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj keccak.obj luc.obj mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj nbtheory.obj neon-simd.obj network.obj oaep.obj osrng.obj padlkrng.obj panama.obj pkcspad.obj poly1305.obj polynomi.obj pssr.obj pubkey.obj queue.obj rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj rijndael-simd.obj rijndael.obj ripemd.obj rng.obj rsa.obj rw.obj safer.obj salsa.obj seal.obj seed.obj serpent.obj sha-simd.obj sha.obj sha3.obj shacal2-simd.obj shacal2.obj shark.obj sharkbox.obj simon.obj simon-simd.obj skipjack.obj sm3.obj sm4.obj socketft.obj sosemanuk.obj speck.obj speck-simd.obj square.obj squaretb.obj sse-simd.obj strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj trdlocal.obj ttmac.obj twofish.obj vmac.obj wait.obj wake.obj whrlpool.obj winpipes.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj
+LIB_OBJS = cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj algparam.obj arc4.obj aria-simd.obj aria.obj ariatab.obj asn.obj authenc.obj base32.obj base64.obj basecode.obj bfinit.obj blake2-simd.obj blake2.obj blowfish.obj blumshub.obj camellia.obj cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj channels.obj cmac.obj crc-simd.obj crc.obj default.obj des.obj dessp.obj dh.obj dh2.obj dll.obj dsa.obj eax.obj ec2n.obj eccrypto.obj ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj filters.obj fips140.obj fipstest.obj gcm-simd.obj gcm.obj gf256.obj gf2_32.obj gf2n.obj gfpcrypt.obj gost.obj gzip.obj hex.obj hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj keccak.obj luc.obj mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj nbtheory.obj neon-simd.obj network.obj oaep.obj osrng.obj padlkrng.obj panama.obj pkcspad.obj poly1305.obj polynomi.obj pssr.obj pubkey.obj queue.obj rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj rijndael-simd.obj rijndael.obj ripemd.obj rng.obj rsa.obj rw.obj safer.obj salsa.obj seal.obj seed.obj serpent.obj sha-simd.obj sha.obj sha3.obj shacal2-simd.obj shacal2.obj shark.obj sharkbox.obj simon.obj simon-simd.obj skipjack.obj sm3.obj sm4.obj socketft.obj sosemanuk.obj speck.obj speck-simd.obj square.obj squaretb.obj sse-simd.obj strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj trdlocal.obj ttmac.obj tweetnacl.obj twofish.obj vmac.obj wait.obj wake.obj whrlpool.obj winpipes.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj
-TEST_SRCS = bench1.cpp bench2.cpp test.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp fipsalgt.cpp dlltest.cpp fipstest.cpp
+TEST_SRCS = bench1.cpp bench2.cpp test.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp fipsalgt.cpp dlltest.cpp fipstest.cpp
-TEST_OBJS = bench1.obj bench2.obj test.obj validat0.obj validat1.obj validat2.obj validat3.obj datatest.obj regtest1.obj regtest2.obj regtest3.obj fipsalgt.obj dlltest.obj fipstest.obj
+TEST_OBJS = bench1.obj bench2.obj test.obj validat0.obj validat1.obj validat2.obj validat3.obj validat4.obj datatest.obj regtest1.obj regtest2.obj regtest3.obj fipsalgt.obj dlltest.obj fipstest.obj
CXX = cl.exe
LD = link.exe
diff --git a/cryptest.vcxproj b/cryptest.vcxproj index 40078795..72dfad26 100644 --- a/cryptest.vcxproj +++ b/cryptest.vcxproj @@ -212,6 +212,7 @@ <ClCompile Include="validat1.cpp" />
<ClCompile Include="validat2.cpp" />
<ClCompile Include="validat3.cpp" />
+ <ClCompile Include="validat4.cpp" />
</ItemGroup>
<!-- Header Files -->
<ItemGroup>
diff --git a/cryptest.vcxproj.filters b/cryptest.vcxproj.filters index 894c4ce5..b9728bdf 100644 --- a/cryptest.vcxproj.filters +++ b/cryptest.vcxproj.filters @@ -397,6 +397,9 @@ <ClCompile Include="validat3.cpp">
<Filter>Source Code</Filter>
</ClCompile>
+ <ClCompile Include="validat4.cpp">
+ <Filter>Source Code</Filter>
+ </ClCompile>
<ClCompile Include="fipsalgt.cpp">
<Filter>Source Code</Filter>
</ClCompile>
@@ -545,6 +545,12 @@ DOCUMENTED_NAMESPACE_BEGIN(Weak) DOCUMENTED_NAMESPACE_END
#endif
+/// \brief Namespace containing NaCl library functions
+/// \details TweetNaCl is a compact and portable reimplementation of the NaCl library.
+DOCUMENTED_NAMESPACE_BEGIN(NaCl)
+// crypto_box, crypto_box_open, crypto_sign, and crypto_sign_open (and friends)
+DOCUMENTED_NAMESPACE_END
+
/// \brief Namespace containing testing and benchmark classes.
/// \details Source files for classes in the Test namespaces include
/// <tt>test.cpp</tt>, <tt>validat#.cpp</tt> and <tt>bench#.cpp</tt>.
diff --git a/cryptlib.vcxproj b/cryptlib.vcxproj index a87637ee..fd6e58fc 100644 --- a/cryptlib.vcxproj +++ b/cryptlib.vcxproj @@ -309,6 +309,7 @@ <ClCompile Include="tigertab.cpp" />
<ClCompile Include="trdlocal.cpp" />
<ClCompile Include="ttmac.cpp" />
+ <ClCompile Include="tweetnacl.cpp" />
<ClCompile Include="twofish.cpp" />
<ClCompile Include="vmac.cpp" />
<ClCompile Include="wait.cpp" />
@@ -437,6 +438,7 @@ <ClInclude Include="modexppc.h" />
<ClInclude Include="mqueue.h" />
<ClInclude Include="mqv.h" />
+ <ClInclude Include="nacl.h" />
<ClInclude Include="nbtheory.h" />
<ClInclude Include="network.h" />
<ClInclude Include="nr.h" />
@@ -495,6 +497,7 @@ <ClInclude Include="trdlocal.h" />
<ClInclude Include="trunhash.h" />
<ClInclude Include="ttmac.h" />
+ <ClInclude Include="tweetnacl.h" />
<ClInclude Include="twofish.h" />
<ClInclude Include="vmac.h" />
<ClInclude Include="wait.h" />
diff --git a/cryptlib.vcxproj.filters b/cryptlib.vcxproj.filters index 33fc8da8..7925460a 100644 --- a/cryptlib.vcxproj.filters +++ b/cryptlib.vcxproj.filters @@ -419,6 +419,9 @@ <ClCompile Include="ttmac.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="tweetnacl.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="twofish.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -711,6 +714,9 @@ <ClInclude Include="nbtheory.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="nacl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="network.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -882,6 +888,9 @@ <ClInclude Include="ttmac.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="tweetnacl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="twofish.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -0,0 +1,341 @@ +// nacl.h - written and placed in the public domain by Jeffrey Walton
+// based on public domain NaCl source code written by
+// Daniel J. Bernstein, Bernard van Gastel, Wesley Janssen,
+// Tanja Lange, Peter Schwabe and Sjaak Smetsers.
+
+/// \file nacl.h
+/// \brief Crypto++ interface to TweetNaCl library (20140917)
+/// \details TweetNaCl is a compact reimplementation of the NaCl library by
+/// Daniel J. Bernstein, Bernard van Gastel, Wesley Janssen, Tanja Lange,
+/// Peter Schwabe and Sjaak Smetsers. The library is less than 20 KB in size
+/// and provides 25 of the NaCl library functions.
+/// \details The compact library uses curve25519, XSalsa20, Poly1305 and
+/// SHA-512 as default primitives, and includes both x25519 key exchange and
+/// ed25519 signatures. The complete list of functions can be found in
+/// <A HREF="https://tweetnacl.cr.yp.to/tweetnacl-20140917.pdf">TweetNaCl:
+/// A crypto library in 100 tweets</A> (20140917), Table 1, page 5.
+/// \details Crypto++ retained the function names and signatures but switched to
+/// data types provided by <stdint.h> to promote interoperability with
+/// Crypto++ and avoid size problems on platforms like Cygwin. For example,
+/// NaCl typdef'd <tt>u64</tt> as an <tt>unsigned long long</tt>, but Cygwin,
+/// MinGW and MSYS are <tt>LP64</tt> systems (not <tt>LLP64</tt> systems). In
+/// addition, Crypto++ was missing NaCl's signed 64-bit integer <tt>i64</tt>.
+/// \details TweetNaCl is well written but not well optimzed. It runs 2x to 4x
+/// slower than optimized routines from libsodium. However, the library is still
+/// 2x to 4x faster than the algorithms NaCl was designed to replace.
+/// \details The Crypto++ wrapper for TweetNaCl requires OS features. That is,
+/// <tt>NO_OS_DEPENDENCE</tt> cannot be defined. It is due to TweetNaCl's
+/// internal function <tt>randombytes</tt>. Crypto++ used
+/// <tt>DefaultAutoSeededRNG</tt> within <tt>randombytes</tt>, so OS integration
+/// must be enabled. You can use another generator like <tt>RDRAND</tt> to
+/// avoid the restriction.
+/// \sa <A HREF="https://tweetnacl.cr.yp.to/tweetnacl-20140917.pdf">TweetNaCl:
+/// A crypto library in 100 tweets</A> (20140917)
+/// \since Crypto++ 6.0
+
+#ifndef CRYPTOPP_NACL_H
+#define CRYPTOPP_NACL_H
+
+#include "config.h"
+#include "stdcpp.h"
+
+#if defined(NO_OS_DEPENDENCE)
+# define CRYPTOPP_DISABLE_NACL 1
+#endif
+
+#ifndef CRYPTOPP_DISABLE_NACL
+
+NAMESPACE_BEGIN(CryptoPP)
+NAMESPACE_BEGIN(NaCl)
+
+/// \brief Hash size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/hash.html">NaCl crypto_hash documentation</A>
+CRYPTOPP_CONSTANT(crypto_hash_BYTES = 64)
+
+/// \brief Key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/stream.html">NaCl crypto_stream documentation</A>
+CRYPTOPP_CONSTANT(crypto_stream_KEYBYTES = 32)
+/// \brief Nonce size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/stream.html">NaCl crypto_stream documentation</A>
+CRYPTOPP_CONSTANT(crypto_stream_NONCEBYTES = 24)
+
+/// \brief Key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/auth.html">NaCl crypto_auth documentation</A>
+CRYPTOPP_CONSTANT(crypto_auth_KEYBYTES = 32)
+/// \brief Tag size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/auth.html">NaCl crypto_auth documentation</A>
+CRYPTOPP_CONSTANT(crypto_auth_BYTES = 16)
+
+/// \brief Key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/onetimeauth.html">NaCl crypto_onetimeauth documentation</A>
+CRYPTOPP_CONSTANT(crypto_onetimeauth_KEYBYTES = 32)
+/// \brief Tag size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/onetimeauth.html">NaCl crypto_onetimeauth documentation</A>
+CRYPTOPP_CONSTANT(crypto_onetimeauth_BYTES = 16)
+
+/// \brief Key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/secretbox.html">NaCl crypto_secretbox documentation</A>
+CRYPTOPP_CONSTANT(crypto_secretbox_KEYBYTES = 32)
+/// \brief Nonce size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/secretbox.html">NaCl crypto_secretbox documentation</A>
+CRYPTOPP_CONSTANT(crypto_secretbox_NONCEBYTES = 24)
+/// \brief Zero-padded message prefix in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/secretbox.html">NaCl crypto_secretbox documentation</A>
+CRYPTOPP_CONSTANT(crypto_secretbox_ZEROBYTES = 32)
+/// \brief Zero-padded message prefix in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/secretbox.html">NaCl crypto_secretbox documentation</A>
+CRYPTOPP_CONSTANT(crypto_secretbox_BOXZEROBYTES = 16)
+
+/// \brief Private key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+CRYPTOPP_CONSTANT(crypto_box_SECRETKEYBYTES = 32)
+/// \brief Public key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+CRYPTOPP_CONSTANT(crypto_box_PUBLICKEYBYTES = 32)
+/// \brief Nonce size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+CRYPTOPP_CONSTANT(crypto_box_NONCEBYTES = 24)
+/// \brief Message 0-byte prefix in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+CRYPTOPP_CONSTANT(crypto_box_ZEROBYTES = 32)
+/// \brief Open box 0-byte prefix in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+CRYPTOPP_CONSTANT(crypto_box_BOXZEROBYTES = 16)
+/// \brief Precomputation 0-byte prefix in bytes in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+CRYPTOPP_CONSTANT(crypto_box_BEFORENMBYTES = 32)
+/// \brief MAC size in bytes
+/// \details crypto_box_MACBYTES was missing from tweetnacl.h. Its is defined as
+/// crypto_box_curve25519xsalsa20poly1305_MACBYTES, which is defined as 16U.
+/// \sa <A HREF="https://nacl.cr.yp.to/hash.html">NaCl crypto_box documentation</A>
+CRYPTOPP_CONSTANT(crypto_box_MACBYTES = 16)
+
+/// \brief Private key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/sign.html">NaCl crypto_sign documentation</A>
+CRYPTOPP_CONSTANT(crypto_sign_SECRETKEYBYTES = 64)
+/// \brief Public key size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/sign.html">NaCl crypto_sign documentation</A>
+CRYPTOPP_CONSTANT(crypto_sign_PUBLICKEYBYTES = 32)
+/// \brief Seed size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/sign.html">NaCl crypto_sign documentation</A>
+CRYPTOPP_CONSTANT(crypto_sign_SEEDBYTES = 32)
+/// \brief Signature size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/sign.html">NaCl crypto_sign documentation</A>
+CRYPTOPP_CONSTANT(crypto_sign_BYTES = 64)
+
+/// \brief Group element size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/scalarmult.html">NaCl crypto_scalarmult documentation</A>
+CRYPTOPP_CONSTANT(crypto_scalarmult_BYTES = 32)
+/// \brief Integer size in bytes
+/// \sa <A HREF="https://nacl.cr.yp.to/scalarmult.html">NaCl crypto_scalarmult documentation</A>
+CRYPTOPP_CONSTANT(crypto_scalarmult_SCALARBYTES = 32)
+
+/// \brief Encrypt and authenticate a message
+/// \param c output byte buffer
+/// \param m input byte buffer
+/// \param d size of the input byte buffer
+/// \param n nonce byte buffer
+/// \param y other's public key
+/// \param x private key
+/// \details crypto_box() uses crypto_box_curve25519xsalsa20poly1305
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+/// \since Crypto++ 6.0
+int crypto_box(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x);
+
+/// \brief Verify and decrypt a message
+/// \param m output byte buffer
+/// \param c input byte buffer
+/// \param d size of the input byte buffer
+/// \param n nonce byte buffer
+/// \param y other's public key
+/// \param x private key
+/// \details crypto_box_open() uses crypto_box_curve25519xsalsa20poly1305
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+/// \since Crypto++ 6.0
+int crypto_box_open(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x);
+
+/// \brief Generate a keypair for encryption
+/// \param y public key byte buffer
+/// \param x private key byte buffer
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+/// \since Crypto++ 6.0
+int crypto_box_keypair(uint8_t *y,uint8_t *x);
+
+/// \brief Encrypt and authenticate a message
+/// \param k shared secret byte buffer
+/// \param y other's public key
+/// \param x private key
+/// \details crypto_box_beforenm() performs message-independent precomputation to derive the key.
+/// Once the key is derived multiple calls to crypto_box_afternm() can be made to process the message.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+/// \since Crypto++ 6.0
+int crypto_box_beforenm(uint8_t *k,const uint8_t *y,const uint8_t *x);
+
+/// \brief Encrypt and authenticate a message
+/// \param m output byte buffer
+/// \param c input byte buffer
+/// \param d size of the input byte buffer
+/// \param n nonce byte buffer
+/// \param k shared secret byte buffer
+/// \details crypto_box_afternm() performs message-dependent computation using the derived the key.
+/// Once the key is derived using crypto_box_beforenm() multiple calls to crypto_box_afternm()
+/// can be made to process the message.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+/// \since Crypto++ 6.0
+int crypto_box_afternm(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k);
+
+/// \brief Verify and decrypt a message
+/// \param m output byte buffer
+/// \param c input byte buffer
+/// \param d size of the input byte buffer
+/// \param n nonce byte buffer
+/// \param k shared secret byte buffer
+/// \details crypto_box_afternm() performs message-dependent computation using the derived the key.
+/// Once the key is derived using crypto_box_beforenm() multiple calls to crypto_box_open_afternm()
+/// can be made to process the message.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/box.html">NaCl crypto_box documentation</A>
+/// \since Crypto++ 6.0
+int crypto_box_open_afternm(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k);
+
+/// \brief TODO
+int crypto_core_salsa20(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c);
+
+/// \brief TODO
+/// \returns 0 on success, non-0 otherwise
+/// \since Crypto++ 6.0
+int crypto_core_hsalsa20(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c);
+
+/// \brief Hash multiple blocks
+/// \details crypto_hashblocks() uses crypto_hashblocks_sha512.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/hash.html">NaCl crypto_hash documentation</A>
+/// \since Crypto++ 6.0
+int crypto_hashblocks(uint8_t *x,const uint8_t *m,uint64_t n);
+
+/// \brief Hash a message
+/// \details crypto_hash() uses crypto_hash_sha512.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/hash.html">NaCl crypto_hash documentation</A>
+/// \since Crypto++ 6.0
+int crypto_hash(uint8_t *out,const uint8_t *m,uint64_t n);
+
+/// \brief Create an authentication tag for a message
+/// \details crypto_onetimeauth() uses crypto_onetimeauth_poly1305.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/onetimeauth.html">NaCl crypto_onetimeauth documentation</A>
+/// \since Crypto++ 6.0
+int crypto_onetimeauth(uint8_t *out,const uint8_t *m,uint64_t n,const uint8_t *k);
+
+/// \brief Verify an authentication tag on a message
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/onetimeauth.html">NaCl crypto_onetimeauth documentation</A>
+/// \since Crypto++ 6.0
+int crypto_onetimeauth_verify(const uint8_t *h,const uint8_t *m,uint64_t n,const uint8_t *k);
+
+/// \brief Scalar multiplication of a point
+/// \details crypto_scalarmult() uses crypto_scalarmult_curve25519
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/scalarmult.html">NaCl crypto_scalarmult documentation</A>
+/// \since Crypto++ 6.0
+int crypto_scalarmult(uint8_t *q,const uint8_t *n,const uint8_t *p);
+
+/// \brief Scalar multiplication of base point
+/// \details crypto_scalarmult_base() uses crypto_scalarmult_curve25519
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/scalarmult.html">NaCl crypto_scalarmult documentation</A>
+/// \since Crypto++ 6.0
+int crypto_scalarmult_base(uint8_t *q,const uint8_t *n);
+
+/// \brief Encrypt and authenticate a message
+/// \details crypto_secretbox() uses a symmetric key to encrypt and authenticate a message.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/secretbox.html">NaCl crypto_secretbox documentation</A>
+/// \since Crypto++ 6.0
+int crypto_secretbox(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k);
+
+/// \brief Verify and decrypt a message
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/secretbox.html">NaCl crypto_secretbox documentation</A>
+/// \since Crypto++ 6.0
+int crypto_secretbox_open(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k);
+
+/// \brief Sign a message
+/// \param sm output byte buffer
+/// \param smlen size of the output byte buffer
+/// \param m input byte buffer
+/// \param n size of the input byte buffer
+/// \param sk private key
+/// \details crypto_sign() uses crypto_sign_ed25519.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/sign.html">NaCl crypto_sign documentation</A>
+/// \since Crypto++ 6.0
+int crypto_sign(uint8_t *sm,uint64_t *smlen,const uint8_t *m,uint64_t n,const uint8_t *sk);
+
+/// \brief Verify a message
+/// \param m output byte buffer
+/// \param mlen size of the output byte buffer
+/// \param sm input byte buffer
+/// \param smlen size of the input byte buffer
+/// \param pk public key
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/sign.html">NaCl crypto_sign documentation</A>
+/// \since Crypto++ 6.0
+int crypto_sign_open(uint8_t *m,uint64_t *mlen,const uint8_t *sm,uint64_t n,const uint8_t *pk);
+
+/// \brief Generate a keypair for signing
+/// \param y public key byte buffer
+/// \param x private key byte buffer
+/// \details crypto_sign_keypair() creates an ed25519 keypair.
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/sign.html">NaCl crypto_sign documentation</A>
+/// \since Crypto++ 6.0
+int crypto_sign_keypair(uint8_t *pk, uint8_t *sk);
+
+/// \brief Produce a keystream using XSalsa20
+/// \details crypto_stream() uses crypto_stream_xsalsa20
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/stream.html">NaCl crypto_stream documentation</A>
+/// \since Crypto++ 6.0
+int crypto_stream(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k);
+
+/// \brief Encrypt a message using XSalsa20
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/stream.html">NaCl crypto_stream documentation</A>
+/// \since Crypto++ 6.0
+int crypto_stream_xor(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k);
+
+/// \brief Produce a keystream using Salsa20
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/stream.html">NaCl crypto_stream documentation</A>
+/// \since Crypto++ 6.0
+int crypto_stream_salsa20(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k);
+
+/// \brief Encrypt a message using Salsa20
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/stream.html">NaCl crypto_stream documentation</A>
+/// \since Crypto++ 6.0
+int crypto_stream_salsa20_xor(uint8_t *c,const uint8_t *m,uint64_t b,const uint8_t *n,const uint8_t *k);
+
+/// \brief Compare 16-byte buffers
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/verify.html">NaCl crypto_verify documentation</A>
+/// \since Crypto++ 6.0
+int crypto_verify_16(const uint8_t *x,const uint8_t *y);
+
+/// \brief Compare 32-byte buffers
+/// \returns 0 on success, non-0 otherwise
+/// \sa <A HREF="https://nacl.cr.yp.to/verify.html">NaCl crypto_verify documentation</A>
+/// \since Crypto++ 6.0
+int crypto_verify_32(const uint8_t *x,const uint8_t *y);
+
+NAMESPACE_END // CryptoPP
+NAMESPACE_END // NaCl
+
+#endif // CRYPTOPP_DISABLE_NACL
+#endif // CRYPTOPP_NACL_H
@@ -946,6 +946,7 @@ bool Validate(int alg, bool thorough, const char *seedInput) case 78: result = ValidateSipHash(); break;
case 79: result = ValidateHashDRBG(); break;
case 80: result = ValidateHmacDRBG(); break;
+ case 90: result = ValidateNaCl(); break;
#if defined(CRYPTOPP_EXTENDED_VALIDATION)
// http://github.com/weidai11/cryptopp/issues/92
diff --git a/tweetnacl.cpp b/tweetnacl.cpp new file mode 100644 index 00000000..f61bca00 --- /dev/null +++ b/tweetnacl.cpp @@ -0,0 +1,837 @@ +// tweetnacl.cpp - modified tweetnacl.c placed in public domain by Jeffrey Walton.
+// The NaCl library and tweetnacl.c is public domain source code
+// written by Daniel J. Bernstein, Bernard van Gastel, Wesley
+// Janssen, Tanja Lange, Peter Schwabe and Sjaak Smetsers.
+
+#include "pch.h"
+#include "config.h"
+#include "nacl.h"
+#include "misc.h"
+#include "osrng.h"
+#include "stdcpp.h"
+
+// Don't destroy const time properties when squashing warnings.
+#if CRYPTOPP_MSC_VERSION
+# pragma warning(disable: 4242 4244 4245)
+#endif
+
+#ifndef CRYPTOPP_DISABLE_NACL
+
+NAMESPACE_BEGIN(CryptoPP)
+NAMESPACE_BEGIN(NaCl)
+
+typedef int64_t gf[16];
+
+static const uint8_t
+ _0[32] = {0},
+ _9[32] = {9};
+
+static const gf
+ gf0 = {0},
+ gf1 = {1},
+ _121665 = {0xDB41,1},
+ D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
+ D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
+ X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
+ Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
+ I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
+
+// Added by Crypto++ for TweetNaCl
+static void randombytes(uint8_t * block, uint64_t size)
+{
+ DefaultAutoSeededRNG prng;
+ prng.GenerateBlock(block, (size_t)size);
+}
+
+static uint32_t L32(uint32_t x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
+
+static uint32_t ld32(const uint8_t *x)
+{
+ uint32_t u = x[3];
+ u = (u<<8)|x[2];
+ u = (u<<8)|x[1];
+ return (u<<8)|x[0];
+}
+
+static uint64_t dl64(const uint8_t *x)
+{
+ uint64_t i,u=0;
+ for(i=0; i<8; ++i) u=(u<<8)|x[i];
+ return u;
+}
+
+static void st32(uint8_t *x,uint32_t u)
+{
+ int i;
+ for(i=0; i<4; ++i) { x[i] = u; u >>= 8; }
+}
+
+static void ts64(uint8_t *x,uint64_t u)
+{
+ int i;
+ for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
+}
+
+static int verify_n(const uint8_t *x,const uint8_t *y,uint32_t n)
+{
+ uint32_t i,d = 0;
+ for(i=0; i<n; ++i) d |= x[i]^y[i];
+ return (1 & ((d - 1) >> 8)) - 1;
+}
+
+int crypto_verify_16(const uint8_t *x,const uint8_t *y)
+{
+ return verify_n(x,y,16);
+}
+
+int crypto_verify_32(const uint8_t *x,const uint8_t *y)
+{
+ return verify_n(x,y,32);
+}
+
+static void core(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c,int h)
+{
+ uint32_t w[16],x[16],y[16],t[4];
+ int i,j,m;
+
+ for(i=0; i<4; ++i) {
+ x[5*i] = ld32(c+4*i);
+ x[1+i] = ld32(k+4*i);
+ x[6+i] = ld32(in+4*i);
+ x[11+i] = ld32(k+16+4*i);
+ }
+
+ for(i=0; i<16; ++i) y[i] = x[i];
+
+ for(i=0; i<20; ++i) {
+ for(j=0; j<4; ++j) {
+ for(m=0; m<4; ++m) t[m] = x[(5*j+4*m)%16];
+ t[1] ^= L32(t[0]+t[3], 7);
+ t[2] ^= L32(t[1]+t[0], 9);
+ t[3] ^= L32(t[2]+t[1],13);
+ t[0] ^= L32(t[3]+t[2],18);
+ for(m=0; m<4; ++m) w[4*j+(j+m)%4] = t[m];
+ }
+ for(m=0; m<16; ++m) x[m] = w[m];
+ }
+
+ if (h) {
+ for(i=0; i<16; ++i) x[i] += y[i];
+ for(i=0; i<4; ++i) {
+ x[5*i] -= ld32(c+4*i);
+ x[6+i] -= ld32(in+4*i);
+ }
+ for(i=0; i<4; ++i) {
+ st32(out+4*i,x[5*i]);
+ st32(out+16+4*i,x[6+i]);
+ }
+ } else
+ for(i=0; i<16; ++i) st32(out + 4 * i,x[i] + y[i]);
+}
+
+int crypto_core_salsa20(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c)
+{
+ core(out,in,k,c,0);
+ return 0;
+}
+
+int crypto_core_hsalsa20(uint8_t *out,const uint8_t *in,const uint8_t *k,const uint8_t *c)
+{
+ core(out,in,k,c,1);
+ return 0;
+}
+
+static const uint8_t sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B};
+
+int crypto_stream_salsa20_xor(uint8_t *c,const uint8_t *m,uint64_t b,const uint8_t *n,const uint8_t *k)
+{
+ uint8_t z[16],x[64];
+ uint32_t u,i;
+ if (!b) return 0;
+ for(i=0; i<16; ++i) z[i] = 0;
+ for(i=0; i<8; ++i) z[i] = n[i];
+ while (b >= 64) {
+ crypto_core_salsa20(x,z,k,sigma);
+ for(i=0; i<64; ++i) c[i] = (m?m[i]:0) ^ x[i];
+ u = 1;
+ for (i = 8;i < 16;++i) {
+ u += (uint32_t) z[i];
+ z[i] = u;
+ u >>= 8;
+ }
+ b -= 64;
+ c += 64;
+ if (m) m += 64;
+ }
+ if (b) {
+ crypto_core_salsa20(x,z,k,sigma);
+ for(i=0; i<b; ++i) c[i] = (m?m[i]:0) ^ x[i];
+ }
+ return 0;
+}
+
+int crypto_stream_salsa20(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
+{
+ return crypto_stream_salsa20_xor(c,0,d,n,k);
+}
+
+int crypto_stream(uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
+{
+ uint8_t s[32];
+ crypto_core_hsalsa20(s,n,k,sigma);
+ return crypto_stream_salsa20(c,d,n+16,s);
+}
+
+int crypto_stream_xor(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k)
+{
+ uint8_t s[32];
+ crypto_core_hsalsa20(s,n,k,sigma);
+ return crypto_stream_salsa20_xor(c,m,d,n+16,s);
+}
+
+static void add1305(uint32_t *h,const uint32_t *c)
+{
+ uint32_t j,u = 0;
+ for(j=0; j<17; ++j) {
+ u += h[j] + c[j];
+ h[j] = u & 255;
+ u >>= 8;
+ }
+}
+
+static const uint32_t minusp[17] = {
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
+} ;
+
+int crypto_onetimeauth(uint8_t *out,const uint8_t *m,uint64_t n,const uint8_t *k)
+{
+ uint32_t s,i,j,u,x[17],r[17],h[17],c[17],g[17];
+
+ for(j=0; j<17; ++j) r[j]=h[j]=0;
+ for(j=0; j<16; ++j) r[j]=k[j];
+ r[3]&=15;
+ r[4]&=252;
+ r[7]&=15;
+ r[8]&=252;
+ r[11]&=15;
+ r[12]&=252;
+ r[15]&=15;
+
+ while (n > 0) {
+ for(j=0; j<17; ++j) c[j] = 0;
+ for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
+ c[j] = 1;
+ m += j; n -= j;
+ add1305(h,c);
+ for(i=0; i<17; ++i) {
+ x[i] = 0;
+ for(j=0; j<17; ++j) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
+ }
+ for(i=0; i<17; ++i) h[i] = x[i];
+ u = 0;
+ for(j=0; j<16; ++j) {
+ u += h[j];
+ h[j] = u & 255;
+ u >>= 8;
+ }
+ u += h[16]; h[16] = u & 3;
+ u = 5 * (u >> 2);
+ for(j=0; j<16; ++j) {
+ u += h[j];
+ h[j] = u & 255;
+ u >>= 8;
+ }
+ u += h[16]; h[16] = u;
+ }
+
+ for(j=0; j<17; ++j) g[j] = h[j];
+ add1305(h,minusp);
+ s = -(h[16] >> 7);
+ for(j=0; j<17; ++j) h[j] ^= s & (g[j] ^ h[j]);
+
+ for(j=0; j<16; ++j) c[j] = k[j + 16];
+ c[16] = 0;
+ add1305(h,c);
+ for(j=0; j<16; ++j) out[j] = h[j];
+ return 0;
+}
+
+int crypto_onetimeauth_verify(const uint8_t *h,const uint8_t *m,uint64_t n,const uint8_t *k)
+{
+ uint8_t x[16];
+ crypto_onetimeauth(x,m,n,k);
+ return crypto_verify_16(h,x);
+}
+
+int crypto_secretbox(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k)
+{
+ int i;
+ if (d < 32) return -1;
+ crypto_stream_xor(c,m,d,n,k);
+ crypto_onetimeauth(c + 16,c + 32,d - 32,c);
+ for(i=0; i<16; ++i) c[i] = 0;
+ return 0;
+}
+
+int crypto_secretbox_open(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
+{
+ int i;
+ uint8_t x[32];
+ if (d < 32) return -1;
+ crypto_stream(x,32,n,k);
+ if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
+ crypto_stream_xor(m,c,d,n,k);
+ for(i=0; i<32; ++i) m[i] = 0;
+ return 0;
+}
+
+static void set25519(gf r, const gf a)
+{
+ int i;
+ for(i=0; i<16; ++i) r[i]=a[i];
+}
+
+static void car25519(gf o)
+{
+ int i;
+ int64_t c;
+ for(i=0; i<16; ++i) {
+ o[i]+=(1LL<<16);
+ c=o[i]>>16;
+ o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
+ o[i]-=((uint64_t)c)<<16;
+ }
+}
+
+static void sel25519(gf p,gf q,int b)
+{
+ int64_t t,i,c=~(b-1);
+ for(i=0; i<16; ++i) {
+ t= c&(p[i]^q[i]);
+ p[i]^=t;
+ q[i]^=t;
+ }
+}
+
+static void pack25519(uint8_t *o,const gf n)
+{
+ int i,j,b;
+ gf m,t;
+ for(i=0; i<16; ++i) t[i]=n[i];
+ car25519(t);
+ car25519(t);
+ car25519(t);
+ for(j=0; j<2; ++j) {
+ m[0]=t[0]-0xffed;
+ for(i=1;i<15;i++) {
+ m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
+ m[i-1]&=0xffff;
+ }
+ m[15]=t[15]-0x7fff-((m[14]>>16)&1);
+ b=(m[15]>>16)&1;
+ m[14]&=0xffff;
+ sel25519(t,m,1-b);
+ }
+ for(i=0; i<16; ++i) {
+ o[2*i]=t[i]&0xff;
+ o[2*i+1]=t[i]>>8;
+ }
+}
+
+static int neq25519(const gf a, const gf b)
+{
+ uint8_t c[32],d[32];
+ pack25519(c,a);
+ pack25519(d,b);
+ return crypto_verify_32(c,d);
+}
+
+static uint8_t par25519(const gf a)
+{
+ uint8_t d[32];
+ pack25519(d,a);
+ return d[0]&1;
+}
+
+static void unpack25519(gf o, const uint8_t *n)
+{
+ int i;
+ for(i=0; i<16; ++i) o[i]=n[2*i]+((int64_t)n[2*i+1]<<8);
+ o[15]&=0x7fff;
+}
+
+static void A(gf o,const gf a,const gf b)
+{
+ int i;
+ for(i=0; i<16; ++i) o[i]=a[i]+b[i];
+}
+
+static void Z(gf o,const gf a,const gf b)
+{
+ int i;
+ for(i=0; i<16; ++i) o[i]=a[i]-b[i];
+}
+
+static void M(gf o,const gf a,const gf b)
+{
+ int64_t i,j,t[31];
+ for(i=0; i<31; ++i) t[i]=0;
+ for(i=0; i<16; ++i) for(j=0; j<16; ++j) t[i+j]+=a[i]*b[j];
+ for(i=0; i<15; ++i) t[i]+=38*t[i+16];
+ for(i=0; i<16; ++i) o[i]=t[i];
+ car25519(o);
+ car25519(o);
+}
+
+static void S(gf o,const gf a)
+{
+ M(o,a,a);
+}
+
+static void inv25519(gf o,const gf i)
+{
+ gf c;
+ int a;
+ for(a=0; a<16; ++a) c[a]=i[a];
+ for(a=253;a>=0;a--) {
+ S(c,c);
+ if(a!=2&&a!=4) M(c,c,i);
+ }
+ for(a=0; a<16; ++a) o[a]=c[a];
+}
+
+static void pow2523(gf o,const gf i)
+{
+ gf c;
+ int a;
+ for(a=0; a<16; ++a) c[a]=i[a];
+ for(a=250;a>=0;a--) {
+ S(c,c);
+ if(a!=1) M(c,c,i);
+ }
+ for(a=0; a<16; ++a) o[a]=c[a];
+}
+
+int crypto_scalarmult(uint8_t *q,const uint8_t *n,const uint8_t *p)
+{
+ uint8_t z[32];
+ int64_t x[80],r,i;
+ gf a,b,c,d,e,f;
+ for(i=0; i<31; ++i) z[i]=n[i];
+ z[31]=(n[31]&127)|64;
+ z[0]&=248;
+ unpack25519(x,p);
+ for(i=0; i<16; ++i) {
+ b[i]=x[i];
+ d[i]=a[i]=c[i]=0;
+ }
+ a[0]=d[0]=1;
+ for(i=254;i>=0;--i) {
+ r=(z[i>>3]>>(i&7))&1;
+ sel25519(a,b,r);
+ sel25519(c,d,r);
+ A(e,a,c);
+ Z(a,a,c);
+ A(c,b,d);
+ Z(b,b,d);
+ S(d,e);
+ S(f,a);
+ M(a,c,a);
+ M(c,b,e);
+ A(e,a,c);
+ Z(a,a,c);
+ S(b,a);
+ Z(c,d,f);
+ M(a,c,_121665);
+ A(a,a,d);
+ M(c,c,a);
+ M(a,d,f);
+ M(d,b,x);
+ S(b,e);
+ sel25519(a,b,r);
+ sel25519(c,d,r);
+ }
+ for(i=0; i<16; ++i) {
+ x[i+16]=a[i];
+ x[i+32]=c[i];
+ x[i+48]=b[i];
+ x[i+64]=d[i];
+ }
+ inv25519(x+32,x+32);
+ M(x+16,x+16,x+32);
+ pack25519(q,x+16);
+ return 0;
+}
+
+int crypto_scalarmult_base(uint8_t *q,const uint8_t *n)
+{
+ return crypto_scalarmult(q,n,_9);
+}
+
+int crypto_box_keypair(uint8_t *y,uint8_t *x)
+{
+ randombytes(x,32);
+ return crypto_scalarmult_base(y,x);
+}
+
+// S must not be all 0's
+int crypto_box_beforenm(uint8_t *k,const uint8_t *y,const uint8_t *x)
+{
+ uint8_t s[32];
+ if(crypto_scalarmult(s,x,y) != 0) return -1;
+ if(verify_n(s,_0,32) != -1) return -1;
+ return crypto_core_hsalsa20(k,_0,s,sigma);
+}
+
+int crypto_box_afternm(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *k)
+{
+ return crypto_secretbox(c,m,d,n,k);
+}
+
+int crypto_box_open_afternm(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *k)
+{
+ return crypto_secretbox_open(m,c,d,n,k);
+}
+
+int crypto_box(uint8_t *c,const uint8_t *m,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x)
+{
+ uint8_t k[32];
+ if(crypto_box_beforenm(k,y,x) != 0) return -1;
+ return crypto_box_afternm(c,m,d,n,k);
+}
+
+int crypto_box_open(uint8_t *m,const uint8_t *c,uint64_t d,const uint8_t *n,const uint8_t *y,const uint8_t *x)
+{
+ uint8_t k[32];
+ if(crypto_box_beforenm(k,y,x) != 0) return -1;
+ return crypto_box_open_afternm(m,c,d,n,k);
+}
+
+static uint64_t R(uint64_t x,int c) { return (x >> c) | (x << (64 - c)); }
+static uint64_t Ch(uint64_t x,uint64_t y,uint64_t z) { return (x & y) ^ (~x & z); }
+static uint64_t Maj(uint64_t x,uint64_t y,uint64_t z) { return (x & y) ^ (x & z) ^ (y & z); }
+static uint64_t Sigma0(uint64_t x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
+static uint64_t Sigma1(uint64_t x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
+static uint64_t sigma0(uint64_t x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
+static uint64_t sigma1(uint64_t x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
+
+static const uint64_t K[80] =
+{
+ W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
+ W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
+ W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
+ W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
+ W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
+ W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
+ W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
+ W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
+ W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
+ W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
+ W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
+ W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
+ W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
+ W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
+ W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
+ W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
+ W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
+ W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
+ W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
+ W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
+};
+
+int crypto_hashblocks(uint8_t *x,const uint8_t *m,uint64_t n)
+{
+ uint64_t z[8],b[8],a[8],w[16],t;
+ int i,j;
+
+ for(i=0; i<8; ++i) z[i] = a[i] = dl64(x + 8 * i);
+
+ while (n >= 128) {
+ for(i=0; i<16; ++i) w[i] = dl64(m + 8 * i);
+
+ for(i=0; i<80; ++i) {
+ for(j=0; j<8; ++j) b[j] = a[j];
+ t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
+ b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
+ b[3] += t;
+ for(j=0; j<8; ++j) a[(j+1)%8] = b[j];
+ if (i%16 == 15)
+ for(j=0; j<16; ++j)
+ w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
+ }
+
+ for(i=0; i<8; ++i) { a[i] += z[i]; z[i] = a[i]; }
+
+ m += 128;
+ n -= 128;
+ }
+
+ for(i=0; i<8; ++i) ts64(x+8*i,z[i]);
+
+ return n;
+}
+
+static const uint8_t iv[64] = {
+ 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
+ 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
+ 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
+ 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
+ 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
+ 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
+ 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
+ 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
+} ;
+
+int crypto_hash(uint8_t *out,const uint8_t *m,uint64_t n)
+{
+ uint8_t h[64],x[256];
+ uint64_t i,b = n;
+
+ for(i=0; i<64; ++i) h[i] = iv[i];
+
+ crypto_hashblocks(h,m,n);
+ m += n;
+ n &= 127;
+ m -= n;
+
+ for(i=0; i<256; ++i) x[i] = 0;
+ for(i=0; i<n; ++i) x[i] = m[i];
+ x[n] = 128;
+
+ n = 256-128*(n<112);
+ x[n-9] = b >> 61;
+ ts64(x+n-8,b<<3);
+ crypto_hashblocks(h,x,n);
+
+ for(i=0; i<64; ++i) out[i] = h[i];
+
+ return 0;
+}
+
+static void add(gf p[4],gf q[4])
+{
+ gf a,b,c,d,t,e,f,g,h;
+
+ Z(a, p[1], p[0]);
+ Z(t, q[1], q[0]);
+ M(a, a, t);
+ A(b, p[0], p[1]);
+ A(t, q[0], q[1]);
+ M(b, b, t);
+ M(c, p[3], q[3]);
+ M(c, c, D2);
+ M(d, p[2], q[2]);
+ A(d, d, d);
+ Z(e, b, a);
+ Z(f, d, c);
+ A(g, d, c);
+ A(h, b, a);
+
+ M(p[0], e, f);
+ M(p[1], h, g);
+ M(p[2], g, f);
+ M(p[3], e, h);
+}
+
+static void cswap(gf p[4],gf q[4],uint8_t b)
+{
+ int i;
+ for(i=0; i<4; ++i)
+ sel25519(p[i],q[i],b);
+}
+
+static void pack(uint8_t *r,gf p[4])
+{
+ gf tx, ty, zi;
+ inv25519(zi, p[2]);
+ M(tx, p[0], zi);
+ M(ty, p[1], zi);
+ pack25519(r, ty);
+ r[31] ^= par25519(tx) << 7;
+}
+
+static void scalarmult(gf p[4],gf q[4],const uint8_t *s)
+{
+ int i;
+ set25519(p[0],gf0);
+ set25519(p[1],gf1);
+ set25519(p[2],gf1);
+ set25519(p[3],gf0);
+ for (i = 255;i >= 0;--i) {
+ uint8_t b = (s[i/8]>>(i&7))&1;
+ cswap(p,q,b);
+ add(q,p);
+ add(p,p);
+ cswap(p,q,b);
+ }
+}
+
+static void scalarbase(gf p[4],const uint8_t *s)
+{
+ gf q[4];
+ set25519(q[0],X);
+ set25519(q[1],Y);
+ set25519(q[2],gf1);
+ M(q[3],X,Y);
+ scalarmult(p,q,s);
+}
+
+int crypto_sign_keypair(uint8_t *pk, uint8_t *sk)
+{
+ uint8_t d[64];
+ gf p[4];
+ int i;
+
+ randombytes(sk, 32);
+ crypto_hash(d, sk, 32);
+ d[0] &= 248;
+ d[31] &= 127;
+ d[31] |= 64;
+
+ scalarbase(p,d);
+ pack(pk,p);
+
+ for(i=0; i<32; ++i) sk[32 + i] = pk[i];
+ return 0;
+}
+
+static const uint64_t 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};
+
+static void modL(uint8_t *r,int64_t x[64])
+{
+ int64_t carry,i,j;
+ for (i = 63;i >= 32;--i) {
+ carry = 0;
+ for (j = i - 32;j < i - 12;++j) {
+ x[j] += carry - 16 * x[i] * L[j - (i - 32)];
+ carry = (x[j] + 128) >> 8;
+ x[j] -= ((uint64_t)carry) << 8;
+ }
+ x[j] += carry;
+ x[i] = 0;
+ }
+ carry = 0;
+ for(j=0; j<32; ++j) {
+ x[j] += carry - (x[31] >> 4) * L[j];
+ carry = x[j] >> 8;
+ x[j] &= 255;
+ }
+ for(j=0; j<32; ++j) x[j] -= carry * L[j];
+ for(i=0; i<32; ++i) {
+ x[i+1] += x[i] >> 8;
+ r[i] = x[i] & 255;
+ }
+}
+
+static void reduce(uint8_t *r)
+{
+ int64_t x[64],i;
+ for(i=0; i<64; ++i) x[i] = (uint64_t) r[i];
+ for(i=0; i<64; ++i) r[i] = 0;
+ modL(r,x);
+}
+
+int crypto_sign(uint8_t *sm,uint64_t *smlen,const uint8_t *m,uint64_t n,const uint8_t *sk)
+{
+ uint8_t d[64],h[64],r[64];
+ uint64_t i; int64_t j,x[64];
+ gf p[4];
+
+ crypto_hash(d, sk, 32);
+ d[0] &= 248;
+ d[31] &= 127;
+ d[31] |= 64;
+
+ *smlen = n+64;
+ for(i=0; i<n; ++i) sm[64 + i] = m[i];
+ for(i=0; i<32; ++i) sm[32 + i] = d[32 + i];
+
+ crypto_hash(r, sm+32, n+32);
+ reduce(r);
+ scalarbase(p,r);
+ pack(sm,p);
+
+ for(i=0; i<32; ++i) sm[i+32] = sk[i+32];
+ crypto_hash(h,sm,n + 64);
+ reduce(h);
+
+ for(i=0; i<64; ++i) x[i] = 0;
+ for(i=0; i<32; ++i) x[i] = (uint64_t) r[i];
+ for(i=0; i<32; ++i) for(j=0; j<32; ++j) x[i+j] += h[i] * (uint64_t) d[j];
+ modL(sm + 32,x);
+
+ return 0;
+}
+
+static int unpackneg(gf r[4],const uint8_t p[32])
+{
+ gf t, chk, num, den, den2, den4, den6;
+ set25519(r[2],gf1);
+ unpack25519(r[1],p);
+ S(num,r[1]);
+ M(den,num,D);
+ Z(num,num,r[2]);
+ A(den,r[2],den);
+
+ S(den2,den);
+ S(den4,den2);
+ M(den6,den4,den2);
+ M(t,den6,num);
+ M(t,t,den);
+
+ pow2523(t,t);
+ M(t,t,num);
+ M(t,t,den);
+ M(t,t,den);
+ M(r[0],t,den);
+
+ S(chk,r[0]);
+ M(chk,chk,den);
+ if (neq25519(chk, num)) M(r[0],r[0],I);
+
+ S(chk,r[0]);
+ M(chk,chk,den);
+ if (neq25519(chk, num)) return -1;
+
+ if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
+
+ M(r[3],r[0],r[1]);
+ return 0;
+}
+
+int crypto_sign_open(uint8_t *m,uint64_t *mlen,const uint8_t *sm,uint64_t n,const uint8_t *pk)
+{
+ int i;
+ uint8_t t[32],h[64];
+ gf p[4],q[4];
+
+ *mlen = -1;
+ if (n < 64) return -1;
+
+ if (unpackneg(q,pk)) return -1;
+
+ for(i=0; i<n; ++i) m[i] = sm[i];
+ for(i=0; i<32; ++i) m[i+32] = pk[i];
+ crypto_hash(h,m,n);
+ reduce(h);
+ scalarmult(p,q,h);
+
+ scalarbase(q,sm + 32);
+ add(p,q);
+ pack(t,p);
+
+ n -= 64;
+ if (crypto_verify_32(sm, t)) {
+ for(i=0; i<n; ++i) m[i] = 0;
+ return -1;
+ }
+
+ for(i=0; i<n; ++i) m[i] = sm[i + 64];
+ *mlen = n;
+ return 0;
+}
+
+NAMESPACE_END // CryptoPP
+NAMESPACE_END // NaCl
+
+#endif // NO_OS_DEPENDENCE
\ No newline at end of file diff --git a/tweetnacl.h b/tweetnacl.h new file mode 100644 index 00000000..3c097281 --- /dev/null +++ b/tweetnacl.h @@ -0,0 +1,272 @@ +#ifndef TWEETNACL_H
+#define TWEETNACL_H
+#define crypto_auth_PRIMITIVE "hmacsha512256"
+#define crypto_auth crypto_auth_hmacsha512256
+#define crypto_auth_verify crypto_auth_hmacsha512256_verify
+#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
+#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
+#define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION
+#define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION
+#define crypto_auth_hmacsha512256_tweet_BYTES 32
+#define crypto_auth_hmacsha512256_tweet_KEYBYTES 32
+extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+#define crypto_auth_hmacsha512256_tweet_VERSION "-"
+#define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet
+#define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify
+#define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES
+#define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES
+#define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION
+#define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet"
+#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
+#define crypto_box crypto_box_curve25519xsalsa20poly1305
+#define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open
+#define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair
+#define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
+#define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
+#define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
+#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
+#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
+#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
+#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
+#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
+#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
+#define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION
+#define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION
+#define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24
+#define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16
+extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-"
+#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet
+#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open
+#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair
+#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm
+#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm
+#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm
+#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES
+#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES
+#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES
+#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES
+#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES
+#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES
+#define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION
+#define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet"
+#define crypto_core_PRIMITIVE "salsa20"
+#define crypto_core crypto_core_salsa20
+#define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES
+#define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES
+#define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES
+#define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES
+#define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION
+#define crypto_core_VERSION crypto_core_salsa20_VERSION
+#define crypto_core_salsa20_tweet_OUTPUTBYTES 64
+#define crypto_core_salsa20_tweet_INPUTBYTES 16
+#define crypto_core_salsa20_tweet_KEYBYTES 32
+#define crypto_core_salsa20_tweet_CONSTBYTES 16
+extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
+#define crypto_core_salsa20_tweet_VERSION "-"
+#define crypto_core_salsa20 crypto_core_salsa20_tweet
+#define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES
+#define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES
+#define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES
+#define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES
+#define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION
+#define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet"
+#define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32
+#define crypto_core_hsalsa20_tweet_INPUTBYTES 16
+#define crypto_core_hsalsa20_tweet_KEYBYTES 32
+#define crypto_core_hsalsa20_tweet_CONSTBYTES 16
+extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
+#define crypto_core_hsalsa20_tweet_VERSION "-"
+#define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet
+#define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES
+#define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES
+#define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES
+#define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES
+#define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION
+#define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet"
+#define crypto_hashblocks_PRIMITIVE "sha512"
+#define crypto_hashblocks crypto_hashblocks_sha512
+#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES
+#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES
+#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION
+#define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION
+#define crypto_hashblocks_sha512_tweet_STATEBYTES 64
+#define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128
+extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hashblocks_sha512_tweet_VERSION "-"
+#define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet
+#define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES
+#define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES
+#define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION
+#define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet"
+#define crypto_hashblocks_sha256_tweet_STATEBYTES 32
+#define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64
+extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hashblocks_sha256_tweet_VERSION "-"
+#define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet
+#define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES
+#define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES
+#define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION
+#define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet"
+#define crypto_hash_PRIMITIVE "sha512"
+#define crypto_hash crypto_hash_sha512
+#define crypto_hash_BYTES crypto_hash_sha512_BYTES
+#define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION
+#define crypto_hash_VERSION crypto_hash_sha512_VERSION
+#define crypto_hash_sha512_tweet_BYTES 64
+extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hash_sha512_tweet_VERSION "-"
+#define crypto_hash_sha512 crypto_hash_sha512_tweet
+#define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES
+#define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION
+#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet"
+#define crypto_hash_sha256_tweet_BYTES 32
+extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hash_sha256_tweet_VERSION "-"
+#define crypto_hash_sha256 crypto_hash_sha256_tweet
+#define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES
+#define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION
+#define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet"
+#define crypto_onetimeauth_PRIMITIVE "poly1305"
+#define crypto_onetimeauth crypto_onetimeauth_poly1305
+#define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify
+#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
+#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
+#define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION
+#define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION
+#define crypto_onetimeauth_poly1305_tweet_BYTES 16
+#define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32
+extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+#define crypto_onetimeauth_poly1305_tweet_VERSION "-"
+#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet
+#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify
+#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES
+#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES
+#define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION
+#define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet"
+#define crypto_scalarmult_PRIMITIVE "curve25519"
+#define crypto_scalarmult crypto_scalarmult_curve25519
+#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
+#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
+#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
+#define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION
+#define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION
+#define crypto_scalarmult_curve25519_tweet_BYTES 32
+#define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32
+extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *);
+#define crypto_scalarmult_curve25519_tweet_VERSION "-"
+#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet
+#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base
+#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES
+#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES
+#define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION
+#define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet"
+#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
+#define crypto_secretbox crypto_secretbox_xsalsa20poly1305
+#define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open
+#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
+#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
+#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
+#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
+#define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION
+#define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION
+#define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32
+#define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24
+#define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32
+#define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16
+extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-"
+#define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet
+#define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open
+#define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES
+#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES
+#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES
+#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES
+#define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION
+#define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet"
+#define crypto_sign_PRIMITIVE "ed25519"
+#define crypto_sign crypto_sign_ed25519
+#define crypto_sign_open crypto_sign_ed25519_open
+#define crypto_sign_keypair crypto_sign_ed25519_keypair
+#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
+#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
+#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
+#define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
+#define crypto_sign_VERSION crypto_sign_ed25519_VERSION
+#define crypto_sign_ed25519_tweet_BYTES 64
+#define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32
+#define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64
+extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *);
+#define crypto_sign_ed25519_tweet_VERSION "-"
+#define crypto_sign_ed25519 crypto_sign_ed25519_tweet
+#define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open
+#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair
+#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES
+#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES
+#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES
+#define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION
+#define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet"
+#define crypto_stream_PRIMITIVE "xsalsa20"
+#define crypto_stream crypto_stream_xsalsa20
+#define crypto_stream_xor crypto_stream_xsalsa20_xor
+#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
+#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
+#define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION
+#define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION
+#define crypto_stream_xsalsa20_tweet_KEYBYTES 32
+#define crypto_stream_xsalsa20_tweet_NONCEBYTES 24
+extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_stream_xsalsa20_tweet_VERSION "-"
+#define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet
+#define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor
+#define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES
+#define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES
+#define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION
+#define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet"
+#define crypto_stream_salsa20_tweet_KEYBYTES 32
+#define crypto_stream_salsa20_tweet_NONCEBYTES 8
+extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_stream_salsa20_tweet_VERSION "-"
+#define crypto_stream_salsa20 crypto_stream_salsa20_tweet
+#define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor
+#define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES
+#define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES
+#define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION
+#define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet"
+#define crypto_verify_PRIMITIVE "16"
+#define crypto_verify crypto_verify_16
+#define crypto_verify_BYTES crypto_verify_16_BYTES
+#define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION
+#define crypto_verify_VERSION crypto_verify_16_VERSION
+#define crypto_verify_16_tweet_BYTES 16
+extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *);
+#define crypto_verify_16_tweet_VERSION "-"
+#define crypto_verify_16 crypto_verify_16_tweet
+#define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES
+#define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION
+#define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet"
+#define crypto_verify_32_tweet_BYTES 32
+extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *);
+#define crypto_verify_32_tweet_VERSION "-"
+#define crypto_verify_32 crypto_verify_32_tweet
+#define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES
+#define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION
+#define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet"
+#endif
diff --git a/validat1.cpp b/validat1.cpp index 715c13c8..d3eafea2 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -208,6 +208,8 @@ bool ValidateAll(bool thorough) pass=ValidateECGDSA(thorough) && pass;
pass=ValidateESIGN() && pass;
+ pass=ValidateNaCl() && pass;
+
if (pass)
std::cout << "\nAll tests passed!\n";
else
diff --git a/validat4.cpp b/validat4.cpp new file mode 100644 index 00000000..53756cae --- /dev/null +++ b/validat4.cpp @@ -0,0 +1,488 @@ +// validat4.cpp - written and placed in the public domain by Jeffrey Walton
+// Routines in this source file test NaCl library routines.
+//
+// There are two types or sets of self tests. First is a known answer test,
+// and second are pairwise consitency checks. The known answer tests are test
+// vectors lifted from libsodium. The pairwise consitency checks are randomized
+// and confirm the library can arrive at the same result or round trip data
+// using it's own transformations.
+//
+// A link like https://github.com/jedisct1/libsodium/blob/master/test/default/box.c
+// references the libsodium test data for a test. For example, box.c is one of the
+// test runners for crypto_box, and there is a box.exp with the known answer. The
+// glue code for box.c and box.exp is in "cmptest.h". box.c runs the test and
+// generates output, while cmptest.h gathers the output and compares them.
+
+#include "pch.h"
+
+#include "cryptlib.h"
+#include "secblock.h"
+#include "integer.h"
+#include "nacl.h"
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+
+#include "validate.h"
+
+// Aggressive stack checking with VS2005 SP1 and above.
+#if (_MSC_FULL_VER >= 140050727)
+# pragma strict_gs_check (on)
+#endif
+
+#if CRYPTOPP_MSC_VERSION
+# pragma warning(disable: 4505 4355)
+#endif
+
+NAMESPACE_BEGIN(CryptoPP)
+NAMESPACE_BEGIN(Test)
+
+#ifndef CRYPTOPP_DISABLE_NACL
+
+USING_NAMESPACE(NaCl)
+
+bool TestCryptoBox()
+{
+ // https://github.com/jedisct1/libsodium/blob/master/test/default/box.c
+ const uint8_t alicesk[32] = {
+ 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1,
+ 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0,
+ 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
+ };
+
+ const uint8_t bobpk[32] = {
+ 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61,
+ 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78,
+ 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f
+ };
+
+ const uint8_t small_order_p[crypto_box_PUBLICKEYBYTES] = {
+ 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
+ };
+
+ const uint8_t nonce[24] = {
+ 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8,
+ 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37
+ };
+
+ /* API requires first 32 bytes to be 0 */
+ const uint8_t m[163] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0xbe, 0x07, 0x5f, 0xc5,
+ 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b,
+ 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, 0x4b, 0x66, 0x84, 0x9b,
+ 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a,
+ 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, 0x6c, 0xdc, 0x3c, 0x01,
+ 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31,
+ 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, 0xce, 0xea, 0x3a, 0x7f,
+ 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a,
+ 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, 0x04, 0x89, 0x77, 0xeb,
+ 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52,
+ 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, 0xe0, 0x82, 0xf9, 0x37,
+ 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05
+ };
+
+ const uint8_t exp1[] = {
+ 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,
+ 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,
+ 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,
+ 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,
+ 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,
+ 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,
+ 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,
+ 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,
+ 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,
+ 0xe3,0x55,0xa5
+ };
+
+ const uint8_t exp2[] = {
+ 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,
+ 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,
+ 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,
+ 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,
+ 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,
+ 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,
+ 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,
+ 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,
+ 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,
+ 0xe3,0x55,0xa5
+ };
+
+ uint8_t c[163];
+ uint8_t k[crypto_box_BEFORENMBYTES];
+
+ bool pass = true; int rc;
+
+ rc = crypto_box(c, m, 163, nonce, bobpk, alicesk);
+ pass = (rc == 0) && pass;
+ pass = (std::memcmp(c+16, exp1, 163-16) == 0) && pass;
+
+ rc = crypto_box(c, m, 163, nonce, small_order_p, alicesk);
+ pass = (rc != 0) && pass;
+ std::memset(c, 0, sizeof(c));
+
+ rc = crypto_box_beforenm(k, bobpk, alicesk);
+ pass = (rc == 0) && pass;
+ rc = crypto_box_afternm(c, m, 163, nonce, k);
+ pass = (rc == 0) && pass;
+ pass = (std::memcmp(c+16, exp2, 163-16) == 0) && pass;
+
+ rc = crypto_box_beforenm(k, small_order_p, alicesk);
+ pass = (rc != 0) && pass;
+
+ return pass;
+}
+
+bool TestCryptoBoxOpen()
+{
+ // https://github.com/jedisct1/libsodium/blob/master/test/default/box2.c
+ const uint8_t bobsk[32] = {
+ 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80,
+ 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27,
+ 0xff, 0x88, 0xe0, 0xeb
+ };
+
+ const uint8_t alicepk[32] = {
+ 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e,
+ 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e,
+ 0xaa, 0x9b, 0x4e, 0x6a
+ };
+
+ static const uint8_t small_order_p[crypto_box_PUBLICKEYBYTES] = {
+ 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
+ };
+
+ const uint8_t nonce[24] = {
+ 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8,
+ 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37
+ };
+
+ /* API requires first 16 bytes to be 0 */
+ const uint8_t c[163] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
+ 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, 0x8e, 0x99, 0x3b, 0x9f,
+ 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
+ 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, 0x47, 0x6f, 0xb8, 0xc5,
+ 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
+ 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, 0x71, 0xd2, 0xc2, 0x0f,
+ 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
+ 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, 0xb9, 0x32, 0x16, 0x45,
+ 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
+ 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, 0x99, 0x83, 0x2b, 0x61,
+ 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
+ 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, 0x59, 0x9b, 0x1f, 0x65,
+ 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5
+ };
+
+ const uint8_t exp1[] = {
+ 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5, 0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b,
+ 0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4, 0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc,
+ 0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a, 0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29,
+ 0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4, 0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31,
+ 0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d, 0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57,
+ 0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a, 0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde,
+ 0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd, 0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52,
+ 0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40, 0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64,
+ 0x5e,0x07,0x05
+ };
+
+ const uint8_t exp2[] = {
+ 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5, 0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b,
+ 0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4, 0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc,
+ 0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a, 0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29,
+ 0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4, 0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31,
+ 0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d, 0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57,
+ 0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a, 0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde,
+ 0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd, 0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52,
+ 0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40, 0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64,
+ 0x5e,0x07,0x05
+ };
+
+ uint8_t m[163];
+ uint8_t k[crypto_box_BEFORENMBYTES];
+
+ bool pass = true; int rc;
+
+ rc = crypto_box_open(m, c, 163, nonce, alicepk, bobsk);
+ pass = (rc == 0) && pass;
+ pass = (std::memcmp(m+32, exp1, 163-32) == 0) && pass;
+
+ rc = crypto_box_open(m, c, 163, nonce, small_order_p, bobsk);
+ pass = (rc != 0) && pass;
+
+ rc = crypto_box_beforenm(k, small_order_p, bobsk);
+ pass = (rc != 0) && pass;
+ rc = crypto_box_beforenm(k, alicepk, bobsk);
+ pass = (rc == 0) && pass;
+
+ rc = crypto_box_open_afternm(m, c, 163, nonce, k);
+ pass = (rc == 0) && pass;
+ pass = (std::memcmp(m+32, exp2, 163-32) == 0) && pass;
+
+ return pass;
+}
+
+bool TestCryptoBoxKeys()
+{
+ // https://github.com/jedisct1/libsodium/blob/master/test/default/box7.c
+ const unsigned int MAX_TEST = 128;
+ const unsigned int MAX_MESSAGE = 4096;
+
+ uint8_t alicesk[crypto_box_SECRETKEYBYTES];
+ uint8_t alicepk[crypto_box_PUBLICKEYBYTES];
+ uint8_t bobsk[crypto_box_SECRETKEYBYTES];
+ uint8_t bobpk[crypto_box_PUBLICKEYBYTES];
+
+ // uint8_t m[MAX_MESSAGE+32];
+ // uint8_t c[MAX_MESSAGE+32];
+ // uint8_t r[MAX_MESSAGE+32];
+
+ bool pass = true, fail; int rc;
+ for (unsigned int i=0; i < MAX_TEST; ++i)
+ {
+ fail = (crypto_box_keypair(alicepk, alicesk) != 0);
+ pass = !fail && pass;
+ fail = (crypto_box_keypair(bobpk, bobsk) != 0);
+ pass = !fail && pass;
+
+ SecByteBlock m, c, r, n;
+ const uint32_t len = (i == 0 ? 0 : GlobalRNG().GenerateWord32(1, MAX_MESSAGE));
+
+ m.New(len+crypto_box_ZEROBYTES);
+ c.New(len+crypto_box_BOXZEROBYTES+crypto_box_MACBYTES);
+ r.New(len+crypto_box_ZEROBYTES);
+ n.New(crypto_box_NONCEBYTES);
+
+ GlobalRNG().GenerateBlock(m+crypto_box_ZEROBYTES, len);
+ GlobalRNG().GenerateBlock(n, crypto_box_NONCEBYTES);
+
+ std::memset(m, 0x00, crypto_box_ZEROBYTES);
+ rc = crypto_box(c, m, len + crypto_box_ZEROBYTES, n, bobpk, alicesk);
+ fail = (rc != 0); pass = !fail && pass;
+
+ std::memset(c, 0x00, crypto_box_BOXZEROBYTES);
+ rc = crypto_box_open(r, c, len + crypto_box_BOXZEROBYTES + crypto_box_MACBYTES, n, alicepk, bobsk);
+ fail = (rc != 0); pass = !fail && pass;
+
+ fail = std::memcmp(m+crypto_box_ZEROBYTES, r+crypto_box_ZEROBYTES, len) != 0;
+ pass = !fail && pass;
+
+ m.SetMark(16); c.SetMark(16); r.SetMark(16);
+ }
+
+ return pass;
+}
+
+struct TestData {
+ const uint8_t sk[crypto_sign_SEEDBYTES];
+ const uint8_t pk[crypto_sign_PUBLICKEYBYTES];
+ const uint8_t sig[crypto_sign_BYTES];
+ const uint32_t len;
+ const char* msg;
+};
+
+// https://github.com/jedisct1/libsodium/blob/master/test/default/sign.c
+const TestData test_data[] = {
+ {{0x9d,0x61,0xb1,0x9d,0xef,0xfd,0x5a,0x60,0xba,0x84,0x4a,0xf4,0x92,0xec,0x2c,0xc4,0x44,0x49,0xc5,0x69,0x7b,0x32,0x69,0x19,0x70,0x3b,0xac,0x03,0x1c,0xae,0x7f,0x60,},{0xd7,0x5a,0x98,0x01,0x82,0xb1,0x0a,0xb7,0xd5,0x4b,0xfe,0xd3,0xc9,0x64,0x07,0x3a,0x0e,0xe1,0x72,0xf3,0xda,0xa6,0x23,0x25,0xaf,0x02,0x1a,0x68,0xf7,0x07,0x51,0x1a,},{0xe5,0x56,0x43,0x00,0xc3,0x60,0xac,0x72,0x90,0x86,0xe2,0xcc,0x80,0x6e,0x82,0x8a,0x84,0x87,0x7f,0x1e,0xb8,0xe5,0xd9,0x74,0xd8,0x73,0xe0,0x65,0x22,0x49,0x01,0x55,0x5f,0xb8,0x82,0x15,0x90,0xa3,0x3b,0xac,0xc6,0x1e,0x39,0x70,0x1c,0xf9,0xb4,0x6b,0xd2,0x5b,0xf5,0xf0,0x59,0x5b,0xbe,0x24,0x65,0x51,0x41,0x43,0x8e,0x7a,0x10,0x0b,},0,""},
+ {{0x4c,0xcd,0x08,0x9b,0x28,0xff,0x96,0xda,0x9d,0xb6,0xc3,0x46,0xec,0x11,0x4e,0x0f,0x5b,0x8a,0x31,0x9f,0x35,0xab,0xa6,0x24,0xda,0x8c,0xf6,0xed,0x4f,0xb8,0xa6,0xfb,},{0x3d,0x40,0x17,0xc3,0xe8,0x43,0x89,0x5a,0x92,0xb7,0x0a,0xa7,0x4d,0x1b,0x7e,0xbc,0x9c,0x98,0x2c,0xcf,0x2e,0xc4,0x96,0x8c,0xc0,0xcd,0x55,0xf1,0x2a,0xf4,0x66,0x0c,},{0x92,0xa0,0x09,0xa9,0xf0,0xd4,0xca,0xb8,0x72,0x0e,0x82,0x0b,0x5f,0x64,0x25,0x40,0xa2,0xb2,0x7b,0x54,0x16,0x50,0x3f,0x8f,0xb3,0x76,0x22,0x23,0xeb,0xdb,0x69,0xda,0x08,0x5a,0xc1,0xe4,0x3e,0x15,0x99,0x6e,0x45,0x8f,0x36,0x13,0xd0,0xf1,0x1d,0x8c,0x38,0x7b,0x2e,0xae,0xb4,0x30,0x2a,0xee,0xb0,0x0d,0x29,0x16,0x12,0xbb,0x0c,0x00,},1,"\x72"},
+ {{0xc5,0xaa,0x8d,0xf4,0x3f,0x9f,0x83,0x7b,0xed,0xb7,0x44,0x2f,0x31,0xdc,0xb7,0xb1,0x66,0xd3,0x85,0x35,0x07,0x6f,0x09,0x4b,0x85,0xce,0x3a,0x2e,0x0b,0x44,0x58,0xf7,},{0xfc,0x51,0xcd,0x8e,0x62,0x18,0xa1,0xa3,0x8d,0xa4,0x7e,0xd0,0x02,0x30,0xf0,0x58,0x08,0x16,0xed,0x13,0xba,0x33,0x03,0xac,0x5d,0xeb,0x91,0x15,0x48,0x90,0x80,0x25,},{0x62,0x91,0xd6,0x57,0xde,0xec,0x24,0x02,0x48,0x27,0xe6,0x9c,0x3a,0xbe,0x01,0xa3,0x0c,0xe5,0x48,0xa2,0x84,0x74,0x3a,0x44,0x5e,0x36,0x80,0xd7,0xdb,0x5a,0xc3,0xac,0x18,0xff,0x9b,0x53,0x8d,0x16,0xf2,0x90,0xae,0x67,0xf7,0x60,0x98,0x4d,0xc6,0x59,0x4a,0x7c,0x15,0xe9,0x71,0x6e,0xd2,0x8d,0xc0,0x27,0xbe,0xce,0xea,0x1e,0xc4,0x0a,},2,"\xaf\x82"},
+ {{0x0d,0x4a,0x05,0xb0,0x73,0x52,0xa5,0x43,0x6e,0x18,0x03,0x56,0xda,0x0a,0xe6,0xef,0xa0,0x34,0x5f,0xf7,0xfb,0x15,0x72,0x57,0x57,0x72,0xe8,0x00,0x5e,0xd9,0x78,0xe9,},{0xe6,0x1a,0x18,0x5b,0xce,0xf2,0x61,0x3a,0x6c,0x7c,0xb7,0x97,0x63,0xce,0x94,0x5d,0x3b,0x24,0x5d,0x76,0x11,0x4d,0xd4,0x40,0xbc,0xf5,0xf2,0xdc,0x1a,0xa5,0x70,0x57,},{0xd9,0x86,0x8d,0x52,0xc2,0xbe,0xbc,0xe5,0xf3,0xfa,0x5a,0x79,0x89,0x19,0x70,0xf3,0x09,0xcb,0x65,0x91,0xe3,0xe1,0x70,0x2a,0x70,0x27,0x6f,0xa9,0x7c,0x24,0xb3,0xa8,0xe5,0x86,0x06,0xc3,0x8c,0x97,0x58,0x52,0x9d,0xa5,0x0e,0xe3,0x1b,0x82,0x19,0xcb,0xa4,0x52,0x71,0xc6,0x89,0xaf,0xa6,0x0b,0x0e,0xa2,0x6c,0x99,0xdb,0x19,0xb0,0x0c,},3,"\xcb\xc7\x7b"},
+ {{0x6d,0xf9,0x34,0x0c,0x13,0x8c,0xc1,0x88,0xb5,0xfe,0x44,0x64,0xeb,0xaa,0x3f,0x7f,0xc2,0x06,0xa2,0xd5,0x5c,0x34,0x34,0x70,0x7e,0x74,0xc9,0xfc,0x04,0xe2,0x0e,0xbb,},{0xc0,0xda,0xc1,0x02,0xc4,0x53,0x31,0x86,0xe2,0x5d,0xc4,0x31,0x28,0x47,0x23,0x53,0xea,0xab,0xdb,0x87,0x8b,0x15,0x2a,0xeb,0x8e,0x00,0x1f,0x92,0xd9,0x02,0x33,0xa7,},{0x12,0x4f,0x6f,0xc6,0xb0,0xd1,0x00,0x84,0x27,0x69,0xe7,0x1b,0xd5,0x30,0x66,0x4d,0x88,0x8d,0xf8,0x50,0x7d,0xf6,0xc5,0x6d,0xed,0xfd,0xb5,0x09,0xae,0xb9,0x34,0x16,0xe2,0x6b,0x91,0x8d,0x38,0xaa,0x06,0x30,0x5d,0xf3,0x09,0x56,0x97,0xc1,0x8b,0x2a,0xa8,0x32,0xea,0xa5,0x2e,0xdc,0x0a,0xe4,0x9f,0xba,0xe5,0xa8,0x5e,0x15,0x0c,0x07,},4,"\x5f\x4c\x89\x89"},
+ {{0xb7,0x80,0x38,0x1a,0x65,0xed,0xf8,0xb7,0x8f,0x69,0x45,0xe8,0xdb,0xec,0x79,0x41,0xac,0x04,0x9f,0xd4,0xc6,0x10,0x40,0xcf,0x0c,0x32,0x43,0x57,0x97,0x5a,0x29,0x3c,},{0xe2,0x53,0xaf,0x07,0x66,0x80,0x4b,0x86,0x9b,0xb1,0x59,0x5b,0xe9,0x76,0x5b,0x53,0x48,0x86,0xbb,0xaa,0xb8,0x30,0x5b,0xf5,0x0d,0xbc,0x7f,0x89,0x9b,0xfb,0x5f,0x01,},{0xb2,0xfc,0x46,0xad,0x47,0xaf,0x46,0x44,0x78,0xc1,0x99,0xe1,0xf8,0xbe,0x16,0x9f,0x1b,0xe6,0x32,0x7c,0x7f,0x9a,0x0a,0x66,0x89,0x37,0x1c,0xa9,0x4c,0xaf,0x04,0x06,0x4a,0x01,0xb2,0x2a,0xff,0x15,0x20,0xab,0xd5,0x89,0x51,0x34,0x16,0x03,0xfa,0xed,0x76,0x8c,0xf7,0x8c,0xe9,0x7a,0xe7,0xb0,0x38,0xab,0xfe,0x45,0x6a,0xa1,0x7c,0x09,},5,"\x18\xb6\xbe\xc0\x97"},
+ {{0x78,0xae,0x9e,0xff,0xe6,0xf2,0x45,0xe9,0x24,0xa7,0xbe,0x63,0x04,0x11,0x46,0xeb,0xc6,0x70,0xdb,0xd3,0x06,0x0c,0xba,0x67,0xfb,0xc6,0x21,0x6f,0xeb,0xc4,0x45,0x46,},{0xfb,0xcf,0xbf,0xa4,0x05,0x05,0xd7,0xf2,0xbe,0x44,0x4a,0x33,0xd1,0x85,0xcc,0x54,0xe1,0x6d,0x61,0x52,0x60,0xe1,0x64,0x0b,0x2b,0x50,0x87,0xb8,0x3e,0xe3,0x64,0x3d,},{0x6e,0xd6,0x29,0xfc,0x1d,0x9c,0xe9,0xe1,0x46,0x87,0x55,0xff,0x63,0x6d,0x5a,0x3f,0x40,0xa5,0xd9,0xc9,0x1a,0xfd,0x93,0xb7,0x9d,0x24,0x18,0x30,0xf7,0xe5,0xfa,0x29,0x85,0x4b,0x8f,0x20,0xcc,0x6e,0xec,0xbb,0x24,0x8d,0xbd,0x8d,0x16,0xd1,0x4e,0x99,0x75,0x21,0x94,0xe4,0x90,0x4d,0x09,0xc7,0x4d,0x63,0x95,0x18,0x83,0x9d,0x23,0x00,},6,"\x89\x01\x0d\x85\x59\x72"},
+ {{0x69,0x18,0x65,0xbf,0xc8,0x2a,0x1e,0x4b,0x57,0x4e,0xec,0xde,0x4c,0x75,0x19,0x09,0x3f,0xaf,0x0c,0xf8,0x67,0x38,0x02,0x34,0xe3,0x66,0x46,0x45,0xc6,0x1c,0x5f,0x79,},{0x98,0xa5,0xe3,0xa3,0x6e,0x67,0xaa,0xba,0x89,0x88,0x8b,0xf0,0x93,0xde,0x1a,0xd9,0x63,0xe7,0x74,0x01,0x3b,0x39,0x02,0xbf,0xab,0x35,0x6d,0x8b,0x90,0x17,0x8a,0x63,},{0x6e,0x0a,0xf2,0xfe,0x55,0xae,0x37,0x7a,0x6b,0x7a,0x72,0x78,0xed,0xfb,0x41,0x9b,0xd3,0x21,0xe0,0x6d,0x0d,0xf5,0xe2,0x70,0x37,0xdb,0x88,0x12,0xe7,0xe3,0x52,0x98,0x10,0xfa,0x55,0x52,0xf6,0xc0,0x02,0x09,0x85,0xca,0x17,0xa0,0xe0,0x2e,0x03,0x6d,0x7b,0x22,0x2a,0x24,0xf9,0x9b,0x77,0xb7,0x5f,0xdd,0x16,0xcb,0x05,0x56,0x81,0x07,},7,"\xb4\xa8\xf3\x81\xe7\x0e\x7a"},
+ {{0x3b,0x26,0x51,0x6f,0xb3,0xdc,0x88,0xeb,0x18,0x1b,0x9e,0xd7,0x3f,0x0b,0xcd,0x52,0xbc,0xd6,0xb4,0xc7,0x88,0xe4,0xbc,0xaf,0x46,0x05,0x7f,0xd0,0x78,0xbe,0xe0,0x73,},{0xf8,0x1f,0xb5,0x4a,0x82,0x5f,0xce,0xd9,0x5e,0xb0,0x33,0xaf,0xcd,0x64,0x31,0x40,0x75,0xab,0xfb,0x0a,0xbd,0x20,0xa9,0x70,0x89,0x25,0x03,0x43,0x6f,0x34,0xb8,0x63,},{0xd6,0xad,0xde,0xc5,0xaf,0xb0,0x52,0x8a,0xc1,0x7b,0xb1,0x78,0xd3,0xe7,0xf2,0x88,0x7f,0x9a,0xdb,0xb1,0xad,0x16,0xe1,0x10,0x54,0x5e,0xf3,0xbc,0x57,0xf9,0xde,0x23,0x14,0xa5,0xc8,0x38,0x8f,0x72,0x3b,0x89,0x07,0xbe,0x0f,0x3a,0xc9,0x0c,0x62,0x59,0xbb,0xe8,0x85,0xec,0xc1,0x76,0x45,0xdf,0x3d,0xb7,0xd4,0x88,0xf8,0x05,0xfa,0x08,},8,"\x42\x84\xab\xc5\x1b\xb6\x72\x35"},
+ {{0xed,0xc6,0xf5,0xfb,0xdd,0x1c,0xee,0x4d,0x10,0x1c,0x06,0x35,0x30,0xa3,0x04,0x90,0xb2,0x21,0xbe,0x68,0xc0,0x36,0xf5,0xb0,0x7d,0x0f,0x95,0x3b,0x74,0x5d,0xf1,0x92,},{0xc1,0xa4,0x9c,0x66,0xe6,0x17,0xf9,0xef,0x5e,0xc6,0x6b,0xc4,0xc6,0x56,0x4c,0xa3,0x3d,0xe2,0xa5,0xfb,0x5e,0x14,0x64,0x06,0x2e,0x6d,0x6c,0x62,0x19,0x15,0x5e,0xfd,},{0x2c,0x76,0xa0,0x4a,0xf2,0x39,0x1c,0x14,0x70,0x82,0xe3,0x3f,0xaa,0xcd,0xbe,0x56,0x64,0x2a,0x1e,0x13,0x4b,0xd3,0x88,0x62,0x0b,0x85,0x2b,0x90,0x1a,0x6b,0xc1,0x6f,0xf6,0xc9,0xcc,0x94,0x04,0xc4,0x1d,0xea,0x12,0xed,0x28,0x1d,0xa0,0x67,0xa1,0x51,0x38,0x66,0xf9,0xd9,0x64,0xf8,0xbd,0xd2,0x49,0x53,0x85,0x6c,0x50,0x04,0x29,0x01,},9,"\x67\x2b\xf8\x96\x5d\x04\xbc\x51\x46"},
+ {{0x4e,0x7d,0x21,0xfb,0x3b,0x18,0x97,0x57,0x1a,0x44,0x58,0x33,0xbe,0x0f,0x9f,0xd4,0x1c,0xd6,0x2b,0xe3,0xaa,0x04,0x04,0x0f,0x89,0x34,0xe1,0xfc,0xbd,0xca,0xcd,0x45,},{0x31,0xb2,0x52,0x4b,0x83,0x48,0xf7,0xab,0x1d,0xfa,0xfa,0x67,0x5c,0xc5,0x38,0xe9,0xa8,0x4e,0x3f,0xe5,0x81,0x9e,0x27,0xc1,0x2a,0xd8,0xbb,0xc1,0xa3,0x6e,0x4d,0xff,},{0x28,0xe4,0x59,0x8c,0x41,0x5a,0xe9,0xde,0x01,0xf0,0x3f,0x9f,0x3f,0xab,0x4e,0x91,0x9e,0x8b,0xf5,0x37,0xdd,0x2b,0x0c,0xdf,0x6e,0x79,0xb9,0xe6,0x55,0x9c,0x94,0x09,0xd9,0x15,0x1a,0x4c,0x40,0xf0,0x83,0x19,0x39,0x37,0x62,0x7c,0x36,0x94,0x88,0x25,0x9e,0x99,0xda,0x5a,0x9f,0x0a,0x87,0x49,0x7f,0xa6,0x69,0x6a,0x5d,0xd6,0xce,0x08,},10,"\x33\xd7\xa7\x86\xad\xed\x8c\x1b\xf6\x91"},
+ {{0xa9,0x80,0xf8,0x92,0xdb,0x13,0xc9,0x9a,0x3e,0x89,0x71,0xe9,0x65,0xb2,0xff,0x3d,0x41,0xea,0xfd,0x54,0x09,0x3b,0xc9,0xf3,0x4d,0x1f,0xd2,0x2d,0x84,0x11,0x5b,0xb6,},{0x44,0xb5,0x7e,0xe3,0x0c,0xdb,0x55,0x82,0x9d,0x0a,0x5d,0x4f,0x04,0x6b,0xae,0xf0,0x78,0xf1,0xe9,0x7a,0x7f,0x21,0xb6,0x2d,0x75,0xf8,0xe9,0x6e,0xa1,0x39,0xc3,0x5f,},{0x77,0xd3,0x89,0xe5,0x99,0x63,0x0d,0x93,0x40,0x76,0x32,0x95,0x83,0xcd,0x41,0x05,0xa6,0x49,0xa9,0x29,0x2a,0xbc,0x44,0xcd,0x28,0xc4,0x00,0x00,0xc8,0xe2,0xf5,0xac,0x76,0x60,0xa8,0x1c,0x85,0xb7,0x2a,0xf8,0x45,0x2d,0x7d,0x25,0xc0,0x70,0x86,0x1d,0xae,0x91,0x60,0x1c,0x78,0x03,0xd6,0x56,0x53,0x16,0x50,0xdd,0x4e,0x5c,0x41,0x00,},11,"\x34\x86\xf6\x88\x48\xa6\x5a\x0e\xb5\x50\x7d"},
+ {{0x5b,0x5a,0x61,0x9f,0x8c,0xe1,0xc6,0x6d,0x7c,0xe2,0x6e,0x5a,0x2a,0xe7,0xb0,0xc0,0x4f,0xeb,0xcd,0x34,0x6d,0x28,0x6c,0x92,0x9e,0x19,0xd0,0xd5,0x97,0x3b,0xfe,0xf9,},{0x6f,0xe8,0x36,0x93,0xd0,0x11,0xd1,0x11,0x13,0x1c,0x4f,0x3f,0xba,0xaa,0x40,0xa9,0xd3,0xd7,0x6b,0x30,0x01,0x2f,0xf7,0x3b,0xb0,0xe3,0x9e,0xc2,0x7a,0xb1,0x82,0x57,},{0x0f,0x9a,0xd9,0x79,0x30,0x33,0xa2,0xfa,0x06,0x61,0x4b,0x27,0x7d,0x37,0x38,0x1e,0x6d,0x94,0xf6,0x5a,0xc2,0xa5,0xa9,0x45,0x58,0xd0,0x9e,0xd6,0xce,0x92,0x22,0x58,0xc1,0xa5,0x67,0x95,0x2e,0x86,0x3a,0xc9,0x42,0x97,0xae,0xc3,0xc0,0xd0,0xc8,0xdd,0xf7,0x10,0x84,0xe5,0x04,0x86,0x0b,0xb6,0xba,0x27,0x44,0x9b,0x55,0xad,0xc4,0x0e,},12,"\x5a\x8d\x9d\x0a\x22\x35\x7e\x66\x55\xf9\xc7\x85"},
+ {{0x94,0x0c,0x89,0xfe,0x40,0xa8,0x1d,0xaf,0xbd,0xb2,0x41,0x6d,0x14,0xae,0x46,0x91,0x19,0x86,0x97,0x44,0x41,0x0c,0x33,0x03,0xbf,0xaa,0x02,0x41,0xda,0xc5,0x78,0x00,},{0xa2,0xeb,0x8c,0x05,0x01,0xe3,0x0b,0xae,0x0c,0xf8,0x42,0xd2,0xbd,0xe8,0xde,0xc7,0x38,0x6f,0x6b,0x7f,0xc3,0x98,0x1b,0x8c,0x57,0xc9,0x79,0x2b,0xb9,0x4c,0xf2,0xdd,},{0xd8,0xbb,0x64,0xaa,0xd8,0xc9,0x95,0x5a,0x11,0x5a,0x79,0x3a,0xdd,0xd2,0x4f,0x7f,0x2b,0x07,0x76,0x48,0x71,0x4f,0x49,0xc4,0x69,0x4e,0xc9,0x95,0xb3,0x30,0xd0,0x9d,0x64,0x0d,0xf3,0x10,0xf4,0x47,0xfd,0x7b,0x6c,0xb5,0xc1,0x4f,0x9f,0xe9,0xf4,0x90,0xbc,0xf8,0xcf,0xad,0xbf,0xd2,0x16,0x9c,0x8a,0xc2,0x0d,0x3b,0x8a,0xf4,0x9a,0x0c,},13,"\xb8\x7d\x38\x13\xe0\x3f\x58\xcf\x19\xfd\x0b\x63\x95"},
+ {{0x9a,0xca,0xd9,0x59,0xd2,0x16,0x21,0x2d,0x78,0x9a,0x11,0x92,0x52,0xeb,0xfe,0x0c,0x96,0x51,0x2a,0x23,0xc7,0x3b,0xd9,0xf3,0xb2,0x02,0x29,0x2d,0x69,0x16,0xa7,0x38,},{0xcf,0x3a,0xf8,0x98,0x46,0x7a,0x5b,0x7a,0x52,0xd3,0x3d,0x53,0xbc,0x03,0x7e,0x26,0x42,0xa8,0xda,0x99,0x69,0x03,0xfc,0x25,0x22,0x17,0xe9,0xc0,0x33,0xe2,0xf2,0x91,},{0x6e,0xe3,0xfe,0x81,0xe2,0x3c,0x60,0xeb,0x23,0x12,0xb2,0x00,0x6b,0x3b,0x25,0xe6,0x83,0x8e,0x02,0x10,0x66,0x23,0xf8,0x44,0xc4,0x4e,0xdb,0x8d,0xaf,0xd6,0x6a,0xb0,0x67,0x10,0x87,0xfd,0x19,0x5d,0xf5,0xb8,0xf5,0x8a,0x1d,0x6e,0x52,0xaf,0x42,0x90,0x80,0x53,0xd5,0x5c,0x73,0x21,0x01,0x00,0x92,0x74,0x87,0x95,0xef,0x94,0xcf,0x06,},14,"\x55\xc7\xfa\x43\x4f\x5e\xd8\xcd\xec\x2b\x7a\xea\xc1\x73"},
+ {{0xd5,0xae,0xee,0x41,0xee,0xb0,0xe9,0xd1,0xbf,0x83,0x37,0xf9,0x39,0x58,0x7e,0xbe,0x29,0x61,0x61,0xe6,0xbf,0x52,0x09,0xf5,0x91,0xec,0x93,0x9e,0x14,0x40,0xc3,0x00,},{0xfd,0x2a,0x56,0x57,0x23,0x16,0x3e,0x29,0xf5,0x3c,0x9d,0xe3,0xd5,0xe8,0xfb,0xe3,0x6a,0x7a,0xb6,0x6e,0x14,0x39,0xec,0x4e,0xae,0x9c,0x0a,0x60,0x4a,0xf2,0x91,0xa5,},{0xf6,0x8d,0x04,0x84,0x7e,0x5b,0x24,0x97,0x37,0x89,0x9c,0x01,0x4d,0x31,0xc8,0x05,0xc5,0x00,0x7a,0x62,0xc0,0xa1,0x0d,0x50,0xbb,0x15,0x38,0xc5,0xf3,0x55,0x03,0x95,0x1f,0xbc,0x1e,0x08,0x68,0x2f,0x2c,0xc0,0xc9,0x2e,0xfe,0x8f,0x49,0x85,0xde,0xc6,0x1d,0xcb,0xd5,0x4d,0x4b,0x94,0xa2,0x25,0x47,0xd2,0x44,0x51,0x27,0x1c,0x8b,0x00,},15,"\x0a\x68\x8e\x79\xbe\x24\xf8\x66\x28\x6d\x46\x46\xb5\xd8\x1c"},
+ {{0x0a,0x47,0xd1,0x04,0x52,0xae,0x2f,0xeb,0xec,0x51,0x8a,0x1c,0x7c,0x36,0x28,0x90,0xc3,0xfc,0x1a,0x49,0xd3,0x4b,0x03,0xb6,0x46,0x7d,0x35,0xc9,0x04,0xa8,0x36,0x2d,},{0x34,0xe5,0xa8,0x50,0x8c,0x47,0x43,0x74,0x69,0x62,0xc0,0x66,0xe4,0xba,0xde,0xa2,0x20,0x1b,0x8a,0xb4,0x84,0xde,0x5c,0x4f,0x94,0x47,0x6c,0xcd,0x21,0x43,0x95,0x5b,},{0x2a,0x3d,0x27,0xdc,0x40,0xd0,0xa8,0x12,0x79,0x49,0xa3,0xb7,0xf9,0x08,0xb3,0x68,0x8f,0x63,0xb7,0xf1,0x4f,0x65,0x1a,0xac,0xd7,0x15,0x94,0x0b,0xdb,0xe2,0x7a,0x08,0x09,0xaa,0xc1,0x42,0xf4,0x7a,0xb0,0xe1,0xe4,0x4f,0xa4,0x90,0xba,0x87,0xce,0x53,0x92,0xf3,0x3a,0x89,0x15,0x39,0xca,0xf1,0xef,0x4c,0x36,0x7c,0xae,0x54,0x50,0x0c,},16,"\xc9\x42\xfa\x7a\xc6\xb2\x3a\xb7\xff\x61\x2f\xdc\x8e\x68\xef\x39"},
+ {{0xf8,0x14,0x8f,0x75,0x06,0xb7,0x75,0xef,0x46,0xfd,0xc8,0xe8,0xc7,0x56,0x51,0x68,0x12,0xd4,0x7d,0x6c,0xfb,0xfa,0x31,0x8c,0x27,0xc9,0xa2,0x26,0x41,0xe5,0x6f,0x17,},{0x04,0x45,0xe4,0x56,0xda,0xcc,0x7d,0x5b,0x0b,0xbe,0xd2,0x3c,0x82,0x00,0xcd,0xb7,0x4b,0xdc,0xb0,0x3e,0x4c,0x7b,0x73,0xf0,0xa2,0xb9,0xb4,0x6e,0xac,0x5d,0x43,0x72,},{0x36,0x53,0xcc,0xb2,0x12,0x19,0x20,0x2b,0x84,0x36,0xfb,0x41,0xa3,0x2b,0xa2,0x61,0x8c,0x4a,0x13,0x34,0x31,0xe6,0xe6,0x34,0x63,0xce,0xb3,0xb6,0x10,0x6c,0x4d,0x56,0xe1,0xd2,0xba,0x16,0x5b,0xa7,0x6e,0xaa,0xd3,0xdc,0x39,0xbf,0xfb,0x13,0x0f,0x1d,0xe3,0xd8,0xe6,0x42,0x7d,0xb5,0xb7,0x19,0x38,0xdb,0x4e,0x27,0x2b,0xc3,0xe2,0x0b,},17,"\x73\x68\x72\x4a\x5b\x0e\xfb\x57\xd2\x8d\x97\x62\x2d\xbd\xe7\x25\xaf"},
+ {{0x77,0xf8,0x86,0x91,0xc4,0xef,0xf2,0x3e,0xbb,0x73,0x64,0x94,0x70,0x92,0x95,0x1a,0x5f,0xf3,0xf1,0x07,0x85,0xb4,0x17,0xe9,0x18,0x82,0x3a,0x55,0x2d,0xab,0x7c,0x75,},{0x74,0xd2,0x91,0x27,0xf1,0x99,0xd8,0x6a,0x86,0x76,0xae,0xc3,0x3b,0x4c,0xe3,0xf2,0x25,0xcc,0xb1,0x91,0xf5,0x2c,0x19,0x1c,0xcd,0x1e,0x8c,0xca,0x65,0x21,0x3a,0x6b,},{0xfb,0xe9,0x29,0xd7,0x43,0xa0,0x3c,0x17,0x91,0x05,0x75,0x49,0x2f,0x30,0x92,0xee,0x2a,0x2b,0xf1,0x4a,0x60,0xa3,0xfc,0xac,0xec,0x74,0xa5,0x8c,0x73,0x34,0x51,0x0f,0xc2,0x62,0xdb,0x58,0x27,0x91,0x32,0x2d,0x6c,0x8c,0x41,0xf1,0x70,0x0a,0xdb,0x80,0x02,0x7e,0xca,0xbc,0x14,0x27,0x0b,0x70,0x34,0x44,0xae,0x3e,0xe7,0x62,0x3e,0x0a,},18,"\xbd\x8e\x05\x03\x3f\x3a\x8b\xcd\xcb\xf4\xbe\xce\xb7\x09\x01\xc8\x2e\x31"},
+ {{0xab,0x6f,0x7a,0xee,0x6a,0x08,0x37,0xb3,0x34,0xba,0x5e,0xb1,0xb2,0xad,0x7f,0xce,0xcf,0xab,0x7e,0x32,0x3c,0xab,0x18,0x7f,0xe2,0xe0,0xa9,0x5d,0x80,0xef,0xf1,0x32,},{0x5b,0x96,0xdc,0xa4,0x97,0x87,0x5b,0xf9,0x66,0x4c,0x5e,0x75,0xfa,0xcf,0x3f,0x9b,0xc5,0x4b,0xae,0x91,0x3d,0x66,0xca,0x15,0xee,0x85,0xf1,0x49,0x1c,0xa2,0x4d,0x2c,},{0x73,0xbc,0xa6,0x4e,0x9d,0xd0,0xdb,0x88,0x13,0x8e,0xed,0xfa,0xfc,0xea,0x8f,0x54,0x36,0xcf,0xb7,0x4b,0xfb,0x0e,0x77,0x33,0xcf,0x34,0x9b,0xaa,0x0c,0x49,0x77,0x5c,0x56,0xd5,0x93,0x4e,0x1d,0x38,0xe3,0x6f,0x39,0xb7,0xc5,0xbe,0xb0,0xa8,0x36,0x51,0x0c,0x45,0x12,0x6f,0x8e,0xc4,0xb6,0x81,0x05,0x19,0x90,0x5b,0x0c,0xa0,0x7c,0x09,},19,"\x81\x71\x45\x6f\x8b\x90\x71\x89\xb1\xd7\x79\xe2\x6b\xc5\xaf\xbb\x08\xc6\x7a"},
+ {{0x8d,0x13,0x5d,0xe7,0xc8,0x41,0x1b,0xbd,0xbd,0x1b,0x31,0xe5,0xdc,0x67,0x8f,0x2a,0xc7,0x10,0x9e,0x79,0x2b,0x60,0xf3,0x8c,0xd2,0x49,0x36,0xe8,0xa8,0x98,0xc3,0x2d,},{0x1c,0xa2,0x81,0x93,0x85,0x29,0x89,0x65,0x35,0xa7,0x71,0x4e,0x35,0x84,0x08,0x5b,0x86,0xef,0x9f,0xec,0x72,0x3f,0x42,0x81,0x9f,0xc8,0xdd,0x5d,0x8c,0x00,0x81,0x7f,},{0xa1,0xad,0xc2,0xbc,0x6a,0x2d,0x98,0x06,0x62,0x67,0x7e,0x7f,0xdf,0xf6,0x42,0x4d,0xe7,0xdb,0xa5,0x0f,0x57,0x95,0xca,0x90,0xfd,0xf3,0xe9,0x6e,0x25,0x6f,0x32,0x85,0xca,0xc7,0x1d,0x33,0x60,0x48,0x2e,0x99,0x3d,0x02,0x94,0xba,0x4e,0xc7,0x44,0x0c,0x61,0xaf,0xfd,0xf3,0x5f,0xe8,0x3e,0x6e,0x04,0x26,0x39,0x37,0xdb,0x93,0xf1,0x05,},20,"\x8b\xa6\xa4\xc9\xa1\x5a\x24\x4a\x9c\x26\xbb\x2a\x59\xb1\x02\x6f\x21\x34\x8b\x49"},
+ {{0x0e,0x76,0x5d,0x72,0x0e,0x70,0x5f,0x93,0x66,0xc1,0xab,0x8c,0x3f,0xa8,0x4c,0x9a,0x44,0x37,0x0c,0x06,0x96,0x9f,0x80,0x32,0x96,0x88,0x4b,0x28,0x46,0xa6,0x52,0xa4,},{0x7f,0xae,0x45,0xdd,0x0a,0x05,0x97,0x10,0x26,0xd4,0x10,0xbc,0x49,0x7a,0xf5,0xbe,0x7d,0x08,0x27,0xa8,0x2a,0x14,0x5c,0x20,0x3f,0x62,0x5d,0xfc,0xb8,0xb0,0x3b,0xa8,},{0xbb,0x61,0xcf,0x84,0xde,0x61,0x86,0x22,0x07,0xc6,0xa4,0x55,0x25,0x8b,0xc4,0xdb,0x4e,0x15,0xee,0xa0,0x31,0x7f,0xf8,0x87,0x18,0xb8,0x82,0xa0,0x6b,0x5c,0xf6,0xec,0x6f,0xd2,0x0c,0x5a,0x26,0x9e,0x5d,0x5c,0x80,0x5b,0xaf,0xbc,0xc5,0x79,0xe2,0x59,0x0a,0xf4,0x14,0xc7,0xc2,0x27,0x27,0x3c,0x10,0x2a,0x10,0x07,0x0c,0xdf,0xe8,0x0f,},21,"\x1d\x56\x6a\x62\x32\xbb\xaa\xb3\xe6\xd8\x80\x4b\xb5\x18\xa4\x98\xed\x0f\x90\x49\x86"},
+ {{0xdb,0x36,0xe3,0x26,0xd6,0x76,0xc2,0xd1,0x9c,0xc8,0xfe,0x0c,0x14,0xb7,0x09,0x20,0x2e,0xcf,0xc7,0x61,0xd2,0x70,0x89,0xeb,0x6e,0xa4,0xb1,0xbb,0x02,0x1e,0xcf,0xa7,},{0x48,0x35,0x9b,0x85,0x0d,0x23,0xf0,0x71,0x5d,0x94,0xbb,0x8b,0xb7,0x5e,0x7e,0x14,0x32,0x2e,0xaf,0x14,0xf0,0x6f,0x28,0xa8,0x05,0x40,0x3f,0xbd,0xa0,0x02,0xfc,0x85,},{0xb6,0xdc,0xd0,0x99,0x89,0xdf,0xba,0xc5,0x43,0x22,0xa3,0xce,0x87,0x87,0x6e,0x1d,0x62,0x13,0x4d,0xa9,0x98,0xc7,0x9d,0x24,0xb5,0x0b,0xd7,0xa6,0xa7,0x97,0xd8,0x6a,0x0e,0x14,0xdc,0x9d,0x74,0x91,0xd6,0xc1,0x4a,0x67,0x3c,0x65,0x2c,0xfb,0xec,0x9f,0x96,0x2a,0x38,0xc9,0x45,0xda,0x3b,0x2f,0x08,0x79,0xd0,0xb6,0x8a,0x92,0x13,0x00,},22,"\x1b\x0a\xfb\x0a\xc4\xba\x9a\xb7\xb7\x17\x2c\xdd\xc9\xeb\x42\xbb\xa1\xa6\x4b\xce\x47\xd4"},
+ {{0xc8,0x99,0x55,0xe0,0xf7,0x74,0x1d,0x90,0x5d,0xf0,0x73,0x0b,0x3d,0xc2,0xb0,0xce,0x1a,0x13,0x13,0x4e,0x44,0xfe,0xf3,0xd4,0x0d,0x60,0xc0,0x20,0xef,0x19,0xdf,0x77,},{0xfd,0xb3,0x06,0x73,0x40,0x2f,0xaf,0x1c,0x80,0x33,0x71,0x4f,0x35,0x17,0xe4,0x7c,0xc0,0xf9,0x1f,0xe7,0x0c,0xf3,0x83,0x6d,0x6c,0x23,0x63,0x6e,0x3f,0xd2,0x28,0x7c,},{0x7e,0xf6,0x6e,0x5e,0x86,0xf2,0x36,0x08,0x48,0xe0,0x01,0x4e,0x94,0x88,0x0a,0xe2,0x92,0x0a,0xd8,0xa3,0x18,0x5a,0x46,0xb3,0x5d,0x1e,0x07,0xde,0xa8,0xfa,0x8a,0xe4,0xf6,0xb8,0x43,0xba,0x17,0x4d,0x99,0xfa,0x79,0x86,0x65,0x4a,0x08,0x91,0xc1,0x2a,0x79,0x44,0x55,0x66,0x93,0x75,0xbf,0x92,0xaf,0x4c,0xc2,0x77,0x0b,0x57,0x9e,0x0c,},23,"\x50\x7c\x94\xc8\x82\x0d\x2a\x57\x93\xcb\xf3\x44\x2b\x3d\x71\x93\x6f\x35\xfe\x3a\xfe\xf3\x16"},
+ {{0x4e,0x62,0x62,0x7f,0xc2,0x21,0x14,0x24,0x78,0xae,0xe7,0xf0,0x07,0x81,0xf8,0x17,0xf6,0x62,0xe3,0xb7,0x5d,0xb2,0x9b,0xb1,0x4a,0xb4,0x7c,0xf8,0xe8,0x41,0x04,0xd6,},{0xb1,0xd3,0x98,0x01,0x89,0x20,0x27,0xd5,0x8a,0x8c,0x64,0x33,0x51,0x63,0x19,0x58,0x93,0xbf,0xc1,0xb6,0x1d,0xbe,0xca,0x32,0x60,0x49,0x7e,0x1f,0x30,0x37,0x11,0x07,},{0x83,0x6a,0xfa,0x76,0x4d,0x9c,0x48,0xaa,0x47,0x70,0xa4,0x38,0x8b,0x65,0x4e,0x97,0xb3,0xc1,0x6f,0x08,0x29,0x67,0xfe,0xbc,0xa2,0x7f,0x2f,0xc4,0x7d,0xdf,0xd9,0x24,0x4b,0x03,0xcf,0xc7,0x29,0x69,0x8a,0xcf,0x51,0x09,0x70,0x43,0x46,0xb6,0x0b,0x23,0x0f,0x25,0x54,0x30,0x08,0x9d,0xdc,0x56,0x91,0x23,0x99,0xd1,0x12,0x2d,0xe7,0x0a,},24,"\xd3\xd6\x15\xa8\x47\x2d\x99\x62\xbb\x70\xc5\xb5\x46\x6a\x3d\x98\x3a\x48\x11\x04\x6e\x2a\x0e\xf5"},
+ {{0x6b,0x83,0xd7,0xda,0x89,0x08,0xc3,0xe7,0x20,0x5b,0x39,0x86,0x4b,0x56,0xe5,0xf3,0xe1,0x71,0x96,0xa3,0xfc,0x9c,0x2f,0x58,0x05,0xaa,0xd0,0xf5,0x55,0x4c,0x14,0x2d,},{0xd0,0xc8,0x46,0xf9,0x7f,0xe2,0x85,0x85,0xc0,0xee,0x15,0x90,0x15,0xd6,0x4c,0x56,0x31,0x1c,0x88,0x6e,0xdd,0xcc,0x18,0x5d,0x29,0x6d,0xbb,0x16,0x5d,0x26,0x25,0xd6,},{0x16,0xe4,0x62,0xa2,0x9a,0x6d,0xd4,0x98,0x68,0x5a,0x37,0x18,0xb3,0xee,0xd0,0x0c,0xc1,0x59,0x86,0x01,0xee,0x47,0x82,0x04,0x86,0x03,0x2d,0x6b,0x9a,0xcc,0x9b,0xf8,0x9f,0x57,0x68,0x4e,0x08,0xd8,0xc0,0xf0,0x55,0x89,0xcd,0xa2,0x88,0x2a,0x05,0xdc,0x4c,0x63,0xf9,0xd0,0x43,0x1d,0x65,0x52,0x71,0x08,0x12,0x43,0x30,0x03,0xbc,0x08,},25,"\x6a\xda\x80\xb6\xfa\x84\xf7\x03\x49\x20\x78\x9e\x85\x36\xb8\x2d\x5e\x46\x78\x05\x9a\xed\x27\xf7\x1c"},
+ {{0x19,0xa9,0x1f,0xe2,0x3a,0x4e,0x9e,0x33,0xec,0xc4,0x74,0x87,0x8f,0x57,0xc6,0x4c,0xf1,0x54,0xb3,0x94,0x20,0x34,0x87,0xa7,0x03,0x5e,0x1a,0xd9,0xcd,0x69,0x7b,0x0d,},{0x2b,0xf3,0x2b,0xa1,0x42,0xba,0x46,0x22,0xd8,0xf3,0xe2,0x9e,0xcd,0x85,0xee,0xa0,0x7b,0x9c,0x47,0xbe,0x9d,0x64,0x41,0x2c,0x9b,0x51,0x0b,0x27,0xdd,0x21,0x8b,0x23,},{0x88,0x1f,0x5b,0x8c,0x5a,0x03,0x0d,0xf0,0xf7,0x5b,0x66,0x34,0xb0,0x70,0xdd,0x27,0xbd,0x1e,0xe3,0xc0,0x87,0x38,0xae,0x34,0x93,0x38,0xb3,0xee,0x64,0x69,0xbb,0xf9,0x76,0x0b,0x13,0x57,0x8a,0x23,0x7d,0x51,0x82,0x53,0x5e,0xde,0x12,0x12,0x83,0x02,0x7a,0x90,0xb5,0xf8,0x65,0xd6,0x3a,0x65,0x37,0xdc,0xa0,0x7b,0x44,0x04,0x9a,0x0f,},26,"\x82\xcb\x53\xc4\xd5\xa0\x13\xba\xe5\x07\x07\x59\xec\x06\xc3\xc6\x95\x5a\xb7\xa4\x05\x09\x58\xec\x32\x8c"},
+ {{0x1d,0x5b,0x8c,0xb6,0x21,0x5c,0x18,0x14,0x16,0x66,0xba,0xee,0xfc,0xf5,0xd6,0x9d,0xad,0x5b,0xea,0x9a,0x34,0x93,0xdd,0xda,0xa3,0x57,0xa4,0x39,0x7a,0x13,0xd4,0xde,},{0x94,0xd2,0x3d,0x97,0x7c,0x33,0xe4,0x9e,0x5e,0x49,0x92,0xc6,0x8f,0x25,0xec,0x99,0xa2,0x7c,0x41,0xce,0x6b,0x91,0xf2,0xbf,0xa0,0xcd,0x82,0x92,0xfe,0x96,0x28,0x35,},{0x3a,0xcd,0x39,0xbe,0xc8,0xc3,0xcd,0x2b,0x44,0x29,0x97,0x22,0xb5,0x85,0x0a,0x04,0x00,0xc1,0x44,0x35,0x90,0xfd,0x48,0x61,0xd5,0x9a,0xae,0x74,0x96,0xac,0xb3,0xdf,0x73,0xfc,0x3f,0xdf,0x79,0x69,0xae,0x5f,0x50,0xba,0x47,0xdd,0xdc,0x43,0x52,0x46,0xe5,0xfd,0x37,0x6f,0x6b,0x89,0x1c,0xd4,0xc2,0xca,0xf5,0xd6,0x14,0xb6,0x17,0x0c,},27,"\xa9\xa8\xcb\xb0\xad\x58\x51\x24\xe5\x22\xab\xbf\xb4\x05\x33\xbd\xd6\xf4\x93\x47\xb5\x5b\x18\xe8\x55\x8c\xb0"},
+ {{0x6a,0x91,0xb3,0x22,0x7c,0x47,0x22,0x99,0x08,0x9b,0xdc,0xe9,0x35,0x6e,0x72,0x6a,0x40,0xef,0xd8,0x40,0xf1,0x10,0x02,0x70,0x8b,0x7e,0xe5,0x5b,0x64,0x10,0x5a,0xc2,},{0x9d,0x08,0x4a,0xa8,0xb9,0x7a,0x6b,0x9b,0xaf,0xa4,0x96,0xdb,0xc6,0xf7,0x6f,0x33,0x06,0xa1,0x16,0xc9,0xd9,0x17,0xe6,0x81,0x52,0x0a,0x0f,0x91,0x43,0x69,0x42,0x7e,},{0xf5,0x87,0x54,0x23,0x78,0x1b,0x66,0x21,0x6c,0xb5,0xe8,0x99,0x8d,0xe5,0xd9,0xff,0xc2,0x9d,0x1d,0x67,0x10,0x70,0x54,0xac,0xe3,0x37,0x45,0x03,0xa9,0xc3,0xef,0x81,0x15,0x77,0xf2,0x69,0xde,0x81,0x29,0x67,0x44,0xbd,0x70,0x6f,0x1a,0xc4,0x78,0xca,0xf0,0x9b,0x54,0xcd,0xf8,0x71,0xb3,0xf8,0x02,0xbd,0x57,0xf9,0xa6,0xcb,0x91,0x01,},28,"\x5c\xb6\xf9\xaa\x59\xb8\x0e\xca\x14\xf6\xa6\x8f\xb4\x0c\xf0\x7b\x79\x4e\x75\x17\x1f\xba\x96\x26\x2c\x1c\x6a\xdc"},
+ {{0x93,0xea,0xa8,0x54,0xd7,0x91,0xf0,0x53,0x72,0xce,0x72,0xb9,0x4f,0xc6,0x50,0x3b,0x2f,0xf8,0xae,0x68,0x19,0xe6,0xa2,0x1a,0xfe,0x82,0x5e,0x27,0xad,0xa9,0xe4,0xfb,},{0x16,0xce,0xe8,0xa3,0xf2,0x63,0x18,0x34,0xc8,0x8b,0x67,0x08,0x97,0xff,0x0b,0x08,0xce,0x90,0xcc,0x14,0x7b,0x45,0x93,0xb3,0xf1,0xf4,0x03,0x72,0x7f,0x7e,0x7a,0xd5,},{0xd8,0x34,0x19,0x7c,0x1a,0x30,0x80,0x61,0x4e,0x0a,0x5f,0xa0,0xaa,0xaa,0x80,0x88,0x24,0xf2,0x1c,0x38,0xd6,0x92,0xe6,0xff,0xbd,0x20,0x0f,0x7d,0xfb,0x3c,0x8f,0x44,0x40,0x2a,0x73,0x82,0x18,0x0b,0x98,0xad,0x0a,0xfc,0x8e,0xec,0x1a,0x02,0xac,0xec,0xf3,0xcb,0x7f,0xde,0x62,0x7b,0x9f,0x18,0x11,0x1f,0x26,0x0a,0xb1,0xdb,0x9a,0x07,},29,"\x32\xfe\x27\x99\x41\x24\x20\x21\x53\xb5\xc7\x0d\x38\x13\xfd\xee\x9c\x2a\xa6\xe7\xdc\x74\x3d\x4d\x53\x5f\x18\x40\xa5"},
+ {{0x94,0x1c,0xac,0x69,0xfb,0x7b,0x18,0x15,0xc5,0x7b,0xb9,0x87,0xc4,0xd6,0xc2,0xad,0x2c,0x35,0xd5,0xf9,0xa3,0x18,0x2a,0x79,0xd4,0xba,0x13,0xea,0xb2,0x53,0xa8,0xad,},{0x23,0xbe,0x32,0x3c,0x56,0x2d,0xfd,0x71,0xce,0x65,0xf5,0xbb,0xa5,0x6a,0x74,0xa3,0xa6,0xdf,0xc3,0x6b,0x57,0x3d,0x2f,0x94,0xf6,0x35,0xc7,0xf9,0xb4,0xfd,0x5a,0x5b,},{0x0f,0x8f,0xad,0x1e,0x6b,0xde,0x77,0x1b,0x4f,0x54,0x20,0xea,0xc7,0x5c,0x37,0x8b,0xae,0x6d,0xb5,0xac,0x66,0x50,0xcd,0x2b,0xc2,0x10,0xc1,0x82,0x3b,0x43,0x2b,0x48,0xe0,0x16,0xb1,0x05,0x95,0x45,0x8f,0xfa,0xb9,0x2f,0x7a,0x89,0x89,0xb2,0x93,0xce,0xb8,0xdf,0xed,0x6c,0x24,0x3a,0x20,0x38,0xfc,0x06,0x65,0x2a,0xaa,0xf1,0x6f,0x02,},30,"\xbb\x31\x72\x79\x57\x10\xfe\x00\x05\x4d\x3b\x5d\xfe\xf8\xa1\x16\x23\x58\x2d\xa6\x8b\xf8\xe4\x6d\x72\xd2\x7c\xec\xe2\xaa"},
+ {{0x1a,0xcd,0xbb,0x79,0x3b,0x03,0x84,0x93,0x46,0x27,0x47,0x0d,0x79,0x5c,0x3d,0x1d,0xd4,0xd7,0x9c,0xea,0x59,0xef,0x98,0x3f,0x29,0x5b,0x9b,0x59,0x17,0x9c,0xbb,0x28,},{0x3f,0x60,0xc7,0x54,0x1a,0xfa,0x76,0xc0,0x19,0xcf,0x5a,0xa8,0x2d,0xcd,0xb0,0x88,0xed,0x9e,0x4e,0xd9,0x78,0x05,0x14,0xae,0xfb,0x37,0x9d,0xab,0xc8,0x44,0xf3,0x1a,},{0xbe,0x71,0xef,0x48,0x06,0xcb,0x04,0x1d,0x88,0x5e,0xff,0xd9,0xe6,0xb0,0xfb,0xb7,0x3d,0x65,0xd7,0xcd,0xec,0x47,0xa8,0x9c,0x8a,0x99,0x48,0x92,0xf4,0xe5,0x5a,0x56,0x8c,0x4c,0xc7,0x8d,0x61,0xf9,0x01,0xe8,0x0d,0xbb,0x62,0x8b,0x86,0xa2,0x3c,0xcd,0x59,0x4e,0x71,0x2b,0x57,0xfa,0x94,0xc2,0xd6,0x7e,0xc2,0x66,0x34,0x87,0x85,0x07,},31,"\x7c\xf3\x4f\x75\xc3\xda\xc9\xa8\x04\xd0\xfc\xd0\x9e\xba\x9b\x29\xc9\x48\x4e\x8a\x01\x8f\xa9\xe0\x73\x04\x2d\xf8\x8e\x3c\x56"},
+ {{0x8e,0xd7,0xa7,0x97,0xb9,0xce,0xa8,0xa8,0x37,0x0d,0x41,0x91,0x36,0xbc,0xdf,0x68,0x3b,0x75,0x9d,0x2e,0x3c,0x69,0x47,0xf1,0x7e,0x13,0xe2,0x48,0x5a,0xa9,0xd4,0x20,},{0xb4,0x9f,0x3a,0x78,0xb1,0xc6,0xa7,0xfc,0xa8,0xf3,0x46,0x6f,0x33,0xbc,0x0e,0x92,0x9f,0x01,0xfb,0xa0,0x43,0x06,0xc2,0xa7,0x46,0x5f,0x46,0xc3,0x75,0x93,0x16,0xd9,},{0x04,0x26,0x6c,0x03,0x3b,0x91,0xc1,0x32,0x2c,0xeb,0x34,0x46,0xc9,0x01,0xff,0xcf,0x3c,0xc4,0x0c,0x40,0x34,0xe8,0x87,0xc9,0x59,0x7c,0xa1,0x89,0x3b,0xa7,0x33,0x0b,0xec,0xbb,0xd8,0xb4,0x81,0x42,0xef,0x35,0xc0,0x12,0xc6,0xba,0x51,0xa6,0x6d,0xf9,0x30,0x8c,0xb6,0x26,0x8a,0xd6,0xb1,0xe4,0xb0,0x3e,0x70,0x10,0x24,0x95,0x79,0x0b,},32,"\xa7\x50\xc2\x32\x93\x3d\xc1\x4b\x11\x84\xd8\x6d\x8b\x4c\xe7\x2e\x16\xd6\x97\x44\xba\x69\x81\x8b\x6a\xc3\x3b\x1d\x82\x3b\xb2\xc3"},
+ {{0xf2,0xab,0x39,0x6f,0xe8,0x90,0x6e,0x3e,0x56,0x33,0xe9,0x9c,0xab,0xcd,0x5b,0x09,0xdf,0x08,0x59,0xb5,0x16,0x23,0x0b,0x1e,0x04,0x50,0xb5,0x80,0xb6,0x5f,0x61,0x6c,},{0x8e,0xa0,0x74,0x24,0x51,0x59,0xa1,0x16,0xaa,0x71,0x22,0xa2,0x5e,0xc1,0x6b,0x89,0x1d,0x62,0x5a,0x68,0xf3,0x36,0x60,0x42,0x39,0x08,0xf6,0xbd,0xc4,0x4f,0x8c,0x1b,},{0xa0,0x6a,0x23,0xd9,0x82,0xd8,0x1a,0xb8,0x83,0xaa,0xe2,0x30,0xad,0xbc,0x36,0x8a,0x6a,0x99,0x77,0xf0,0x03,0xce,0xbb,0x00,0xd4,0xc2,0xe4,0x01,0x84,0x90,0x19,0x1a,0x84,0xd3,0xa2,0x82,0xfd,0xbf,0xb2,0xfc,0x88,0x04,0x6e,0x62,0xde,0x43,0xe1,0x5f,0xb5,0x75,0x33,0x6b,0x3c,0x8b,0x77,0xd1,0x9c,0xe6,0xa0,0x09,0xce,0x51,0xf5,0x0c,},33,"\x5a\x44\xe3\x4b\x74\x6c\x5f\xd1\x89\x8d\x55\x2a\xb3\x54\xd2\x8f\xb4\x71\x38\x56\xd7\x69\x7d\xd6\x3e\xb9\xbd\x6b\x99\xc2\x80\xe1\x87"},
+ {{0x55,0x0a,0x41,0xc0,0x13,0xf7,0x9b,0xab,0x8f,0x06,0xe4,0x3a,0xd1,0x83,0x6d,0x51,0x31,0x27,0x36,0xa9,0x71,0x38,0x06,0xfa,0xfe,0x66,0x45,0x21,0x9e,0xaa,0x1f,0x9d,},{0xaf,0x6b,0x71,0x45,0x47,0x4d,0xc9,0x95,0x4b,0x9a,0xf9,0x3a,0x9c,0xdb,0x34,0x44,0x9d,0x5b,0x7c,0x65,0x1c,0x82,0x4d,0x24,0xe2,0x30,0xb9,0x00,0x33,0xce,0x59,0xc0,},{0x16,0xdc,0x1e,0x2b,0x9f,0xa9,0x09,0xee,0xfd,0xc2,0x77,0xba,0x16,0xeb,0xe2,0x07,0xb8,0xda,0x5e,0x91,0x14,0x3c,0xde,0x78,0xc5,0x04,0x7a,0x89,0xf6,0x81,0xc3,0x3c,0x4e,0x4e,0x34,0x28,0xd5,0xc9,0x28,0x09,0x59,0x03,0xa8,0x11,0xec,0x00,0x2d,0x52,0xa3,0x9e,0xd7,0xf8,0xb3,0xfe,0x19,0x27,0x20,0x0c,0x6d,0xd0,0xb9,0xab,0x3e,0x04,},34,"\x8b\xc4\x18\x5e\x50\xe5\x7d\x5f\x87\xf4\x75\x15\xfe\x2b\x18\x37\xd5\x85\xf0\xaa\xe9\xe1\xca\x38\x3b\x3e\xc9\x08\x88\x4b\xb9\x00\xff\x27"},
+ {{0x19,0xac,0x3e,0x27,0x24,0x38,0xc7,0x2d,0xdf,0x7b,0x88,0x19,0x64,0x86,0x7c,0xb3,0xb3,0x1f,0xf4,0xc7,0x93,0xbb,0x7e,0xa1,0x54,0x61,0x3c,0x1d,0xb0,0x68,0xcb,0x7e,},{0xf8,0x5b,0x80,0xe0,0x50,0xa1,0xb9,0x62,0x0d,0xb1,0x38,0xbf,0xc9,0xe1,0x00,0x32,0x7e,0x25,0xc2,0x57,0xc5,0x92,0x17,0xb6,0x01,0xf1,0xf6,0xac,0x9a,0x41,0x3d,0x3f,},{0xea,0x85,0x5d,0x78,0x1c,0xbe,0xa4,0x68,0x2e,0x35,0x01,0x73,0xcb,0x89,0xe8,0x61,0x9c,0xcf,0xdd,0xb9,0x7c,0xdc,0xe1,0x6f,0x9a,0x2f,0x6f,0x68,0x92,0xf4,0x6d,0xbe,0x68,0xe0,0x4b,0x12,0xb8,0xd8,0x86,0x89,0xa7,0xa3,0x16,0x70,0xcd,0xff,0x40,0x9a,0xf9,0x8a,0x93,0xb4,0x9a,0x34,0x53,0x7b,0x6a,0xa0,0x09,0xd2,0xeb,0x8b,0x47,0x01,},35,"\x95\x87\x2d\x5f\x78\x9f\x95\x48\x4e\x30\xcb\xb0\xe1\x14\x02\x89\x53\xb1\x6f\x5c\x6a\x8d\x9f\x65\xc0\x03\xa8\x35\x43\xbe\xaa\x46\xb3\x86\x45"},
+ {{0xca,0x26,0x7d,0xe9,0x6c,0x93,0xc2,0x38,0xfa,0xfb,0x12,0x79,0x81,0x20,0x59,0xab,0x93,0xac,0x03,0x05,0x96,0x57,0xfd,0x99,0x4f,0x8f,0xa5,0xa0,0x92,0x39,0xc8,0x21,},{0x01,0x73,0x70,0xc8,0x79,0x09,0x0a,0x81,0xc7,0xf2,0x72,0xc2,0xfc,0x80,0xe3,0xaa,0xc2,0xbc,0x60,0x3f,0xcb,0x37,0x9a,0xfc,0x98,0x69,0x11,0x60,0xab,0x74,0x5b,0x26,},{0xac,0x95,0x7f,0x82,0x33,0x5a,0xa7,0x14,0x1e,0x96,0xb5,0x9d,0x63,0xe3,0xcc,0xee,0x95,0xc3,0xa2,0xc4,0x7d,0x02,0x65,0x40,0xc2,0xaf,0x42,0xdc,0x95,0x33,0xd5,0xfd,0x81,0x82,0x7d,0x16,0x79,0xad,0x18,0x7a,0xea,0xf3,0x78,0x34,0x91,0x5e,0x75,0xb1,0x47,0xa9,0x28,0x68,0x06,0xc8,0x01,0x75,0x16,0xba,0x43,0xdd,0x05,0x1a,0x5e,0x0c,},36,"\xe0\x5f\x71\xe4\xe4\x9a\x72\xec\x55\x0c\x44\xa3\xb8\x5a\xca\x8f\x20\xff\x26\xc3\xee\x94\xa8\x0f\x1b\x43\x1c\x7d\x15\x4e\xc9\x60\x3e\xe0\x25\x31"},
+ {{0x3d,0xff,0x5e,0x89,0x94,0x75,0xe7,0xe9,0x1d,0xd2,0x61,0x32,0x2f,0xab,0x09,0x98,0x0c,0x52,0x97,0x0d,0xe1,0xda,0x6e,0x2e,0x20,0x16,0x60,0xcc,0x4f,0xce,0x70,0x32,},{0xf3,0x01,0x62,0xba,0xc9,0x84,0x47,0xc4,0x04,0x2f,0xac,0x05,0xda,0x44,0x80,0x34,0x62,0x9b,0xe2,0xc6,0xa5,0x8d,0x30,0xdf,0xd5,0x78,0xba,0x9f,0xb5,0xe3,0x93,0x0b,},{0x5e,0xfe,0x7a,0x92,0xff,0x96,0x23,0x08,0x9b,0x3e,0x3b,0x78,0xf3,0x52,0x11,0x53,0x66,0xe2,0x6b,0xa3,0xfb,0x1a,0x41,0x62,0x09,0xbc,0x02,0x9e,0x9c,0xad,0xcc,0xd9,0xf4,0xaf,0xfa,0x33,0x35,0x55,0xa8,0xf3,0xa3,0x5a,0x9d,0x0f,0x7c,0x34,0xb2,0x92,0xca,0xe7,0x7e,0xc9,0x6f,0xa3,0xad,0xfc,0xaa,0xde,0xe2,0xd9,0xce,0xd8,0xf8,0x05,},37,"\x93\x8f\x0e\x77\x62\x1b\xf3\xea\x52\xc7\xc4\x91\x1c\x51\x57\xc2\xd8\xa2\xa8\x58\x09\x3e\xf1\x6a\xa9\xb1\x07\xe6\x9d\x98\x03\x7b\xa1\x39\xa3\xc3\x82"},
+ {{0x9a,0x6b,0x84,0x78,0x64,0xe7,0x0c,0xfe,0x8b,0xa6,0xab,0x22,0xfa,0x0c,0xa3,0x08,0xc0,0xcc,0x8b,0xec,0x71,0x41,0xfb,0xca,0xa3,0xb8,0x1f,0x5d,0x1e,0x1c,0xfc,0xfc,},{0x34,0xad,0x0f,0xbd,0xb2,0x56,0x65,0x07,0xa8,0x1c,0x2b,0x1f,0x8a,0xa8,0xf5,0x3d,0xcc,0xaa,0x64,0xcc,0x87,0xad,0xa9,0x1b,0x90,0x3e,0x90,0x0d,0x07,0xee,0xe9,0x30,},{0x2a,0xb2,0x55,0x16,0x9c,0x48,0x9c,0x54,0xc7,0x32,0x23,0x2e,0x37,0xc8,0x73,0x49,0xd4,0x86,0xb1,0xeb,0xa2,0x05,0x09,0xdb,0xab,0xe7,0xfe,0xd3,0x29,0xef,0x08,0xfd,0x75,0xba,0x1c,0xd1,0x45,0xe6,0x7b,0x2e,0xa2,0x6c,0xb5,0xcc,0x51,0xca,0xb3,0x43,0xee,0xb0,0x85,0xfe,0x1f,0xd7,0xb0,0xec,0x4c,0x6a,0xfc,0xd9,0xb9,0x79,0xf9,0x05,},38,"\x83\x83\x67\x47\x11\x83\xc7\x1f\x7e\x71\x77\x24\xf8\x9d\x40\x1c\x3a\xd9\x86\x3f\xd9\xcc\x7a\xa3\xcf\x33\xd3\xc5\x29\x86\x0c\xb5\x81\xf3\x09\x3d\x87\xda"},
+ {{0x57,0x5b,0xe0,0x7a,0xfc,0xa5,0xd0,0x63,0xc2,0x38,0xcd,0x9b,0x80,0x28,0x77,0x2c,0xc4,0x9c,0xda,0x34,0x47,0x14,0x32,0xa2,0xe1,0x66,0xe0,0x96,0xe2,0x21,0x9e,0xfc,},{0x94,0xe5,0xeb,0x4d,0x50,0x24,0xf4,0x9d,0x7e,0xbf,0x79,0x81,0x7c,0x8d,0xe1,0x14,0x97,0xdc,0x2b,0x55,0x62,0x2a,0x51,0xae,0x12,0x3f,0xfc,0x74,0x9d,0xbb,0x16,0xe0,},{0x58,0x27,0x1d,0x44,0x23,0x6f,0x3b,0x98,0xc5,0x8f,0xd7,0xae,0x0d,0x2f,0x49,0xef,0x2b,0x6e,0x3a,0xff,0xdb,0x22,0x5a,0xa3,0xba,0x55,0x5f,0x0e,0x11,0xcc,0x53,0xc2,0x3a,0xd1,0x9b,0xaf,0x24,0x34,0x65,0x90,0xd0,0x5d,0x7d,0x53,0x90,0x58,0x20,0x82,0xcf,0x94,0xd3,0x9c,0xad,0x65,0x30,0xab,0x93,0xd1,0x3e,0xfb,0x39,0x27,0x95,0x06,},39,"\x33\xe5\x91\x8b\x66\xd3\x3d\x55\xfe\x71\x7c\xa3\x43\x83\xea\xe7\x8f\x0a\xf8\x28\x89\xca\xf6\x69\x6e\x1a\xc9\xd9\x5d\x1f\xfb\x32\xcb\xa7\x55\xf9\xe3\x50\x3e"},
+ {{0x15,0xff,0xb4,0x55,0x14,0xd4,0x34,0x44,0xd6,0x1f,0xcb,0x10,0x5e,0x30,0xe1,0x35,0xfd,0x26,0x85,0x23,0xdd,0xa2,0x0b,0x82,0x75,0x8b,0x17,0x94,0x23,0x11,0x04,0x41,},{0x17,0x72,0xc5,0xab,0xc2,0xd2,0x3f,0xd2,0xf9,0xd1,0xc3,0x25,0x7b,0xe7,0xbc,0x3c,0x1c,0xd7,0x9c,0xee,0x40,0x84,0x4b,0x74,0x9b,0x3a,0x77,0x43,0xd2,0xf9,0x64,0xb8,},{0x68,0x28,0xcd,0x76,0x24,0xe7,0x93,0xb8,0xa4,0xce,0xb9,0x6d,0x3c,0x2a,0x97,0x5b,0xf7,0x73,0xe5,0xff,0x66,0x45,0xf3,0x53,0x61,0x40,0x58,0x62,0x1e,0x58,0x83,0x52,0x89,0xe7,0xf3,0x1f,0x42,0xdf,0xe6,0xaf,0x6d,0x73,0x6f,0x26,0x44,0x51,0x1e,0x32,0x0c,0x0f,0xa6,0x98,0x58,0x2a,0x79,0x77,0x8d,0x18,0x73,0x0e,0xd3,0xe8,0xcb,0x08,},40,"\xda\x9c\x55\x59\xd0\xea\x51\xd2\x55\xb6\xbd\x9d\x76\x38\xb8\x76\x47\x2f\x94\x2b\x33\x0f\xc0\xe2\xb3\x0a\xea\x68\xd7\x73\x68\xfc\xe4\x94\x82\x72\x99\x1d\x25\x7e"},
+ {{0xfe,0x05,0x68,0x64,0x29,0x43,0xb2,0xe1,0xaf,0xbf,0xd1,0xf1,0x0f,0xe8,0xdf,0x87,0xa4,0x23,0x6b,0xea,0x40,0xdc,0xe7,0x42,0x07,0x2c,0xb2,0x18,0x86,0xee,0xc1,0xfa,},{0x29,0x9e,0xbd,0x1f,0x13,0x17,0x7d,0xbd,0xb6,0x6a,0x91,0x2b,0xbf,0x71,0x20,0x38,0xfd,0xf7,0x3b,0x06,0xc3,0xac,0x02,0x0c,0x7b,0x19,0x12,0x67,0x55,0xd4,0x7f,0x61,},{0xd5,0x9e,0x6d,0xfc,0xc6,0xd7,0xe3,0xe2,0xc5,0x8d,0xec,0x81,0xe9,0x85,0xd2,0x45,0xe6,0x81,0xac,0xf6,0x59,0x4a,0x23,0xc5,0x92,0x14,0xf7,0xbe,0xd8,0x01,0x5d,0x81,0x3c,0x76,0x82,0xb6,0x0b,0x35,0x83,0x44,0x03,0x11,0xe7,0x2a,0x86,0x65,0xba,0x2c,0x96,0xde,0xc2,0x3c,0xe8,0x26,0xe1,0x60,0x12,0x7e,0x18,0x13,0x2b,0x03,0x04,0x04,},41,"\xc5\x9d\x08\x62\xec\x1c\x97\x46\xab\xcc\x3c\xf8\x3c\x9e\xeb\xa2\xc7\x08\x2a\x03\x6a\x8c\xb5\x7c\xe4\x87\xe7\x63\x49\x27\x96\xd4\x7e\x6e\x06\x3a\x0c\x1f\xec\xcc\x2d"},
+ {{0x5e,0xcb,0x16,0xc2,0xdf,0x27,0xc8,0xcf,0x58,0xe4,0x36,0xa9,0xd3,0xaf,0xfb,0xd5,0x8e,0x95,0x38,0xa9,0x26,0x59,0xa0,0xf9,0x7c,0x4c,0x4f,0x99,0x46,0x35,0xa8,0xca,},{0xda,0x76,0x8b,0x20,0xc4,0x37,0xdd,0x3a,0xa5,0xf8,0x4b,0xb6,0xa0,0x77,0xff,0xa3,0x4a,0xb6,0x85,0x01,0xc5,0x35,0x2b,0x5c,0xc3,0xfd,0xce,0x7f,0xe6,0xc2,0x39,0x8d,},{0x1c,0x72,0x3a,0x20,0xc6,0x77,0x24,0x26,0xa6,0x70,0xe4,0xd5,0xc4,0xa9,0x7c,0x6e,0xbe,0x91,0x47,0xf7,0x1b,0xb0,0xa4,0x15,0x63,0x1e,0x44,0x40,0x6e,0x29,0x03,0x22,0xe4,0xca,0x97,0x7d,0x34,0x8f,0xe7,0x85,0x6a,0x8e,0xdc,0x23,0x5d,0x0f,0xe9,0x5f,0x7e,0xd9,0x1a,0xef,0xdd,0xf2,0x8a,0x77,0xe2,0xc7,0xdb,0xfd,0x8f,0x55,0x2f,0x0a,},42,"\x56\xf1\x32\x9d\x9a\x6b\xe2\x5a\x61\x59\xc7\x2f\x12\x68\x8d\xc8\x31\x4e\x85\xdd\x9e\x7e\x4d\xc0\x5b\xbe\xcb\x77\x29\xe0\x23\xc8\x6f\x8e\x09\x37\x35\x3f\x27\xc7\xed\xe9"},
+ {{0xd5,0x99,0xd6,0x37,0xb3,0xc3,0x0a,0x82,0xa9,0x98,0x4e,0x2f,0x75,0x84,0x97,0xd1,0x44,0xde,0x6f,0x06,0xb9,0xfb,0xa0,0x4d,0xd4,0x0f,0xd9,0x49,0x03,0x9d,0x7c,0x84,},{0x67,0x91,0xd8,0xce,0x50,0xa4,0x46,0x89,0xfc,0x17,0x87,0x27,0xc5,0xc3,0xa1,0xc9,0x59,0xfb,0xee,0xd7,0x4e,0xf7,0xd8,0xe7,0xbd,0x3c,0x1a,0xb4,0xda,0x31,0xc5,0x1f,},{0xeb,0xf1,0x0d,0x9a,0xc7,0xc9,0x61,0x08,0x14,0x0e,0x7d,0xef,0x6f,0xe9,0x53,0x3d,0x72,0x76,0x46,0xff,0x5b,0x3a,0xf2,0x73,0xc1,0xdf,0x95,0x76,0x2a,0x66,0xf3,0x2b,0x65,0xa0,0x96,0x34,0xd0,0x13,0xf5,0x4b,0x5d,0xd6,0x01,0x1f,0x91,0xbc,0x33,0x6c,0xa8,0xb3,0x55,0xce,0x33,0xf8,0xcf,0xbe,0xc2,0x53,0x5a,0x4c,0x42,0x7f,0x82,0x05,},43,"\xa7\xc0\x4e\x8b\xa7\x5d\x0a\x03\xd8\xb1\x66\xad\x7a\x1d\x77\xe1\xb9\x1c\x7a\xaf\x7b\xef\xdd\x99\x31\x1f\xc3\xc5\x4a\x68\x4d\xdd\x97\x1d\x5b\x32\x11\xc3\xee\xaf\xf1\xe5\x4e"},
+ {{0x30,0xab,0x82,0x32,0xfa,0x70,0x18,0xf0,0xce,0x6c,0x39,0xbd,0x8f,0x78,0x2f,0xe2,0xe1,0x59,0x75,0x8b,0xb0,0xf2,0xf4,0x38,0x6c,0x7f,0x28,0xcf,0xd2,0xc8,0x58,0x98,},{0xec,0xfb,0x6a,0x2b,0xd4,0x2f,0x31,0xb6,0x12,0x50,0xba,0x5d,0xe7,0xe4,0x6b,0x47,0x19,0xaf,0xdf,0xbc,0x66,0x0d,0xb7,0x1a,0x7b,0xd1,0xdf,0x7b,0x0a,0x3a,0xbe,0x37,},{0x9a,0xf8,0x85,0x34,0x4c,0xc7,0x23,0x94,0x98,0xf7,0x12,0xdf,0x80,0xbc,0x01,0xb8,0x06,0x38,0x29,0x1e,0xd4,0xa1,0xd2,0x8b,0xaa,0x55,0x45,0x01,0x7a,0x72,0xe2,0xf6,0x56,0x49,0xcc,0xf9,0x60,0x3d,0xa6,0xeb,0x5b,0xfa,0xb9,0xf5,0x54,0x3a,0x6c,0xa4,0xa7,0xaf,0x38,0x66,0x15,0x3c,0x76,0xbf,0x66,0xbf,0x95,0xde,0xf6,0x15,0xb0,0x0c,},44,"\x63\xb8\x0b\x79\x56\xac\xbe\xcf\x0c\x35\xe9\xab\x06\xb9\x14\xb0\xc7\x01\x4f\xe1\xa4\xbb\xc0\x21\x72\x40\xc1\xa3\x30\x95\xd7\x07\x95\x3e\xd7\x7b\x15\xd2\x11\xad\xaf\x9b\x97\xdc"},
+ {{0x0d,0xdc,0xdc,0x87,0x2c,0x7b,0x74,0x8d,0x40,0xef,0xe9,0x6c,0x28,0x81,0xae,0x18,0x9d,0x87,0xf5,0x61,0x48,0xed,0x8a,0xf3,0xeb,0xbb,0xc8,0x03,0x24,0xe3,0x8b,0xdd,},{0x58,0x8d,0xda,0xdc,0xbc,0xed,0xf4,0x0d,0xf0,0xe9,0x69,0x7d,0x8b,0xb2,0x77,0xc7,0xbb,0x14,0x98,0xfa,0x1d,0x26,0xce,0x0a,0x83,0x5a,0x76,0x0b,0x92,0xca,0x7c,0x85,},{0xc1,0x79,0xc0,0x94,0x56,0xe2,0x35,0xfe,0x24,0x10,0x5a,0xfa,0x6e,0x8e,0xc0,0x46,0x37,0xf8,0xf9,0x43,0x81,0x7c,0xd0,0x98,0xba,0x95,0x38,0x7f,0x96,0x53,0xb2,0xad,0xd1,0x81,0xa3,0x14,0x47,0xd9,0x2d,0x1a,0x1d,0xdf,0x1c,0xeb,0x0d,0xb6,0x21,0x18,0xde,0x9d,0xff,0xb7,0xdc,0xd2,0x42,0x40,0x57,0xcb,0xdf,0xf5,0xd4,0x1d,0x04,0x03,},45,"\x65\x64\x1c\xd4\x02\xad\xd8\xbf\x3d\x1d\x67\xdb\xeb\x6d\x41\xde\xbf\xbe\xf6\x7e\x43\x17\xc3\x5b\x0a\x6d\x5b\xbb\xae\x0e\x03\x4d\xe7\xd6\x70\xba\x14\x13\xd0\x56\xf2\xd6\xf1\xde\x12"},
+ {{0x89,0xf0,0xd6,0x82,0x99,0xba,0x0a,0x5a,0x83,0xf2,0x48,0xae,0x0c,0x16,0x9f,0x8e,0x38,0x49,0xa9,0xb4,0x7b,0xd4,0x54,0x98,0x84,0x30,0x5c,0x99,0x12,0xb4,0x66,0x03,},{0xab,0xa3,0xe7,0x95,0xaa,0xb2,0x01,0x2a,0xcc,0xea,0xdd,0x7b,0x3b,0xd9,0xda,0xee,0xed,0x6f,0xf5,0x25,0x8b,0xdc,0xd7,0xc9,0x36,0x99,0xc2,0xa3,0x83,0x6e,0x38,0x32,},{0x2c,0x69,0x1f,0xa8,0xd4,0x87,0xce,0x20,0xd5,0xd2,0xfa,0x41,0x55,0x91,0x16,0xe0,0xbb,0xf4,0x39,0x7c,0xf5,0x24,0x0e,0x15,0x25,0x56,0x18,0x35,0x41,0xd6,0x6c,0xf7,0x53,0x58,0x24,0x01,0xa4,0x38,0x8d,0x39,0x03,0x39,0xdb,0xef,0x4d,0x38,0x47,0x43,0xca,0xa3,0x46,0xf5,0x5f,0x8d,0xab,0xa6,0x8b,0xa7,0xb9,0x13,0x1a,0x8a,0x6e,0x0b,},46,"\x4f\x18\x46\xdd\x7a\xd5\x0e\x54\x5d\x4c\xfb\xff\xbb\x1d\xc2\xff\x14\x5d\xc1\x23\x75\x4d\x08\xaf\x4e\x44\xec\xc0\xbc\x8c\x91\x41\x13\x88\xbc\x76\x53\xe2\xd8\x93\xd1\xea\xc2\x10\x7d\x05"},
+ {{0x0a,0x3c,0x18,0x44,0xe2,0xdb,0x07,0x0f,0xb2,0x4e,0x3c,0x95,0xcb,0x1c,0xc6,0x71,0x4e,0xf8,0x4e,0x2c,0xcd,0x2b,0x9d,0xd2,0xf1,0x46,0x0e,0xbf,0x7e,0xcf,0x13,0xb1,},{0x72,0xe4,0x09,0x93,0x7e,0x06,0x10,0xeb,0x5c,0x20,0xb3,0x26,0xdc,0x6e,0xa1,0xbb,0xbc,0x04,0x06,0x70,0x1c,0x5c,0xd6,0x7d,0x1f,0xbd,0xe0,0x91,0x92,0xb0,0x7c,0x01,},{0x87,0xf7,0xfd,0xf4,0x60,0x95,0x20,0x1e,0x87,0x7a,0x58,0x8f,0xe3,0xe5,0xaa,0xf4,0x76,0xbd,0x63,0x13,0x8d,0x8a,0x87,0x8b,0x89,0xd6,0xac,0x60,0x63,0x1b,0x34,0x58,0xb9,0xd4,0x1a,0x3c,0x61,0xa5,0x88,0xe1,0xdb,0x8d,0x29,0xa5,0x96,0x89,0x81,0xb0,0x18,0x77,0x6c,0x58,0x87,0x80,0x92,0x2f,0x5a,0xa7,0x32,0xba,0x63,0x79,0xdd,0x05,},47,"\x4c\x82\x74\xd0\xed\x1f\x74\xe2\xc8\x6c\x08\xd9\x55\xbd\xe5\x5b\x2d\x54\x32\x7e\x82\x06\x2a\x1f\x71\xf7\x0d\x53\x6f\xdc\x87\x22\xcd\xea\xd7\xd2\x2a\xae\xad\x2b\xfa\xa1\xad\x00\xb8\x29\x57"},
+ {{0xc8,0xd7,0xa8,0x81,0x8b,0x98,0xdf,0xdb,0x20,0x83,0x9c,0x87,0x1c,0xb5,0xc4,0x8e,0x9e,0x94,0x70,0xca,0x3a,0xd3,0x5b,0xa2,0x61,0x3a,0x5d,0x31,0x99,0xc8,0xab,0x23,},{0x90,0xd2,0xef,0xbb,0xa4,0xd4,0x3e,0x6b,0x2b,0x99,0x2c,0xa1,0x60,0x83,0xdb,0xcf,0xa2,0xb3,0x22,0x38,0x39,0x07,0xb0,0xee,0x75,0xf3,0xe9,0x58,0x45,0xd3,0xc4,0x7f,},{0xfa,0x2e,0x99,0x44,0x21,0xae,0xf1,0xd5,0x85,0x66,0x74,0x81,0x3d,0x05,0xcb,0xd2,0xcf,0x84,0xef,0x5e,0xb4,0x24,0xaf,0x6e,0xcd,0x0d,0xc6,0xfd,0xbd,0xc2,0xfe,0x60,0x5f,0xe9,0x85,0x88,0x33,0x12,0xec,0xf3,0x4f,0x59,0xbf,0xb2,0xf1,0xc9,0x14,0x9e,0x5b,0x9c,0xc9,0xec,0xda,0x05,0xb2,0x73,0x11,0x30,0xf3,0xed,0x28,0xdd,0xae,0x0b,},48,"\x78\x3e\x33\xc3\xac\xbd\xbb\x36\xe8\x19\xf5\x44\xa7\x78\x1d\x83\xfc\x28\x3d\x33\x09\xf5\xd3\xd1\x2c\x8d\xcd\x6b\x0b\x3d\x0e\x89\xe3\x8c\xfd\x3b\x4d\x08\x85\x66\x1c\xa5\x47\xfb\x97\x64\xab\xff"},
+ {{0xb4,0x82,0x70,0x36,0x12,0xd0,0xc5,0x86,0xf7,0x6c,0xfc,0xb2,0x1c,0xfd,0x21,0x03,0xc9,0x57,0x25,0x15,0x04,0xa8,0xc0,0xac,0x4c,0x86,0xc9,0xc6,0xf3,0xe4,0x29,0xff,},{0xfd,0x71,0x1d,0xc7,0xdd,0x3b,0x1d,0xfb,0x9d,0xf9,0x70,0x4b,0xe3,0xe6,0xb2,0x6f,0x58,0x7f,0xe7,0xdd,0x7b,0xa4,0x56,0xa9,0x1b,0xa4,0x3f,0xe5,0x1a,0xec,0x09,0xad,},{0x58,0x83,0x2b,0xde,0xb2,0x6f,0xea,0xfc,0x31,0xb4,0x62,0x77,0xcf,0x3f,0xb5,0xd7,0xa1,0x7d,0xfb,0x7c,0xcd,0x9b,0x1f,0x58,0xec,0xbe,0x6f,0xeb,0x97,0x96,0x66,0x82,0x8f,0x23,0x9b,0xa4,0xd7,0x52,0x19,0x26,0x0e,0xca,0xc0,0xac,0xf4,0x0f,0x0e,0x5e,0x25,0x90,0xf4,0xca,0xa1,0x6b,0xbb,0xcd,0x8a,0x15,0x5d,0x34,0x79,0x67,0xa6,0x07,},49,"\x29\xd7\x7a\xcf\xd9\x9c\x7a\x00\x70\xa8\x8f\xeb\x62\x47\xa2\xbc\xe9\x98\x4f\xe3\xe6\xfb\xf1\x9d\x40\x45\x04\x2a\x21\xab\x26\xcb\xd7\x71\xe1\x84\xa9\xa7\x5f\x31\x6b\x64\x8c\x69\x20\xdb\x92\xb8\x7b"},
+ {{0x84,0xe5,0x0d,0xd9,0xa0,0xf1,0x97,0xe3,0x89,0x3c,0x38,0xdb,0xd9,0x1f,0xaf,0xc3,0x44,0xc1,0x77,0x6d,0x3a,0x40,0x0e,0x2f,0x0f,0x0e,0xe7,0xaa,0x82,0x9e,0xb8,0xa2,},{0x2c,0x50,0xf8,0x70,0xee,0x48,0xb3,0x6b,0x0a,0xc2,0xf8,0xa5,0xf3,0x36,0xfb,0x09,0x0b,0x11,0x30,0x50,0xdb,0xcc,0x25,0xe0,0x78,0x20,0x0a,0x6e,0x16,0x15,0x3e,0xea,},{0x69,0xe6,0xa4,0x49,0x1a,0x63,0x83,0x73,0x16,0xe8,0x6a,0x5f,0x4b,0xa7,0xcd,0x0d,0x73,0x1e,0xcc,0x58,0xf1,0xd0,0xa2,0x64,0xc6,0x7c,0x89,0xbe,0xfd,0xd8,0xd3,0x82,0x9d,0x8d,0xe1,0x3b,0x33,0xcc,0x0b,0xf5,0x13,0x93,0x17,0x15,0xc7,0x80,0x96,0x57,0xe2,0xbf,0xb9,0x60,0xe5,0xc7,0x64,0xc9,0x71,0xd7,0x33,0x74,0x60,0x93,0xe5,0x00,},50,"\xf3\x99\x2c\xde\x64\x93\xe6\x71\xf1\xe1\x29\xdd\xca\x80\x38\xb0\xab\xdb\x77\xbb\x90\x35\xf9\xf8\xbe\x54\xbd\x5d\x68\xc1\xae\xff\x72\x4f\xf4\x7d\x29\x34\x43\x91\xdc\x53\x61\x66\xb8\x67\x1c\xbb\xf1\x23"},
+ {{0xb3,0x22,0xd4,0x65,0x77,0xa2,0xa9,0x91,0xa4,0xd1,0x69,0x82,0x87,0x83,0x2a,0x39,0xc4,0x87,0xef,0x77,0x6b,0x4b,0xff,0x03,0x7a,0x05,0xc7,0xf1,0x81,0x2b,0xde,0xec,},{0xeb,0x2b,0xca,0xdf,0xd3,0xee,0xc2,0x98,0x6b,0xaf,0xf3,0x2b,0x98,0xe7,0xc4,0xdb,0xf0,0x3f,0xf9,0x5d,0x8a,0xd5,0xff,0x9a,0xa9,0x50,0x6e,0x54,0x72,0xff,0x84,0x5f,},{0xc7,0xb5,0x51,0x37,0x31,0x7c,0xa2,0x1e,0x33,0x48,0x9f,0xf6,0xa9,0xbf,0xab,0x97,0xc8,0x55,0xdc,0x6f,0x85,0x68,0x4a,0x70,0xa9,0x12,0x5a,0x26,0x1b,0x56,0xd5,0xe6,0xf1,0x49,0xc5,0x77,0x4d,0x73,0x4f,0x2d,0x8d,0xeb,0xfc,0x77,0xb7,0x21,0x89,0x6a,0x82,0x67,0xc2,0x37,0x68,0xe9,0xba,0xdb,0x91,0x0e,0xef,0x83,0xec,0x25,0x88,0x02,},51,"\x19\xf1\xbf\x5d\xcf\x17\x50\xc6\x11\xf1\xc4\xa2\x86\x52\x00\x50\x4d\x82\x29\x8e\xdd\x72\x67\x1f\x62\xa7\xb1\x47\x1a\xc3\xd4\xa3\x0f\x7d\xe9\xe5\xda\x41\x08\xc5\x2a\x4c\xe7\x0a\x3e\x11\x4a\x52\xa3\xb3\xc5"},
+ {{0x96,0x0c,0xab,0x50,0x34,0xb9,0x83,0x8d,0x09,0x8d,0x2d,0xcb,0xf4,0x36,0x4b,0xec,0x16,0xd3,0x88,0xf6,0x37,0x6d,0x73,0xa6,0x27,0x3b,0x70,0xf8,0x2b,0xbc,0x98,0xc0,},{0x5e,0x3c,0x19,0xf2,0x41,0x5a,0xcf,0x72,0x9f,0x82,0x9a,0x4e,0xbd,0x5c,0x40,0xe1,0xa6,0xbc,0x9f,0xbc,0xa9,0x57,0x03,0xa9,0x37,0x60,0x87,0xed,0x09,0x37,0xe5,0x1a,},{0x27,0xd4,0xc3,0xa1,0x81,0x1e,0xf9,0xd4,0x36,0x0b,0x3b,0xdd,0x13,0x3c,0x2c,0xcc,0x30,0xd0,0x2c,0x2f,0x24,0x82,0x15,0x77,0x6c,0xb0,0x7e,0xe4,0x17,0x7f,0x9b,0x13,0xfc,0x42,0xdd,0x70,0xa6,0xc2,0xfe,0xd8,0xf2,0x25,0xc7,0x66,0x3c,0x7f,0x18,0x2e,0x7e,0xe8,0xec,0xcf,0xf2,0x0d,0xc7,0xb0,0xe1,0xd5,0x83,0x4e,0xc5,0xb1,0xea,0x01,},52,"\xf8\xb2\x19\x62\x44\x7b\x0a\x8f\x2e\x42\x79\xde\x41\x1b\xea\x12\x8e\x0b\xe4\x4b\x69\x15\xe6\xcd\xa8\x83\x41\xa6\x8a\x0d\x81\x83\x57\xdb\x93\x8e\xac\x73\xe0\xaf\x6d\x31\x20\x6b\x39\x48\xf8\xc4\x8a\x44\x73\x08"},
+ {{0xeb,0x77,0xb2,0x63,0x8f,0x23,0xee,0xbc,0x82,0xef,0xe4,0x5e,0xe9,0xe5,0xa0,0x32,0x66,0x37,0x40,0x1e,0x66,0x3e,0xd0,0x29,0x69,0x9b,0x21,0xe6,0x44,0x3f,0xb4,0x8e,},{0x9e,0xf2,0x76,0x08,0x96,0x1a,0xc7,0x11,0xde,0x71,0xa6,0xe2,0xd4,0xd4,0x66,0x3e,0xa3,0xec,0xd4,0x2f,0xb7,0xe4,0xe8,0x62,0x7c,0x39,0x62,0x2d,0xf4,0xaf,0x0b,0xbc,},{0x18,0xdc,0x56,0xd7,0xbd,0x9a,0xcd,0x4f,0x4d,0xaa,0x78,0x54,0x0b,0x4a,0xc8,0xff,0x7a,0xa9,0x81,0x5f,0x45,0xa0,0xbb,0xa3,0x70,0x73,0x1a,0x14,0xea,0xab,0xe9,0x6d,0xf8,0xb5,0xf3,0x7d,0xbf,0x8e,0xae,0x4c,0xb1,0x5a,0x64,0xb2,0x44,0x65,0x1e,0x59,0xd6,0xa3,0xd6,0x76,0x1d,0x9e,0x3c,0x50,0xf2,0xd0,0xcb,0xb0,0x9c,0x05,0xec,0x06,},53,"\x99\xe3\xd0\x09\x34\x00\x3e\xba\xfc\x3e\x9f\xdb\x68\x7b\x0f\x5f\xf9\xd5\x78\x2a\x4b\x1f\x56\xb9\x70\x00\x46\xc0\x77\x91\x56\x02\xc3\x13\x4e\x22\xfc\x90\xed\x7e\x69\x0f\xdd\xd4\x43\x3e\x20\x34\xdc\xb2\xdc\x99\xab"},
+ {{0xb6,0x25,0xaa,0x89,0xd3,0xf7,0x30,0x87,0x15,0x42,0x7b,0x6c,0x39,0xbb,0xac,0x58,0xef,0xfd,0x3a,0x0f,0xb7,0x31,0x6f,0x7a,0x22,0xb9,0x9e,0xe5,0x92,0x2f,0x2d,0xc9,},{0x65,0xa9,0x9c,0x3e,0x16,0xfe,0xa8,0x94,0xec,0x33,0xc6,0xb2,0x0d,0x91,0x05,0xe2,0xa0,0x4e,0x27,0x64,0xa4,0x76,0x9d,0x9b,0xbd,0x4d,0x8b,0xac,0xfe,0xab,0x4a,0x2e,},{0x01,0xbb,0x90,0x1d,0x83,0xb8,0xb6,0x82,0xd3,0x61,0x4a,0xf4,0x6a,0x80,0x7b,0xa2,0x69,0x13,0x58,0xfe,0xb7,0x75,0x32,0x5d,0x34,0x23,0xf5,0x49,0xff,0x0a,0xa5,0x75,0x7e,0x4e,0x1a,0x74,0xe9,0xc7,0x0f,0x97,0x21,0xd8,0xf3,0x54,0xb3,0x19,0xd4,0xf4,0xa1,0xd9,0x14,0x45,0xc8,0x70,0xfd,0x0f,0xfb,0x94,0xfe,0xd6,0x46,0x64,0x73,0x0d,},54,"\xe0\x72\x41\xdb\xd3\xad\xbe\x61\x0b\xbe\x4d\x00\x5d\xd4\x67\x32\xa4\xc2\x50\x86\xec\xb8\xec\x29\xcd\x7b\xca\x11\x6e\x1b\xf9\xf5\x3b\xfb\xf3\xe1\x1f\xa4\x90\x18\xd3\x9f\xf1\x15\x4a\x06\x66\x8e\xf7\xdf\x5c\x67\x8e\x6a"},
+ {{0xb1,0xc9,0xf8,0xbd,0x03,0xfe,0x82,0xe7,0x8f,0x5c,0x0f,0xb0,0x64,0x50,0xf2,0x7d,0xac,0xdf,0x71,0x64,0x34,0xdb,0x26,0x82,0x75,0xdf,0x3e,0x1d,0xc1,0x77,0xaf,0x42,},{0x7f,0xc8,0x8b,0x1f,0x7b,0x3f,0x11,0xc6,0x29,0xbe,0x67,0x1c,0x21,0x62,0x1f,0x5c,0x10,0x67,0x2f,0xaf,0xc8,0x49,0x2d,0xa8,0x85,0x74,0x20,0x59,0xee,0x67,0x74,0xcf,},{0x4b,0x22,0x99,0x51,0xef,0x26,0x2f,0x16,0x97,0x8f,0x79,0x14,0xbc,0x67,0x2e,0x72,0x26,0xc5,0xf8,0x37,0x9d,0x27,0x78,0xc5,0xa2,0xdc,0x0a,0x26,0x50,0x86,0x9f,0x7a,0xcf,0xbd,0x0b,0xcd,0x30,0xfd,0xb0,0x61,0x9b,0xb4,0x4f,0xc1,0xae,0x59,0x39,0xb8,0x7c,0xc3,0x18,0x13,0x30,0x09,0xc2,0x03,0x95,0xb6,0xc7,0xeb,0x98,0x10,0x77,0x01,},55,"\x33\x1d\xa7\xa9\xc1\xf8\x7b\x2a\xc9\x1e\xe3\xb8\x6d\x06\xc2\x91\x63\xc0\x5e\xd6\xf8\xd8\xa9\x72\x5b\x47\x1b\x7d\xb0\xd6\xac\xec\x7f\x0f\x70\x24\x87\x16\x3f\x5e\xda\x02\x0c\xa5\xb4\x93\xf3\x99\xe1\xc8\xd3\x08\xc3\xc0\xc2"},
+ {{0x6d,0x8c,0xdb,0x2e,0x07,0x5f,0x3a,0x2f,0x86,0x13,0x72,0x14,0xcb,0x23,0x6c,0xeb,0x89,0xa6,0x72,0x8b,0xb4,0xa2,0x00,0x80,0x6b,0xf3,0x55,0x7f,0xb7,0x8f,0xac,0x69,},{0x57,0xa0,0x4c,0x7a,0x51,0x13,0xcd,0xdf,0xe4,0x9a,0x4c,0x12,0x46,0x91,0xd4,0x6c,0x1f,0x9c,0xdc,0x8f,0x34,0x3f,0x9d,0xcb,0x72,0xa1,0x33,0x0a,0xec,0xa7,0x1f,0xda,},{0xa6,0xcb,0xc9,0x47,0xf9,0xc8,0x7d,0x14,0x55,0xcf,0x1a,0x70,0x85,0x28,0xc0,0x90,0xf1,0x1e,0xce,0xe4,0x85,0x5d,0x1d,0xba,0xad,0xf4,0x74,0x54,0xa4,0xde,0x55,0xfa,0x4c,0xe8,0x4b,0x36,0xd7,0x3a,0x5b,0x5f,0x8f,0x59,0x29,0x8c,0xcf,0x21,0x99,0x2d,0xf4,0x92,0xef,0x34,0x16,0x3d,0x87,0x75,0x3b,0x7e,0x9d,0x32,0xf2,0xc3,0x66,0x0b,},56,"\x7f\x31\x8d\xbd\x12\x1c\x08\xbf\xdd\xfe\xff\x4f\x6a\xff\x4e\x45\x79\x32\x51\xf8\xab\xf6\x58\x40\x33\x58\x23\x89\x84\x36\x00\x54\xf2\xa8\x62\xc5\xbb\x83\xed\x89\x02\x5d\x20\x14\xa7\xa0\xce\xe5\x0d\xa3\xcb\x0e\x76\xbb\xb6\xbf"},
+ {{0x47,0xad,0xc6,0xd6,0xbf,0x57,0x1e,0xe9,0x57,0x0c,0xa0,0xf7,0x5b,0x60,0x4a,0xc4,0x3e,0x30,0x3e,0x4a,0xb3,0x39,0xca,0x9b,0x53,0xca,0xcc,0x5b,0xe4,0x5b,0x2c,0xcb,},{0xa3,0xf5,0x27,0xa1,0xc1,0xf1,0x7d,0xfe,0xed,0x92,0x27,0x73,0x47,0xc9,0xf9,0x8a,0xb4,0x75,0xde,0x17,0x55,0xb0,0xab,0x54,0x6b,0x8a,0x15,0xd0,0x1b,0x9b,0xd0,0xbe,},{0x4e,0x8c,0x31,0x83,0x43,0xc3,0x06,0xad,0xbb,0xa6,0x0c,0x92,0xb7,0x5c,0xb0,0x56,0x9b,0x92,0x19,0xd8,0xa8,0x6e,0x5d,0x57,0x75,0x2e,0xd2,0x35,0xfc,0x10,0x9a,0x43,0xc2,0xcf,0x4e,0x94,0x2c,0xac,0xf2,0x97,0x27,0x9f,0xbb,0x28,0x67,0x53,0x47,0xe0,0x80,0x27,0x72,0x2a,0x4e,0xb7,0x39,0x5e,0x00,0xa1,0x74,0x95,0xd3,0x2e,0xdf,0x0b,},57,"\xce\x49\x7c\x5f\xf5\xa7\x79\x90\xb7\xd8\xf8\x69\x9e\xb1\xf5\xd8\xc0\x58\x2f\x70\xcb\x7a\xc5\xc5\x4d\x9d\x92\x49\x13\x27\x8b\xc6\x54\xd3\x7e\xa2\x27\x59\x0e\x15\x20\x22\x17\xfc\x98\xda\xc4\xc0\xf3\xbe\x21\x83\xd1\x33\x31\x57\x39"},
+ {{0x3c,0x19,0xb5,0x0b,0x0f,0xe4,0x79,0x61,0x71,0x9c,0x38,0x1d,0x0d,0x8d,0xa9,0xb9,0x86,0x9d,0x31,0x2f,0x13,0xe3,0x29,0x8b,0x97,0xfb,0x22,0xf0,0xaf,0x29,0xcb,0xbe,},{0x0f,0x7e,0xda,0x09,0x14,0x99,0x62,0x5e,0x2b,0xae,0x85,0x36,0xea,0x35,0xcd,0xa5,0x48,0x3b,0xd1,0x6a,0x9c,0x7e,0x41,0x6b,0x34,0x1d,0x6f,0x2c,0x83,0x34,0x36,0x12,},{0xef,0xbd,0x41,0xf2,0x6a,0x5d,0x62,0x68,0x55,0x16,0xf8,0x82,0xb6,0xec,0x74,0xe0,0xd5,0xa7,0x18,0x30,0xd2,0x03,0xc2,0x31,0x24,0x8f,0x26,0xe9,0x9a,0x9c,0x65,0x78,0xec,0x90,0x0d,0x68,0xcd,0xb8,0xfa,0x72,0x16,0xad,0x0d,0x24,0xf9,0xec,0xbc,0x9f,0xfa,0x65,0x53,0x51,0x66,0x65,0x82,0xf6,0x26,0x64,0x53,0x95,0xa3,0x1f,0xa7,0x04,},58,"\x8d\xdc\xd6\x30\x43\xf5\x5e\xc3\xbf\xc8\x3d\xce\xae\x69\xd8\xf8\xb3\x2f\x4c\xdb\x6e\x2a\xeb\xd9\x4b\x43\x14\xf8\xfe\x72\x87\xdc\xb6\x27\x32\xc9\x05\x2e\x75\x57\xfe\x63\x53\x43\x38\xef\xb5\xb6\x25\x4c\x5d\x41\xd2\x69\x0c\xf5\x14\x4f"},
+ {{0x34,0xe1,0xe9,0xd5,0x39,0x10,0x7e,0xb8,0x6b,0x39,0x3a,0x5c,0xce,0xa1,0x49,0x6d,0x35,0xbc,0x7d,0x5e,0x9a,0x8c,0x51,0x59,0xd9,0x57,0xe4,0xe5,0x85,0x2b,0x3e,0xb0,},{0x0e,0xcb,0x26,0x01,0xd5,0xf7,0x04,0x74,0x28,0xe9,0xf9,0x09,0x88,0x3a,0x12,0x42,0x00,0x85,0xf0,0x4e,0xe2,0xa8,0x8b,0x6d,0x95,0xd3,0xd7,0xf2,0xc9,0x32,0xbd,0x76,},{0x32,0xd2,0x29,0x04,0xd3,0xe7,0x01,0x2d,0x6f,0x5a,0x44,0x1b,0x0b,0x42,0x28,0x06,0x4a,0x5c,0xf9,0x5b,0x72,0x3a,0x66,0xb0,0x48,0xa0,0x87,0xec,0xd5,0x59,0x20,0xc3,0x1c,0x20,0x4c,0x3f,0x20,0x06,0x89,0x1a,0x85,0xdd,0x19,0x32,0xe3,0xf1,0xd6,0x14,0xcf,0xd6,0x33,0xb5,0xe6,0x32,0x91,0xc6,0xd8,0x16,0x6f,0x30,0x11,0x43,0x1e,0x09,},59,"\xa6\xd4\xd0\x54\x2c\xfe\x0d\x24\x0a\x90\x50\x7d\xeb\xac\xab\xce\x7c\xbb\xd4\x87\x32\x35\x3f\x4f\xad\x82\xc7\xbb\x7d\xbd\x9d\xf8\xe7\xd9\xa1\x69\x80\xa4\x51\x86\xd8\x78\x6c\x5e\xf6\x54\x45\xbc\xc5\xb2\xad\x5f\x66\x0f\xfc\x7c\x8e\xaa\xc0"},
+ {{0x49,0xdd,0x47,0x3e,0xde,0x6a,0xa3,0xc8,0x66,0x82,0x4a,0x40,0xad,0xa4,0x99,0x6c,0x23,0x9a,0x20,0xd8,0x4c,0x93,0x65,0xe4,0xf0,0xa4,0x55,0x4f,0x80,0x31,0xb9,0xcf,},{0x78,0x8d,0xe5,0x40,0x54,0x4d,0x3f,0xeb,0x0c,0x91,0x92,0x40,0xb3,0x90,0x72,0x9b,0xe4,0x87,0xe9,0x4b,0x64,0xad,0x97,0x3e,0xb6,0x5b,0x46,0x69,0xec,0xf2,0x35,0x01,},{0xd2,0xfd,0xe0,0x27,0x91,0xe7,0x20,0x85,0x25,0x07,0xfa,0xa7,0xc3,0x78,0x90,0x40,0xd9,0xef,0x86,0x64,0x63,0x21,0xf3,0x13,0xac,0x55,0x7f,0x40,0x02,0x49,0x15,0x42,0xdd,0x67,0xd0,0x5c,0x69,0x90,0xcd,0xb0,0xd4,0x95,0x50,0x1f,0xbc,0x5d,0x51,0x88,0xbf,0xbb,0x84,0xdc,0x1b,0xf6,0x09,0x8b,0xee,0x06,0x03,0xa4,0x7f,0xc2,0x69,0x0f,},60,"\x3a\x53\x59\x4f\x3f\xba\x03\x02\x93\x18\xf5\x12\xb0\x84\xa0\x71\xeb\xd6\x0b\xae\xc7\xf5\x5b\x02\x8d\xc7\x3b\xfc\x9c\x74\xe0\xca\x49\x6b\xf8\x19\xdd\x92\xab\x61\xcd\x8b\x74\xbe\x3c\x0d\x6d\xcd\x12\x8e\xfc\x5e\xd3\x34\x2c\xba\x12\x4f\x72\x6c"},
+ {{0x33,0x1c,0x64,0xda,0x48,0x2b,0x6b,0x55,0x13,0x73,0xc3,0x64,0x81,0xa0,0x2d,0x81,0x36,0xec,0xad,0xbb,0x01,0xab,0x11,0x4b,0x44,0x70,0xbf,0x41,0x60,0x7a,0xc5,0x71,},{0x52,0xa0,0x0d,0x96,0xa3,0x14,0x8b,0x47,0x26,0x69,0x2d,0x9e,0xff,0x89,0x16,0x0e,0xa9,0xf9,0x9a,0x5c,0xc4,0x38,0x9f,0x36,0x1f,0xed,0x0b,0xb1,0x6a,0x42,0xd5,0x21,},{0x22,0xc9,0x9a,0xa9,0x46,0xea,0xd3,0x9a,0xc7,0x99,0x75,0x62,0x81,0x0c,0x01,0xc2,0x0b,0x46,0xbd,0x61,0x06,0x45,0xbd,0x2d,0x56,0xdc,0xdc,0xba,0xac,0xc5,0x45,0x2c,0x74,0xfb,0xf4,0xb8,0xb1,0x81,0x3b,0x0e,0x94,0xc3,0x0d,0x80,0x8c,0xe5,0x49,0x8e,0x61,0xd4,0xf7,0xcc,0xbb,0x4c,0xc5,0xf0,0x4d,0xfc,0x61,0x40,0x82,0x5a,0x96,0x00,},61,"\x20\xe1\xd0\x5a\x0d\x5b\x32\xcc\x81\x50\xb8\x11\x6c\xef\x39\x65\x9d\xd5\xfb\x44\x3a\xb1\x56\x00\xf7\x8e\x5b\x49\xc4\x53\x26\xd9\x32\x3f\x28\x50\xa6\x3c\x38\x08\x85\x94\x95\xae\x27\x3f\x58\xa5\x1e\x9d\xe9\xa1\x45\xd7\x74\xb4\x0b\xa9\xd7\x53\xd3"},
+ {{0x5c,0x0b,0x96,0xf2,0xaf,0x87,0x12,0x12,0x2c,0xf7,0x43,0xc8,0xf8,0xdc,0x77,0xb6,0xcd,0x55,0x70,0xa7,0xde,0x13,0x29,0x7b,0xb3,0xdd,0xe1,0x88,0x62,0x13,0xcc,0xe2,},{0x05,0x10,0xea,0xf5,0x7d,0x73,0x01,0xb0,0xe1,0xd5,0x27,0x03,0x9b,0xf4,0xc6,0xe2,0x92,0x30,0x0a,0x3a,0x61,0xb4,0x76,0x54,0x34,0xf3,0x20,0x3c,0x10,0x03,0x51,0xb1,},{0x06,0xe5,0xd8,0x43,0x6a,0xc7,0x70,0x5b,0x3a,0x90,0xf1,0x63,0x1c,0xdd,0x38,0xec,0x1a,0x3f,0xa4,0x97,0x78,0xa9,0xb9,0xf2,0xfa,0x5e,0xbe,0xa4,0xe7,0xd5,0x60,0xad,0xa7,0xdd,0x26,0xff,0x42,0xfa,0xfa,0x8b,0xa4,0x20,0x32,0x37,0x42,0x76,0x1a,0xca,0x69,0x04,0x94,0x0d,0xc2,0x1b,0xbe,0xf6,0x3f,0xf7,0x2d,0xaa,0xb4,0x5d,0x43,0x0b,},62,"\x54\xe0\xca\xa8\xe6\x39\x19\xca\x61\x4b\x2b\xfd\x30\x8c\xcf\xe5\x0c\x9e\xa8\x88\xe1\xee\x44\x46\xd6\x82\xcb\x50\x34\x62\x7f\x97\xb0\x53\x92\xc0\x4e\x83\x55\x56\xc3\x1c\x52\x81\x6a\x48\xe4\xfb\x19\x66\x93\x20\x6b\x8a\xfb\x44\x08\x66\x2b\x3c\xb5\x75"},
+ {{0xde,0x84,0xf2,0x43,0x5f,0x78,0xde,0xdb,0x87,0xda,0x18,0x19,0x4f,0xf6,0xa3,0x36,0xf0,0x81,0x11,0x15,0x0d,0xef,0x90,0x1c,0x1a,0xc4,0x18,0x14,0x6e,0xb7,0xb5,0x4a,},{0xd3,0xa9,0x2b,0xba,0xa4,0xd6,0x3a,0xf7,0x9c,0x22,0x26,0xa7,0x23,0x6e,0x64,0x27,0x42,0x8d,0xf8,0xb3,0x62,0x42,0x7f,0x87,0x30,0x23,0xb2,0x2d,0x2f,0x5e,0x03,0xf2,},{0x47,0x1e,0xbc,0x97,0x3c,0xfd,0xac,0xee,0xc0,0x72,0x79,0x30,0x73,0x68,0xb7,0x3b,0xe3,0x5b,0xc6,0xf8,0xd8,0x31,0x2b,0x70,0x15,0x05,0x67,0x36,0x90,0x96,0x70,0x6d,0xc4,0x71,0x12,0x6c,0x35,0x76,0xf9,0xf0,0xeb,0x55,0x0d,0xf5,0xac,0x6a,0x52,0x51,0x81,0x11,0x00,0x29,0xdd,0x1f,0xc1,0x11,0x74,0xd1,0xaa,0xce,0xd4,0x8d,0x63,0x0f,},63,"\x20\x51\x35\xec\x7f\x41\x7c\x85\x80\x72\xd5\x23\x3f\xb3\x64\x82\xd4\x90\x6a\xbd\x60\xa7\x4a\x49\x8c\x34\x7f\xf2\x48\xdf\xa2\x72\x2c\xa7\x4e\x87\x9d\xe3\x31\x69\xfa\xdc\x7c\xd4\x4d\x6c\x94\xa1\x7d\x16\xe1\xe6\x30\x82\x4b\xa3\xe0\xdf\x22\xed\x68\xea\xab"},
+ {{0xba,0x4d,0x6e,0x67,0xb2,0xce,0x67,0xa1,0xe4,0x43,0x26,0x49,0x40,0x44,0xf3,0x7a,0x44,0x2f,0x3b,0x81,0x72,0x5b,0xc1,0xf9,0x34,0x14,0x62,0x71,0x8b,0x55,0xee,0x20,},{0xf7,0x3f,0xa0,0x76,0xf8,0x4b,0x6d,0xb6,0x75,0xa5,0xfd,0xa5,0xad,0x67,0xe3,0x51,0xa4,0x1e,0x8e,0x7f,0x29,0xad,0xd1,0x68,0x09,0xca,0x01,0x03,0x87,0xe9,0xc6,0xcc,},{0x57,0xb9,0xd2,0xa7,0x11,0x20,0x7f,0x83,0x74,0x21,0xba,0xe7,0xdd,0x48,0xea,0xa1,0x8e,0xab,0x1a,0x9a,0x70,0xa0,0xf1,0x30,0x58,0x06,0xfe,0xe1,0x7b,0x45,0x8f,0x3a,0x09,0x64,0xb3,0x02,0xd1,0x83,0x4d,0x3e,0x0a,0xc9,0xe8,0x49,0x6f,0x00,0x0b,0x77,0xf0,0x08,0x3b,0x41,0xf8,0xa9,0x57,0xe6,0x32,0xfb,0xc7,0x84,0x0e,0xee,0x6a,0x06,},64,"\x4b\xaf\xda\xc9\x09\x9d\x40\x57\xed\x6d\xd0\x8b\xca\xee\x87\x56\xe9\xa4\x0f\x2c\xb9\x59\x80\x20\xeb\x95\x01\x95\x28\x40\x9b\xbe\xa3\x8b\x38\x4a\x59\xf1\x19\xf5\x72\x97\xbf\xb2\xfa\x14\x2f\xc7\xbb\x1d\x90\xdb\xdd\xde\x77\x2b\xcd\xe4\x8c\x56\x70\xd5\xfa\x13"},
+ {{0x0d,0x13,0x1c,0x45,0xae,0xa6,0xf3,0xa4,0xe1,0xb9,0xa2,0xcf,0x60,0xc5,0x51,0x04,0x58,0x7e,0xfa,0xa8,0x46,0xb2,0x22,0xbf,0x0a,0x7b,0x74,0xce,0x7a,0x3f,0x63,0xb6,},{0x3c,0x67,0x29,0xdb,0xe9,0x3b,0x49,0x9c,0x4e,0x61,0x4a,0x2f,0x21,0xbe,0xb7,0x29,0x43,0x8d,0x49,0x8e,0x1a,0xc8,0xd1,0x4c,0xba,0xd9,0x71,0x7a,0x5d,0xbd,0x97,0xcd,},{0xa9,0xc5,0xee,0x86,0xfb,0x06,0xd9,0xe4,0x6b,0x37,0x9c,0x32,0xdd,0xa7,0xc9,0x2c,0x9c,0x13,0xdb,0x27,0x4d,0xc2,0x41,0x16,0xfb,0xdd,0x87,0x86,0x96,0x04,0x54,0x88,0xcc,0x75,0xa5,0x2f,0xff,0x67,0xd1,0xa5,0x11,0x3d,0x06,0xe3,0x33,0xac,0x67,0xff,0x66,0x4b,0x3f,0x2a,0x40,0x5f,0xa1,0xd1,0x4d,0xd5,0xbb,0xb9,0x74,0x09,0xb6,0x06,},65,"\xb4\x29\x1d\x08\xb8\x8f\xb2\xf7\xb8\xf9\x9d\x0d\xce\x40\x07\x9f\xcb\xab\x71\x8b\xbd\x8f\x4e\x8e\xab\xc3\xc1\x42\x8b\x6a\x07\x1f\xb2\xa3\xc8\xeb\xa1\xca\xcc\xcf\xa8\x71\xb3\x65\xc7\x08\xbe\xf2\x68\x5b\xc1\x3e\x6b\x80\xbc\x14\xa5\xf2\x49\x17\x0f\xfc\x56\xd0\x14"},
+};
+
+bool TestCryptoSign()
+{
+ // https://github.com/jedisct1/libsodium/blob/master/test/default/sign.c
+ const unsigned int MAX_MESSAGE = 65; // Sync with test data
+
+ uint8_t pk[crypto_sign_PUBLICKEYBYTES];
+ uint8_t sk[crypto_sign_SECRETKEYBYTES];
+ SecByteBlock sm(MAX_MESSAGE+crypto_sign_BYTES);
+ SecByteBlock rm(MAX_MESSAGE+crypto_sign_BYTES);
+
+ bool pass = true, fail; int rc;
+
+ for (unsigned int i=0; i<COUNTOF(test_data); ++i)
+ {
+ const TestData& data = test_data[i];
+ std::memcpy(sk, data.sk, crypto_sign_SEEDBYTES);
+ std::memcpy(sk+crypto_sign_SEEDBYTES, data.pk, crypto_sign_PUBLICKEYBYTES);
+ std::memcpy(pk, data.pk, crypto_sign_PUBLICKEYBYTES);
+
+ const uint8_t* m = reinterpret_cast<const uint8_t*>(data.msg);
+ const uint64_t l = data.len;
+ uint64_t smlen;
+
+ rc = crypto_sign(sm, &smlen, m, l, sk);
+ fail = (rc != 0); pass = !fail && pass;
+
+ uint64_t s = STDMIN(smlen, (uint64_t)crypto_sign_BYTES);
+ pass = (s >= crypto_sign_BYTES) && pass;
+
+ fail = std::memcmp(sm, data.sig, s) != 0;
+ pass = !fail && pass;
+
+ uint64_t rmlen;
+ rc = crypto_sign_open(rm, &rmlen, sm, smlen, pk);
+ fail = (rc != 0); pass = !fail && pass;
+
+ pass = (l == rmlen) && pass;
+ fail = std::memcmp(m, rm, STDMIN(l, rmlen)) != 0;
+ pass = !fail && pass;
+ }
+
+ return pass;
+}
+
+bool TestCryptoSignKeys()
+{
+ // https://github.com/jedisct1/libsodium/blob/master/test/default/sign.c
+ const unsigned int MAX_TEST = 128;
+ const unsigned int MAX_MESSAGE = 4096;
+
+ uint8_t pk[crypto_sign_PUBLICKEYBYTES];
+ uint8_t sk[crypto_sign_SECRETKEYBYTES];
+
+ bool pass = true, fail; int rc;
+
+ for (unsigned int i=0; i<MAX_TEST; ++i)
+ {
+ fail = (crypto_sign_keypair(pk, sk) != 0);
+ pass = !fail && pass;
+
+ const uint32_t len = (i == 0 ? 0 : GlobalRNG().GenerateWord32(1, MAX_MESSAGE));
+ SecByteBlock m(len), sm(len+crypto_sign_BYTES), rm(len+crypto_sign_BYTES);
+ if (len) { GlobalRNG().GenerateBlock(m, len); }
+
+ uint64_t mlen = len, smlen, rmlen;
+ rc = crypto_sign(sm, &smlen, m, mlen, sk);
+ fail = (rc != 0); pass = !fail && pass;
+
+ rc = crypto_sign_open(rm, &rmlen, sm, smlen, pk);
+ fail = (rc != 0); pass = !fail && pass;
+
+ if(mlen && rmlen)
+ {
+ pass = (mlen == rmlen) && pass;
+ fail = std::memcmp(m, rm, STDMIN(mlen, rmlen)) != 0;
+ pass = !fail && pass;
+ }
+
+ m.SetMark(16); sm.SetMark(16); rm.SetMark(16);
+ }
+
+ return pass;
+}
+
+#endif // CRYPTOPP_DISABLE_NACL
+
+// NaCl requires an integrated random number generator; see randombytes()
+// in tweetnacl.cpp. We use DefaultAutoSeededRNG but it means we need
+// Operating System features to seed the generator. If you use another
+// generator, like RDRAND, then undefine CRYPTOPP_DISABLE_NACL in nacl.h.
+bool ValidateNaCl()
+{
+ std::cout << "\nTesting NaCl library functions...\n\n";
+ bool pass = true, fail = false;
+
+#ifdef CRYPTOPP_DISABLE_NACL
+
+ std::cout << "NaCl not available, skipping test." << std::endl;
+
+#else
+
+ fail = !TestCryptoBox();
+ std::cout << (fail ? "FAILED" : "passed") << " crypto_box, crypto_box_beforenm, crypto_box_afternm\n";
+ pass = !fail && pass;
+
+ fail = !TestCryptoBoxOpen();
+ std::cout << (fail ? "FAILED" : "passed") << " crypto_box_open, crypto_box_open_afternm\n";
+ pass = !fail && pass;
+
+ fail = !TestCryptoBoxKeys();
+ std::cout << (fail ? "FAILED" : "passed") << " crypto_box_keypair pairwise consistency\n";
+ pass = !fail && pass;
+
+ fail = !TestCryptoSign();
+ std::cout << (fail ? "FAILED" : "passed") << " crypto_sign, crypto_sign_open, crypto_sign_keypair\n";
+ pass = !fail && pass;
+
+ fail = !TestCryptoSignKeys();
+ std::cout << (fail ? "FAILED" : "passed") << " crypto_sign_keypair pairwise consistency\n";
+ pass = !fail && pass;
+
+#endif
+
+ return pass;
+}
+
+NAMESPACE_END
+NAMESPACE_END
@@ -114,6 +114,8 @@ bool ValidateESIGN(); bool ValidateHashDRBG();
bool ValidateHmacDRBG();
+bool ValidateNaCl();
+
// If CRYPTOPP_DEBUG or CRYPTOPP_COVERAGE is in effect, then perform additional tests
#if (defined(CRYPTOPP_DEBUG) || defined(CRYPTOPP_COVERAGE) || defined(CRYPTOPP_VALGRIND)) && !defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_EXTENDED_VALIDATION 1
|