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(string 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
);
288 ubyte[16] z
; // autoclear
291 uint cpos
= 0, mpos
= 0;
292 size_t b
= output
.length
;
294 z
[0..8] = nonce
[0..8];
296 crypto_core_salsa20(x
, z
, key
, sigma
);
298 foreach (v
; x
) output
[cpos
++] = msg
[mpos
++]^v
;
300 output
[cpos
..cpos
+64] = x
[];
312 crypto_core_salsa20(x
, z
, key
, sigma
);
314 foreach (i
; 0..b
) output
[cpos
++] = msg
[mpos
++]^x
[i
];
316 output
[cpos
..cpos
+b
] = x
[0..b
];
322 * The crypto_stream_salsa20() function produces a stream 'c'
323 * as a function of a secret key 'key' and a nonce 'nonce'.
326 * c = resulting stream
333 void crypto_stream_salsa20() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
335 assert(nonce
.length
== crypto_stream_salsa20_NONCEBYTES
);
336 assert(key
.length
== crypto_stream_salsa20_KEYBYTES
);
339 crypto_stream_salsa20_xor(c
, null, nonce
, key
);
343 * The crypto_stream() function produces a stream 'c'
344 * as a function of a secret key 'key' and a nonce 'nonce'.
354 void crypto_stream() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
357 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
358 assert(key
.length
== crypto_stream_KEYBYTES
);
362 crypto_core_hsalsa20(s
, nonce
, key
, sigma
);
363 crypto_stream_salsa20(c
, nonce
[16..$], s
);
367 * The crypto_stream_xor() function encrypts a message 'msg' using a secret key 'key'
368 * and a nonce 'nonce'. The crypto_stream_xor() function returns the ciphertext 'c'.
378 void crypto_stream_xor() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
381 assert(msg
.length
>= c
.length
);
382 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
383 assert(key
.length
== crypto_stream_KEYBYTES
);
387 crypto_core_hsalsa20(s
, nonce
, key
, sigma
);
388 crypto_stream_salsa20_xor(c
, msg
, nonce
[16..$], s
);
391 private @tweetNaCl_gdc_attribute("forceinline") void add1305() (uint[] h
, const(uint)[] c
) @safe nothrow {
400 private static __gshared
immutable uint[17] minusp
= [5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252];
403 * The crypto_onetimeauth() function authenticates a message 'msg'
404 * using a secret key 'key'. The function returns an authenticator 'output'.
407 * output = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
409 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
412 * authenticator in 'output'
414 void crypto_onetimeauth() (ubyte[] output
, const(ubyte)[] msg
, const(ubyte)[] key
) @safe nothrow
416 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
417 assert(output
.length
>= crypto_onetimeauth_BYTES
);
421 uint[17] x
= void, r
= void, h
/*autoclear*/, c
= void, g
= void;
423 size_t n
= msg
.length
;
425 foreach (i
; 0..16) r
[i
] = key
[i
];
440 for (jj
= 0; jj
< 16 && jj
< n
; ++jj
) c
[jj
] = msg
[mpos
+jj
];
448 foreach (j
; 0..17) x
[i
] += h
[j
]*(j
<= i ? r
[i
-j
] : 320*r
[i
+17-j
]);
472 foreach (j
; 0..17) h
[j
] ^
= s
&(g
[j
]^h
[j
]);
474 foreach (j
; 0..16) c
[j
] = key
[j
+16];
477 foreach (j
; 0..16) output
[j
] = cast(ubyte)(h
[j
]&0xff);
481 * The crypto_onetimeauth_verify() function checks that
482 * 'h' is a correct authenticator of a message 'msg' under the secret key 'key'.
485 * h = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
487 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
492 bool crypto_onetimeauth_verify() (const(ubyte)[] h
, const(ubyte)[] msg
, const(ubyte)[] key
) @safe nothrow
494 assert(h
.length
>= crypto_onetimeauth_BYTES
);
495 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
499 crypto_onetimeauth(x
, msg
, key
);
500 return crypto_verify_16(h
, x
);
504 * The crypto_secretbox() function encrypts and authenticates
505 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
506 * The crypto_secretbox() function returns the resulting ciphertext 'c'.
509 * c = resulting cyphertext
514 * success flag and cyphertext in 'c'
516 bool crypto_secretbox() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
518 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
519 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
522 //c.length = msg.length+crypto_secretbox_ZEROBYTES;
523 if (c
is null || c
.length
< 32) return false;
524 crypto_stream_xor(c
, msg
, nonce
, key
);
525 crypto_onetimeauth(c
[16..$], c
[32..$], c
);
527 //return c[crypto_secretbox_BOXZEROBYTES..$];
532 * The crypto_secretbox_open() function verifies and decrypts
533 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
534 * The crypto_secretbox_open() function returns the resulting plaintext 'output'.
537 * output = resulting message
543 * success flag and message in 'output'
545 bool crypto_secretbox_open() (ubyte[] output
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
547 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
548 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
552 if (output
is null || output
.length
< 32) return false;
553 crypto_stream(x
, nonce
, key
);
554 if (!crypto_onetimeauth_verify(c
[16..$], c
[32../*$*/32+(output
.length
-32)], x
)) return false;
555 crypto_stream_xor(output
, c
, nonce
, key
);
561 private @tweetNaCl_gdc_attribute("forceinline") void car25519() (long[] o
) @safe nothrow {
565 o
[(i
+1)*(i
<15)] += c
-1+37*(c
-1)*(i
==15);
570 private @tweetNaCl_gdc_attribute("forceinline") void sel25519() (long[] p
,long[] q
, int b
) @safe nothrow {
573 long t
= c
&(p
[i
]^q
[i
]);
579 private @tweetNaCl_gdc_attribute("forceinline") void pack25519() (ubyte[] o
, const(long)[] n
) @safe nothrow {
581 long[16] m
= void, t
= void;
589 m
[i
] = t
[i
]-0xffff-((m
[i
-1]>>16)&1);
592 m
[15] = t
[15]-0x7fff-((m
[14]>>16)&1);
599 o
[2*i
+1] = (t
[i
]>>8)&0xff;
603 private @tweetNaCl_gdc_attribute("forceinline") bool neq25519() (const(long)[] a
, const(long)[] b
) @safe nothrow {
604 ubyte[32] c
= void, d
= void;
607 return crypto_verify_32(c
, d
);
610 private @tweetNaCl_gdc_attribute("forceinline") ubyte par25519() (const(long)[] a
) @safe nothrow {
616 private @tweetNaCl_gdc_attribute("forceinline") void unpack25519() (long[] o
, const(ubyte)[] n
) @safe nothrow {
617 foreach (i
; 0..16) o
[i
] = n
[2*i
]+(cast(long)n
[2*i
+1]<<8);
621 private @tweetNaCl_gdc_attribute("forceinline") void A() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
622 foreach (i
; 0..16) o
[i
] = a
[i
]+b
[i
];
625 private @tweetNaCl_gdc_attribute("forceinline") void Z() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
626 foreach (i
; 0..16) o
[i
] = a
[i
]-b
[i
];
629 private @tweetNaCl_gdc_attribute("forceinline") void M() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
630 long[31] t
; // automatically becomes 0
631 foreach (i
; 0..16) foreach (j
; 0..16) t
[i
+j
] += a
[i
]*b
[j
];
632 foreach (i
; 0..15) t
[i
] += 38*t
[i
+16];
638 private @tweetNaCl_gdc_attribute("forceinline") void S() (long[] o
, const(long)[] a
) @safe nothrow {
642 private @tweetNaCl_gdc_attribute("forceinline") void inv25519() (long[] o
, const(long)[] i
) @safe nothrow {
645 for (auto a
= 253; a
>= 0; --a
) {
647 if (a
!= 2 && a
!= 4) M(c
, c
, i
);
652 private @tweetNaCl_gdc_attribute("forceinline") void pow2523() (long[] o
, const(long)[] i
) @safe nothrow {
655 for(auto a
= 250; a
>= 0; --a
) {
657 if (a
!= 1) M(c
, c
, i
);
663 * This function multiplies a group element 'p' by an integer 'n'.
670 * resulting group element 'q' of length crypto_scalarmult_BYTES.
672 private void crypto_scalarmult (ubyte[] q
, const(ubyte)[] n
, const(ubyte)[] p
) @safe nothrow
674 assert(q
.length
== crypto_scalarmult_BYTES
);
675 assert(n
.length
== crypto_scalarmult_BYTES
);
676 assert(p
.length
== crypto_scalarmult_BYTES
);
682 long[16] a
= void, b
= void, c
= void, d
= void, e
= void, f
= void;
684 z
[31] = (n
[31]&127)|
64;
689 d
[i
] = a
[i
] = c
[i
] = 0;
692 for (int 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
);
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
740 assert(q
.length
== crypto_scalarmult_BYTES
);
741 assert(n
.length
== crypto_scalarmult_SCALARBYTES
);
744 crypto_scalarmult(q
, n
, _9
);
748 * The crypto_box_keypair() function randomly generates a secret key and
749 * a corresponding public key.
752 * pk = slice to put generated public key into
753 * sk = slice to put generated secret key into
758 void crypto_box_keypair() (ubyte[] pk
, ubyte[] sk
) @trusted
760 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
761 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
765 crypto_scalarmult_base(pk
, sk
);
769 * Function crypto_box_beforenm() computes a shared secret 's' from
770 * public key 'pk' and secret key 'sk'.
773 * skey = slice to put secret into
780 void crypto_box_beforenm() (ubyte[] skey
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
782 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
783 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
784 assert(skey
.length
>= crypto_box_BEFORENMBYTES
);
788 crypto_scalarmult(s
, sk
, pk
);
789 crypto_core_hsalsa20(skey
, _0
, s
, sigma
);
793 * The crypto_box_afternm() function encrypts and authenticates
794 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
795 * The crypto_box_afternm() function returns the resulting ciphertext 'c'.
798 * c = resulting cyphertext
804 * success flag and cyphertext in 'c'
806 bool crypto_box_afternm() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
808 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
809 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
812 return crypto_secretbox(c
, msg
, nonce
, key
);
816 * The crypto_box_open_afternm() function verifies and decrypts
817 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
818 * The crypto_box_open_afternm() function returns the resulting message 'msg'.
821 * msg = resulting message
827 * success flag and resulting message in 'msg'
829 bool crypto_box_open_afternm() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
831 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
832 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
835 return crypto_secretbox_open(msg
, c
, nonce
, key
);
839 * The crypto_box() function encrypts and authenticates a message 'msg'
840 * using the sender's secret key 'sk', the receiver's public key 'pk',
841 * and a nonce 'nonce'. The crypto_box() function returns the resulting ciphertext 'c'.
844 * c = resulting cyphertext
847 * pk = receiver's public key
848 * sk = sender's secret key
851 * success flag and cyphertext in 'c'
853 bool crypto_box() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
855 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
856 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
857 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
861 crypto_box_beforenm(k
, pk
, sk
);
862 return crypto_box_afternm(c
, msg
, nonce
, k
);
866 * The crypto_box_open() function verifies and decrypts
867 * a ciphertext 'c' using the receiver's secret key 'sk',
868 * the sender's public key 'pk', and a nonce 'nonce'.
869 * The crypto_box_open() function returns the resulting message 'msg'.
872 * msg = resulting message
875 * pk = receiver's public key
876 * sk = sender's secret key
879 * success flag and message in 'msg'
881 bool crypto_box_open() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
883 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
884 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
885 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
889 crypto_box_beforenm(k
, pk
, sk
);
890 return crypto_box_open_afternm(msg
, c
, nonce
, k
);
893 private @tweetNaCl_gdc_attribute("forceinline") ulong R() (ulong x
, int c
) @safe nothrow pure { return (x
>>c
)|
(x
<<(64-c
)); }
894 private @tweetNaCl_gdc_attribute("forceinline") ulong Ch() (ulong x
, ulong y
, ulong z
) @safe nothrow pure { return (x
&y
)^
(~x
&z
); }
895 private @tweetNaCl_gdc_attribute("forceinline") ulong Maj() (ulong x
, ulong y
, ulong z
) @safe nothrow pure { return (x
&y
)^
(x
&z
)^
(y
&z
); }
896 private @tweetNaCl_gdc_attribute("forceinline") ulong Sigma0() (ulong x
) @safe nothrow pure { return R(x
, 28)^
R(x
, 34)^
R(x
, 39); }
897 private @tweetNaCl_gdc_attribute("forceinline") ulong Sigma1() (ulong x
) @safe nothrow pure { return R(x
, 14)^
R(x
, 18)^
R(x
, 41); }
898 private @tweetNaCl_gdc_attribute("forceinline") ulong sigma0() (ulong x
) @safe nothrow pure { return R(x
, 1)^
R(x
, 8)^
(x
>>7); }
899 private @tweetNaCl_gdc_attribute("forceinline") ulong sigma1() (ulong x
) @safe nothrow pure { return R(x
, 19)^
R(x
, 61)^
(x
>>6); }
901 private static __gshared
immutable ulong[80] K
= [
902 0x428a2f98d728ae22UL
, 0x7137449123ef65cdUL
, 0xb5c0fbcfec4d3b2fUL
, 0xe9b5dba58189dbbcUL
,
903 0x3956c25bf348b538UL
, 0x59f111f1b605d019UL
, 0x923f82a4af194f9bUL
, 0xab1c5ed5da6d8118UL
,
904 0xd807aa98a3030242UL
, 0x12835b0145706fbeUL
, 0x243185be4ee4b28cUL
, 0x550c7dc3d5ffb4e2UL
,
905 0x72be5d74f27b896fUL
, 0x80deb1fe3b1696b1UL
, 0x9bdc06a725c71235UL
, 0xc19bf174cf692694UL
,
906 0xe49b69c19ef14ad2UL
, 0xefbe4786384f25e3UL
, 0x0fc19dc68b8cd5b5UL
, 0x240ca1cc77ac9c65UL
,
907 0x2de92c6f592b0275UL
, 0x4a7484aa6ea6e483UL
, 0x5cb0a9dcbd41fbd4UL
, 0x76f988da831153b5UL
,
908 0x983e5152ee66dfabUL
, 0xa831c66d2db43210UL
, 0xb00327c898fb213fUL
, 0xbf597fc7beef0ee4UL
,
909 0xc6e00bf33da88fc2UL
, 0xd5a79147930aa725UL
, 0x06ca6351e003826fUL
, 0x142929670a0e6e70UL
,
910 0x27b70a8546d22ffcUL
, 0x2e1b21385c26c926UL
, 0x4d2c6dfc5ac42aedUL
, 0x53380d139d95b3dfUL
,
911 0x650a73548baf63deUL
, 0x766a0abb3c77b2a8UL
, 0x81c2c92e47edaee6UL
, 0x92722c851482353bUL
,
912 0xa2bfe8a14cf10364UL
, 0xa81a664bbc423001UL
, 0xc24b8b70d0f89791UL
, 0xc76c51a30654be30UL
,
913 0xd192e819d6ef5218UL
, 0xd69906245565a910UL
, 0xf40e35855771202aUL
, 0x106aa07032bbd1b8UL
,
914 0x19a4c116b8d2d0c8UL
, 0x1e376c085141ab53UL
, 0x2748774cdf8eeb99UL
, 0x34b0bcb5e19b48a8UL
,
915 0x391c0cb3c5c95a63UL
, 0x4ed8aa4ae3418acbUL
, 0x5b9cca4f7763e373UL
, 0x682e6ff3d6b2b8a3UL
,
916 0x748f82ee5defb2fcUL
, 0x78a5636f43172f60UL
, 0x84c87814a1f0ab72UL
, 0x8cc702081a6439ecUL
,
917 0x90befffa23631e28UL
, 0xa4506cebde82bde9UL
, 0xbef9a3f7b2c67915UL
, 0xc67178f2e372532bUL
,
918 0xca273eceea26619cUL
, 0xd186b8c721c0c207UL
, 0xeada7dd6cde0eb1eUL
, 0xf57d4f7fee6ed178UL
,
919 0x06f067aa72176fbaUL
, 0x0a637dc5a2c898a6UL
, 0x113f9804bef90daeUL
, 0x1b710b35131c471bUL
,
920 0x28db77f523047d84UL
, 0x32caab7b40c72493UL
, 0x3c9ebe0a15c9bebcUL
, 0x431d67c49c100d4cUL
,
921 0x4cc5d4becb3e42b6UL
, 0x597f299cfc657e2aUL
, 0x5fcb6fab3ad6faecUL
, 0x6c44198c4a475817UL
924 private void crypto_hashblocks (ubyte[] x
, const(ubyte)[] m
, ulong n
) @safe nothrow {
925 ulong[8] z
= void, b
= void, a
= void;
929 foreach (i
; 0..8) z
[i
] = a
[i
] = dl64(x
[8*i
..$]);
931 foreach (i
; 0..16) w
[i
] = dl64(m
[mpos
+8*i
..$]);
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 //foreach (j; 0..8) a[(j+1)%8] = b[j];
941 foreach (j
; 0..16) w
[j
] += w
[(j
+9)%16]+sigma0(w
[(j
+1)%16])+sigma1(w
[(j
+14)%16]);
944 foreach (i
; 0..8) { a
[i
] += z
[i
]; z
[i
] = a
[i
]; }
948 foreach (i
; 0..8) ts64(x
[8*i
..$], z
[i
]);
951 private static __gshared
immutable ubyte[64] iv
= [
952 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
953 0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
954 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
955 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
956 0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
957 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
958 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
959 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
963 * The crypto_hash() function hashes a message 'msg'.
964 * It returns a hash 'output'. The output length of 'output' should be at least crypto_hash_BYTES.
967 * output = resulting hash
973 void crypto_hash() (ubyte[] output
, const(ubyte)[] msg
) @safe nothrow
975 assert(output
.length
>= crypto_hash_BYTES
);
979 ubyte[256] x
; /*autoinit*/
980 size_t n
= msg
.length
;
986 crypto_hashblocks(h
, msg
, n
);
991 x
[0..n
] = msg
[mpos
..mpos
+n
];
996 ts64(x
[n
-8..$], b
<<3);
997 crypto_hashblocks(h
, x
, n
);
1002 private @tweetNaCl_gdc_attribute("forceinline") void add() (ref long[16][4] p
, ref long[16][4] q
) @safe nothrow {
1003 long[16] a
= void, b
= void, c
= void, d
= void, t
= void, e
= void, f
= void, g
= void, h
= void;
1026 private @tweetNaCl_gdc_attribute("forceinline") void cswap() (ref long[16][4] p
, ref long[16][4] q
, ubyte b
) @safe nothrow {
1027 foreach (i
; 0..4) sel25519(p
[i
], q
[i
], b
);
1030 private @tweetNaCl_gdc_attribute("forceinline") void pack() (ubyte[] r
, ref long[16][4] p
) @safe nothrow {
1031 long[16] tx
= void, ty
= void, zi
= void;
1036 r
[31] ^
= par25519(tx
)<<7;
1039 private @tweetNaCl_gdc_attribute("forceinline") void scalarmult() (ref long[16][4] p
, ref long[16][4] q
, const(ubyte)[] s
) @safe nothrow {
1044 for (int i
= 255; i
>= 0; --i
) {
1045 ubyte b
= (s
[i
/8]>>(i
&7))&1;
1053 private @tweetNaCl_gdc_attribute("forceinline") void scalarbase() (ref long[16][4] p
, const(ubyte)[] s
) @safe nothrow {
1054 long[16][4] q
= void;
1059 scalarmult(p
, q
, s
);
1063 * The crypto_sign_keypair() function randomly generates a secret key and
1064 * a corresponding public key.
1067 * pk = slice to put generated public key into
1068 * sk = slice to put generated secret key into
1073 void crypto_sign_keypair() (ubyte[] pk
, ubyte[] sk
) @trusted
1075 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1076 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1080 long[16][4] p
= void;
1082 randombytes(sk
, 32);
1083 crypto_hash(d
, sk
[0..32]);
1091 sk
[32..64] = pk
[0..32];
1094 private static __gshared
immutable ulong[32] L
= [
1095 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
1098 private @tweetNaCl_gdc_attribute("forceinline") void modL() (ubyte[] r
, long[] x
) @safe nothrow {
1100 for (auto i
= 63; i
>= 32; --i
) {
1103 for (j
= i
-32; j
< i
-12; ++j
) {
1104 x
[j
] += carry
-16*x
[i
]*L
[j
-(i
-32)];
1105 carry
= (x
[j
]+128)>>8;
1112 foreach (j
; 0..32) {
1113 x
[j
] += carry
-(x
[31]>>4)*L
[j
];
1117 foreach (j
; 0..32) x
[j
] -= carry
*L
[j
];
1118 foreach (i
; 0..32) {
1124 private @tweetNaCl_gdc_attribute("forceinline") void reduce() (ubyte[] r
) @safe nothrow {
1126 foreach (i
; 0..64) x
[i
] = cast(ulong)r
[i
];
1132 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1133 * The crypto_sign() function returns the resulting signed message.
1136 * sm = buffer to receive signed message, must be of size at least msg.length+64
1138 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1143 void crypto_sign() (ubyte[] sm
, const(ubyte)[] msg
, const(ubyte)[] sk
) @trusted nothrow
1145 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1146 assert(sm
.length
>= msg
.length
+64);
1149 ubyte[64] d
= void, h
= void, r
= void;
1150 ulong[64] x
;/*autoinit*/
1151 long[16][4] p
= void;
1152 size_t n
= msg
.length
;
1153 size_t smlen
= n
+64;
1155 crypto_hash(d
, sk
[0..32]);
1160 sm
[64..64+n
] = msg
[];
1161 sm
[32..64] = d
[32..64];
1163 crypto_hash(r
, sm
[32..32+n
+32]);
1168 sm
[32..64] = sk
[32..64];
1169 crypto_hash(h
, sm
[0..n
+64]);
1172 foreach (i
; 0..32) x
[i
] = cast(ulong)r
[i
];
1173 foreach (i
; 0..32) foreach (j
; 0..32) x
[i
+j
] += h
[i
]*cast(ulong)d
[j
];
1174 modL(sm
[32..$], cast(long[])x
);
1178 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1179 * The crypto_sign() function returns the resulting signed message.
1181 * WARNING! This function allocates!
1185 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1190 ubyte[] crypto_sign() (const(ubyte)[] msg
, const(ubyte)[] sk
) @safe nothrow
1192 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1196 size_t n
= msg
.length
;
1197 size_t smlen
= n
+64;
1199 crypto_sign(sm
, msg
, sk
);
1203 private @tweetNaCl_gdc_attribute("forceinline") bool unpackneg() (ref long[16][4] r
, const(ubyte)[] p
) @safe nothrow {
1204 long[16] t
= void, chk
= void, num
= void, den
= void, den2
= void, den4
= void, den6
= void;
1206 unpack25519(r
[1], p
);
1214 M(den6
, den4
, den2
);
1226 if (!neq25519(chk
, num
)) M(r
[0], r
[0], I
);
1230 if (!neq25519(chk
, num
)) return false;
1232 if (par25519(r
[0]) == (p
[31]>>7)) Z(r
[0], gf0
, r
[0]);
1234 M(r
[3], r
[0], r
[1]);
1239 * The crypto_sign_open() function verifies the signature in
1240 * 'sm' using the receiver's public key 'pk'.
1243 * msg = decrypted message, last 64 bytes are useless zeroes, must be of size at least sm.length
1244 * sm == signed message
1245 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1250 bool crypto_sign_open() (ubyte[] msg
, const(ubyte)[] sm
, const(ubyte)[] pk
) @safe nothrow
1252 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1253 assert(msg
.length
>= sm
.length
);
1258 long[16][4] p
= void, q
= void;
1259 size_t n
= sm
.length
;
1261 if (n
< 64) return false;
1263 if (!unpackneg(q
, pk
)) return false;
1265 msg
[32..64] = pk
[0..32];
1266 crypto_hash(h
, msg
);
1268 scalarmult(p
, q
, h
);
1270 scalarbase(q
, sm
[32..$]);
1275 if (!crypto_verify_32(sm
, t
)) {
1280 msg
[0..n
] = sm
[64..64+n
];
1288 * The crypto_sign_open() function verifies the signature in
1289 * 'sm' using the receiver's public key 'pk'.
1290 * The crypto_sign_open() function returns the message.
1292 * WARNING! This function allocates!
1295 * sm == signed message
1296 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1299 * decrypted message or null on error
1301 ubyte[] crypto_sign_open() (const(ubyte)[] sm
, const(ubyte)[] pk
) @safe nothrow {
1303 msg
.length
= sm
.length
;
1304 if (!crypto_sign_open(msg
, sm
, pk
)) return null;
1305 return msg
[0..sm
.length
-64]; // remove signature
1310 import std
.exception
;
1316 private extern(C) int open(const(char)* filename, int flags, ...);
1317 void randombytes (ubyte[] dest, size_t len) {
1318 import core.sys.posix.unistd;
1322 fd = open("/dev/urandom", /*O_RDONLY*/0);
1323 if (fd != -1) break;
1329 ssize_t i = read(fd, cast(void*)(&dest[pos]), (len < 1048576 ? len : 1048576));
1340 static void rnd (ubyte[] dest, size_t len) {
1341 for (size_t f = 0; f < len; ++f) dest[f] = cast(ubyte)uniform(0, 256);
1346 randombytes
= (ubyte[] dest
, size_t len
) {
1347 for (size_t f
= 0; f
< len
; ++f
) dest
[f
] = cast(ubyte)uniform(0, 256);
1350 void dumpArray(T
) (T
[] arr
) @trusted {
1351 writefln("============================= (%s)", arr
.length
);
1352 for (auto f
= 0; f
< arr
.length
; ++f
) {
1353 if (f
&& f
%16 == 0) writeln();
1354 static if (T
.sizeof
== 1) writef(" 0x%02x", arr
[f
]);
1355 else static if (T
.sizeof
== 2) writef(" 0x%04x", arr
[f
]);
1356 else static if (T
.sizeof
== 4) writef(" 0x%08x", arr
[f
]);
1357 else writef(" 0x%08x", arr
[f
]);
1360 writeln("-----------------------------");
1363 string
hashToString (const(ubyte)[] hash
) {
1365 s
.length
= hash
.length
*2;
1366 char toHex(int a
) { return cast(char)(a
< 10 ? a
+'0' : a
+'a'-10); }
1367 for (int a
= 0; a
< hash
.length
; ++a
) {
1368 s
[a
*2] = toHex(hash
[a
]>>4);
1369 s
[a
*2+1] = toHex(hash
[a
]&0x0f);
1371 return assumeUnique(s
);
1374 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];
1375 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];
1376 static immutable ubyte[5] m
= [0x61,0x68,0x6f,0x6a,0x0a];
1377 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];
1380 writeln("crypto_sign");
1381 smres
= crypto_sign(m
, sk
);
1382 assert(smres
.length
== sm
.length
);
1383 assert(smres
== sm
);
1385 writeln("crypto_sign_open");
1386 t
= crypto_sign_open(smres
, pk
);
1388 assert(t
.length
== m
.length
);
1392 // based on the code by Adam D. Ruppe
1393 // 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
1394 template SHARange(T
) if (isInputRange
!(T
)) {
1398 bool empty () { return state
== 5; }
1410 bool hackforward
= false;
1414 if (((position
+length
+8)*8)%512 == 8) {
1420 } else if (state
== 2) {
1422 if (!(((position
+length
+8)*8)%512)) {
1426 if (hackforward
) goto proceedmoar
;
1430 } else if (state
== 3) {
1432 current
= (length
>>(position
*8))&0xff;
1433 if (position
== 0) state
= 4; else --position
;
1434 } else if (state
== 4) {
1442 if (state
== 0) return cast(ubyte)r
.front();
1444 //writefln("%x", current);
1451 int state
= 0; // reading range, reading appended bit, reading padding, reading length, done
1456 immutable(ubyte)[] SHA256(T
) (T data
) if (isInputRange
!(T
)) {
1457 uint[8] h
= [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
1458 static immutable(uint[64]) k
= [
1459 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1460 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1461 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1462 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1463 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1464 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1465 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1466 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1471 static if (is(data
== SHARange
)) range
= data
; else range
.r
= data
;
1474 while(!range
.empty
) {
1477 for(int a
= 0; a
< 16; ++a
) {
1478 for(int b
= 3; b
>= 0; --b
) {
1479 words
[a
] |
= cast(uint)(range
.front())<<(b
*8);
1484 uint ror (uint n
, int cnt
) {
1485 return cast(uint)(n
>>cnt
)|
cast(uint)(n
<<(32-(cnt
)));
1488 uint xrot00 (uint reax
, int r0
, int r1
, int r2
) {
1489 uint rebx
= reax
, recx
= reax
;
1490 reax
= ror(reax
, r0
);
1491 rebx
= ror(rebx
, r1
);
1498 for(int a
= 16; a
< 64; ++a
) {
1499 uint t1
= xrot00(words
[a
-15], 7, 18, 3);
1500 uint t2
= xrot00(words
[a
-2], 17, 19, 10);
1501 words
[a
] = words
[a
-16]+t1
+words
[a
-7]+t2
;
1513 uint xrot01 (uint reax
, int r0
, int r1
, int r2
) {
1514 uint rebx
= reax
, recx
= reax
;
1515 reax
= ror(reax
, r0
);
1516 rebx
= ror(rebx
, r1
);
1517 recx
= ror(recx
, r2
);
1523 for(int i
= 0; i
< 64; ++i
) {
1524 uint s0
= xrot01(A
, 2, 13, 22);
1525 uint maj
= (A
&B
)^
(A
&C
)^
(B
&C
);
1527 uint s1
= xrot01(E
, 6, 11, 25);
1528 uint ch
= (E
&F
)^
((~E
)&G
);
1529 uint t1
= H
+s1
+ch
+k
[i
]+words
[i
];
1552 for(int j
= 0; j
< 8; ++j
)
1553 for(int i
= 3; i
>= 0; --i
) {
1554 hash
~= cast(ubyte)(h
[j
]>>(i
*8))&0xff;
1564 static immutable ubyte[32] alicesk
= [
1565 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
1566 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
1567 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
1568 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
1571 static immutable ubyte[32] bobpk
= [
1572 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
1573 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
1574 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
1575 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
1578 static immutable ubyte[24] nonce
= [
1579 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1580 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1581 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1584 // API requires first 32 bytes to be 0
1585 static immutable ubyte[163] m
= [
1586 0, 0, 0, 0, 0, 0, 0, 0
1587 , 0, 0, 0, 0, 0, 0, 0, 0
1588 , 0, 0, 0, 0, 0, 0, 0, 0
1589 , 0, 0, 0, 0, 0, 0, 0, 0
1590 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1591 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1592 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1593 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1594 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1595 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1596 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1597 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1598 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1599 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1600 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1601 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1602 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1603 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1604 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1605 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1612 static immutable ubyte[] res
= [
1613 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1614 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1615 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1616 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1617 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1618 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1619 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1620 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1621 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1622 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1623 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1624 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1625 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1626 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1627 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1628 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1629 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1630 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1632 /*crypto_box_curve25519xsalsa20poly1305*/crypto_box(c
,m
,nonce
,bobpk
,alicesk
);
1633 for (auto f
= 16; f
< 163; ++f
) assert(c
[f
] == res
[f
-16]);
1639 static immutable ubyte[32] bobsk
= [
1640 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
1641 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
1642 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
1643 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
1646 static immutable ubyte[32] alicepk
= [
1647 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
1648 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
1649 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
1650 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
1653 static immutable ubyte[24] nonce
= [
1654 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1655 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1656 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1659 // API requires first 16 bytes to be 0
1660 static immutable ubyte[163] c
= [
1661 0, 0, 0, 0, 0, 0, 0, 0
1662 , 0, 0, 0, 0, 0, 0, 0, 0
1663 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1664 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1665 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1666 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1667 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1668 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1669 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1670 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1671 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1672 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1673 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1674 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1675 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1676 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1677 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1678 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1679 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1680 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1686 static immutable ubyte[] res
= [
1687 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1688 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1689 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1690 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1691 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1692 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1693 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1694 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1695 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1696 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1697 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1698 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1699 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1700 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1701 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1702 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1706 assert(/*crypto_box_curve25519xsalsa20poly1305_open*/crypto_box_open(m
,c
,nonce
,alicepk
,bobsk
));
1707 for (auto f
= 32; f
< 163; ++f
) assert(m
[f
] == res
[f
-32]);
1713 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1714 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1715 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1716 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1717 ubyte[crypto_box_NONCEBYTES
] n
;
1718 ubyte[10000] m
, c
, m2
;
1719 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1720 crypto_box_keypair(alicepk
,alicesk
);
1721 crypto_box_keypair(bobpk
,bobsk
);
1722 randombytes(n
,crypto_box_NONCEBYTES
);
1723 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1724 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1725 assert(crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
));
1726 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1729 version(unittest_full
) box7(); // it's slow
1733 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1734 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1735 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1736 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1737 ubyte[crypto_box_NONCEBYTES
] n
;
1738 ubyte[10000] m
, c
, m2
;
1739 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1740 crypto_box_keypair(alicepk
,alicesk
);
1741 crypto_box_keypair(bobpk
,bobsk
);
1742 randombytes(n
,crypto_box_NONCEBYTES
);
1743 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1744 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1746 while (caught
< 10) {
1747 c
[uniform(0, mlen
+crypto_box_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
1748 if (crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
)) {
1749 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1754 assert(caught
== 10);
1757 version(unittest_full
) box8(); // it's slow
1761 static immutable ubyte[32] shared_
= [
1762 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
1763 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
1764 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
1765 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
1768 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];
1770 static immutable ubyte[16] c
= [
1771 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1772 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1777 static immutable ubyte[32] res
= [
1778 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1779 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1780 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1781 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1784 crypto_core_hsalsa20(firstkey
,zero
,shared_
,c
);
1785 assert(firstkey
== res
);
1791 static immutable ubyte[32]firstkey
= [
1792 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1793 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1794 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1795 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1798 static immutable ubyte[16]nonceprefix
= [
1799 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1800 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1803 static immutable ubyte[16] c
= [
1804 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1805 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1808 ubyte[32] secondkey
;
1810 static immutable ubyte[32] res
= [
1811 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1812 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1813 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1814 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1817 crypto_core_hsalsa20(secondkey
,nonceprefix
,firstkey
,c
);
1818 assert(secondkey
== res
);
1824 static immutable ubyte[32] secondkey
= [
1825 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1826 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1827 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1828 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1831 static immutable ubyte[8] noncesuffix
= [
1832 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1835 static immutable ubyte[16] c
= [
1836 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1837 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1840 static ubyte[16] input
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ;
1842 static ubyte output
[64*256*256];
1846 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];
1849 for (auto i
= 0; i
< 8; ++i
) input
[i
] = noncesuffix
[i
];
1852 crypto_core_salsa20(output
[pos
..$],input
,secondkey
,c
);
1854 } while (++input
[8]);
1855 } while (++input
[9]);
1856 crypto_hash(h
,output
);
1859 version(unittest_full
) core3(); // it's slow
1863 static immutable ubyte[32] k
= [
1864 1, 2, 3, 4, 5, 6, 7, 8
1865 , 9, 10, 11, 12, 13, 14, 15, 16
1866 ,201,202,203,204,205,206,207,208
1867 ,209,210,211,212,213,214,215,216
1870 static immutable ubyte[16] input
= [
1871 101,102,103,104,105,106,107,108
1872 ,109,110,111,112,113,114,115,116
1875 static immutable ubyte[16] c
= [
1876 101,120,112, 97,110,100, 32, 51
1877 , 50, 45, 98,121,116,101, 32,107
1882 static immutable ubyte[64] res
= [
1883 69, 37, 68, 39, 41, 15,107,193
1884 ,255,139,122, 6,170,233,217, 98
1885 , 89,144,182,106, 21, 51,200, 65
1886 ,239, 49,222, 34,215,114, 40,126
1887 ,104,197, 7,225,197,153, 31, 2
1888 ,102, 78, 76,176, 84,245,246,184
1889 ,177,160,133,130, 6, 72,149,119
1890 ,192,195,132,236,234,103,246, 74
1893 crypto_core_salsa20(output
,input
,k
,c
);
1894 assert(output
== res
);
1900 static immutable ubyte[32] k
= [
1901 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1902 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1903 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1904 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1907 static immutable ubyte[16] input
= [
1908 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1909 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1912 static immutable ubyte[16] c
= [
1913 101,120,112, 97,110,100, 32, 51
1914 , 50, 45, 98,121,116,101, 32,107
1919 static immutable ubyte[32] res
= [
1920 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1921 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1922 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1923 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1926 crypto_core_hsalsa20(output
,input
,k
,c
);
1927 assert(output
== res
);
1933 static immutable ubyte[32] k
= [
1934 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1935 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1936 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1937 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1940 static immutable ubyte[16] input
= [
1941 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1942 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1945 static immutable ubyte[16] c
= [
1946 101,120,112, 97,110,100, 32, 51
1947 , 50, 45, 98,121,116,101, 32,107
1952 static immutable ubyte[32] res
= [
1953 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1954 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1955 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1956 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1962 void print(const(ubyte)[] x
, const(ubyte)[] y
)
1965 for (auto i
= 0; i
< 4; ++i
) {
1968 //printf(",0x%02x",255&(xi-yi-borrow));
1969 pp
[pppos
++] = cast(ubyte)(255&(xi
-yi
-borrow
));
1970 borrow
= (xi
< yi
+borrow
);
1974 crypto_core_salsa20(output
,input
,k
,c
);
1976 print(output
[20..$],c
[4..$]);
1977 print(output
[40..$],c
[8..$]);
1978 print(output
[60..$],c
[12..$]);
1979 print(output
[24..$],input
);
1980 print(output
[28..$],input
[4..$]);
1981 print(output
[32..$],input
[8..$]);
1982 print(output
[36..$],input
[12..$]);
1989 static immutable ubyte x
[8] = ['t','e','s','t','i','n','g','\n'];
1990 static ubyte[crypto_hash_BYTES
] h
;
1991 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];
1993 //for (auto f = 0; f < crypto_hash_BYTES; ++f) assert(h[f] == res[f]);
1998 void onetimeauth () {
1999 writeln("onetimeauth");
2000 static immutable ubyte rs
[32] = [
2001 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2002 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2003 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2004 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2007 static immutable ubyte c
[131] = [
2008 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2009 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2010 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2011 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2012 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2013 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2014 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2015 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2016 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2017 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2018 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2019 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2020 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2021 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2022 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2023 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2029 static immutable ubyte[16] res
= [0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9];
2031 /*crypto_onetimeauth_poly1305*/crypto_onetimeauth(a
,c
,rs
);
2036 void onetimeauth2 () {
2037 writeln("onetimeauth2");
2038 static immutable ubyte[32] rs
= [
2039 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2040 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2041 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2042 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2045 static immutable ubyte[131] c
= [
2046 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2047 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2048 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2049 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2050 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2051 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2052 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2053 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2054 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2055 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2056 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2057 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2058 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2059 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2060 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2061 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2065 static immutable ubyte[16] a
= [
2066 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2067 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2070 assert(/*crypto_onetimeauth_poly1305_verify*/crypto_onetimeauth_verify(a
,c
,rs
));
2074 void onetimeauth7 () {
2075 writeln("onetimeauth7");
2076 static ubyte[32] key
;
2077 static ubyte[10000] c
;
2080 for (auto clen
= 0; clen
< 10000; ++clen
) {
2081 //if (clen%512 == 0) { writef("\r%s", clen); stdout.flush(); }
2082 randombytes(key
, key
.length
);
2083 randombytes(c
, clen
);
2084 crypto_onetimeauth(a
,c
[0..clen
],key
);
2085 assert(crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2087 c
[uniform(0, clen
)] += 1+(uniform(0, 255));
2088 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2089 a
[uniform(0, a
.length
)] += 1+(uniform(0, 255));
2090 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2094 version(unittest_full
) onetimeauth7(); // it's slow
2096 void scalarmult () {
2097 writeln("scalarmult");
2098 static immutable ubyte[32] alicesk
= [
2099 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2100 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2101 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2102 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2107 static immutable ubyte[32] res
= [
2108 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2109 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2110 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2111 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2114 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(alicepk
,alicesk
);
2115 assert(alicepk
== res
);
2119 void scalarmult2 () {
2120 writeln("scalarmult2");
2121 static immutable ubyte[32] bobsk
= [
2122 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2123 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2124 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2125 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2130 static immutable ubyte[32] res
= [
2131 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2132 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2133 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2134 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2137 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(bobpk
,bobsk
);
2138 assert(bobpk
== res
);
2142 void scalarmult5 () {
2143 writeln("scalarmult5");
2144 static immutable ubyte[32] alicesk
= [
2145 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2146 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2147 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2148 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2151 static immutable ubyte[32] bobpk
= [
2152 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2153 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2154 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2155 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2160 static immutable ubyte[32] res
= [
2161 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2162 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2163 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2164 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2167 crypto_scalarmult(k
,alicesk
,bobpk
);
2172 void scalarmult6 () {
2173 writeln("scalarmult6");
2174 static immutable ubyte[32] bobsk
= [
2175 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2176 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2177 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2178 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2181 static immutable ubyte[32] alicepk
= [
2182 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2183 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2184 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2185 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2190 static immutable ubyte[32] res
= [
2191 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2192 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2193 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2194 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2197 crypto_scalarmult(k
,bobsk
,alicepk
);
2203 writeln("secretbox");
2204 static immutable ubyte[32] firstkey
= [
2205 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2206 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2207 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2208 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2211 static immutable ubyte[24] nonce
= [
2212 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2213 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2214 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2217 // API requires first 32 bytes to be 0
2218 static immutable ubyte[163] m
= [
2219 0, 0, 0, 0, 0, 0, 0, 0
2220 , 0, 0, 0, 0, 0, 0, 0, 0
2221 , 0, 0, 0, 0, 0, 0, 0, 0
2222 , 0, 0, 0, 0, 0, 0, 0, 0
2223 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2224 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2225 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2226 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2227 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2228 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2229 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2230 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2231 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2232 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2233 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2234 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2235 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2236 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2237 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2238 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2242 static immutable ubyte[] res
= [
2243 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2244 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2245 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2246 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2247 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2248 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2249 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2250 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2251 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2252 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2253 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2254 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2255 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2256 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2257 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2258 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2259 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2260 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2265 crypto_secretbox(c
,m
,nonce
,firstkey
);
2266 for (auto i
= 16; i
< 163; ++i
) assert(c
[i
] == res
[i
-16]);
2270 void secretbox2 () {
2271 writeln("secretbox2");
2272 static immutable ubyte[32] firstkey
= [
2273 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2274 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2275 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2276 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2279 static immutable ubyte[24] nonce
= [
2280 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2281 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2282 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2285 // API requires first 16 bytes to be 0
2286 static immutable ubyte[163] c
= [
2287 0, 0, 0, 0, 0, 0, 0, 0
2288 , 0, 0, 0, 0, 0, 0, 0, 0
2289 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2290 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2291 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2292 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2293 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2294 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2295 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2296 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2297 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2298 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2299 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2300 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2301 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2302 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2303 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2304 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2305 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2306 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2310 static immutable ubyte[] res
= [
2311 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2312 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2313 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2314 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2315 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2316 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2317 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2318 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2319 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2320 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2321 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2322 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2323 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2324 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2325 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2326 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2332 assert(crypto_secretbox_open(m
,c
,nonce
,firstkey
));
2333 for (auto i
= 32; i
< 163; ++i
) assert(m
[i
] == res
[i
-32]);
2337 void secretbox7 () {
2338 writeln("secretbox7");
2339 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2340 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2341 static ubyte[10000] m
, c
, m2
;
2342 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2343 randombytes(k
,crypto_secretbox_KEYBYTES
);
2344 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2345 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2346 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2347 assert(crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
));
2348 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2353 void secretbox8 () {
2354 writeln("secretbox8");
2355 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2356 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2357 static ubyte[10000] m
, c
, m2
;
2358 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2359 randombytes(k
,crypto_secretbox_KEYBYTES
);
2360 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2361 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2362 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2364 while (caught
< 10) {
2365 c
[uniform(0, mlen
+crypto_secretbox_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
2366 if (crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
)) {
2367 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2371 assert(caught
== 10);
2374 version(unittest_full
) secretbox8(); // it's slow
2378 static immutable ubyte[32] firstkey
= [
2379 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2380 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2381 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2382 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2385 static immutable ubyte[24] nonce
= [
2386 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2387 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2388 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2391 static ubyte[4194304] output
;
2394 //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];
2396 crypto_stream(output
,nonce
,firstkey
);
2397 //crypto_hash_sha256(h,output,sizeof output);
2398 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2404 static immutable ubyte[32] secondkey
= [
2405 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
2406 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
2407 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
2408 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
2411 static immutable ubyte[8] noncesuffix
= [
2412 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2415 static ubyte[4194304] output
;
2417 crypto_stream_salsa20(output
,noncesuffix
,secondkey
);
2418 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2424 static immutable ubyte[32] firstkey
= [
2425 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2426 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2427 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2428 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2431 static immutable ubyte[24] nonce
= [
2432 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2433 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2434 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2439 static immutable ubyte[32] res
= [
2440 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2441 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2442 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2443 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2446 crypto_stream
/*_xsalsa20*/(rs
,nonce
,firstkey
);
2453 static immutable ubyte[32] firstkey
= [
2454 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2455 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2456 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2457 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2460 static immutable ubyte[24] nonce
= [
2461 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2462 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2463 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2466 static immutable ubyte[163] m
= [
2467 0, 0, 0, 0, 0, 0, 0, 0
2468 , 0, 0, 0, 0, 0, 0, 0, 0
2469 , 0, 0, 0, 0, 0, 0, 0, 0
2470 , 0, 0, 0, 0, 0, 0, 0, 0
2471 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2472 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2473 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2474 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2475 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2476 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2477 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2478 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2479 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2480 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2481 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2482 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2483 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2484 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2485 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2486 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2492 static immutable ubyte[] res
= [
2493 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2494 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2495 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2496 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2497 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2498 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2499 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2500 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2501 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2502 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2503 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2504 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2505 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2506 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2507 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2508 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2512 /*crypto_stream_xsalsa20_xor*/crypto_stream_xor(c
,m
,nonce
,firstkey
);
2513 for (auto i
= 32; i
< 163; ++i
) assert(c
[i
] == res
[i
-32]);
2518 version(unittest_main
) {