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).
12 //k8: yes, i know that this code sux. i know that i should rewrite it to be more 'D-ish'.
13 // i'll not do that. make your own port or do it yourself if you dissatisfied with my
14 // attitude. thank you.
17 // define tweetnacl_enable_inlining to speed up tweetNaCl on GDC
19 version(tweetnacl_enable_inlining
) version=tweetnacl_enable_inlining_on_
;
20 else version=tweetnacl_enable_inlining_off_
;
22 version=tweetnacl_enable_inlining_off_
;
25 version(tweetnacl_enable_inlining_on_
) {
26 static import gcc
.attribute
;
27 private enum gcc_inline
= gcc
.attribute
.attribute("forceinline");
29 // hackery for non-gcc compilers
30 private enum gcc_inline
;
35 crypto_auth_BYTES
= 32,
36 crypto_auth_KEYBYTES
= 32,
38 crypto_box_PUBLICKEYBYTES
= 32,
39 crypto_box_SECRETKEYBYTES
= 32,
40 crypto_box_BEFORENMBYTES
= 32,
41 crypto_box_NONCEBYTES
= 24,
42 crypto_box_ZEROBYTES
= 32,
43 crypto_box_BOXZEROBYTES
= 16,
45 crypto_core_salsa20_OUTPUTBYTES
= 64,
46 crypto_core_salsa20_INPUTBYTES
= 16,
47 crypto_core_salsa20_KEYBYTES
= 32,
48 crypto_core_salsa20_CONSTBYTES
= 16,
50 crypto_core_hsalsa20_OUTPUTBYTES
= 32,
51 crypto_core_hsalsa20_INPUTBYTES
= 16,
52 crypto_core_hsalsa20_KEYBYTES
= 32,
53 crypto_core_hsalsa20_CONSTBYTES
= 16,
55 crypto_hash_BYTES
= 64,
57 crypto_onetimeauth_BYTES
= 16,
58 crypto_onetimeauth_KEYBYTES
= 32,
60 crypto_scalarmult_BYTES
= 32,
61 crypto_scalarmult_SCALARBYTES
= 32,
63 crypto_secretbox_KEYBYTES
= 32,
64 crypto_secretbox_NONCEBYTES
= 24,
65 crypto_secretbox_ZEROBYTES
= 32,
66 crypto_secretbox_BOXZEROBYTES
= 16,
68 crypto_sign_BYTES
= 64,
69 crypto_sign_PUBLICKEYBYTES
= 32,
70 crypto_sign_SECRETKEYBYTES
= 64,
72 crypto_stream_xsalsa20_KEYBYTES
= 32,
73 crypto_stream_xsalsa20_NONCEBYTES
= 24,
75 crypto_stream_salsa20_KEYBYTES
= 32,
76 crypto_stream_salsa20_NONCEBYTES
= 8,
78 crypto_stream_KEYBYTES
= 32,
79 crypto_stream_NONCEBYTES
= 24,
81 crypto_verify_16_BYTES
= 16,
82 crypto_verify_32_BYTES
= 32,
86 /// set this callback to good (cryptograpic strong) random bytes generator
87 /// you can use /dev/urandom as prng
88 void function (ubyte[] dest
, size_t len
) randombytes
= null;
91 private immutable ubyte[16] _0
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
92 private 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];
94 private immutable long[16]
95 gf0
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
96 gf1
= [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
97 _121665
= [0xDB41,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
98 D
= [0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203],
99 D2
=[0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406],
100 X
= [0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169],
101 Y
= [0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666],
102 I
= [0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83];
104 private @gcc_inline uint ld32() (const(ubyte)[] x
) @safe nothrow
106 assert(x
.length
>= 4);
115 private @gcc_inline ulong dl64() (const(ubyte)[] x
) @safe nothrow
117 assert(x
.length
>= 8);
130 private @gcc_inline void st32() (ubyte[] x
, uint u
) @safe nothrow
132 assert(x
.length
>= 4);
141 private @gcc_inline void ts64() (ubyte[] x
, ulong u
) @safe nothrow
143 assert(x
.length
>= 8);
156 private @gcc_inline bool vn() (const(ubyte)[] x
, const(ubyte)[] y
) @safe nothrow
158 assert(x
.length
>= y
.length
);
162 foreach (immutable i
, immutable v
; x
) d |
= v^y
[i
];
163 return (1&((d
-1)>>8)) != 0;
167 * The crypto_verify_16() function checks that strings 'x' and 'y' has same content.
170 * x = first string, slice length must be at least crypto_verify_16_BYTES, extra ignored
171 * y = second string, slice length must be at least crypto_verify_16_BYTES, extra ignored
176 @gcc_inline bool crypto_verify_16() (const(ubyte)[] x
, const(ubyte)[] y
) @safe nothrow
178 assert(x
.length
>= 16 && y
.length
>= 16);
181 return vn(x
[0..16], y
[0..16]);
185 * The crypto_verify_32() function checks that strings 'x' and 'y' has same content.
188 * x = first string, slice length must be at least crypto_verify_32_BYTES, extra ignored
189 * y = second string, slice length must be at least crypto_verify_32_BYTES, extra ignored
194 @gcc_inline bool crypto_verify_32() (const(ubyte)[] x
, const(ubyte)[] y
) @safe nothrow
196 assert(x
.length
>= 32 && y
.length
>= 32);
199 return vn(x
[0..32], y
[0..32]);
203 private void salsa_core(string type
) (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
) @safe nothrow
204 if (type
== "salsa" || type
== "hsalsa") // constraint
207 assert(mixin(`output.length >= crypto_core_`~type
~`20_OUTPUTBYTES`));
208 assert(mixin(`input.length >= crypto_core_`~type
~`20_INPUTBYTES`));
209 assert(mixin(`key.length >= crypto_core_`~type
~`20_KEYBYTES`));
210 assert(mixin(`constant.length >= crypto_core_`~type
~`20_CONSTBYTES`));
213 static @gcc_inline uint ROTL32() (uint x
, int c
) @safe nothrow pure { return (x
<<c
)|
((x
&0xffffffff)>>(32-c
)); }
215 uint[16] w
= void, x
= void, y
= void;
219 x
[5*i
] = ld32(constant
[4*i
..$]);
220 x
[1+i
] = ld32(key
[4*i
..$]);
221 x
[6+i
] = ld32(input
[4*i
..$]);
222 x
[11+i
] = ld32(key
[16+4*i
..$]);
229 foreach (m
; 0..4) t
[m
] = x
[(5*j
+4*m
)%16];
230 t
[1] ^
= ROTL32(t
[0]+t
[3], 7);
231 t
[2] ^
= ROTL32(t
[1]+t
[0], 9);
232 t
[3] ^
= ROTL32(t
[2]+t
[1], 13);
233 t
[0] ^
= ROTL32(t
[3]+t
[2], 18);
234 for (auto m
= 0; m
< 4; ++m
) w
[4*j
+(j
+m
)%4] = t
[m
];
236 for (auto m
= 0; m
< 16; ++m
) x
[m
] = w
[m
];
239 static if (type
== "hsalsa") {
240 for (auto i
= 0; i
< 16; ++i
) x
[i
] += y
[i
];
241 for (auto i
= 0; i
< 4; ++i
) {
242 x
[5*i
] -= ld32(constant
[4*i
..$]);
243 x
[6+i
] -= ld32(input
[4*i
..$]);
245 for (auto i
= 0; i
< 4; ++i
) {
246 st32(output
[4*i
..$], x
[5*i
]);
247 st32(output
[16+4*i
..$], x
[6+i
]);
250 for (auto i
= 0; i
< 16; ++i
) st32(output
[4*i
..$], x
[i
]+y
[i
]);
254 @gcc_inline void crypto_core_salsa20() (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
)
256 salsa_core
!"salsa"(output
, input
, key
, constant
);
259 @gcc_inline void crypto_core_hsalsa20() (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
)
261 salsa_core
!"hsalsa"(output
, input
, key
, constant
);
264 private immutable(ubyte)[] sigma
= cast(immutable(ubyte)[])"expand 32-byte k";
267 * The crypto_stream_salsa20_xor() function encrypts a message 'msg' using a secret key 'key'
268 * and a nonce 'nonce'. The crypto_stream_salsa20_xor() function returns the ciphertext 'output'.
271 * output = resulting ciphertext
277 * ciphertext in 'output'
279 void crypto_stream_salsa20_xor (ubyte[] output
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @trusted nothrow
281 assert(nonce
.length
== crypto_stream_salsa20_NONCEBYTES
);
282 assert(key
.length
== crypto_stream_salsa20_KEYBYTES
);
284 assert(msg
.length
== 0 || output
.length
<= msg
.length
);
287 ubyte[16] z
; // autoclear
290 uint cpos
= 0, mpos
= 0;
291 size_t b
= output
.length
;
293 z
[0..8] = nonce
[0..8];
295 crypto_core_salsa20(x
, z
, key
, sigma
);
297 foreach (v
; x
) output
[cpos
++] = msg
[mpos
++]^v
;
299 output
[cpos
..cpos
+64] = x
[];
311 crypto_core_salsa20(x
, z
, key
, sigma
);
313 foreach (i
; 0..b
) output
[cpos
++] = msg
[mpos
++]^x
[i
];
315 output
[cpos
..cpos
+b
] = x
[0..b
];
321 * The crypto_stream_salsa20() function produces a stream 'c'
322 * as a function of a secret key 'key' and a nonce 'nonce'.
325 * c = resulting stream
332 void crypto_stream_salsa20() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
334 assert(nonce
.length
== crypto_stream_salsa20_NONCEBYTES
);
335 assert(key
.length
== crypto_stream_salsa20_KEYBYTES
);
338 crypto_stream_salsa20_xor(c
, null, nonce
, key
);
342 * The crypto_stream() function produces a stream 'c'
343 * as a function of a secret key 'key' and a nonce 'nonce'.
353 void crypto_stream() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
356 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
357 assert(key
.length
== crypto_stream_KEYBYTES
);
361 crypto_core_hsalsa20(s
, nonce
, key
, sigma
);
362 crypto_stream_salsa20(c
, nonce
[16..$], s
);
366 * The crypto_stream_xor() function encrypts a message 'msg' using a secret key 'key'
367 * and a nonce 'nonce'. The crypto_stream_xor() function returns the ciphertext 'c'.
377 void crypto_stream_xor() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
380 assert(msg
.length
>= c
.length
);
381 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
382 assert(key
.length
== crypto_stream_KEYBYTES
);
386 crypto_core_hsalsa20(s
, nonce
, key
, sigma
);
387 crypto_stream_salsa20_xor(c
, msg
, nonce
[16..$], s
);
390 private @gcc_inline void add1305() (uint[] h
, const(uint)[] c
) @safe nothrow {
399 private immutable uint[17] minusp
= [5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252];
402 * The crypto_onetimeauth() function authenticates a message 'msg'
403 * using a secret key 'key'. The function returns an authenticator 'output'.
406 * output = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
408 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
411 * authenticator in 'output'
413 void crypto_onetimeauth() (ubyte[] output
, const(ubyte)[] msg
, const(ubyte)[] key
) @safe nothrow
415 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
416 assert(output
.length
>= crypto_onetimeauth_BYTES
);
420 uint[17] x
= void, r
= void, h
/*autoclear*/, c
= void, g
= void;
422 size_t n
= msg
.length
;
424 foreach (i
; 0..16) r
[i
] = key
[i
];
439 for (jj
= 0; jj
< 16 && jj
< n
; ++jj
) c
[jj
] = msg
[mpos
+jj
];
447 foreach (j
; 0..17) x
[i
] += h
[j
]*(j
<= i ? r
[i
-j
] : 320*r
[i
+17-j
]);
471 foreach (j
; 0..17) h
[j
] ^
= s
&(g
[j
]^h
[j
]);
473 foreach (j
; 0..16) c
[j
] = key
[j
+16];
476 foreach (j
; 0..16) output
[j
] = cast(ubyte)(h
[j
]&0xff);
480 * The crypto_onetimeauth_verify() function checks that
481 * 'h' is a correct authenticator of a message 'msg' under the secret key 'key'.
484 * h = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
486 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
491 bool crypto_onetimeauth_verify() (const(ubyte)[] h
, const(ubyte)[] msg
, const(ubyte)[] key
) @safe nothrow
493 assert(h
.length
>= crypto_onetimeauth_BYTES
);
494 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
498 crypto_onetimeauth(x
, msg
, key
);
499 return crypto_verify_16(h
, x
);
503 * The crypto_secretbox() function encrypts and authenticates
504 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
505 * The crypto_secretbox() function returns the resulting ciphertext 'c'.
508 * c = resulting cyphertext
513 * success flag and cyphertext in 'c'
515 bool crypto_secretbox() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
517 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
518 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
521 //c.length = msg.length+crypto_secretbox_ZEROBYTES;
522 if (c
is null || c
.length
< 32) return false;
523 crypto_stream_xor(c
, msg
, nonce
, key
);
524 crypto_onetimeauth(c
[16..$], c
[32..$], c
);
526 //return c[crypto_secretbox_BOXZEROBYTES..$];
531 * The crypto_secretbox_open() function verifies and decrypts
532 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
533 * The crypto_secretbox_open() function returns the resulting plaintext 'output'.
536 * output = resulting message
542 * success flag and message in 'output'
544 bool crypto_secretbox_open() (ubyte[] output
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
546 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
547 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
551 if (output
is null || output
.length
< 32) return false;
552 crypto_stream(x
, nonce
, key
);
553 if (!crypto_onetimeauth_verify(c
[16..$], c
[32../*$*/32+(output
.length
-32)], x
)) return false;
554 crypto_stream_xor(output
, c
, nonce
, key
);
560 private @gcc_inline void car25519() (long[] o
) @safe nothrow {
564 o
[(i
+1)*(i
<15)] += c
-1+37*(c
-1)*(i
==15);
569 private @gcc_inline void sel25519() (long[] p
,long[] q
, int b
) @safe nothrow {
572 long t
= c
&(p
[i
]^q
[i
]);
578 private @gcc_inline void pack25519() (ubyte[] o
, const(long)[] n
) @safe nothrow {
580 long[16] m
= void, t
= void;
588 m
[i
] = t
[i
]-0xffff-((m
[i
-1]>>16)&1);
591 m
[15] = t
[15]-0x7fff-((m
[14]>>16)&1);
598 o
[2*i
+1] = (t
[i
]>>8)&0xff;
602 private @gcc_inline bool neq25519() (const(long)[] a
, const(long)[] b
) @safe nothrow {
603 ubyte[32] c
= void, d
= void;
606 return crypto_verify_32(c
, d
);
609 private @gcc_inline ubyte par25519() (const(long)[] a
) @safe nothrow {
615 private @gcc_inline void unpack25519() (long[] o
, const(ubyte)[] n
) @safe nothrow {
616 foreach (i
; 0..16) o
[i
] = n
[2*i
]+(cast(long)n
[2*i
+1]<<8);
620 private @gcc_inline void A() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
621 foreach (i
; 0..16) o
[i
] = a
[i
]+b
[i
];
624 private @gcc_inline void Z() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
625 foreach (i
; 0..16) o
[i
] = a
[i
]-b
[i
];
628 private @gcc_inline void M() (long[] o
, const(long)[] a
, const(long)[] b
) @safe nothrow {
629 long[31] t
; // automatically becomes 0
630 foreach (i
; 0..16) foreach (j
; 0..16) t
[i
+j
] += a
[i
]*b
[j
];
631 foreach (i
; 0..15) t
[i
] += 38*t
[i
+16];
637 private @gcc_inline void S() (long[] o
, const(long)[] a
) @safe nothrow {
641 private @gcc_inline void inv25519() (long[] o
, const(long)[] i
) @safe nothrow {
644 for (auto a
= 253; a
>= 0; --a
) {
646 if (a
!= 2 && a
!= 4) M(c
, c
, i
);
651 private @gcc_inline void pow2523() (long[] o
, const(long)[] i
) @safe nothrow {
654 for(auto a
= 250; a
>= 0; --a
) {
656 if (a
!= 1) M(c
, c
, i
);
662 * This function multiplies a group element 'p' by an integer 'n'.
669 * resulting group element 'q' of length crypto_scalarmult_BYTES.
671 private void crypto_scalarmult (ubyte[] q
, const(ubyte)[] n
, const(ubyte)[] p
) @safe nothrow
673 assert(q
.length
== crypto_scalarmult_BYTES
);
674 assert(n
.length
== crypto_scalarmult_BYTES
);
675 assert(p
.length
== crypto_scalarmult_BYTES
);
681 long[16] a
= void, b
= void, c
= void, d
= void, e
= void, f
= void;
683 z
[31] = (n
[31]&127)|
64;
688 d
[i
] = a
[i
] = c
[i
] = 0;
691 for (int i
= 254; i
>= 0; --i
) {
692 r
= (z
[i
>>3]>>(i
&7))&1;
693 sel25519(a
, b
, cast(int)r
);
694 sel25519(c
, d
, cast(int)r
);
713 sel25519(a
, b
, cast(int)r
);
714 sel25519(c
, d
, cast(int)r
);
722 inv25519(x
[32..$], x
[32..$]);
723 M(x
[16..$], x
[16..$], x
[32..$]);
724 pack25519(q
, x
[16..$]);
728 * The crypto_scalarmult_base() function computes
729 * the scalar product of a standard group element and an integer 'n'.
735 * resulting group element 'q' of length crypto_scalarmult_BYTES.
737 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
);
743 crypto_scalarmult(q
, n
, _9
);
747 * The crypto_box_keypair() function randomly generates a secret key and
748 * a corresponding public key.
751 * pk = slice to put generated public key into
752 * sk = slice to put generated secret key into
757 void crypto_box_keypair() (ubyte[] pk
, ubyte[] sk
) @trusted
759 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
760 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
764 crypto_scalarmult_base(pk
, sk
);
768 * Function crypto_box_beforenm() computes a shared secret 's' from
769 * public key 'pk' and secret key 'sk'.
772 * skey = slice to put secret into
779 void crypto_box_beforenm() (ubyte[] skey
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
781 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
782 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
783 assert(skey
.length
>= crypto_box_BEFORENMBYTES
);
787 crypto_scalarmult(s
, sk
, pk
);
788 crypto_core_hsalsa20(skey
, _0
, s
, sigma
);
792 * The crypto_box_afternm() function encrypts and authenticates
793 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
794 * The crypto_box_afternm() function returns the resulting ciphertext 'c'.
797 * c = resulting cyphertext
803 * success flag and cyphertext in 'c'
805 bool crypto_box_afternm() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
807 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
808 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
811 return crypto_secretbox(c
, msg
, nonce
, key
);
815 * The crypto_box_open_afternm() function verifies and decrypts
816 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
817 * The crypto_box_open_afternm() function returns the resulting message 'msg'.
820 * msg = resulting message
826 * success flag and resulting message in 'msg'
828 bool crypto_box_open_afternm() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
) @safe nothrow
830 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
831 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
834 return crypto_secretbox_open(msg
, c
, nonce
, key
);
838 * The crypto_box() function encrypts and authenticates a message 'msg'
839 * using the sender's secret key 'sk', the receiver's public key 'pk',
840 * and a nonce 'nonce'. The crypto_box() function returns the resulting ciphertext 'c'.
843 * c = resulting cyphertext
846 * pk = receiver's public key
847 * sk = sender's secret key
850 * success flag and cyphertext in 'c'
852 bool crypto_box() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
854 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
855 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
856 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
860 crypto_box_beforenm(k
, pk
, sk
);
861 return crypto_box_afternm(c
, msg
, nonce
, k
);
865 * The crypto_box_open() function verifies and decrypts
866 * a ciphertext 'c' using the receiver's secret key 'sk',
867 * the sender's public key 'pk', and a nonce 'nonce'.
868 * The crypto_box_open() function returns the resulting message 'msg'.
871 * msg = resulting message
874 * pk = receiver's public key
875 * sk = sender's secret key
878 * success flag and message in 'msg'
880 bool crypto_box_open() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
) @safe nothrow
882 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
883 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
884 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
888 crypto_box_beforenm(k
, pk
, sk
);
889 return crypto_box_open_afternm(msg
, c
, nonce
, k
);
892 private @gcc_inline ulong R() (ulong x
, int c
) @safe nothrow pure { return (x
>>c
)|
(x
<<(64-c
)); }
893 private @gcc_inline ulong Ch() (ulong x
, ulong y
, ulong z
) @safe nothrow pure { return (x
&y
)^
(~x
&z
); }
894 private @gcc_inline ulong Maj() (ulong x
, ulong y
, ulong z
) @safe nothrow pure { return (x
&y
)^
(x
&z
)^
(y
&z
); }
895 private @gcc_inline ulong Sigma0() (ulong x
) @safe nothrow pure { return R(x
, 28)^
R(x
, 34)^
R(x
, 39); }
896 private @gcc_inline ulong Sigma1() (ulong x
) @safe nothrow pure { return R(x
, 14)^
R(x
, 18)^
R(x
, 41); }
897 private @gcc_inline ulong sigma0() (ulong x
) @safe nothrow pure { return R(x
, 1)^
R(x
, 8)^
(x
>>7); }
898 private @gcc_inline ulong sigma1() (ulong x
) @safe nothrow pure { return R(x
, 19)^
R(x
, 61)^
(x
>>6); }
900 private immutable ulong[80] K
= [
901 0x428a2f98d728ae22UL
, 0x7137449123ef65cdUL
, 0xb5c0fbcfec4d3b2fUL
, 0xe9b5dba58189dbbcUL
,
902 0x3956c25bf348b538UL
, 0x59f111f1b605d019UL
, 0x923f82a4af194f9bUL
, 0xab1c5ed5da6d8118UL
,
903 0xd807aa98a3030242UL
, 0x12835b0145706fbeUL
, 0x243185be4ee4b28cUL
, 0x550c7dc3d5ffb4e2UL
,
904 0x72be5d74f27b896fUL
, 0x80deb1fe3b1696b1UL
, 0x9bdc06a725c71235UL
, 0xc19bf174cf692694UL
,
905 0xe49b69c19ef14ad2UL
, 0xefbe4786384f25e3UL
, 0x0fc19dc68b8cd5b5UL
, 0x240ca1cc77ac9c65UL
,
906 0x2de92c6f592b0275UL
, 0x4a7484aa6ea6e483UL
, 0x5cb0a9dcbd41fbd4UL
, 0x76f988da831153b5UL
,
907 0x983e5152ee66dfabUL
, 0xa831c66d2db43210UL
, 0xb00327c898fb213fUL
, 0xbf597fc7beef0ee4UL
,
908 0xc6e00bf33da88fc2UL
, 0xd5a79147930aa725UL
, 0x06ca6351e003826fUL
, 0x142929670a0e6e70UL
,
909 0x27b70a8546d22ffcUL
, 0x2e1b21385c26c926UL
, 0x4d2c6dfc5ac42aedUL
, 0x53380d139d95b3dfUL
,
910 0x650a73548baf63deUL
, 0x766a0abb3c77b2a8UL
, 0x81c2c92e47edaee6UL
, 0x92722c851482353bUL
,
911 0xa2bfe8a14cf10364UL
, 0xa81a664bbc423001UL
, 0xc24b8b70d0f89791UL
, 0xc76c51a30654be30UL
,
912 0xd192e819d6ef5218UL
, 0xd69906245565a910UL
, 0xf40e35855771202aUL
, 0x106aa07032bbd1b8UL
,
913 0x19a4c116b8d2d0c8UL
, 0x1e376c085141ab53UL
, 0x2748774cdf8eeb99UL
, 0x34b0bcb5e19b48a8UL
,
914 0x391c0cb3c5c95a63UL
, 0x4ed8aa4ae3418acbUL
, 0x5b9cca4f7763e373UL
, 0x682e6ff3d6b2b8a3UL
,
915 0x748f82ee5defb2fcUL
, 0x78a5636f43172f60UL
, 0x84c87814a1f0ab72UL
, 0x8cc702081a6439ecUL
,
916 0x90befffa23631e28UL
, 0xa4506cebde82bde9UL
, 0xbef9a3f7b2c67915UL
, 0xc67178f2e372532bUL
,
917 0xca273eceea26619cUL
, 0xd186b8c721c0c207UL
, 0xeada7dd6cde0eb1eUL
, 0xf57d4f7fee6ed178UL
,
918 0x06f067aa72176fbaUL
, 0x0a637dc5a2c898a6UL
, 0x113f9804bef90daeUL
, 0x1b710b35131c471bUL
,
919 0x28db77f523047d84UL
, 0x32caab7b40c72493UL
, 0x3c9ebe0a15c9bebcUL
, 0x431d67c49c100d4cUL
,
920 0x4cc5d4becb3e42b6UL
, 0x597f299cfc657e2aUL
, 0x5fcb6fab3ad6faecUL
, 0x6c44198c4a475817UL
923 private void crypto_hashblocks (ubyte[] x
, const(ubyte)[] m
, ulong n
) @safe nothrow {
924 ulong[8] z
= void, b
= void, a
= void;
928 foreach (i
; 0..8) z
[i
] = a
[i
] = dl64(x
[8*i
..$]);
930 foreach (i
; 0..16) w
[i
] = dl64(m
[mpos
+8*i
..$]);
933 t
= a
[7]+Sigma1(a
[4])+Ch(a
[4], a
[5], a
[6])+K
[i
]+w
[i
%16];
934 b
[7] = t
+Sigma0(a
[0])+Maj(a
[0], a
[1], a
[2]);
936 //foreach (j; 0..8) a[(j+1)%8] = b[j];
940 foreach (j
; 0..16) w
[j
] += w
[(j
+9)%16]+sigma0(w
[(j
+1)%16])+sigma1(w
[(j
+14)%16]);
943 foreach (i
; 0..8) { a
[i
] += z
[i
]; z
[i
] = a
[i
]; }
947 foreach (i
; 0..8) ts64(x
[8*i
..$], z
[i
]);
950 private immutable ubyte[64] iv
= [
951 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
952 0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
953 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
954 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
955 0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
956 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
957 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
958 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
962 * The crypto_hash() function hashes a message 'msg'.
963 * It returns a hash 'output'. The output length of 'output' should be at least crypto_hash_BYTES.
966 * output = resulting hash
972 void crypto_hash() (ubyte[] output
, const(ubyte)[] msg
) @safe nothrow
974 assert(output
.length
>= crypto_hash_BYTES
);
978 ubyte[256] x
; /*autoinit*/
979 size_t n
= msg
.length
;
985 crypto_hashblocks(h
, msg
, n
);
990 x
[0..n
] = msg
[mpos
..mpos
+n
];
995 ts64(x
[n
-8..$], b
<<3);
996 crypto_hashblocks(h
, x
, n
);
1001 private @gcc_inline void add() (ref long[16][4] p
, ref long[16][4] q
) @safe nothrow {
1002 long[16] a
= void, b
= void, c
= void, d
= void, t
= void, e
= void, f
= void, g
= void, h
= void;
1025 private @gcc_inline void cswap() (ref long[16][4] p
, ref long[16][4] q
, ubyte b
) @safe nothrow {
1026 foreach (i
; 0..4) sel25519(p
[i
], q
[i
], b
);
1029 private @gcc_inline void pack() (ubyte[] r
, ref long[16][4] p
) @safe nothrow {
1030 long[16] tx
= void, ty
= void, zi
= void;
1035 r
[31] ^
= par25519(tx
)<<7;
1038 private @gcc_inline void scalarmult() (ref long[16][4] p
, ref long[16][4] q
, const(ubyte)[] s
) @safe nothrow {
1043 for (int i
= 255; i
>= 0; --i
) {
1044 ubyte b
= (s
[i
/8]>>(i
&7))&1;
1052 private @gcc_inline void scalarbase() (ref long[16][4] p
, const(ubyte)[] s
) @safe nothrow {
1053 long[16][4] q
= void;
1058 scalarmult(p
, q
, s
);
1062 * The crypto_sign_keypair() function randomly generates a secret key and
1063 * a corresponding public key.
1066 * pk = slice to put generated public key into
1067 * sk = slice to put generated secret key into
1072 void crypto_sign_keypair() (ubyte[] pk
, ubyte[] sk
) @trusted
1074 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1075 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1079 long[16][4] p
= void;
1081 randombytes(sk
, 32);
1082 crypto_hash(d
, sk
[0..32]);
1090 sk
[32..64] = pk
[0..32];
1093 private immutable ulong[32] L
= [
1094 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
1097 private @gcc_inline void modL() (ubyte[] r
, long[] x
) @safe nothrow {
1099 for (auto i
= 63; i
>= 32; --i
) {
1102 for (j
= i
-32; j
< i
-12; ++j
) {
1103 x
[j
] += carry
-16*x
[i
]*L
[j
-(i
-32)];
1104 carry
= (x
[j
]+128)>>8;
1111 foreach (j
; 0..32) {
1112 x
[j
] += carry
-(x
[31]>>4)*L
[j
];
1116 foreach (j
; 0..32) x
[j
] -= carry
*L
[j
];
1117 foreach (i
; 0..32) {
1123 private @gcc_inline void reduce() (ubyte[] r
) @safe nothrow {
1125 foreach (i
; 0..64) x
[i
] = cast(ulong)r
[i
];
1131 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1132 * The crypto_sign() function returns the resulting signed message.
1135 * sm = buffer to receive signed message, must be of size at least msg.length+64
1137 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1142 void crypto_sign() (ubyte[] sm
, const(ubyte)[] msg
, const(ubyte)[] sk
) @trusted nothrow
1144 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1145 assert(sm
.length
>= msg
.length
+64);
1148 ubyte[64] d
= void, h
= void, r
= void;
1149 ulong[64] x
;/*autoinit*/
1150 long[16][4] p
= void;
1151 size_t n
= msg
.length
;
1152 size_t smlen
= n
+64;
1154 crypto_hash(d
, sk
[0..32]);
1159 sm
[64..64+n
] = msg
[];
1160 sm
[32..64] = d
[32..64];
1162 crypto_hash(r
, sm
[32..32+n
+32]);
1167 sm
[32..64] = sk
[32..64];
1168 crypto_hash(h
, sm
[0..n
+64]);
1171 foreach (i
; 0..32) x
[i
] = cast(ulong)r
[i
];
1172 foreach (i
; 0..32) foreach (j
; 0..32) x
[i
+j
] += h
[i
]*cast(ulong)d
[j
];
1173 modL(sm
[32..$], cast(long[])x
);
1177 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1178 * The crypto_sign() function returns the resulting signed message.
1180 * WARNING! This function allocates!
1184 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1189 ubyte[] crypto_sign() (const(ubyte)[] msg
, const(ubyte)[] sk
) @safe nothrow
1191 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1195 size_t n
= msg
.length
;
1196 size_t smlen
= n
+64;
1198 crypto_sign(sm
, msg
, sk
);
1202 private @gcc_inline bool unpackneg() (ref long[16][4] r
, const(ubyte)[] p
) @safe nothrow {
1203 long[16] t
= void, chk
= void, num
= void, den
= void, den2
= void, den4
= void, den6
= void;
1205 unpack25519(r
[1], p
);
1213 M(den6
, den4
, den2
);
1225 if (!neq25519(chk
, num
)) M(r
[0], r
[0], I
);
1229 if (!neq25519(chk
, num
)) return false;
1231 if (par25519(r
[0]) == (p
[31]>>7)) Z(r
[0], gf0
, r
[0]);
1233 M(r
[3], r
[0], r
[1]);
1238 * The crypto_sign_open() function verifies the signature in
1239 * 'sm' using the receiver's public key 'pk'.
1242 * msg = decrypted message, last 64 bytes are useless zeroes, must be of size at least sm.length
1243 * sm == signed message
1244 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1249 bool crypto_sign_open() (ubyte[] msg
, const(ubyte)[] sm
, const(ubyte)[] pk
) @safe nothrow
1251 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1252 assert(msg
.length
>= sm
.length
);
1257 long[16][4] p
= void, q
= void;
1258 size_t n
= sm
.length
;
1260 if (n
< 64) return false;
1262 if (!unpackneg(q
, pk
)) return false;
1264 msg
[32..64] = pk
[0..32];
1265 crypto_hash(h
, msg
);
1267 scalarmult(p
, q
, h
);
1269 scalarbase(q
, sm
[32..$]);
1274 if (!crypto_verify_32(sm
, t
)) {
1279 msg
[0..n
] = sm
[64..64+n
];
1287 * The crypto_sign_open() function verifies the signature in
1288 * 'sm' using the receiver's public key 'pk'.
1289 * The crypto_sign_open() function returns the message.
1291 * WARNING! This function allocates!
1294 * sm == signed message
1295 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1298 * decrypted message or null on error
1300 ubyte[] crypto_sign_open() (const(ubyte)[] sm
, const(ubyte)[] pk
) @safe nothrow {
1302 msg
.length
= sm
.length
;
1303 if (!crypto_sign_open(msg
, sm
, pk
)) return null;
1304 return msg
[0..sm
.length
-64]; // remove signature
1309 import std
.exception
;
1315 private extern(C) int open(const(char)* filename, int flags, ...);
1316 void randombytes (ubyte[] dest, size_t len) {
1317 import core.sys.posix.unistd;
1321 fd = open("/dev/urandom", /*O_RDONLY*/0);
1322 if (fd != -1) break;
1328 ssize_t i = read(fd, cast(void*)(&dest[pos]), (len < 1048576 ? len : 1048576));
1339 static void rnd (ubyte[] dest, size_t len) {
1340 for (size_t f = 0; f < len; ++f) dest[f] = cast(ubyte)uniform(0, 256);
1345 randombytes
= (ubyte[] dest
, size_t len
) {
1346 for (size_t f
= 0; f
< len
; ++f
) dest
[f
] = cast(ubyte)uniform(0, 256);
1349 void dumpArray(T
) (T
[] arr
) @trusted {
1350 writefln("============================= (%s)", arr
.length
);
1351 for (auto f
= 0; f
< arr
.length
; ++f
) {
1352 if (f
&& f
%16 == 0) writeln();
1353 static if (T
.sizeof
== 1) writef(" 0x%02x", arr
[f
]);
1354 else static if (T
.sizeof
== 2) writef(" 0x%04x", arr
[f
]);
1355 else static if (T
.sizeof
== 4) writef(" 0x%08x", arr
[f
]);
1356 else writef(" 0x%08x", arr
[f
]);
1359 writeln("-----------------------------");
1362 string
hashToString (const(ubyte)[] hash
) {
1364 s
.length
= hash
.length
*2;
1365 char toHex(int a
) { return cast(char)(a
< 10 ? a
+'0' : a
+'a'-10); }
1366 for (int a
= 0; a
< hash
.length
; ++a
) {
1367 s
[a
*2] = toHex(hash
[a
]>>4);
1368 s
[a
*2+1] = toHex(hash
[a
]&0x0f);
1370 return assumeUnique(s
);
1373 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];
1374 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];
1375 static immutable ubyte[5] m
= [0x61,0x68,0x6f,0x6a,0x0a];
1376 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];
1379 writeln("crypto_sign");
1380 smres
= crypto_sign(m
, sk
);
1381 assert(smres
.length
== sm
.length
);
1382 assert(smres
== sm
);
1384 writeln("crypto_sign_open");
1385 t
= crypto_sign_open(smres
, pk
);
1387 assert(t
.length
== m
.length
);
1391 // based on the code by Adam D. Ruppe
1392 // 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
1393 template SHARange(T
) if (isInputRange
!(T
)) {
1397 bool empty () { return state
== 5; }
1409 bool hackforward
= false;
1413 if (((position
+length
+8)*8)%512 == 8) {
1419 } else if (state
== 2) {
1421 if (!(((position
+length
+8)*8)%512)) {
1425 if (hackforward
) goto proceedmoar
;
1429 } else if (state
== 3) {
1431 current
= (length
>>(position
*8))&0xff;
1432 if (position
== 0) state
= 4; else --position
;
1433 } else if (state
== 4) {
1441 if (state
== 0) return cast(ubyte)r
.front();
1443 //writefln("%x", current);
1450 int state
= 0; // reading range, reading appended bit, reading padding, reading length, done
1455 immutable(ubyte)[] SHA256(T
) (T data
) if (isInputRange
!(T
)) {
1456 uint[8] h
= [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
1457 static immutable(uint[64]) k
= [
1458 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1459 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1460 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1461 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1462 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1463 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1464 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1465 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1470 static if (is(data
== SHARange
)) range
= data
; else range
.r
= data
;
1473 while(!range
.empty
) {
1476 for(int a
= 0; a
< 16; ++a
) {
1477 for(int b
= 3; b
>= 0; --b
) {
1478 words
[a
] |
= cast(uint)(range
.front())<<(b
*8);
1483 uint ror (uint n
, int cnt
) {
1484 return cast(uint)(n
>>cnt
)|
cast(uint)(n
<<(32-(cnt
)));
1487 uint xrot00 (uint reax
, int r0
, int r1
, int r2
) {
1488 uint rebx
= reax
, recx
= reax
;
1489 reax
= ror(reax
, r0
);
1490 rebx
= ror(rebx
, r1
);
1497 for(int a
= 16; a
< 64; ++a
) {
1498 uint t1
= xrot00(words
[a
-15], 7, 18, 3);
1499 uint t2
= xrot00(words
[a
-2], 17, 19, 10);
1500 words
[a
] = words
[a
-16]+t1
+words
[a
-7]+t2
;
1512 uint xrot01 (uint reax
, int r0
, int r1
, int r2
) {
1513 uint rebx
= reax
, recx
= reax
;
1514 reax
= ror(reax
, r0
);
1515 rebx
= ror(rebx
, r1
);
1516 recx
= ror(recx
, r2
);
1522 for(int i
= 0; i
< 64; ++i
) {
1523 uint s0
= xrot01(A
, 2, 13, 22);
1524 uint maj
= (A
&B
)^
(A
&C
)^
(B
&C
);
1526 uint s1
= xrot01(E
, 6, 11, 25);
1527 uint ch
= (E
&F
)^
((~E
)&G
);
1528 uint t1
= H
+s1
+ch
+k
[i
]+words
[i
];
1551 for(int j
= 0; j
< 8; ++j
)
1552 for(int i
= 3; i
>= 0; --i
) {
1553 hash
~= cast(ubyte)(h
[j
]>>(i
*8))&0xff;
1563 static immutable ubyte[32] alicesk
= [
1564 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
1565 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
1566 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
1567 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
1570 static immutable ubyte[32] bobpk
= [
1571 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
1572 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
1573 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
1574 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
1577 static immutable ubyte[24] nonce
= [
1578 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1579 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1580 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1583 // API requires first 32 bytes to be 0
1584 static immutable ubyte[163] m
= [
1585 0, 0, 0, 0, 0, 0, 0, 0
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 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1590 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1591 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1592 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1593 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1594 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1595 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1596 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1597 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1598 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1599 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1600 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1601 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1602 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1603 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1604 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1611 static immutable ubyte[] res
= [
1612 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1613 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1614 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1615 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1616 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1617 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1618 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1619 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1620 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1621 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1622 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1623 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1624 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1625 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1626 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1627 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1628 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1629 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1631 /*crypto_box_curve25519xsalsa20poly1305*/crypto_box(c
,m
,nonce
,bobpk
,alicesk
);
1632 for (auto f
= 16; f
< 163; ++f
) assert(c
[f
] == res
[f
-16]);
1638 static immutable ubyte[32] bobsk
= [
1639 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
1640 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
1641 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
1642 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
1645 static immutable ubyte[32] alicepk
= [
1646 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
1647 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
1648 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
1649 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
1652 static immutable ubyte[24] nonce
= [
1653 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1654 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1655 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1658 // API requires first 16 bytes to be 0
1659 static immutable ubyte[163] c
= [
1660 0, 0, 0, 0, 0, 0, 0, 0
1661 , 0, 0, 0, 0, 0, 0, 0, 0
1662 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1663 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1664 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1665 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1666 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1667 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1668 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1669 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1670 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1671 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1672 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1673 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1674 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1675 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1676 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1677 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1678 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1679 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1685 static immutable ubyte[] res
= [
1686 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1687 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1688 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1689 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1690 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1691 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1692 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1693 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1694 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1695 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1696 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1697 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1698 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1699 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1700 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1701 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1705 assert(/*crypto_box_curve25519xsalsa20poly1305_open*/crypto_box_open(m
,c
,nonce
,alicepk
,bobsk
));
1706 for (auto f
= 32; f
< 163; ++f
) assert(m
[f
] == res
[f
-32]);
1712 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1713 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1714 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1715 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1716 ubyte[crypto_box_NONCEBYTES
] n
;
1717 ubyte[10000] m
, c
, m2
;
1718 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1719 crypto_box_keypair(alicepk
,alicesk
);
1720 crypto_box_keypair(bobpk
,bobsk
);
1721 randombytes(n
,crypto_box_NONCEBYTES
);
1722 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1723 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1724 assert(crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
));
1725 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1728 version(unittest_full
) box7(); // it's slow
1732 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1733 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1734 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1735 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1736 ubyte[crypto_box_NONCEBYTES
] n
;
1737 ubyte[10000] m
, c
, m2
;
1738 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1739 crypto_box_keypair(alicepk
,alicesk
);
1740 crypto_box_keypair(bobpk
,bobsk
);
1741 randombytes(n
,crypto_box_NONCEBYTES
);
1742 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1743 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1745 while (caught
< 10) {
1746 c
[uniform(0, mlen
+crypto_box_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
1747 if (crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
)) {
1748 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1753 assert(caught
== 10);
1756 version(unittest_full
) box8(); // it's slow
1760 static immutable ubyte[32] shared_
= [
1761 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
1762 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
1763 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
1764 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
1767 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];
1769 static immutable ubyte[16] c
= [
1770 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1771 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1776 static immutable ubyte[32] res
= [
1777 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1778 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1779 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1780 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1783 crypto_core_hsalsa20(firstkey
,zero
,shared_
,c
);
1784 assert(firstkey
== res
);
1790 static immutable ubyte[32]firstkey
= [
1791 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1792 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1793 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1794 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1797 static immutable ubyte[16]nonceprefix
= [
1798 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1799 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1802 static immutable ubyte[16] c
= [
1803 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1804 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1807 ubyte[32] secondkey
;
1809 static immutable ubyte[32] res
= [
1810 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1811 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1812 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1813 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1816 crypto_core_hsalsa20(secondkey
,nonceprefix
,firstkey
,c
);
1817 assert(secondkey
== res
);
1823 static immutable ubyte[32] secondkey
= [
1824 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1825 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1826 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1827 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1830 static immutable ubyte[8] noncesuffix
= [
1831 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1834 static immutable ubyte[16] c
= [
1835 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1836 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1839 static ubyte[16] input
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ;
1841 static ubyte[64*256*256] output
;
1845 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];
1848 for (auto i
= 0; i
< 8; ++i
) input
[i
] = noncesuffix
[i
];
1851 crypto_core_salsa20(output
[pos
..$],input
,secondkey
,c
);
1853 } while (++input
[8]);
1854 } while (++input
[9]);
1855 crypto_hash(h
,output
);
1858 version(unittest_full
) core3(); // it's slow
1862 static immutable ubyte[32] k
= [
1863 1, 2, 3, 4, 5, 6, 7, 8
1864 , 9, 10, 11, 12, 13, 14, 15, 16
1865 ,201,202,203,204,205,206,207,208
1866 ,209,210,211,212,213,214,215,216
1869 static immutable ubyte[16] input
= [
1870 101,102,103,104,105,106,107,108
1871 ,109,110,111,112,113,114,115,116
1874 static immutable ubyte[16] c
= [
1875 101,120,112, 97,110,100, 32, 51
1876 , 50, 45, 98,121,116,101, 32,107
1881 static immutable ubyte[64] res
= [
1882 69, 37, 68, 39, 41, 15,107,193
1883 ,255,139,122, 6,170,233,217, 98
1884 , 89,144,182,106, 21, 51,200, 65
1885 ,239, 49,222, 34,215,114, 40,126
1886 ,104,197, 7,225,197,153, 31, 2
1887 ,102, 78, 76,176, 84,245,246,184
1888 ,177,160,133,130, 6, 72,149,119
1889 ,192,195,132,236,234,103,246, 74
1892 crypto_core_salsa20(output
,input
,k
,c
);
1893 assert(output
== res
);
1899 static immutable ubyte[32] k
= [
1900 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1901 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1902 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1903 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1906 static immutable ubyte[16] input
= [
1907 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1908 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1911 static immutable ubyte[16] c
= [
1912 101,120,112, 97,110,100, 32, 51
1913 , 50, 45, 98,121,116,101, 32,107
1918 static immutable ubyte[32] res
= [
1919 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1920 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1921 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1922 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1925 crypto_core_hsalsa20(output
,input
,k
,c
);
1926 assert(output
== res
);
1932 static immutable ubyte[32] k
= [
1933 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1934 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1935 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1936 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1939 static immutable ubyte[16] input
= [
1940 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1941 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1944 static immutable ubyte[16] c
= [
1945 101,120,112, 97,110,100, 32, 51
1946 , 50, 45, 98,121,116,101, 32,107
1951 static immutable ubyte[32] res
= [
1952 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1953 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1954 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1955 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1961 void print(const(ubyte)[] x
, const(ubyte)[] y
)
1964 for (auto i
= 0; i
< 4; ++i
) {
1967 //printf(",0x%02x",255&(xi-yi-borrow));
1968 pp
[pppos
++] = cast(ubyte)(255&(xi
-yi
-borrow
));
1969 borrow
= (xi
< yi
+borrow
);
1973 crypto_core_salsa20(output
,input
,k
,c
);
1975 print(output
[20..$],c
[4..$]);
1976 print(output
[40..$],c
[8..$]);
1977 print(output
[60..$],c
[12..$]);
1978 print(output
[24..$],input
);
1979 print(output
[28..$],input
[4..$]);
1980 print(output
[32..$],input
[8..$]);
1981 print(output
[36..$],input
[12..$]);
1988 static immutable ubyte[8] x
= ['t','e','s','t','i','n','g','\n'];
1989 static ubyte[crypto_hash_BYTES
] h
;
1990 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];
1992 //for (auto f = 0; f < crypto_hash_BYTES; ++f) assert(h[f] == res[f]);
1997 void onetimeauth () {
1998 writeln("onetimeauth");
1999 static immutable ubyte[32] rs
= [
2000 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2001 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2002 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2003 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2006 static immutable ubyte[131] c
= [
2007 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2008 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2009 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2010 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2011 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2012 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2013 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2014 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2015 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2016 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2017 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2018 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2019 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2020 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2021 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2022 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2028 static immutable ubyte[16] res
= [0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9];
2030 /*crypto_onetimeauth_poly1305*/crypto_onetimeauth(a
,c
,rs
);
2035 void onetimeauth2 () {
2036 writeln("onetimeauth2");
2037 static immutable ubyte[32] rs
= [
2038 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2039 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2040 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2041 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2044 static immutable ubyte[131] c
= [
2045 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2046 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2047 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2048 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2049 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2050 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2051 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2052 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2053 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2054 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2055 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2056 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2057 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2058 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2059 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2060 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2064 static immutable ubyte[16] a
= [
2065 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2066 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2069 assert(/*crypto_onetimeauth_poly1305_verify*/crypto_onetimeauth_verify(a
,c
,rs
));
2073 void onetimeauth7 () {
2074 writeln("onetimeauth7");
2075 static ubyte[32] key
;
2076 static ubyte[10000] c
;
2079 for (auto clen
= 0; clen
< 10000; ++clen
) {
2080 //if (clen%512 == 0) { writef("\r%s", clen); stdout.flush(); }
2081 randombytes(key
, key
.length
);
2082 randombytes(c
, clen
);
2083 crypto_onetimeauth(a
,c
[0..clen
],key
);
2084 assert(crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2086 c
[uniform(0, clen
)] += 1+(uniform(0, 255));
2087 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2088 a
[uniform(0, a
.length
)] += 1+(uniform(0, 255));
2089 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2093 version(unittest_full
) onetimeauth7(); // it's slow
2095 void scalarmult () {
2096 writeln("scalarmult");
2097 static immutable ubyte[32] alicesk
= [
2098 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2099 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2100 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2101 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2106 static immutable ubyte[32] res
= [
2107 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2108 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2109 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2110 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2113 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(alicepk
,alicesk
);
2114 assert(alicepk
== res
);
2118 void scalarmult2 () {
2119 writeln("scalarmult2");
2120 static immutable ubyte[32] bobsk
= [
2121 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2122 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2123 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2124 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2129 static immutable ubyte[32] res
= [
2130 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2131 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2132 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2133 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2136 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(bobpk
,bobsk
);
2137 assert(bobpk
== res
);
2141 void scalarmult5 () {
2142 writeln("scalarmult5");
2143 static immutable ubyte[32] alicesk
= [
2144 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2145 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2146 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2147 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2150 static immutable ubyte[32] bobpk
= [
2151 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2152 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2153 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2154 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2159 static immutable ubyte[32] res
= [
2160 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2161 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2162 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2163 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2166 crypto_scalarmult(k
,alicesk
,bobpk
);
2171 void scalarmult6 () {
2172 writeln("scalarmult6");
2173 static immutable ubyte[32] bobsk
= [
2174 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2175 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2176 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2177 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2180 static immutable ubyte[32] alicepk
= [
2181 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2182 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2183 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2184 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2189 static immutable ubyte[32] res
= [
2190 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2191 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2192 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2193 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2196 crypto_scalarmult(k
,bobsk
,alicepk
);
2202 writeln("secretbox");
2203 static immutable ubyte[32] firstkey
= [
2204 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2205 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2206 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2207 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2210 static immutable ubyte[24] nonce
= [
2211 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2212 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2213 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2216 // API requires first 32 bytes to be 0
2217 static immutable ubyte[163] m
= [
2218 0, 0, 0, 0, 0, 0, 0, 0
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 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2223 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2224 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2225 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2226 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2227 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2228 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2229 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2230 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2231 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2232 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2233 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2234 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2235 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2236 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2237 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2241 static immutable ubyte[] res
= [
2242 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2243 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2244 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2245 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2246 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2247 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2248 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2249 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2250 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2251 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2252 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2253 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2254 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2255 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2256 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2257 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2258 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2259 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2264 crypto_secretbox(c
,m
,nonce
,firstkey
);
2265 for (auto i
= 16; i
< 163; ++i
) assert(c
[i
] == res
[i
-16]);
2269 void secretbox2 () {
2270 writeln("secretbox2");
2271 static immutable ubyte[32] firstkey
= [
2272 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2273 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2274 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2275 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2278 static immutable ubyte[24] nonce
= [
2279 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2280 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2281 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2284 // API requires first 16 bytes to be 0
2285 static immutable ubyte[163] c
= [
2286 0, 0, 0, 0, 0, 0, 0, 0
2287 , 0, 0, 0, 0, 0, 0, 0, 0
2288 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2289 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2290 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2291 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2292 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2293 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2294 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2295 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2296 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2297 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2298 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2299 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2300 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2301 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2302 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2303 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2304 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2305 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2309 static immutable ubyte[] res
= [
2310 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2311 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2312 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2313 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2314 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2315 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2316 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2317 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2318 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2319 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2320 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2321 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2322 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2323 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2324 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2325 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2331 assert(crypto_secretbox_open(m
,c
,nonce
,firstkey
));
2332 for (auto i
= 32; i
< 163; ++i
) assert(m
[i
] == res
[i
-32]);
2336 void secretbox7 () {
2337 writeln("secretbox7");
2338 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2339 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2340 static ubyte[10000] m
, c
, m2
;
2341 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2342 randombytes(k
,crypto_secretbox_KEYBYTES
);
2343 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2344 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2345 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2346 assert(crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
));
2347 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2352 void secretbox8 () {
2353 writeln("secretbox8");
2354 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2355 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2356 static ubyte[10000] m
, c
, m2
;
2357 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2358 randombytes(k
,crypto_secretbox_KEYBYTES
);
2359 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2360 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2361 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2363 while (caught
< 10) {
2364 c
[uniform(0, mlen
+crypto_secretbox_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
2365 if (crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
)) {
2366 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2370 assert(caught
== 10);
2373 version(unittest_full
) secretbox8(); // it's slow
2377 static immutable ubyte[32] firstkey
= [
2378 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2379 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2380 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2381 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2384 static immutable ubyte[24] nonce
= [
2385 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2386 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2387 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2390 static ubyte[4194304] output
;
2393 //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];
2395 crypto_stream(output
,nonce
,firstkey
);
2396 //crypto_hash_sha256(h,output,sizeof output);
2397 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2403 static immutable ubyte[32] secondkey
= [
2404 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
2405 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
2406 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
2407 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
2410 static immutable ubyte[8] noncesuffix
= [
2411 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2414 static ubyte[4194304] output
;
2416 crypto_stream_salsa20(output
,noncesuffix
,secondkey
);
2417 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2423 static immutable ubyte[32] firstkey
= [
2424 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2425 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2426 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2427 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2430 static immutable ubyte[24] nonce
= [
2431 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2432 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2433 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2438 static immutable ubyte[32] res
= [
2439 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2440 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2441 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2442 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2445 crypto_stream
/*_xsalsa20*/(rs
,nonce
,firstkey
);
2452 static immutable ubyte[32] firstkey
= [
2453 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2454 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2455 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2456 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2459 static immutable ubyte[24] nonce
= [
2460 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2461 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2462 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2465 static immutable ubyte[163] m
= [
2466 0, 0, 0, 0, 0, 0, 0, 0
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 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2471 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2472 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2473 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2474 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2475 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2476 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2477 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2478 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2479 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2480 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2481 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2482 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2483 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2484 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2485 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2491 static immutable ubyte[] res
= [
2492 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2493 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2494 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2495 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2496 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2497 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2498 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2499 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2500 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2501 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2502 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2503 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2504 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2505 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2506 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2507 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2511 /*crypto_stream_xsalsa20_xor*/crypto_stream_xor(c
,m
,nonce
,firstkey
);
2512 for (auto i
= 32; i
< 163; ++i
) assert(c
[i
] == res
[i
-32]);
2517 version(unittest_main
) {