2 * Contributors (alphabetical order)
3 * Daniel J. Bernstein, University of Illinois at Chicago and Technische Universiteit Eindhoven
4 * Wesley Janssen, Radboud Universiteit Nijmegen
5 * Tanja Lange, Technische Universiteit Eindhoven
6 * Peter Schwabe, Radboud Universiteit Nijmegen
8 * Ported by Ketmar // Invisible Vector ( ketmar@ketmar.no-ip.org )
10 * Public Domain (or WTFPL).
14 // define tweetnacl_enable_inlining to speed up tweetNaCl on GDC
16 version(tweetnacl_enable_inlining
) version=tweetnacl_enable_inlining_on_
;
17 else version=tweetnacl_enable_inlining_off_
;
19 version=tweetnacl_enable_inlining_off_
;
22 version(tweetnacl_enable_inlining_off_
) {
23 private struct tweetNaCl_gdc_Attribute(A
...) {
26 auto tweetNaCl_gdc_attribute(A
...)(A args
) if(A
.length
> 0 && is(A
[0] == string
)) {
27 return tweetNaCl_gdc_Attribute
!A(args
);
31 alias tweetNaCl_gdc_attribute
= attribute
;
36 crypto_auth_BYTES
= 32,
37 crypto_auth_KEYBYTES
= 32,
39 crypto_box_PUBLICKEYBYTES
= 32,
40 crypto_box_SECRETKEYBYTES
= 32,
41 crypto_box_BEFORENMBYTES
= 32,
42 crypto_box_NONCEBYTES
= 24,
43 crypto_box_ZEROBYTES
= 32,
44 crypto_box_BOXZEROBYTES
= 16,
46 crypto_core_salsa20_OUTPUTBYTES
= 64,
47 crypto_core_salsa20_INPUTBYTES
= 16,
48 crypto_core_salsa20_KEYBYTES
= 32,
49 crypto_core_salsa20_CONSTBYTES
= 16,
51 crypto_core_hsalsa20_OUTPUTBYTES
= 32,
52 crypto_core_hsalsa20_INPUTBYTES
= 16,
53 crypto_core_hsalsa20_KEYBYTES
= 32,
54 crypto_core_hsalsa20_CONSTBYTES
= 16,
56 crypto_hash_BYTES
= 64,
58 crypto_onetimeauth_BYTES
= 16,
59 crypto_onetimeauth_KEYBYTES
= 32,
61 crypto_scalarmult_BYTES
= 32,
62 crypto_scalarmult_SCALARBYTES
= 32,
64 crypto_secretbox_KEYBYTES
= 32,
65 crypto_secretbox_NONCEBYTES
= 24,
66 crypto_secretbox_ZEROBYTES
= 32,
67 crypto_secretbox_BOXZEROBYTES
= 16,
69 crypto_sign_BYTES
= 64,
70 crypto_sign_PUBLICKEYBYTES
= 32,
71 crypto_sign_SECRETKEYBYTES
= 64,
73 crypto_stream_xsalsa20_KEYBYTES
= 32,
74 crypto_stream_xsalsa20_NONCEBYTES
= 24,
76 crypto_stream_salsa20_KEYBYTES
= 32,
77 crypto_stream_salsa20_NONCEBYTES
= 8,
79 crypto_stream_KEYBYTES
= 32,
80 crypto_stream_NONCEBYTES
= 24,
82 crypto_verify_16_BYTES
= 16,
83 crypto_verify_32_BYTES
= 32,
87 /// set this callback to good (cryptograpic strong) random bytes generator
88 /// you can use /dev/urandom as prng
89 void function (ubyte[] dest
, size_t len
) randombytes
= null;
92 private static __gshared
immutable ubyte[16] _0
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
93 private static __gshared
immutable ubyte[32] _9
= [9,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];
95 private static __gshared
immutable long[16]
96 gf0
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
97 gf1
= [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
98 _121665
= [0xDB41,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
99 D
= [0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203],
100 D2
=[0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406],
101 X
= [0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169],
102 Y
= [0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666],
103 I
= [0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83];
105 private @tweetNaCl_gdc_attribute("forceinline") uint ld32() (const(ubyte)[] x
) @safe nothrow
107 assert(x
.length
>= 4);
116 private @tweetNaCl_gdc_attribute("forceinline") ulong dl64() (const(ubyte)[] x
) @safe nothrow
118 assert(x
.length
>= 8);
131 private @tweetNaCl_gdc_attribute("forceinline") void st32() (ubyte[] x
, uint u
) @safe nothrow
133 assert(x
.length
>= 4);
142 private @tweetNaCl_gdc_attribute("forceinline") void ts64() (ubyte[] x
, ulong u
) @safe nothrow
144 assert(x
.length
>= 8);
157 private @tweetNaCl_gdc_attribute("forceinline") bool vn() (const(ubyte)[] x
, const(ubyte)[] y
) @safe nothrow
159 assert(x
.length
>= y
.length
);
163 foreach (immutable i
, immutable v
; x
) d |
= v^y
[i
];
164 return (1&((d
-1)>>8)) != 0;
168 * The crypto_verify_16() function checks that strings 'x' and 'y' has same content.
171 * x = first string, slice length must be at least crypto_verify_16_BYTES, extra ignored
172 * y = second string, slice length must be at least crypto_verify_16_BYTES, extra ignored
177 @tweetNaCl_gdc_attribute("forceinline") bool crypto_verify_16() (const(ubyte)[] x
, const(ubyte)[] y
) @safe nothrow
179 assert(x
.length
>= 16 && y
.length
>= 16);
182 return vn(x
[0..16], y
[0..16]);
186 * The crypto_verify_32() function checks that strings 'x' and 'y' has same content.
189 * x = first string, slice length must be at least crypto_verify_32_BYTES, extra ignored
190 * y = second string, slice length must be at least crypto_verify_32_BYTES, extra ignored
195 @tweetNaCl_gdc_attribute("forceinline") bool crypto_verify_32() (const(ubyte)[] x
, const(ubyte)[] y
) @safe nothrow
197 assert(x
.length
>= 32 && y
.length
>= 32);
200 return vn(x
[0..32], y
[0..32]);
204 private void salsa_core(alias type
) (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
) @safe nothrow
205 if (type
== "salsa" || type
== "hsalsa") // constraint
208 assert(mixin(`output.length >= crypto_core_`~type
~`20_OUTPUTBYTES`));
209 assert(mixin(`input.length >= crypto_core_`~type
~`20_INPUTBYTES`));
210 assert(mixin(`key.length >= crypto_core_`~type
~`20_KEYBYTES`));
211 assert(mixin(`constant.length >= crypto_core_`~type
~`20_CONSTBYTES`));
214 static @tweetNaCl_gdc_attribute("forceinline") uint ROTL32() (uint x
, int c
) @safe nothrow pure { return (x
<<c
)|
((x
&0xffffffff)>>(32-c
)); }
216 uint[16] w
= void, x
= void, y
= void;
220 x
[5*i
] = ld32(constant
[4*i
..$]);
221 x
[1+i
] = ld32(key
[4*i
..$]);
222 x
[6+i
] = ld32(input
[4*i
..$]);
223 x
[11+i
] = ld32(key
[16+4*i
..$]);
230 foreach (m
; 0..4) t
[m
] = x
[(5*j
+4*m
)%16];
231 t
[1] ^
= ROTL32(t
[0]+t
[3], 7);
232 t
[2] ^
= ROTL32(t
[1]+t
[0], 9);
233 t
[3] ^
= ROTL32(t
[2]+t
[1], 13);
234 t
[0] ^
= ROTL32(t
[3]+t
[2], 18);
235 for (auto m
= 0; m
< 4; ++m
) w
[4*j
+(j
+m
)%4] = t
[m
];
237 for (auto m
= 0; m
< 16; ++m
) x
[m
] = w
[m
];
240 static if (type
== "hsalsa") {
241 for (auto i
= 0; i
< 16; ++i
) x
[i
] += y
[i
];
242 for (auto i
= 0; i
< 4; ++i
) {
243 x
[5*i
] -= ld32(constant
[4*i
..$]);
244 x
[6+i
] -= ld32(input
[4*i
..$]);
246 for (auto i
= 0; i
< 4; ++i
) {
247 st32(output
[4*i
..$], x
[5*i
]);
248 st32(output
[16+4*i
..$], x
[6+i
]);
251 for (auto i
= 0; i
< 16; ++i
) st32(output
[4*i
..$], x
[i
]+y
[i
]);
255 @tweetNaCl_gdc_attribute("forceinline") void crypto_core_salsa20() (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
)
257 salsa_core
!"salsa"(output
, input
, key
, constant
);
260 @tweetNaCl_gdc_attribute("forceinline") void crypto_core_hsalsa20() (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
)
262 salsa_core
!"hsalsa"(output
, input
, key
, constant
);
265 private static __gshared
immutable immutable(ubyte)[] sigma
= cast(immutable(ubyte)[])"expand 32-byte k";
268 * The crypto_stream_salsa20_xor() function encrypts a message 'msg' using a secret key 'key'
269 * and a nonce 'nonce'. The crypto_stream_salsa20_xor() function returns the ciphertext 'output'.
272 * output = resulting ciphertext
278 * ciphertext in 'output'
280 void crypto_stream_salsa20_xor (ubyte[] output
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @trusted nothrow
282 assert(nonce
.length
== crypto_stream_salsa20_NONCEBYTES
);
283 assert(key
.length
== crypto_stream_salsa20_KEYBYTES
);
285 assert(msg
.length
== 0 || output
.length
<= msg
.length
);
291 uint cpos
= 0, mpos
= 0;
292 size_t b
= output
.length
;
295 z
[0..8] = nonce
[0..8];
297 crypto_core_salsa20(x
, z
, key
, sigma
);
299 foreach (v
; x
) output
[cpos
++] = msg
[mpos
++]^v
;
301 output
[cpos
..cpos
+64] = x
[];
313 crypto_core_salsa20(x
, z
, key
, sigma
);
315 foreach (i
; 0..b
) output
[cpos
++] = msg
[mpos
++]^x
[i
];
317 output
[cpos
..cpos
+b
] = x
[0..b
];
323 * The crypto_stream_salsa20() function produces a stream 'c'
324 * as a function of a secret key 'key' and a nonce 'nonce'.
327 * c = resulting stream
334 void crypto_stream_salsa20() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
336 assert(nonce
.length
== crypto_stream_salsa20_NONCEBYTES
);
337 assert(key
.length
== crypto_stream_salsa20_KEYBYTES
);
340 crypto_stream_salsa20_xor(c
, null, nonce
, key
);
344 * The crypto_stream() function produces a stream 'c'
345 * as a function of a secret key 'key' and a nonce 'nonce'.
355 void crypto_stream() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
358 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
359 assert(key
.length
== crypto_stream_KEYBYTES
);
363 crypto_core_hsalsa20(s
, nonce
, key
, sigma
);
364 crypto_stream_salsa20(c
, nonce
[16..$], s
);
368 * The crypto_stream_xor() function encrypts a message 'msg' using a secret key 'key'
369 * and a nonce 'nonce'. The crypto_stream_xor() function returns the ciphertext 'c'.
379 void crypto_stream_xor() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
382 assert(msg
.length
>= c
.length
);
383 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
384 assert(key
.length
== crypto_stream_KEYBYTES
);
388 crypto_core_hsalsa20(s
, nonce
, key
, sigma
);
389 crypto_stream_salsa20_xor(c
, msg
, nonce
[16..$], s
);
392 private @tweetNaCl_gdc_attribute("forceinline") void add1305() (uint[] h
, const(uint)[] c
) @safe nothrow {
401 private static __gshared
immutable uint[17] minusp
= [5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252];
404 * The crypto_onetimeauth() function authenticates a message 'msg'
405 * using a secret key 'key'. The function returns an authenticator 'output'.
408 * output = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
410 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
413 * authenticator in 'output'
415 void crypto_onetimeauth() (ubyte[] output
, const(ubyte)[] msg
, const(ubyte)[] key
) @safe nothrow
417 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
418 assert(output
.length
>= crypto_onetimeauth_BYTES
);
422 uint[17] x
= void, r
= void, h
= void, c
= void, g
= void;
424 size_t n
= msg
.length
;
426 for (j
= 0; j
< 17; ++j
) r
[j
] = h
[j
] = 0;
427 for (j
= 0; j
< 16; ++j
) r
[j
] = key
[j
];
437 for (j
= 0; j
< 17; ++j
) c
[j
] = 0;
438 for (j
= 0; j
< 16 && j
< n
; ++j
) c
[j
] = msg
[mpos
+j
];
443 for (i
= 0; i
< 17; ++i
) {
445 for (j
= 0; j
< 17; ++j
) x
[i
] += h
[j
]*(j
<= i ? r
[i
-j
] : 320*r
[i
+17-j
]);
447 for (i
= 0; i
< 17; ++i
) h
[i
] = x
[i
];
449 for (j
= 0; j
< 16; ++j
) {
457 for (j
= 0; j
< 16; ++j
) {
462 u
+= h
[16]; h
[16] = u
;
465 for (j
= 0; j
< 17; ++j
) g
[j
] = h
[j
];
468 for (j
= 0; j
< 17; ++j
) h
[j
] ^
= s
&(g
[j
]^h
[j
]);
470 for (j
= 0; j
< 16; ++j
) c
[j
] = key
[j
+16];
473 for (j
= 0; j
< 16; ++j
) output
[j
] = cast(ubyte)(h
[j
]&0xff);
477 * The crypto_onetimeauth_verify() function checks that
478 * 'h' is a correct authenticator of a message 'msg' under the secret key 'key'.
481 * h = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
483 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
488 bool crypto_onetimeauth_verify() (const(ubyte)[] h
, const(ubyte)[] msg
, const(ubyte)[] key
) @safe nothrow
490 assert(h
.length
>= crypto_onetimeauth_BYTES
);
491 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
495 crypto_onetimeauth(x
, msg
, key
);
496 return crypto_verify_16(h
, x
);
500 * The crypto_secretbox() function encrypts and authenticates
501 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
502 * The crypto_secretbox() function returns the resulting ciphertext 'c'.
505 * c = resulting cyphertext
510 * success flag and cyphertext in 'c'
512 bool crypto_secretbox() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
514 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
515 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
518 //c.length = msg.length+crypto_secretbox_ZEROBYTES;
519 if (c
is null || c
.length
< 32) return false;
520 //assert(msg.length >= c.length);
521 crypto_stream_xor(c
, msg
, nonce
, key
);
522 crypto_onetimeauth(c
[16..$], c
[32..$], c
);
523 for (auto i
= 0; i
< 16; ++i
) c
[i
] = 0;
524 //return c[crypto_secretbox_BOXZEROBYTES..$];
529 * The crypto_secretbox_open() function verifies and decrypts
530 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
531 * The crypto_secretbox_open() function returns the resulting plaintext 'output'.
534 * output = resulting message
540 * success flag and message in 'output'
542 bool crypto_secretbox_open() (ubyte[] output
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
544 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
545 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
549 if (output
is null || output
.length
< 32) return false;
550 crypto_stream(x
, nonce
, key
);
551 if (!crypto_onetimeauth_verify(c
[16..$], c
[32../*$*/32+(output
.length
-32)], x
)) return false;
552 crypto_stream_xor(output
, c
, nonce
, key
);
553 for (auto i
= 0; i
< 32; ++i
) output
[i
] = 0;
557 private @tweetNaCl_gdc_attribute("forceinline") void set25519() (long[/*16*/] r
, const(long)[/*16*/] a
) @safe nothrow {
558 for (auto i
= 0; i
< 16; ++i
) r
[i
] = a
[i
];
561 private @tweetNaCl_gdc_attribute("forceinline") void car25519() (long[] o
) @safe nothrow {
563 for (auto i
= 0; i
< 16; ++i
) {
566 o
[(i
+1)*(i
<15)]+=c
-1+37*(c
-1)*(i
==15);
571 private @tweetNaCl_gdc_attribute("forceinline") void sel25519() (long[] p
,long[] q
, int b
) @safe nothrow {
573 for (auto i
= 0; i
< 16; ++i
) {
580 private @tweetNaCl_gdc_attribute("forceinline") void pack25519() (ubyte[] o
, const(long)[] n
) @safe nothrow {
583 for (auto i
= 0; i
< 16; ++i
) t
[i
] = n
[i
];
587 for (auto j
= 0; j
< 2; ++j
) {
589 for(auto i
= 1; i
< 15; ++i
) {
590 m
[i
] = t
[i
]-0xffff-((m
[i
-1]>>16)&1);
593 m
[15] = t
[15]-0x7fff-((m
[14]>>16)&1);
598 for (auto i
= 0; i
< 16; ++i
) {
600 o
[2*i
+1] = (t
[i
]>>8)&0xff;
604 private @tweetNaCl_gdc_attribute("forceinline") bool neq25519() (const(long)[] a
, const(long)[] b
) @safe nothrow {
605 ubyte[32] c
= void, d
= void;
608 return crypto_verify_32(c
, d
);
611 private @tweetNaCl_gdc_attribute("forceinline") ubyte par25519() (const(long)[] a
) @safe nothrow {
617 private @tweetNaCl_gdc_attribute("forceinline") void unpack25519() (long[] o
, const(ubyte)[] n
) @safe nothrow {
618 for (auto i
= 0; i
< 16; ++i
) o
[i
] = n
[2*i
]+(cast(long)n
[2*i
+1]<<8);
622 private @tweetNaCl_gdc_attribute("forceinline") void A() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
623 for (auto i
= 0; i
< 16; ++i
) o
[i
] = a
[i
]+b
[i
];
626 private @tweetNaCl_gdc_attribute("forceinline") void Z() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
627 for (auto i
= 0; i
< 16; ++i
) o
[i
] = a
[i
]-b
[i
];
630 private @tweetNaCl_gdc_attribute("forceinline") void M() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
632 for (auto i
= 0; i
< 31; ++i
) t
[i
] = 0;
633 for (auto i
= 0; i
< 16; ++i
) for (auto j
= 0; j
< 16; ++j
) t
[i
+j
]+=a
[i
]*b
[j
];
634 for (auto i
= 0; i
< 15; ++i
) t
[i
]+=38*t
[i
+16];
635 for (auto i
= 0; i
< 16; ++i
) o
[i
] = t
[i
];
640 private @tweetNaCl_gdc_attribute("forceinline") void S() (long[] o
, const(long)[] a
) @safe nothrow {
644 private @tweetNaCl_gdc_attribute("forceinline") void inv25519() (long[] o
, const(long)[] i
) @safe nothrow {
646 for (auto a
= 0; a
< 16; ++a
) c
[a
] = i
[a
];
647 for(auto a
= 253; a
>= 0; --a
) {
649 if (a
!=2 && a
!= 4) M(c
, c
, i
);
651 for (auto a
= 0; a
< 16; ++a
) o
[a
] = c
[a
];
654 private @tweetNaCl_gdc_attribute("forceinline") void pow2523() (long[] o
, const(long)[] i
) @safe nothrow {
656 for (auto a
= 0; a
< 16; ++a
) c
[a
] = i
[a
];
657 for(auto a
= 250; a
>= 0; --a
) {
659 if (a
!= 1) M(c
, c
, i
);
661 for (auto a
= 0; a
< 16; ++a
) o
[a
] = c
[a
];
665 * This function multiplies a group element 'p' by an integer 'n'.
672 * resulting group element 'q' of length crypto_scalarmult_BYTES.
674 private void crypto_scalarmult (ubyte[] q
, const(ubyte)[] n
, const(ubyte)[] p
) @safe nothrow {
675 assert(q
.length
== crypto_scalarmult_BYTES
);
676 assert(n
.length
== crypto_scalarmult_BYTES
);
677 assert(p
.length
== crypto_scalarmult_BYTES
);
682 long[16] a
, b
, c
, d
, e
, f
;
683 for (i
= 0; i
< 31; ++i
) z
[i
] = n
[i
];
684 z
[31] = (n
[31]&127)|
64;
687 for (i
= 0; i
< 16; ++i
) {
689 d
[i
] = a
[i
] = c
[i
] = 0;
692 for (i
= 254; i
>= 0; --i
) {
693 r
= (z
[i
>>3]>>(i
&7))&1;
694 sel25519(a
, b
, cast(int)r
);
695 sel25519(c
, d
, cast(int)r
);
714 sel25519(a
, b
, cast(int)r
);
715 sel25519(c
, d
, cast(int)r
);
717 for (i
= 0; i
< 16; ++i
) {
723 inv25519(x
[32..$], x
[32..$]);
724 M(x
[16..$], x
[16..$], x
[32..$]);
725 pack25519(q
, x
[16..$]);
729 * The crypto_scalarmult_base() function computes
730 * the scalar product of a standard group element and an integer 'n'.
736 * resulting group element 'q' of length crypto_scalarmult_BYTES.
738 private void crypto_scalarmult_base() (ubyte[] q
, const(ubyte)[] n
) @safe nothrow {
739 assert(q
.length
== crypto_scalarmult_BYTES
);
740 assert(n
.length
== crypto_scalarmult_SCALARBYTES
);
741 crypto_scalarmult(q
, n
, _9
);
745 * The crypto_box_keypair() function randomly generates a secret key and
746 * a corresponding public key.
749 * pk = slice to put generated public key into
750 * sk = slice to put generated secret key into
755 void crypto_box_keypair() (ubyte[] pk
, ubyte[] sk
)
757 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
758 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
762 crypto_scalarmult_base(pk
, sk
);
766 * Function crypto_box_beforenm() computes a shared secret 's' from
767 * public key 'pk' and secret key 'sk'.
770 * skey = slice to put secret into
777 void crypto_box_beforenm() (ubyte[] skey
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
779 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
780 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
781 assert(skey
.length
>= crypto_box_BEFORENMBYTES
);
785 crypto_scalarmult(s
, sk
, pk
);
786 crypto_core_hsalsa20(skey
, _0
, s
, sigma
);
790 * The crypto_box_afternm() function encrypts and authenticates
791 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
792 * The crypto_box_afternm() function returns the resulting ciphertext 'c'.
795 * c = resulting cyphertext
801 * success flag and cyphertext in 'c'
803 bool crypto_box_afternm() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
805 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
806 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
809 return crypto_secretbox(c
, msg
, nonce
, key
);
813 * The crypto_box_open_afternm() function verifies and decrypts
814 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
815 * The crypto_box_open_afternm() function returns the resulting message 'msg'.
818 * msg = resulting message
824 * success flag and resulting message in 'msg'
826 bool crypto_box_open_afternm() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
828 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
829 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
832 return crypto_secretbox_open(msg
, c
, nonce
, key
);
836 * The crypto_box() function encrypts and authenticates a message 'msg'
837 * using the sender's secret key 'sk', the receiver's public key 'pk',
838 * and a nonce 'nonce'. The crypto_box() function returns the resulting ciphertext 'c'.
841 * c = resulting cyphertext
844 * pk = receiver's public key
845 * sk = sender's secret key
848 * success flag and cyphertext in 'c'
850 bool crypto_box() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
852 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
853 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
854 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
858 crypto_box_beforenm(k
, pk
, sk
);
859 return crypto_box_afternm(c
, msg
, nonce
, k
);
863 * The crypto_box_open() function verifies and decrypts
864 * a ciphertext 'c' using the receiver's secret key 'sk',
865 * the sender's public key 'pk', and a nonce 'nonce'.
866 * The crypto_box_open() function returns the resulting message 'msg'.
869 * msg = resulting message
872 * pk = receiver's public key
873 * sk = sender's secret key
876 * success flag and message in 'msg'
878 bool crypto_box_open() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
880 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
881 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
882 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
886 crypto_box_beforenm(k
, pk
, sk
);
887 return crypto_box_open_afternm(msg
, c
, nonce
, k
);
890 private @tweetNaCl_gdc_attribute("forceinline") ulong R() (ulong x
, int c
) @safe nothrow pure { return (x
>>c
)|
(x
<<(64-c
)); }
891 private @tweetNaCl_gdc_attribute("forceinline") ulong Ch() (ulong x
, ulong y
, ulong z
) @safe nothrow pure { return (x
&y
)^
(~x
&z
); }
892 private @tweetNaCl_gdc_attribute("forceinline") ulong Maj() (ulong x
, ulong y
, ulong z
) @safe nothrow pure { return (x
&y
)^
(x
&z
)^
(y
&z
); }
893 private @tweetNaCl_gdc_attribute("forceinline") ulong Sigma0() (ulong x
) @safe nothrow pure { return R(x
, 28)^
R(x
, 34)^
R(x
, 39); }
894 private @tweetNaCl_gdc_attribute("forceinline") ulong Sigma1() (ulong x
) @safe nothrow pure { return R(x
, 14)^
R(x
, 18)^
R(x
, 41); }
895 private @tweetNaCl_gdc_attribute("forceinline") ulong sigma0() (ulong x
) @safe nothrow pure { return R(x
, 1)^
R(x
, 8)^
(x
>>7); }
896 private @tweetNaCl_gdc_attribute("forceinline") ulong sigma1() (ulong x
) @safe nothrow pure { return R(x
, 19)^
R(x
, 61)^
(x
>>6); }
898 private static __gshared
immutable ulong[80] K
= [
899 0x428a2f98d728ae22UL
, 0x7137449123ef65cdUL
, 0xb5c0fbcfec4d3b2fUL
, 0xe9b5dba58189dbbcUL
,
900 0x3956c25bf348b538UL
, 0x59f111f1b605d019UL
, 0x923f82a4af194f9bUL
, 0xab1c5ed5da6d8118UL
,
901 0xd807aa98a3030242UL
, 0x12835b0145706fbeUL
, 0x243185be4ee4b28cUL
, 0x550c7dc3d5ffb4e2UL
,
902 0x72be5d74f27b896fUL
, 0x80deb1fe3b1696b1UL
, 0x9bdc06a725c71235UL
, 0xc19bf174cf692694UL
,
903 0xe49b69c19ef14ad2UL
, 0xefbe4786384f25e3UL
, 0x0fc19dc68b8cd5b5UL
, 0x240ca1cc77ac9c65UL
,
904 0x2de92c6f592b0275UL
, 0x4a7484aa6ea6e483UL
, 0x5cb0a9dcbd41fbd4UL
, 0x76f988da831153b5UL
,
905 0x983e5152ee66dfabUL
, 0xa831c66d2db43210UL
, 0xb00327c898fb213fUL
, 0xbf597fc7beef0ee4UL
,
906 0xc6e00bf33da88fc2UL
, 0xd5a79147930aa725UL
, 0x06ca6351e003826fUL
, 0x142929670a0e6e70UL
,
907 0x27b70a8546d22ffcUL
, 0x2e1b21385c26c926UL
, 0x4d2c6dfc5ac42aedUL
, 0x53380d139d95b3dfUL
,
908 0x650a73548baf63deUL
, 0x766a0abb3c77b2a8UL
, 0x81c2c92e47edaee6UL
, 0x92722c851482353bUL
,
909 0xa2bfe8a14cf10364UL
, 0xa81a664bbc423001UL
, 0xc24b8b70d0f89791UL
, 0xc76c51a30654be30UL
,
910 0xd192e819d6ef5218UL
, 0xd69906245565a910UL
, 0xf40e35855771202aUL
, 0x106aa07032bbd1b8UL
,
911 0x19a4c116b8d2d0c8UL
, 0x1e376c085141ab53UL
, 0x2748774cdf8eeb99UL
, 0x34b0bcb5e19b48a8UL
,
912 0x391c0cb3c5c95a63UL
, 0x4ed8aa4ae3418acbUL
, 0x5b9cca4f7763e373UL
, 0x682e6ff3d6b2b8a3UL
,
913 0x748f82ee5defb2fcUL
, 0x78a5636f43172f60UL
, 0x84c87814a1f0ab72UL
, 0x8cc702081a6439ecUL
,
914 0x90befffa23631e28UL
, 0xa4506cebde82bde9UL
, 0xbef9a3f7b2c67915UL
, 0xc67178f2e372532bUL
,
915 0xca273eceea26619cUL
, 0xd186b8c721c0c207UL
, 0xeada7dd6cde0eb1eUL
, 0xf57d4f7fee6ed178UL
,
916 0x06f067aa72176fbaUL
, 0x0a637dc5a2c898a6UL
, 0x113f9804bef90daeUL
, 0x1b710b35131c471bUL
,
917 0x28db77f523047d84UL
, 0x32caab7b40c72493UL
, 0x3c9ebe0a15c9bebcUL
, 0x431d67c49c100d4cUL
,
918 0x4cc5d4becb3e42b6UL
, 0x597f299cfc657e2aUL
, 0x5fcb6fab3ad6faecUL
, 0x6c44198c4a475817UL
921 private void crypto_hashblocks (ubyte[] x
, const(ubyte)[] m
, ulong n
) @safe nothrow {
922 ulong[8] z
= void, b
= void, a
= void;
927 for (auto i
= 0; i
< 8; ++i
) z
[i
] = a
[i
] = dl64(x
[8*i
..$]);
930 for (auto i
= 0; i
< 16; ++i
) w
[i
] = dl64(m
[mpos
+8*i
..$]);
932 for (auto i
= 0; i
< 80; ++i
) {
933 for (auto j
= 0; j
< 8; ++j
) b
[j
] = a
[j
];
934 t
= a
[7]+Sigma1(a
[4])+Ch(a
[4], a
[5], a
[6])+K
[i
]+w
[i
%16];
935 b
[7] = t
+Sigma0(a
[0])+Maj(a
[0], a
[1], a
[2]);
937 for (auto j
= 0; j
< 8; ++j
) a
[(j
+1)%8] = b
[j
];
939 for (auto j
= 0; j
< 16; ++j
) w
[j
] += w
[(j
+9)%16]+sigma0(w
[(j
+1)%16])+sigma1(w
[(j
+14)%16]);
943 for (auto i
= 0; i
< 8; ++i
) { a
[i
] += z
[i
]; z
[i
] = a
[i
]; }
949 for (auto i
= 0; i
< 8; ++i
) ts64(x
[8*i
..$], z
[i
]);
952 private static __gshared
immutable ubyte[64] iv
= [
953 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
954 0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
955 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
956 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
957 0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
958 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
959 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
960 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
964 * The crypto_hash() function hashes a message 'msg'.
965 * It returns a hash 'output'. The output length of 'output' should be at least crypto_hash_BYTES.
968 * output = resulting hash
974 void crypto_hash() (ubyte[] output
, const(ubyte)[] msg
) @safe nothrow
976 assert(output
.length
>= crypto_hash_BYTES
);
981 size_t n
= msg
.length
;
985 for (auto i
= 0; i
< 64; ++i
) h
[i
] = iv
[i
];
987 crypto_hashblocks(h
, msg
, n
);
992 for (auto i
= 0; i
< 256; ++i
) x
[i
] = 0;
993 for (auto i
= 0; i
< n
; ++i
) x
[i
] = msg
[mpos
+i
];
994 x
[cast(uint)n
] = 128;
997 x
[cast(uint)(n
-9)] = b
>>61;
998 ts64(x
[cast(uint)(n
-8)..$], b
<<3);
999 crypto_hashblocks(h
, x
, n
);
1001 for (auto i
= 0; i
< 64; ++i
) output
[i
] = h
[i
];
1004 private @tweetNaCl_gdc_attribute("forceinline") void add() (ref long[16][4] p
, ref long[16][4] q
) @safe nothrow {
1005 long[16] a
= void, b
= void, c
= void, d
= void, t
= void, e
= void, f
= void, g
= void, h
= void;
1028 private @tweetNaCl_gdc_attribute("forceinline") void cswap() (ref long[16][4] p
, ref long[16][4] q
, ubyte b
) @safe nothrow {
1029 for (auto i
= 0; i
< 4; ++i
) sel25519(p
[i
], q
[i
], b
);
1032 private @tweetNaCl_gdc_attribute("forceinline") void pack() (ubyte[] r
, ref long[16][4] p
) @safe nothrow {
1033 long[16] tx
= void, ty
= void, zi
= void;
1038 r
[31] ^
= par25519(tx
)<<7;
1041 private @tweetNaCl_gdc_attribute("forceinline") void scalarmult() (ref long[16][4] p
, ref long[16][4] q
, const(ubyte)[] s
) @safe nothrow {
1042 set25519(p
[0], gf0
);
1043 set25519(p
[1], gf1
);
1044 set25519(p
[2], gf1
);
1045 set25519(p
[3], gf0
);
1046 for (auto i
= 255; i
>= 0; --i
) {
1047 ubyte b
= (s
[i
/8]>>(i
&7))&1;
1055 private @tweetNaCl_gdc_attribute("forceinline") void scalarbase() (ref long[16][4] p
, const(ubyte)[] s
) @safe nothrow {
1056 long[16][4] q
= void;
1059 set25519(q
[2], gf1
);
1061 scalarmult(p
, q
, s
);
1065 * The crypto_sign_keypair() function randomly generates a secret key and
1066 * a corresponding public key.
1069 * pk = slice to put generated public key into
1070 * sk = slice to put generated secret key into
1075 void crypto_sign_keypair() (ubyte[] pk
, ubyte[] sk
)
1077 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1078 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1082 long[16][4] p
= void;
1084 randombytes(sk
, 32);
1085 crypto_hash(d
, sk
[0..32]);
1093 for (auto i
= 0; i
< 32; ++i
) sk
[32+i
] = pk
[i
];
1096 private static __gshared
immutable ulong[32] L
= [
1097 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
1100 private @tweetNaCl_gdc_attribute("forceinline") void modL() (ubyte[] r
, long[] x
) @safe nothrow {
1102 for (auto i
= 63; i
>= 32; --i
) {
1105 for (j
= i
-32; j
< i
-12; ++j
) {
1106 x
[j
] += carry
-16*x
[i
]*L
[j
-(i
-32)];
1107 carry
= (x
[j
]+128)>>8;
1114 for (auto j
= 0; j
< 32; ++j
) {
1115 x
[j
] += carry
-(x
[31]>>4)*L
[j
];
1119 for (auto j
= 0; j
< 32; ++j
) x
[j
] -= carry
*L
[j
];
1120 for (auto i
= 0; i
< 32; ++i
) {
1126 private @tweetNaCl_gdc_attribute("forceinline") void reduce() (ubyte[] r
) @safe nothrow {
1128 for (auto i
= 0; i
< 64; ++i
) x
[i
] = cast(ulong)r
[i
];
1129 for (auto i
= 0; i
< 64; ++i
) r
[i
] = 0;
1134 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1135 * The crypto_sign() function returns the resulting signed message.
1138 * sm = buffer to receive signed message, must be of size at least msg.length+64
1140 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1145 void crypto_sign() (ubyte[] sm
, const(ubyte)[] msg
, const(ubyte)[] sk
) @trusted nothrow
1147 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1148 assert(sm
.length
>= msg
.length
+64);
1151 ubyte[64] d
= void, h
= void, r
= void;
1153 long[16][4] p
= void;
1154 size_t n
= msg
.length
;
1155 size_t smlen
= n
+64;
1157 crypto_hash(d
, sk
[0..32]);
1162 for (auto i
= 0; i
< n
; ++i
) sm
[64+i
] = msg
[i
];
1163 for (auto i
= 0; i
< 32; ++i
) sm
[32+i
] = d
[32+i
];
1165 crypto_hash(r
, sm
[32../*$*/32+n
+32]/*, n+32*/);
1170 for (auto i
= 0; i
< 32; ++i
) sm
[i
+32] = sk
[i
+32];
1171 crypto_hash(h
, sm
[0..n
+64]);
1174 for (auto i
= 0; i
< 64; ++i
) x
[i
] = 0;
1175 for (auto i
= 0; i
< 32; ++i
) x
[i
] = cast(ulong)r
[i
];
1176 for (auto i
= 0; i
< 32; ++i
) for (auto j
= 0; j
< 32; ++j
) x
[i
+j
] += h
[i
]*cast(ulong)d
[j
];
1177 modL(sm
[32..$], cast(long[])x
);
1181 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1182 * The crypto_sign() function returns the resulting signed message.
1184 * WARNING! This function allocates!
1188 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1193 ubyte[] crypto_sign() (const(ubyte)[] msg
, const(ubyte)[] sk
) @safe nothrow
1195 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1199 size_t n
= msg
.length
;
1200 size_t smlen
= n
+64;
1202 crypto_sign(sm
, msg
, sk
);
1206 private @tweetNaCl_gdc_attribute("forceinline") bool unpackneg() (ref long[16][4] r
, const(ubyte)[] p
) @safe nothrow {
1207 long[16] t
= void, chk
= void, num
= void, den
= void, den2
= void, den4
= void, den6
= void;
1208 set25519(r
[2], gf1
);
1209 unpack25519(r
[1], p
);
1217 M(den6
, den4
, den2
);
1229 if (!neq25519(chk
, num
)) M(r
[0], r
[0], I
);
1233 if (!neq25519(chk
, num
)) return false;
1235 if (par25519(r
[0]) == (p
[31]>>7)) Z(r
[0], gf0
, r
[0]);
1237 M(r
[3], r
[0], r
[1]);
1242 * The crypto_sign_open() function verifies the signature in
1243 * 'sm' using the receiver's public key 'pk'.
1246 * msg = decrypted message, last 64 bytes are useless zeroes, must be of size at least sm.length
1247 * sm == signed message
1248 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1253 bool crypto_sign_open() (ubyte[] msg
, const(ubyte)[] sm
, const(ubyte)[] pk
) @safe nothrow
1255 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1256 assert(msg
.length
>= sm
.length
);
1261 long[16][4] p
= void, q
= void;
1262 size_t n
= sm
.length
;
1264 if (n
< 64) return false;
1266 if (!unpackneg(q
, pk
)) return false;
1267 for (auto i
= 0; i
< n
; ++i
) msg
[i
] = sm
[i
];
1268 for (auto i
= 0; i
< 32; ++i
) msg
[i
+32] = pk
[i
];
1269 crypto_hash(h
, msg
/*, n*/);
1271 scalarmult(p
, q
, h
);
1273 scalarbase(q
, sm
[32..$]);
1278 if (!crypto_verify_32(sm
, t
)) {
1279 for (auto i
= 0; i
< n
; ++i
) msg
[i
] = 0;
1283 for (auto i
= 0; i
< n
; ++i
) msg
[i
] = sm
[i
+64];
1284 for (auto i
= n
; i
< n
+64; ++i
) msg
[i
] = 0;
1291 * The crypto_sign_open() function verifies the signature in
1292 * 'sm' using the receiver's public key 'pk'.
1293 * The crypto_sign_open() function returns the message.
1295 * WARNING! This function allocates!
1298 * sm == signed message
1299 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1302 * decrypted message or null on error
1304 ubyte[] crypto_sign_open() (const(ubyte)[] sm
, const(ubyte)[] pk
) @safe nothrow {
1306 msg
.length
= sm
.length
;
1307 if (!crypto_sign_open(msg
, sm
, pk
)) return null;
1308 return msg
[0..sm
.length
-64]; // remove signature
1313 import std
.exception
;
1319 private extern(C) int open(const(char)* filename, int flags, ...);
1320 void randombytes (ubyte[] dest, size_t len) {
1321 import core.sys.posix.unistd;
1325 fd = open("/dev/urandom", /*O_RDONLY*/0);
1326 if (fd != -1) break;
1332 ssize_t i = read(fd, cast(void*)(&dest[pos]), (len < 1048576 ? len : 1048576));
1343 static void rnd (ubyte[] dest, size_t len) {
1344 for (size_t f = 0; f < len; ++f) dest[f] = cast(ubyte)uniform(0, 256);
1349 randombytes
= (ubyte[] dest
, size_t len
) {
1350 for (size_t f
= 0; f
< len
; ++f
) dest
[f
] = cast(ubyte)uniform(0, 256);
1353 void dumpArray(T
) (T
[] arr
) @trusted {
1354 writefln("============================= (%s)", arr
.length
);
1355 for (auto f
= 0; f
< arr
.length
; ++f
) {
1356 if (f
&& f
%16 == 0) writeln();
1357 static if (T
.sizeof
== 1) writef(" 0x%02x", arr
[f
]);
1358 else static if (T
.sizeof
== 2) writef(" 0x%04x", arr
[f
]);
1359 else static if (T
.sizeof
== 4) writef(" 0x%08x", arr
[f
]);
1360 else writef(" 0x%08x", arr
[f
]);
1363 writeln("-----------------------------");
1366 string
hashToString (const(ubyte)[] hash
) {
1368 s
.length
= hash
.length
*2;
1369 char toHex(int a
) { return cast(char)(a
< 10 ? a
+'0' : a
+'a'-10); }
1370 for (int a
= 0; a
< hash
.length
; ++a
) {
1371 s
[a
*2] = toHex(hash
[a
]>>4);
1372 s
[a
*2+1] = toHex(hash
[a
]&0x0f);
1374 return assumeUnique(s
);
1377 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];
1378 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];
1379 static immutable ubyte[5] m
= [0x61,0x68,0x6f,0x6a,0x0a];
1380 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];
1383 writeln("crypto_sign");
1384 smres
= crypto_sign(m
, sk
);
1385 assert(smres
.length
== sm
.length
);
1386 assert(smres
== sm
);
1388 writeln("crypto_sign_open");
1389 t
= crypto_sign_open(smres
, pk
);
1391 assert(t
.length
== m
.length
);
1395 // based on the code by Adam D. Ruppe
1396 // 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
1397 template SHARange(T
) if (isInputRange
!(T
)) {
1401 bool empty () { return state
== 5; }
1413 bool hackforward
= false;
1417 if (((position
+length
+8)*8)%512 == 8) {
1423 } else if (state
== 2) {
1425 if (!(((position
+length
+8)*8)%512)) {
1429 if (hackforward
) goto proceedmoar
;
1433 } else if (state
== 3) {
1435 current
= (length
>>(position
*8))&0xff;
1436 if (position
== 0) state
= 4; else --position
;
1437 } else if (state
== 4) {
1445 if (state
== 0) return cast(ubyte)r
.front();
1447 //writefln("%x", current);
1454 int state
= 0; // reading range, reading appended bit, reading padding, reading length, done
1459 immutable(ubyte)[] SHA256(T
) (T data
) if (isInputRange
!(T
)) {
1460 uint[8] h
= [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
1461 static immutable(uint[64]) k
= [
1462 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1463 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1464 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1465 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1466 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1467 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1468 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1469 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1474 static if (is(data
== SHARange
)) range
= data
; else range
.r
= data
;
1477 while(!range
.empty
) {
1480 for(int a
= 0; a
< 16; ++a
) {
1481 for(int b
= 3; b
>= 0; --b
) {
1482 words
[a
] |
= cast(uint)(range
.front())<<(b
*8);
1487 uint ror (uint n
, int cnt
) {
1488 return cast(uint)(n
>>cnt
)|
cast(uint)(n
<<(32-(cnt
)));
1491 uint xrot00 (uint reax
, int r0
, int r1
, int r2
) {
1492 uint rebx
= reax
, recx
= reax
;
1493 reax
= ror(reax
, r0
);
1494 rebx
= ror(rebx
, r1
);
1501 for(int a
= 16; a
< 64; ++a
) {
1502 uint t1
= xrot00(words
[a
-15], 7, 18, 3);
1503 uint t2
= xrot00(words
[a
-2], 17, 19, 10);
1504 words
[a
] = words
[a
-16]+t1
+words
[a
-7]+t2
;
1516 uint xrot01 (uint reax
, int r0
, int r1
, int r2
) {
1517 uint rebx
= reax
, recx
= reax
;
1518 reax
= ror(reax
, r0
);
1519 rebx
= ror(rebx
, r1
);
1520 recx
= ror(recx
, r2
);
1526 for(int i
= 0; i
< 64; ++i
) {
1527 uint s0
= xrot01(A
, 2, 13, 22);
1528 uint maj
= (A
&B
)^
(A
&C
)^
(B
&C
);
1530 uint s1
= xrot01(E
, 6, 11, 25);
1531 uint ch
= (E
&F
)^
((~E
)&G
);
1532 uint t1
= H
+s1
+ch
+k
[i
]+words
[i
];
1555 for(int j
= 0; j
< 8; ++j
)
1556 for(int i
= 3; i
>= 0; --i
) {
1557 hash
~= cast(ubyte)(h
[j
]>>(i
*8))&0xff;
1567 static immutable ubyte[32] alicesk
= [
1568 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
1569 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
1570 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
1571 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
1574 static immutable ubyte[32] bobpk
= [
1575 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
1576 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
1577 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
1578 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
1581 static immutable ubyte[24] nonce
= [
1582 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1583 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1584 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1587 // API requires first 32 bytes to be 0
1588 static immutable ubyte[163] m
= [
1589 0, 0, 0, 0, 0, 0, 0, 0
1590 , 0, 0, 0, 0, 0, 0, 0, 0
1591 , 0, 0, 0, 0, 0, 0, 0, 0
1592 , 0, 0, 0, 0, 0, 0, 0, 0
1593 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1594 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1595 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1596 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1597 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1598 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1599 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1600 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1601 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1602 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1603 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1604 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1605 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1606 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1607 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1608 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1615 static immutable ubyte[] res
= [
1616 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1617 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1618 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1619 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1620 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1621 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1622 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1623 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1624 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1625 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1626 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1627 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1628 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1629 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1630 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1631 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1632 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1633 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1635 /*crypto_box_curve25519xsalsa20poly1305*/crypto_box(c
,m
,nonce
,bobpk
,alicesk
);
1636 for (auto f
= 16; f
< 163; ++f
) assert(c
[f
] == res
[f
-16]);
1642 static immutable ubyte[32] bobsk
= [
1643 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
1644 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
1645 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
1646 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
1649 static immutable ubyte[32] alicepk
= [
1650 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
1651 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
1652 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
1653 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
1656 static immutable ubyte[24] nonce
= [
1657 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1658 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1659 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1662 // API requires first 16 bytes to be 0
1663 static immutable ubyte[163] c
= [
1664 0, 0, 0, 0, 0, 0, 0, 0
1665 , 0, 0, 0, 0, 0, 0, 0, 0
1666 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1667 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1668 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1669 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1670 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1671 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1672 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1673 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1674 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1675 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1676 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1677 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1678 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1679 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1680 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1681 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1682 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1683 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1689 static immutable ubyte[] res
= [
1690 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1691 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1692 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1693 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1694 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1695 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1696 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1697 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1698 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1699 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1700 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1701 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1702 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1703 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1704 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1705 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1709 assert(/*crypto_box_curve25519xsalsa20poly1305_open*/crypto_box_open(m
,c
,nonce
,alicepk
,bobsk
));
1710 for (auto f
= 32; f
< 163; ++f
) assert(m
[f
] == res
[f
-32]);
1716 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1717 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1718 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1719 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1720 ubyte[crypto_box_NONCEBYTES
] n
;
1721 ubyte[10000] m
, c
, m2
;
1722 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1723 crypto_box_keypair(alicepk
,alicesk
);
1724 crypto_box_keypair(bobpk
,bobsk
);
1725 randombytes(n
,crypto_box_NONCEBYTES
);
1726 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1727 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1728 assert(crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
));
1729 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1732 version(unittest_full
) box7(); // it's slow
1736 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1737 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1738 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1739 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1740 ubyte[crypto_box_NONCEBYTES
] n
;
1741 ubyte[10000] m
, c
, m2
;
1742 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1743 crypto_box_keypair(alicepk
,alicesk
);
1744 crypto_box_keypair(bobpk
,bobsk
);
1745 randombytes(n
,crypto_box_NONCEBYTES
);
1746 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1747 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1749 while (caught
< 10) {
1750 c
[uniform(0, mlen
+crypto_box_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
1751 if (crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
)) {
1752 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1757 assert(caught
== 10);
1760 version(unittest_full
) box8(); // it's slow
1764 static immutable ubyte[32] shared_
= [
1765 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
1766 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
1767 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
1768 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
1771 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];
1773 static immutable ubyte[16] c
= [
1774 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1775 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1780 static immutable ubyte[32] res
= [
1781 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1782 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1783 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1784 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1787 crypto_core_hsalsa20(firstkey
,zero
,shared_
,c
);
1788 assert(firstkey
== res
);
1794 static immutable ubyte[32]firstkey
= [
1795 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1796 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1797 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1798 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1801 static immutable ubyte[16]nonceprefix
= [
1802 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1803 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1806 static immutable ubyte[16] c
= [
1807 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1808 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1811 ubyte[32] secondkey
;
1813 static immutable ubyte[32] res
= [
1814 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1815 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1816 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1817 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1820 crypto_core_hsalsa20(secondkey
,nonceprefix
,firstkey
,c
);
1821 assert(secondkey
== res
);
1827 static immutable ubyte[32] secondkey
= [
1828 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1829 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1830 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1831 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1834 static immutable ubyte[8] noncesuffix
= [
1835 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1838 static immutable ubyte[16] c
= [
1839 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1840 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1843 static ubyte[16] input
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ;
1845 static ubyte output
[64*256*256];
1849 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];
1852 for (auto i
= 0; i
< 8; ++i
) input
[i
] = noncesuffix
[i
];
1855 crypto_core_salsa20(output
[pos
..$],input
,secondkey
,c
);
1857 } while (++input
[8]);
1858 } while (++input
[9]);
1859 crypto_hash(h
,output
);
1862 version(unittest_full
) core3(); // it's slow
1866 static immutable ubyte[32] k
= [
1867 1, 2, 3, 4, 5, 6, 7, 8
1868 , 9, 10, 11, 12, 13, 14, 15, 16
1869 ,201,202,203,204,205,206,207,208
1870 ,209,210,211,212,213,214,215,216
1873 static immutable ubyte[16] input
= [
1874 101,102,103,104,105,106,107,108
1875 ,109,110,111,112,113,114,115,116
1878 static immutable ubyte[16] c
= [
1879 101,120,112, 97,110,100, 32, 51
1880 , 50, 45, 98,121,116,101, 32,107
1885 static immutable ubyte[64] res
= [
1886 69, 37, 68, 39, 41, 15,107,193
1887 ,255,139,122, 6,170,233,217, 98
1888 , 89,144,182,106, 21, 51,200, 65
1889 ,239, 49,222, 34,215,114, 40,126
1890 ,104,197, 7,225,197,153, 31, 2
1891 ,102, 78, 76,176, 84,245,246,184
1892 ,177,160,133,130, 6, 72,149,119
1893 ,192,195,132,236,234,103,246, 74
1896 crypto_core_salsa20(output
,input
,k
,c
);
1897 assert(output
== res
);
1903 static immutable ubyte[32] k
= [
1904 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1905 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1906 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1907 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1910 static immutable ubyte[16] input
= [
1911 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1912 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1915 static immutable ubyte[16] c
= [
1916 101,120,112, 97,110,100, 32, 51
1917 , 50, 45, 98,121,116,101, 32,107
1922 static immutable ubyte[32] res
= [
1923 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1924 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1925 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1926 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1929 crypto_core_hsalsa20(output
,input
,k
,c
);
1930 assert(output
== res
);
1936 static immutable ubyte[32] k
= [
1937 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1938 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1939 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1940 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1943 static immutable ubyte[16] input
= [
1944 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1945 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1948 static immutable ubyte[16] c
= [
1949 101,120,112, 97,110,100, 32, 51
1950 , 50, 45, 98,121,116,101, 32,107
1955 static immutable ubyte[32] res
= [
1956 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1957 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1958 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1959 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1965 void print(const(ubyte)[] x
, const(ubyte)[] y
)
1968 for (auto i
= 0; i
< 4; ++i
) {
1971 //printf(",0x%02x",255&(xi-yi-borrow));
1972 pp
[pppos
++] = cast(ubyte)(255&(xi
-yi
-borrow
));
1973 borrow
= (xi
< yi
+borrow
);
1977 crypto_core_salsa20(output
,input
,k
,c
);
1979 print(output
[20..$],c
[4..$]);
1980 print(output
[40..$],c
[8..$]);
1981 print(output
[60..$],c
[12..$]);
1982 print(output
[24..$],input
);
1983 print(output
[28..$],input
[4..$]);
1984 print(output
[32..$],input
[8..$]);
1985 print(output
[36..$],input
[12..$]);
1992 static immutable ubyte x
[8] = ['t','e','s','t','i','n','g','\n'];
1993 static ubyte[crypto_hash_BYTES
] h
;
1994 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];
1996 //for (auto f = 0; f < crypto_hash_BYTES; ++f) assert(h[f] == res[f]);
2001 void onetimeauth () {
2002 writeln("onetimeauth");
2003 static immutable ubyte rs
[32] = [
2004 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2005 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2006 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2007 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2010 static immutable ubyte c
[131] = [
2011 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2012 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2013 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2014 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2015 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2016 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2017 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2018 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2019 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2020 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2021 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2022 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2023 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2024 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2025 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2026 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2032 static immutable ubyte[16] res
= [0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9];
2034 /*crypto_onetimeauth_poly1305*/crypto_onetimeauth(a
,c
,rs
);
2039 void onetimeauth2 () {
2040 writeln("onetimeauth2");
2041 static immutable ubyte[32] rs
= [
2042 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2043 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2044 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2045 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2048 static immutable ubyte[131] c
= [
2049 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2050 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2051 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2052 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2053 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2054 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2055 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2056 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2057 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2058 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2059 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2060 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2061 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2062 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2063 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2064 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2068 static immutable ubyte[16] a
= [
2069 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2070 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2073 assert(/*crypto_onetimeauth_poly1305_verify*/crypto_onetimeauth_verify(a
,c
,rs
));
2077 void onetimeauth7 () {
2078 writeln("onetimeauth7");
2079 static ubyte[32] key
;
2080 static ubyte[10000] c
;
2083 for (auto clen
= 0; clen
< 10000; ++clen
) {
2084 //if (clen%512 == 0) { writef("\r%s", clen); stdout.flush(); }
2085 randombytes(key
, key
.length
);
2086 randombytes(c
, clen
);
2087 crypto_onetimeauth(a
,c
[0..clen
],key
);
2088 assert(crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2090 c
[uniform(0, clen
)] += 1+(uniform(0, 255));
2091 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2092 a
[uniform(0, a
.length
)] += 1+(uniform(0, 255));
2093 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2097 version(unittest_full
) onetimeauth7(); // it's slow
2099 void scalarmult () {
2100 writeln("scalarmult");
2101 static immutable ubyte[32] alicesk
= [
2102 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2103 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2104 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2105 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2110 static immutable ubyte[32] res
= [
2111 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2112 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2113 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2114 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2117 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(alicepk
,alicesk
);
2118 assert(alicepk
== res
);
2122 void scalarmult2 () {
2123 writeln("scalarmult2");
2124 static immutable ubyte[32] bobsk
= [
2125 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2126 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2127 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2128 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2133 static immutable ubyte[32] res
= [
2134 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2135 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2136 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2137 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2140 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(bobpk
,bobsk
);
2141 assert(bobpk
== res
);
2145 void scalarmult5 () {
2146 writeln("scalarmult5");
2147 static immutable ubyte[32] alicesk
= [
2148 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2149 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2150 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2151 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2154 static immutable ubyte[32] bobpk
= [
2155 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2156 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2157 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2158 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2163 static immutable ubyte[32] res
= [
2164 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2165 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2166 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2167 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2170 crypto_scalarmult(k
,alicesk
,bobpk
);
2175 void scalarmult6 () {
2176 writeln("scalarmult6");
2177 static immutable ubyte[32] bobsk
= [
2178 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2179 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2180 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2181 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2184 static immutable ubyte[32] alicepk
= [
2185 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2186 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2187 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2188 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2193 static immutable ubyte[32] res
= [
2194 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2195 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2196 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2197 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2200 crypto_scalarmult(k
,bobsk
,alicepk
);
2206 writeln("secretbox");
2207 static immutable ubyte[32] firstkey
= [
2208 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2209 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2210 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2211 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2214 static immutable ubyte[24] nonce
= [
2215 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2216 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2217 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2220 // API requires first 32 bytes to be 0
2221 static immutable ubyte[163] m
= [
2222 0, 0, 0, 0, 0, 0, 0, 0
2223 , 0, 0, 0, 0, 0, 0, 0, 0
2224 , 0, 0, 0, 0, 0, 0, 0, 0
2225 , 0, 0, 0, 0, 0, 0, 0, 0
2226 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2227 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2228 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2229 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2230 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2231 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2232 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2233 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2234 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2235 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2236 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2237 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2238 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2239 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2240 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2241 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2245 static immutable ubyte[] res
= [
2246 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2247 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2248 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2249 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2250 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2251 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2252 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2253 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2254 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2255 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2256 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2257 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2258 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2259 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2260 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2261 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2262 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2263 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2268 crypto_secretbox(c
,m
,nonce
,firstkey
);
2269 for (auto i
= 16; i
< 163; ++i
) assert(c
[i
] == res
[i
-16]);
2273 void secretbox2 () {
2274 writeln("secretbox2");
2275 static immutable ubyte[32] firstkey
= [
2276 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2277 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2278 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2279 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2282 static immutable ubyte[24] nonce
= [
2283 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2284 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2285 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2288 // API requires first 16 bytes to be 0
2289 static immutable ubyte[163] c
= [
2290 0, 0, 0, 0, 0, 0, 0, 0
2291 , 0, 0, 0, 0, 0, 0, 0, 0
2292 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2293 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2294 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2295 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2296 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2297 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2298 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2299 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2300 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2301 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2302 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2303 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2304 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2305 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2306 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2307 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2308 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2309 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2313 static immutable ubyte[] res
= [
2314 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2315 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2316 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2317 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2318 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2319 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2320 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2321 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2322 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2323 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2324 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2325 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2326 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2327 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2328 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2329 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2335 assert(crypto_secretbox_open(m
,c
,nonce
,firstkey
));
2336 for (auto i
= 32; i
< 163; ++i
) assert(m
[i
] == res
[i
-32]);
2340 void secretbox7 () {
2341 writeln("secretbox7");
2342 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2343 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2344 static ubyte[10000] m
, c
, m2
;
2345 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2346 randombytes(k
,crypto_secretbox_KEYBYTES
);
2347 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2348 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2349 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2350 assert(crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
));
2351 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2356 void secretbox8 () {
2357 writeln("secretbox8");
2358 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2359 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2360 static ubyte[10000] m
, c
, m2
;
2361 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2362 randombytes(k
,crypto_secretbox_KEYBYTES
);
2363 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2364 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2365 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2367 while (caught
< 10) {
2368 c
[uniform(0, mlen
+crypto_secretbox_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
2369 if (crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
)) {
2370 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2374 assert(caught
== 10);
2377 version(unittest_full
) secretbox8(); // it's slow
2381 static immutable ubyte[32] firstkey
= [
2382 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2383 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2384 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2385 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2388 static immutable ubyte[24] nonce
= [
2389 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2390 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2391 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2394 static ubyte[4194304] output
;
2397 //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];
2399 crypto_stream(output
,nonce
,firstkey
);
2400 //crypto_hash_sha256(h,output,sizeof output);
2401 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2407 static immutable ubyte[32] secondkey
= [
2408 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
2409 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
2410 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
2411 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
2414 static immutable ubyte[8] noncesuffix
= [
2415 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2418 static ubyte[4194304] output
;
2420 crypto_stream_salsa20(output
,noncesuffix
,secondkey
);
2421 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2427 static immutable ubyte[32] firstkey
= [
2428 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2429 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2430 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2431 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2434 static immutable ubyte[24] nonce
= [
2435 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2436 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2437 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2442 static immutable ubyte[32] res
= [
2443 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2444 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2445 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2446 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2449 crypto_stream
/*_xsalsa20*/(rs
,nonce
,firstkey
);
2456 static immutable ubyte[32] firstkey
= [
2457 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2458 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2459 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2460 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2463 static immutable ubyte[24] nonce
= [
2464 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2465 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2466 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2469 static immutable ubyte[163] m
= [
2470 0, 0, 0, 0, 0, 0, 0, 0
2471 , 0, 0, 0, 0, 0, 0, 0, 0
2472 , 0, 0, 0, 0, 0, 0, 0, 0
2473 , 0, 0, 0, 0, 0, 0, 0, 0
2474 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2475 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2476 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2477 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2478 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2479 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2480 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2481 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2482 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2483 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2484 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2485 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2486 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2487 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2488 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2489 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2495 static immutable ubyte[] res
= [
2496 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2497 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2498 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2499 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2500 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2501 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2502 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2503 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2504 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2505 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2506 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2507 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2508 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2509 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2510 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2511 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2515 /*crypto_stream_xsalsa20_xor*/crypto_stream_xor(c
,m
,nonce
,firstkey
);
2516 for (auto i
= 32; i
< 163; ++i
) assert(c
[i
] == res
[i
-32]);
2521 version(unittest_main
) {