egra: don't use ENTER/LEAVE (because intel sux, and they are slower than the correspo...
[iv.d.git] / tweetNaCl_test / tweetNaCl_test.d
blob57ea8c3ab5f5cd651aa109ed18d3ed3eb643e608
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module tweetNaCl_test /*is aliced*/;
18 import iv.alice;
20 void main () {
21 import iv.tweetNaCl;
22 import std.exception;
23 import std.range;
24 import std.stdio;
26 //private extern(C) int open(const(char)* filename, int flags, ...);
27 randombytes = (ubyte[] dest) @trusted nothrow @nogc {
28 version(Posix) {
29 import core.sys.posix.unistd : close, read, sleep;
30 import core.sys.posix.fcntl : open, O_RDONLY;
31 static int fd = -1;
32 if (fd == -1) {
33 for (;;) {
34 fd = open("/dev/urandom", O_RDONLY);
35 if (fd != -1) break;
36 sleep(1);
39 usize pos = 0;
40 usize len = dest.length;
41 while (len > 0) {
42 auto i = read(fd, cast(void*)(&dest[pos]), (len < 1048576 ? len : 1048576));
43 if (i < 1) {
44 sleep(1);
45 continue;
47 pos += i;
48 len -= i;
50 } else {
51 import std.random : uniform;
52 foreach (ref b; dest) b = cast(ubyte)uniform(0, 256);
56 void dumpArray(T) (T[] arr) {
57 writefln("============================= (%s)", arr.length);
58 for (auto f = 0; f < arr.length; ++f) {
59 if (f && f%16 == 0) writeln();
60 static if (T.sizeof == 1) writef(" 0x%02x", arr[f]);
61 else static if (T.sizeof == 2) writef(" 0x%04x", arr[f]);
62 else static if (T.sizeof == 4) writef(" 0x%08x", arr[f]);
63 else writef(" 0x%08x", arr[f]);
65 writeln();
66 writeln("-----------------------------");
69 string hashToString (const(ubyte)[] hash) {
70 char[] s;
71 s.length = hash.length*2;
72 char toHex(int a) { return cast(char)(a < 10 ? a+'0' : a+'a'-10); }
73 for (int a = 0; a < hash.length; ++a) {
74 s[a*2] = toHex(hash[a]>>4);
75 s[a*2+1] = toHex(hash[a]&0x0f);
77 return assumeUnique(s);
80 static immutable ubyte[crypto_sign_PUBLICKEYBYTES] pk = [0x8f,0x58,0xd8,0xbf,0xb1,0x92,0xd1,0xd7,0xe0,0xc3,0x99,0x8a,0x8d,0x5c,0xb5,0xef,0xfc,0x92,0x2a,0x0d,0x70,0x80,0xe8,0x3b,0xe0,0x27,0xeb,0xf6,0x14,0x95,0xfd,0x16];
81 static immutable ubyte[crypto_sign_SECRETKEYBYTES] sk = [0x78,0x34,0x09,0x59,0x54,0xaa,0xa9,0x2c,0x52,0x3a,0x41,0x3f,0xb6,0xfa,0x6b,0xe1,0xd7,0x0f,0x39,0x30,0x5a,0xe1,0x70,0x12,0x59,0x7d,0x32,0x59,0x9b,0x8b,0x6b,0x2f, 0x8f,0x58,0xd8,0xbf,0xb1,0x92,0xd1,0xd7,0xe0,0xc3,0x99,0x8a,0x8d,0x5c,0xb5,0xef,0xfc,0x92,0x2a,0x0d,0x70,0x80,0xe8,0x3b,0xe0,0x27,0xeb,0xf6,0x14,0x95,0xfd,0x16];
82 static immutable ubyte[5] m = [0x61,0x68,0x6f,0x6a,0x0a];
83 static immutable ubyte[69] sm = [0xce,0x1e,0x15,0xad,0xc3,0x17,0x47,0x15,0x7d,0x44,0x60,0xc1,0x7f,0xb8,0xba,0x45,0xf3,0x6d,0x0b,0xbf,0x51,0xf9,0xbb,0x6b,0xb9,0xa1,0xd2,0x4e,0x44,0x8d,0x9e,0x8c,0x36,0x6f,0x7a,0x8b,0x5e,0x2c,0x69,0xba,0x90,0x2e,0x95,0x46,0x19,0xd8,0xc1,0x8a,0x47,0xc5,0x6e,0x4a,0x28,0x9e,0x81,0x17,0xae,0x90,0x69,0x71,0x7d,0x84,0x6a,0x01,0x61,0x68,0x6f,0x6a,0x0a];
84 ubyte[] smres, t;
86 writeln("crypto_sign");
87 smres = crypto_sign(m, sk);
88 assert(smres.length == sm.length);
89 assert(smres == sm);
91 writeln("crypto_sign_open");
92 t = crypto_sign_open(smres, pk);
93 assert(t !is null);
94 assert(t.length == m.length);
95 assert(t == m);
98 // based on the code by Adam D. Ruppe
99 // This does the preprocessing of input data, fetching one byte at a time of the data until it is empty, then the padding and length at the end
100 template SHARange(T) if (isInputRange!(T)) {
101 struct SHARange {
102 T r;
104 bool empty () { return state == 5; }
106 void popFront () {
107 if (state == 0) {
108 r.popFront;
109 ++length; // FIXME
110 if (r.empty) {
111 state = 1;
112 position = 2;
113 current = 0x80;
115 } else {
116 bool hackforward = false;
117 if (state == 1) {
118 current = 0x0;
119 state = 2;
120 if (((position+length+8)*8)%512 == 8) {
121 --position;
122 hackforward = true;
124 goto proceed;
125 //++position;
126 } else if (state == 2) {
127 proceed:
128 if (!(((position+length+8)*8)%512)) {
129 state = 3;
130 position = 7;
131 length *= 8;
132 if (hackforward) goto proceedmoar;
133 } else {
134 ++position;
136 } else if (state == 3) {
137 proceedmoar:
138 current = (length>>(position*8))&0xff;
139 if (position == 0) state = 4; else --position;
140 } else if (state == 4) {
141 current = 0xff;
142 state = 5;
147 ubyte front () {
148 if (state == 0) return cast(ubyte)r.front;
149 assert(state != 5);
150 //writefln("%x", current);
151 return current;
154 ubyte current;
155 uint position;
156 ulong length;
157 int state = 0; // reading range, reading appended bit, reading padding, reading length, done
162 immutable(ubyte)[] SHA256(T) (T data) if (isInputRange!(T)) {
163 uint[8] h = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
164 static immutable(uint[64]) k = [
165 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
166 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
167 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
168 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
169 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
170 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
171 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
172 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
176 SHARange!(T) range;
177 static if (is(data == SHARange)) range = data; else range.r = data;
180 while(!range.empty) {
181 uint[64] words;
183 for(int a = 0; a < 16; ++a) {
184 for(int b = 3; b >= 0; --b) {
185 words[a] |= cast(uint)(range.front())<<(b*8);
186 range.popFront;
190 uint ror (uint n, int cnt) {
191 return cast(uint)(n>>cnt)|cast(uint)(n<<(32-(cnt)));
194 uint xrot00 (uint reax, int r0, int r1, int r2) {
195 uint rebx = reax, recx = reax;
196 reax = ror(reax, r0);
197 rebx = ror(rebx, r1);
198 recx >>= r2;
199 reax ^= rebx;
200 reax ^= recx;
201 return reax;
204 for(int a = 16; a < 64; ++a) {
205 uint t1 = xrot00(words[a-15], 7, 18, 3);
206 uint t2 = xrot00(words[a-2], 17, 19, 10);
207 words[a] = words[a-16]+t1+words[a-7]+t2;
210 uint A = h[0];
211 uint B = h[1];
212 uint C = h[2];
213 uint D = h[3];
214 uint E = h[4];
215 uint F = h[5];
216 uint G = h[6];
217 uint H = h[7];
219 uint xrot01 (uint reax, int r0, int r1, int r2) {
220 uint rebx = reax, recx = reax;
221 reax = ror(reax, r0);
222 rebx = ror(rebx, r1);
223 recx = ror(recx, r2);
224 reax ^= rebx;
225 reax ^= recx;
226 return reax;
229 for(int i = 0; i < 64; ++i) {
230 uint s0 = xrot01(A, 2, 13, 22);
231 uint maj = (A&B)^(A&C)^(B&C);
232 uint t2 = s0+maj;
233 uint s1 = xrot01(E, 6, 11, 25);
234 uint ch = (E&F)^((~E)&G);
235 uint t1 = H+s1+ch+k[i]+words[i];
237 H = G;
238 G = F;
239 F = E;
240 E = D+t1;
241 D = C;
242 C = B;
243 B = A;
244 A = t1+t2;
247 h[0] += A;
248 h[1] += B;
249 h[2] += C;
250 h[3] += D;
251 h[4] += E;
252 h[5] += F;
253 h[6] += G;
254 h[7] += H;
257 ubyte[] hash;
258 for(int j = 0; j < 8; ++j)
259 for(int i = 3; i >= 0; --i) {
260 hash ~= cast(ubyte)(h[j]>>(i*8))&0xff;
263 return hash.idup;
267 void box () {
268 writeln("box");
270 static immutable ubyte[32] alicesk = [
271 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
272 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
273 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
274 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
277 static immutable ubyte[32] bobpk = [
278 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
279 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
280 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
281 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
284 static immutable ubyte[24] nonce = [
285 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
286 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
287 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
290 // API requires first 32 bytes to be 0
291 static immutable ubyte[163] m = [
292 0, 0, 0, 0, 0, 0, 0, 0
293 , 0, 0, 0, 0, 0, 0, 0, 0
294 , 0, 0, 0, 0, 0, 0, 0, 0
295 , 0, 0, 0, 0, 0, 0, 0, 0
296 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
297 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
298 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
299 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
300 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
301 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
302 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
303 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
304 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
305 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
306 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
307 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
308 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
309 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
310 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
311 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
312 ,0x5e,0x07,0x05
315 ubyte[163] c;
318 static immutable ubyte[163] res = [
319 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
320 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
321 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
322 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
323 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
324 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
325 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
326 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
327 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
328 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
329 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
330 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
331 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
332 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
333 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
334 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
335 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
336 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
337 ,0xe3,0x55,0xa5];
338 /*crypto_box_curve25519xsalsa20poly1305*/crypto_box(c, m, nonce, bobpk, alicesk);
339 for (auto f = 16; f < 163; ++f) assert(c[f] == res[f-16]);
341 box();
343 void box2 () {
344 writeln("box2");
345 static immutable ubyte[32] bobsk = [
346 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
347 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
348 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
349 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
352 static immutable ubyte[32] alicepk = [
353 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
354 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
355 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
356 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
359 static immutable ubyte[24] nonce = [
360 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
361 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
362 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
365 // API requires first 16 bytes to be 0
366 static immutable ubyte[163] c = [
367 0, 0, 0, 0, 0, 0, 0, 0
368 , 0, 0, 0, 0, 0, 0, 0, 0
369 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
370 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
371 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
372 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
373 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
374 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
375 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
376 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
377 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
378 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
379 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
380 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
381 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
382 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
383 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
384 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
385 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
386 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
387 ,0xe3,0x55,0xa5
390 ubyte[163] m;
392 static immutable ubyte[163] res = [
393 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
394 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
395 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
396 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
397 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
398 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
399 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
400 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
401 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
402 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
403 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
404 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
405 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
406 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
407 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
408 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
409 ,0x5e,0x07,0x05
412 assert(/*crypto_box_curve25519xsalsa20poly1305_open*/crypto_box_open(m, c, nonce, alicepk, bobsk));
413 for (auto f = 32; f < 163; ++f) assert(m[f] == res[f-32]);
415 box2();
417 void box7 () {
418 writeln("box7");
419 ubyte[crypto_box_SECRETKEYBYTES] alicesk;
420 ubyte[crypto_box_PUBLICKEYBYTES] alicepk;
421 ubyte[crypto_box_SECRETKEYBYTES] bobsk;
422 ubyte[crypto_box_PUBLICKEYBYTES] bobpk;
423 ubyte[crypto_box_NONCEBYTES] n;
424 ubyte[10000] m, c, m2;
425 for (auto mlen = 0; mlen < 1000 && mlen+crypto_box_ZEROBYTES < m.length; ++mlen) {
426 crypto_box_keypair(alicepk, alicesk);
427 crypto_box_keypair(bobpk, bobsk);
428 randombytes(n[0..crypto_box_NONCEBYTES]);
429 randombytes(m[crypto_box_ZEROBYTES..crypto_box_ZEROBYTES+mlen]);
430 crypto_box(c[0..mlen+crypto_box_ZEROBYTES], m[0..crypto_box_ZEROBYTES+mlen], n, bobpk, alicesk);
431 assert(crypto_box_open(m2[0..mlen+crypto_box_ZEROBYTES], c[0..mlen+crypto_box_ZEROBYTES], n, alicepk, bobsk));
432 for (auto i = 0; i < mlen+crypto_box_ZEROBYTES; ++i) assert(m2[i] == m[i]);
435 version(unittest_full) box7(); // it's slow
437 void box8 () {
438 writeln("box8");
439 ubyte[crypto_box_SECRETKEYBYTES] alicesk;
440 ubyte[crypto_box_PUBLICKEYBYTES] alicepk;
441 ubyte[crypto_box_SECRETKEYBYTES] bobsk;
442 ubyte[crypto_box_PUBLICKEYBYTES] bobpk;
443 ubyte[crypto_box_NONCEBYTES] n;
444 ubyte[10000] m, c, m2;
445 for (auto mlen = 0; mlen < 1000 && mlen+crypto_box_ZEROBYTES < m.length; ++mlen) {
446 crypto_box_keypair(alicepk, alicesk);
447 crypto_box_keypair(bobpk, bobsk);
448 randombytes(n[0..crypto_box_NONCEBYTES]);
449 randombytes(m[crypto_box_ZEROBYTES..crypto_box_ZEROBYTES+mlen]);
450 crypto_box(c[0..crypto_box_ZEROBYTES+mlen], m[0..crypto_box_ZEROBYTES+mlen], n, bobpk, alicesk);
451 int caught = 0;
452 while (caught < 10) {
453 import std.random : uniform;
454 c[uniform(0, mlen+crypto_box_ZEROBYTES)] = cast(ubyte)uniform(0, 256);
455 // we need to turn sanity checks off here to test if `crypto_box_open()` can catch invalid padding
456 if (crypto_box_open!false(m2[0..crypto_box_ZEROBYTES+mlen], c[0..crypto_box_ZEROBYTES+mlen], n, alicepk, bobsk)) {
457 for (auto i = 0; i < mlen+crypto_box_ZEROBYTES; ++i) if (m2[i] != m[i]) assert(0, "oops: box8");
458 } else {
459 ++caught;
462 assert(caught == 10);
465 version(unittest_full) box8(); // it's slow
467 void core1 () {
468 writeln("core1");
469 static immutable ubyte[32] shared_ = [
470 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
471 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
472 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
473 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
476 static immutable ubyte[32] zero = [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];
478 static immutable ubyte[16] c = [
479 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
480 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
483 ubyte[32] firstkey;
485 static immutable ubyte[32] res = [
486 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
487 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
488 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
489 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
492 crypto_core_hsalsa20(firstkey, zero, shared_, c);
493 assert(firstkey == res);
495 core1();
497 void core2 () {
498 writeln("core2");
499 static immutable ubyte[32]firstkey = [
500 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
501 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
502 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
503 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
506 static immutable ubyte[16]nonceprefix = [
507 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
508 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
511 static immutable ubyte[16] c = [
512 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
513 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
516 ubyte[32] secondkey;
518 static immutable ubyte[32] res = [
519 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
520 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
521 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
522 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
525 crypto_core_hsalsa20(secondkey, nonceprefix, firstkey, c);
526 assert(secondkey == res);
528 core2();
530 void core3 () {
531 writeln("core3");
532 static immutable ubyte[32] secondkey = [
533 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
534 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
535 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
536 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
539 static immutable ubyte[8] noncesuffix = [
540 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
543 static immutable ubyte[16] c = [
544 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
545 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
548 static ubyte[16] input = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
550 static ubyte[64*256*256] output;
552 static ubyte[64] h;
554 static immutable ubyte[64] res = [0x2b,0xd8,0xe7,0xdb,0x68,0x77,0x53,0x9e,0x4f,0x2b,0x29,0x5e,0xe4,0x15,0xcd,0x37,0x8a,0xe2,0x14,0xaa,0x3b,0xeb,0x3e,0x08,0xe9,0x11,0xa5,0xbd,0x4a,0x25,0xe6,0xac,0x16,0xca,0x28,0x3c,0x79,0xc3,0x4c,0x08,0xc9,0x9f,0x7b,0xdb,0x56,0x01,0x11,0xe8,0xca,0xc1,0xae,0x65,0xee,0xa0,0x8a,0xc3,0x84,0xd7,0xa5,0x91,0x46,0x1a,0xb6,0xe3];
556 int pos = 0;
557 for (auto i = 0; i < 8; ++i) input[i] = noncesuffix[i];
558 do {
559 do {
560 crypto_core_salsa20(output[pos..$], input, secondkey, c);
561 pos += 64;
562 } while (++input[8]);
563 } while (++input[9]);
564 crypto_hash(h, output);
565 assert(h == res);
567 version(unittest_full) core3(); // it's slow
569 void core4 () {
570 writeln("core4");
571 static immutable ubyte[32] k = [
572 1, 2, 3, 4, 5, 6, 7, 8
573 , 9, 10, 11, 12, 13, 14, 15, 16
574 ,201,202,203,204,205,206,207,208
575 ,209,210,211,212,213,214,215,216
578 static immutable ubyte[16] input = [
579 101,102,103,104,105,106,107,108
580 ,109,110,111,112,113,114,115,116
583 static immutable ubyte[16] c = [
584 101,120,112, 97,110,100, 32, 51
585 , 50, 45, 98,121,116,101, 32,107
588 ubyte[64] output;
590 static immutable ubyte[64] res = [
591 69, 37, 68, 39, 41, 15,107,193
592 ,255,139,122, 6,170,233,217, 98
593 , 89,144,182,106, 21, 51,200, 65
594 ,239, 49,222, 34,215,114, 40,126
595 ,104,197, 7,225,197,153, 31, 2
596 ,102, 78, 76,176, 84,245,246,184
597 ,177,160,133,130, 6, 72,149,119
598 ,192,195,132,236,234,103,246, 74
601 crypto_core_salsa20(output, input, k, c);
602 assert(output == res);
604 core4();
606 void core5 () {
607 writeln("core5");
608 static immutable ubyte[32] k = [
609 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
610 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
611 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
612 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
615 static immutable ubyte[16] input = [
616 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
617 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
620 static immutable ubyte[16] c = [
621 101,120,112, 97,110,100, 32, 51
622 , 50, 45, 98,121,116,101, 32,107
625 ubyte[32] output;
627 static immutable ubyte[32] res = [
628 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
629 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
630 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
631 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
634 crypto_core_hsalsa20(output, input, k, c);
635 assert(output == res);
637 core5();
639 void core6 () {
640 writeln("core6");
641 static immutable ubyte[32] k = [
642 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
643 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
644 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
645 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
648 static immutable ubyte[16] input = [
649 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
650 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
653 static immutable ubyte[16] c = [
654 101,120,112, 97,110,100, 32, 51
655 , 50, 45, 98,121,116,101, 32,107
658 ubyte[64] output;
660 static immutable ubyte[32] res = [
661 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
662 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
663 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
664 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
667 ubyte[32] pp;
668 uint pppos = 0;
670 void print(const(ubyte)[] x, const(ubyte)[] y)
672 uint borrow = 0;
673 for (auto i = 0; i < 4; ++i) {
674 uint xi = x[i];
675 uint yi = y[i];
676 //printf(",0x%02x",255&(xi-yi-borrow));
677 pp[pppos++] = cast(ubyte)(255&(xi-yi-borrow));
678 borrow = (xi < yi+borrow);
682 crypto_core_salsa20(output, input, k, c);
683 print(output, c);
684 print(output[20..$], c[4..$]);
685 print(output[40..$], c[8..$]);
686 print(output[60..$], c[12..$]);
687 print(output[24..$], input);
688 print(output[28..$], input[4..$]);
689 print(output[32..$], input[8..$]);
690 print(output[36..$], input[12..$]);
691 assert(pp == res);
693 core6();
695 void hash () {
696 writeln("hash");
697 static immutable ubyte[8] x = ['t','e','s','t','i','n','g','\n'];
698 static ubyte[crypto_hash_BYTES] h;
699 static immutable ubyte[crypto_hash_BYTES] res = [0x24,0xf9,0x50,0xaa,0xc7,0xb9,0xea,0x9b,0x3c,0xb7,0x28,0x22,0x8a,0x0c,0x82,0xb6,0x7c,0x39,0xe9,0x6b,0x4b,0x34,0x47,0x98,0x87,0x0d,0x5d,0xae,0xe9,0x3e,0x3a,0xe5,0x93,0x1b,0xaa,0xe8,0xc7,0xca,0xcf,0xea,0x4b,0x62,0x94,0x52,0xc3,0x80,0x26,0xa8,0x1d,0x13,0x8b,0xc7,0xaa,0xd1,0xaf,0x3e,0xf7,0xbf,0xd5,0xec,0x64,0x6d,0x6c,0x28];
700 crypto_hash(h, x);
701 //for (auto f = 0; f < crypto_hash_BYTES; ++f) assert(h[f] == res[f]);
702 assert(h == res);
704 hash();
706 void onetimeauth () {
707 writeln("onetimeauth");
708 static immutable ubyte[32] rs = [
709 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
710 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
711 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
712 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
715 static immutable ubyte[131] c = [
716 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
717 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
718 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
719 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
720 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
721 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
722 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
723 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
724 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
725 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
726 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
727 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
728 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
729 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
730 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
731 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
732 ,0xe3,0x55,0xa5
735 ubyte[16] a;
737 static immutable ubyte[16] res = [0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9];
739 /*crypto_onetimeauth_poly1305*/crypto_onetimeauth(a, c, rs);
740 assert(a == res);
742 onetimeauth();
744 void onetimeauth2 () {
745 writeln("onetimeauth2");
746 static immutable ubyte[32] rs = [
747 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
748 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
749 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
750 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
753 static immutable ubyte[131] c = [
754 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
755 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
756 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
757 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
758 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
759 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
760 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
761 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
762 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
763 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
764 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
765 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
766 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
767 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
768 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
769 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
770 ,0xe3,0x55,0xa5
773 static immutable ubyte[16] a = [
774 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
775 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
778 assert(/*crypto_onetimeauth_poly1305_verify*/crypto_onetimeauth_verify(a, c, rs));
780 onetimeauth2();
782 void onetimeauth7 () {
783 writeln("onetimeauth7");
784 static ubyte[32] key;
785 static ubyte[10000] c;
786 static ubyte[16] a;
788 for (auto clen = 0; clen < 10000; ++clen) {
789 //if (clen%512 == 0) { writef("\r%s", clen); stdout.flush(); }
790 randombytes(key);
791 randombytes(c[0..clen]);
792 crypto_onetimeauth(a, c[0..clen], key);
793 assert(crypto_onetimeauth_verify(a, c[0..clen], key));
794 if (clen > 0) {
795 import std.random : uniform;
796 c[uniform(0, clen)] += 1+(uniform(0, 255));
797 assert(!crypto_onetimeauth_verify(a, c[0..clen], key));
798 a[uniform(0, a.length)] += 1+(uniform(0, 255));
799 assert(!crypto_onetimeauth_verify(a, c[0..clen], key));
803 version(unittest_full) onetimeauth7(); // it's slow
805 void scalarmult () {
806 writeln("scalarmult");
807 static immutable ubyte[32] alicesk = [
808 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
809 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
810 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
811 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
814 ubyte[32] alicepk;
816 static immutable ubyte[32] res = [
817 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
818 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
819 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
820 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
823 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(alicepk, alicesk);
824 assert(alicepk == res);
826 scalarmult();
828 void scalarmult2 () {
829 writeln("scalarmult2");
830 static immutable ubyte[32] bobsk = [
831 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
832 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
833 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
834 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
837 ubyte[32] bobpk;
839 static immutable ubyte[32] res = [
840 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
841 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
842 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
843 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
846 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(bobpk, bobsk);
847 assert(bobpk == res);
849 scalarmult2();
851 void scalarmult5 () {
852 writeln("scalarmult5");
853 static immutable ubyte[32] alicesk = [
854 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
855 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
856 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
857 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
860 static immutable ubyte[32] bobpk = [
861 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
862 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
863 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
864 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
867 ubyte[32] k;
869 static immutable ubyte[32] res = [
870 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
871 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
872 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
873 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
876 crypto_scalarmult(k, alicesk, bobpk);
877 assert(k == res);
879 scalarmult5();
881 void scalarmult6 () {
882 writeln("scalarmult6");
883 static immutable ubyte[32] bobsk = [
884 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
885 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
886 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
887 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
890 static immutable ubyte[32] alicepk = [
891 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
892 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
893 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
894 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
897 ubyte[32] k;
899 static immutable ubyte[32] res = [
900 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
901 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
902 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
903 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
906 crypto_scalarmult(k, bobsk, alicepk);
907 assert(k == res);
909 scalarmult6();
911 void secretbox () {
912 writeln("secretbox");
913 static immutable ubyte[32] firstkey = [
914 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
915 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
916 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
917 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
920 static immutable ubyte[24] nonce = [
921 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
922 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
923 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
926 // API requires first 32 bytes to be 0
927 static immutable ubyte[163] m = [
928 0, 0, 0, 0, 0, 0, 0, 0
929 , 0, 0, 0, 0, 0, 0, 0, 0
930 , 0, 0, 0, 0, 0, 0, 0, 0
931 , 0, 0, 0, 0, 0, 0, 0, 0
932 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
933 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
934 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
935 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
936 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
937 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
938 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
939 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
940 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
941 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
942 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
943 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
944 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
945 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
946 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
947 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
948 ,0x5e,0x07,0x05
951 static immutable ubyte[163] res = [
952 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
953 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
954 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
955 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
956 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
957 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
958 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
959 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
960 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
961 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
962 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
963 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
964 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
965 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
966 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
967 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
968 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
969 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
970 ,0xe3,0x55,0xa5
973 ubyte[163] c;
974 crypto_secretbox(c, m, nonce, firstkey);
975 for (auto i = 16; i < 163; ++i) assert(c[i] == res[i-16]);
977 secretbox();
979 void secretbox2 () {
980 writeln("secretbox2");
981 static immutable ubyte[32] firstkey = [
982 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
983 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
984 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
985 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
988 static immutable ubyte[24] nonce = [
989 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
990 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
991 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
994 // API requires first 16 bytes to be 0
995 static immutable ubyte[163] c = [
996 0, 0, 0, 0, 0, 0, 0, 0
997 , 0, 0, 0, 0, 0, 0, 0, 0
998 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
999 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1000 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1001 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1002 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1003 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1004 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1005 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1006 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1007 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1008 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1009 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1010 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1011 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1012 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1013 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1014 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1015 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1016 ,0xe3,0x55,0xa5
1019 static immutable ubyte[163] res = [
1020 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1021 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1022 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1023 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1024 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1025 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1026 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1027 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1028 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1029 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1030 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1031 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1032 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1033 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1034 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1035 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1036 ,0x5e,0x07,0x05
1039 ubyte[163] m;
1041 assert(crypto_secretbox_open(m, c, nonce, firstkey));
1042 for (auto i = 32; i < 163; ++i) assert(m[i] == res[i-32]);
1044 secretbox2();
1046 void secretbox7 () {
1047 writeln("secretbox7");
1048 static ubyte[crypto_secretbox_KEYBYTES] k;
1049 static ubyte[crypto_secretbox_NONCEBYTES] n;
1050 static ubyte[10000] m, c, m2;
1051 for (auto mlen = 0; mlen < 1000 && mlen+crypto_secretbox_ZEROBYTES < m.length; ++mlen) {
1052 randombytes(k[0..crypto_secretbox_KEYBYTES]);
1053 randombytes(n[0..crypto_secretbox_NONCEBYTES]);
1054 randombytes(m[crypto_secretbox_ZEROBYTES..crypto_secretbox_ZEROBYTES+mlen]);
1055 crypto_secretbox(c[0..mlen+crypto_secretbox_ZEROBYTES], m[0..crypto_secretbox_ZEROBYTES+mlen], n, k);
1056 assert(crypto_secretbox_open(m2[0..mlen+crypto_secretbox_ZEROBYTES], c[0..mlen+crypto_secretbox_ZEROBYTES], n, k));
1057 for (auto i = 0; i < mlen+crypto_secretbox_ZEROBYTES; ++i) assert(m2[i] == m[i]);
1060 secretbox7();
1062 void secretbox8 () {
1063 writeln("secretbox8");
1064 static ubyte[crypto_secretbox_KEYBYTES] k;
1065 static ubyte[crypto_secretbox_NONCEBYTES] n;
1066 static ubyte[10000] m, c, m2;
1067 for (auto mlen = 0; mlen < 1000 && mlen+crypto_secretbox_ZEROBYTES < m.length; ++mlen) {
1068 randombytes(k[0..crypto_secretbox_KEYBYTES]);
1069 randombytes(n[0..crypto_secretbox_NONCEBYTES]);
1070 randombytes(m[crypto_secretbox_ZEROBYTES..crypto_secretbox_ZEROBYTES+mlen]);
1071 crypto_secretbox(c[0..mlen+crypto_secretbox_ZEROBYTES], m, n, k);
1072 auto caught = 0;
1073 while (caught < 10) {
1074 import std.random : uniform;
1075 c[uniform(0, mlen+crypto_secretbox_ZEROBYTES)] = cast(ubyte)uniform(0, 256);
1076 if (crypto_secretbox_open(m2[0..mlen+crypto_secretbox_ZEROBYTES], c, n, k)) {
1077 for (auto i = 0; i < mlen+crypto_secretbox_ZEROBYTES; ++i) assert(m2[i] == m[i]);
1079 ++caught;
1081 assert(caught == 10);
1084 version(unittest_full) secretbox8(); // it's slow
1086 void stream () {
1087 writeln("stream");
1088 static immutable ubyte[32] firstkey = [
1089 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1090 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1091 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1092 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1095 static immutable ubyte[24] nonce = [
1096 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1097 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1098 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1101 static ubyte[4194304] output;
1103 //ubyte h[32];
1104 //static immutable ubyte[32] res = [0x66,0x2b,0x9d,0x0e,0x34,0x63,0x02,0x91,0x56,0x06,0x9b,0x12,0xf9,0x18,0x69,0x1a,0x98,0xf7,0xdf,0xb2,0xca,0x03,0x93,0xc9,0x6b,0xbf,0xc6,0xb1,0xfb,0xd6,0x30,0xa2];
1106 crypto_stream(output, nonce, firstkey);
1107 //crypto_hash_sha256(h, output, sizeof output);
1108 assert(hashToString(SHA256(output[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
1110 stream();
1112 void stream2 () {
1113 writeln("stream2");
1114 static immutable ubyte[32] secondkey = [
1115 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1116 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1117 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1118 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1121 static immutable ubyte[8] noncesuffix = [
1122 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1125 static ubyte[4194304] output;
1127 crypto_stream_salsa20(output,noncesuffix,secondkey);
1128 assert(hashToString(SHA256(output[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
1130 stream2();
1132 void stream3 () {
1133 writeln("stream3");
1134 static immutable ubyte[32] firstkey = [
1135 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1136 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1137 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1138 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1141 static immutable ubyte[24] nonce = [
1142 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1143 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1144 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1147 ubyte[32] rs;
1149 static immutable ubyte[32] res = [
1150 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
1151 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
1152 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
1153 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
1156 crypto_stream/*_xsalsa20*/(rs, nonce, firstkey);
1157 assert(rs == res);
1159 stream3();
1161 void stream4 () {
1162 writeln("stream4");
1163 static immutable ubyte[32] firstkey = [
1164 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1165 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1166 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1167 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1170 static immutable ubyte[24] nonce = [
1171 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1172 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1173 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1176 static immutable ubyte[163] m = [
1177 0, 0, 0, 0, 0, 0, 0, 0
1178 , 0, 0, 0, 0, 0, 0, 0, 0
1179 , 0, 0, 0, 0, 0, 0, 0, 0
1180 , 0, 0, 0, 0, 0, 0, 0, 0
1181 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1182 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1183 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1184 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1185 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1186 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1187 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1188 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1189 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1190 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1191 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1192 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1193 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1194 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1195 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1196 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1197 ,0x5e,0x07,0x05
1200 ubyte[163] c;
1202 static immutable ubyte[163] res = [
1203 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1204 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1205 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1206 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1207 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1208 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1209 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1210 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1211 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1212 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1213 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1214 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1215 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1216 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1217 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1218 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1219 ,0xe3,0x55,0xa5
1222 /*crypto_stream_xsalsa20_xor*/crypto_stream_xor(c, m, nonce, firstkey);
1223 for (auto i = 32; i < 163; ++i) assert(c[i] == res[i-32]);
1225 stream4();