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.
20 crypto_auth_BYTES
= 32,
21 crypto_auth_KEYBYTES
= 32,
23 crypto_box_PUBLICKEYBYTES
= 32,
24 crypto_box_SECRETKEYBYTES
= 32,
25 crypto_box_BEFORENMBYTES
= 32,
26 crypto_box_NONCEBYTES
= 24,
27 crypto_box_ZEROBYTES
= 32,
28 crypto_box_BOXZEROBYTES
= 16,
30 crypto_core_salsa20_OUTPUTBYTES
= 64,
31 crypto_core_salsa20_INPUTBYTES
= 16,
32 crypto_core_salsa20_KEYBYTES
= 32,
33 crypto_core_salsa20_CONSTBYTES
= 16,
35 crypto_core_hsalsa20_OUTPUTBYTES
= 32,
36 crypto_core_hsalsa20_INPUTBYTES
= 16,
37 crypto_core_hsalsa20_KEYBYTES
= 32,
38 crypto_core_hsalsa20_CONSTBYTES
= 16,
40 crypto_hash_BYTES
= 64,
42 crypto_onetimeauth_BYTES
= 16,
43 crypto_onetimeauth_KEYBYTES
= 32,
45 crypto_scalarmult_BYTES
= 32,
46 crypto_scalarmult_SCALARBYTES
= 32,
48 crypto_secretbox_KEYBYTES
= 32,
49 crypto_secretbox_NONCEBYTES
= 24,
50 crypto_secretbox_ZEROBYTES
= 32,
51 crypto_secretbox_BOXZEROBYTES
= 16,
53 crypto_sign_BYTES
= 64,
54 crypto_sign_PUBLICKEYBYTES
= 32,
55 crypto_sign_SECRETKEYBYTES
= 64,
57 crypto_stream_xsalsa20_KEYBYTES
= 32,
58 crypto_stream_xsalsa20_NONCEBYTES
= 24,
60 crypto_stream_salsa20_KEYBYTES
= 32,
61 crypto_stream_salsa20_NONCEBYTES
= 8,
63 crypto_stream_KEYBYTES
= 32,
64 crypto_stream_NONCEBYTES
= 24,
66 crypto_verify_16_BYTES
= 16,
67 crypto_verify_32_BYTES
= 32,
71 /// set this callback to good (cryptograpic strong) random bytes generator
72 /// you can use /dev/urandom as prng
73 void delegate (ubyte[] dest
, size_t len
) randombytes
= null;
77 immutable ubyte[16] zero_
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
78 immutable ubyte[32] nine_
= [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];
81 gf0
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
82 gf1
= [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
83 xx121665
= [0xDB41,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
84 D
= [0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203],
85 D2
=[0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406],
86 X
= [0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169],
87 Y
= [0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666],
88 I
= [0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83];
90 uint ld32() (const(ubyte)[] x
)
92 assert(x
.length
>= 4);
101 ulong dl64() (const(ubyte)[] x
)
103 assert(x
.length
>= 8);
116 void st32() (ubyte[] x
, uint u
)
118 assert(x
.length
>= 4);
127 void ts64() (ubyte[] x
, ulong u
)
129 assert(x
.length
>= 8);
142 bool vn() (const(ubyte)[] x
, const(ubyte)[] y
)
144 assert(x
.length
>= y
.length
);
148 foreach (immutable i
, immutable v
; x
) d |
= v^y
[i
];
149 return (1&((d
-1)>>8)) != 0;
154 * The crypto_verify_16() function checks that strings 'x' and 'y' has same content.
157 * x = first string, slice length must be at least crypto_verify_16_BYTES, extra ignored
158 * y = second string, slice length must be at least crypto_verify_16_BYTES, extra ignored
163 bool crypto_verify_16() (const(ubyte)[] x
, const(ubyte)[] y
)
165 assert(x
.length
>= 16 && y
.length
>= 16);
168 return vn(x
[0..16], y
[0..16]);
172 * The crypto_verify_32() function checks that strings 'x' and 'y' has same content.
175 * x = first string, slice length must be at least crypto_verify_32_BYTES, extra ignored
176 * y = second string, slice length must be at least crypto_verify_32_BYTES, extra ignored
181 bool crypto_verify_32() (const(ubyte)[] x
, const(ubyte)[] y
)
183 assert(x
.length
>= 32 && y
.length
>= 32);
186 return vn(x
[0..32], y
[0..32]);
190 private void salsa_core(string type
) (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
)
191 if (type
== "salsa" || type
== "hsalsa") // constraint
194 assert(mixin(`output.length >= crypto_core_`~type
~`20_OUTPUTBYTES`));
195 assert(mixin(`input.length >= crypto_core_`~type
~`20_INPUTBYTES`));
196 assert(mixin(`key.length >= crypto_core_`~type
~`20_KEYBYTES`));
197 assert(mixin(`constant.length >= crypto_core_`~type
~`20_CONSTBYTES`));
200 static uint ROTL32() (uint x
, int c
) { return (x
<<c
)|
((x
&0xffffffff)>>(32-c
)); }
202 uint[16] w
= void, x
= void, y
= void;
206 x
[5*i
] = ld32(constant
[4*i
..$]);
207 x
[1+i
] = ld32(key
[4*i
..$]);
208 x
[6+i
] = ld32(input
[4*i
..$]);
209 x
[11+i
] = ld32(key
[16+4*i
..$]);
216 foreach (m
; 0..4) t
[m
] = x
[(5*j
+4*m
)%16];
217 t
[1] ^
= ROTL32(t
[0]+t
[3], 7);
218 t
[2] ^
= ROTL32(t
[1]+t
[0], 9);
219 t
[3] ^
= ROTL32(t
[2]+t
[1], 13);
220 t
[0] ^
= ROTL32(t
[3]+t
[2], 18);
221 for (auto m
= 0; m
< 4; ++m
) w
[4*j
+(j
+m
)%4] = t
[m
];
223 for (auto m
= 0; m
< 16; ++m
) x
[m
] = w
[m
];
226 static if (type
== "hsalsa") {
227 for (auto i
= 0; i
< 16; ++i
) x
[i
] += y
[i
];
228 for (auto i
= 0; i
< 4; ++i
) {
229 x
[5*i
] -= ld32(constant
[4*i
..$]);
230 x
[6+i
] -= ld32(input
[4*i
..$]);
232 for (auto i
= 0; i
< 4; ++i
) {
233 st32(output
[4*i
..$], x
[5*i
]);
234 st32(output
[16+4*i
..$], x
[6+i
]);
237 for (auto i
= 0; i
< 16; ++i
) st32(output
[4*i
..$], x
[i
]+y
[i
]);
241 void crypto_core_salsa20() (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
)
243 salsa_core
!"salsa"(output
, input
, key
, constant
);
246 void crypto_core_hsalsa20() (ubyte[] output
, const(ubyte)[] input
, const(ubyte)[] key
, const(ubyte)[] constant
)
248 salsa_core
!"hsalsa"(output
, input
, key
, constant
);
251 private immutable(ubyte)[] sigma
= cast(immutable(ubyte)[])"expand 32-byte k";
254 * The crypto_stream_salsa20_xor() function encrypts a message 'msg' using a secret key 'key'
255 * and a nonce 'nonce'. The crypto_stream_salsa20_xor() function returns the ciphertext 'output'.
258 * output = resulting ciphertext
264 * ciphertext in 'output'
266 void crypto_stream_salsa20_xor (ubyte[] output
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
)
267 @trusted nothrow @nogc
269 assert(nonce
.length
== crypto_stream_salsa20_NONCEBYTES
);
270 assert(key
.length
== crypto_stream_salsa20_KEYBYTES
);
272 assert(msg
.length
== 0 || output
.length
<= msg
.length
);
275 ubyte[16] z
; // autoclear
278 uint cpos
= 0, mpos
= 0;
279 size_t b
= output
.length
;
281 z
[0..8] = nonce
[0..8];
283 crypto_core_salsa20(x
[], z
[], key
, sigma
[]);
285 foreach (v
; x
) output
[cpos
++] = msg
[mpos
++]^v
;
287 output
[cpos
..cpos
+64] = x
[];
299 crypto_core_salsa20(x
[], z
[], key
, sigma
[]);
301 foreach (i
; 0..b
) output
[cpos
++] = msg
[mpos
++]^x
[i
];
303 output
[cpos
..cpos
+b
] = x
[0..b
];
309 * The crypto_stream_salsa20() function produces a stream 'c'
310 * as a function of a secret key 'key' and a nonce 'nonce'.
313 * c = resulting stream
320 void crypto_stream_salsa20() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
)
322 assert(nonce
.length
== crypto_stream_salsa20_NONCEBYTES
);
323 assert(key
.length
== crypto_stream_salsa20_KEYBYTES
);
326 crypto_stream_salsa20_xor(c
, null, nonce
, key
);
330 * The crypto_stream() function produces a stream 'c'
331 * as a function of a secret key 'key' and a nonce 'nonce'.
341 void crypto_stream() (ubyte[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
)
344 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
345 assert(key
.length
== crypto_stream_KEYBYTES
);
349 crypto_core_hsalsa20(s
[], nonce
, key
, sigma
[]);
350 crypto_stream_salsa20(c
, nonce
[16..$], s
[]);
354 * The crypto_stream_xor() function encrypts a message 'msg' using a secret key 'key'
355 * and a nonce 'nonce'. The crypto_stream_xor() function returns the ciphertext 'c'.
365 void crypto_stream_xor() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
)
368 assert(msg
.length
>= c
.length
);
369 assert(nonce
.length
== crypto_stream_NONCEBYTES
);
370 assert(key
.length
== crypto_stream_KEYBYTES
);
374 crypto_core_hsalsa20(s
[], nonce
, key
, sigma
[]);
375 crypto_stream_salsa20_xor(c
, msg
, nonce
[16..$], s
);
378 private void add1305() (uint[] h
, const(uint)[] c
) {
387 private immutable uint[17] minusp
= [5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252];
390 * The crypto_onetimeauth() function authenticates a message 'msg'
391 * using a secret key 'key'. The function returns an authenticator 'output'.
394 * output = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
396 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
399 * authenticator in 'output'
401 void crypto_onetimeauth() (ubyte[] output
, const(ubyte)[] msg
, const(ubyte)[] key
)
403 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
404 assert(output
.length
>= crypto_onetimeauth_BYTES
);
408 uint[17] x
= void, r
= void, h
/*autoclear*/, c
= void, g
= void;
410 size_t n
= msg
.length
;
412 foreach (i
; 0..16) r
[i
] = key
[i
];
427 for (jj
= 0; jj
< 16 && jj
< n
; ++jj
) c
[jj
] = msg
[mpos
+jj
];
435 foreach (j
; 0..17) x
[i
] += h
[j
]*(j
<= i ? r
[i
-j
] : 320*r
[i
+17-j
]);
459 foreach (j
; 0..17) h
[j
] ^
= s
&(g
[j
]^h
[j
]);
461 foreach (j
; 0..16) c
[j
] = key
[j
+16];
464 foreach (j
; 0..16) output
[j
] = cast(ubyte)(h
[j
]&0xff);
468 * The crypto_onetimeauth_verify() function checks that
469 * 'h' is a correct authenticator of a message 'msg' under the secret key 'key'.
472 * h = authenticator, slice size must be at least crypto_onetimeauth_BYTES, extra ignored
474 * key == secret key, slice size must be at least crypto_onetimeauth_KEYBYTES, extra ignored
479 bool crypto_onetimeauth_verify() (const(ubyte)[] h
, const(ubyte)[] msg
, const(ubyte)[] key
)
481 assert(h
.length
>= crypto_onetimeauth_BYTES
);
482 assert(key
.length
>= crypto_onetimeauth_KEYBYTES
);
486 crypto_onetimeauth(x
, msg
, key
);
487 return crypto_verify_16(h
, x
);
491 * The crypto_secretbox() function encrypts and authenticates
492 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
493 * The crypto_secretbox() function returns the resulting ciphertext 'c'.
496 * c = resulting cyphertext
501 * success flag and cyphertext in 'c'
503 bool crypto_secretbox() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
)
505 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
506 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
509 //c.length = msg.length+crypto_secretbox_ZEROBYTES;
510 if (c
is null || c
.length
< 32) return false;
511 crypto_stream_xor(c
, msg
, nonce
, key
);
512 crypto_onetimeauth(c
[16..$], c
[32..$], c
);
514 //return c[crypto_secretbox_BOXZEROBYTES..$];
519 * The crypto_secretbox_open() function verifies and decrypts
520 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
521 * The crypto_secretbox_open() function returns the resulting plaintext 'output'.
524 * output = resulting message
530 * success flag and message in 'output'
532 bool crypto_secretbox_open() (ubyte[] output
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
)
534 assert(key
.length
>= crypto_secretbox_KEYBYTES
);
535 assert(nonce
.length
>= crypto_secretbox_NONCEBYTES
);
539 if (output
is null || output
.length
< 32) return false;
540 crypto_stream(x
, nonce
, key
);
541 if (!crypto_onetimeauth_verify(c
[16..$], c
[32../*$*/32+(output
.length
-32)], x
)) return false;
542 crypto_stream_xor(output
, c
, nonce
, key
);
549 void car25519() (long[] o
) {
553 o
[(i
+1)*(i
<15)] += c
-1+37*(c
-1)*(i
==15);
558 void sel25519() (long[] p
,long[] q
, int b
) {
561 long t
= c
&(p
[i
]^q
[i
]);
567 void pack25519() (ubyte[] o
, const(long)[] n
) {
569 long[16] m
= void, t
= void;
577 m
[i
] = t
[i
]-0xffff-((m
[i
-1]>>16)&1);
580 m
[15] = t
[15]-0x7fff-((m
[14]>>16)&1);
587 o
[2*i
+1] = (t
[i
]>>8)&0xff;
591 bool neq25519() (const(long)[] a
, const(long)[] b
) {
592 ubyte[32] c
= void, d
= void;
595 return crypto_verify_32(c
, d
);
598 ubyte par25519() (const(long)[] a
) {
604 void unpack25519() (long[] o
, const(ubyte)[] n
) {
605 foreach (i
; 0..16) o
[i
] = n
[2*i
]+(cast(long)n
[2*i
+1]<<8);
609 void A() (long[] o
, const(long)[] a
, const(long)[] b
) {
610 foreach (i
; 0..16) o
[i
] = a
[i
]+b
[i
];
613 void Z() (long[] o
, const(long)[] a
, const(long)[] b
) {
614 foreach (i
; 0..16) o
[i
] = a
[i
]-b
[i
];
617 void M() (long[] o
, const(long)[] a
, const(long)[] b
) {
618 long[31] t
; // automatically becomes 0
619 foreach (i
; 0..16) foreach (j
; 0..16) t
[i
+j
] += a
[i
]*b
[j
];
620 foreach (i
; 0..15) t
[i
] += 38*t
[i
+16];
626 void S() (long[] o
, const(long)[] a
) {
630 void inv25519() (long[] o
, const(long)[] i
) {
633 for (auto a
= 253; a
>= 0; --a
) {
635 if (a
!= 2 && a
!= 4) M(c
, c
, i
);
640 void pow2523() (long[] o
, const(long)[] i
) {
643 for(auto a
= 250; a
>= 0; --a
) {
645 if (a
!= 1) M(c
, c
, i
);
651 * This function multiplies a group element 'p' by an integer 'n'.
658 * resulting group element 'q' of length crypto_scalarmult_BYTES.
660 void crypto_scalarmult (ubyte[] q
, const(ubyte)[] n
, const(ubyte)[] p
) @safe nothrow @nogc
662 assert(q
.length
== crypto_scalarmult_BYTES
);
663 assert(n
.length
== crypto_scalarmult_BYTES
);
664 assert(p
.length
== crypto_scalarmult_BYTES
);
670 long[16] a
= void, b
= void, c
= void, d
= void, e
= void, f
= void;
672 z
[31] = (n
[31]&127)|
64;
677 d
[i
] = a
[i
] = c
[i
] = 0;
680 for (int i
= 254; i
>= 0; --i
) {
681 r
= (z
[i
>>3]>>(i
&7))&1;
682 sel25519(a
, b
, cast(int)r
);
683 sel25519(c
, d
, cast(int)r
);
702 sel25519(a
, b
, cast(int)r
);
703 sel25519(c
, d
, cast(int)r
);
711 inv25519(x
[32..$], x
[32..$]);
712 M(x
[16..$], x
[16..$], x
[32..$]);
713 pack25519(q
, x
[16..$]);
717 * The crypto_scalarmult_base() function computes
718 * the scalar product of a standard group element and an integer 'n'.
724 * resulting group element 'q' of length crypto_scalarmult_BYTES.
726 void crypto_scalarmult_base() (ubyte[] q
, const(ubyte)[] n
)
728 assert(q
.length
== crypto_scalarmult_BYTES
);
729 assert(n
.length
== crypto_scalarmult_SCALARBYTES
);
732 crypto_scalarmult(q
, n
, nine_
);
737 * The crypto_box_keypair() function randomly generates a secret key and
738 * a corresponding public key.
741 * pk = slice to put generated public key into
742 * sk = slice to put generated secret key into
747 void crypto_box_keypair() (ubyte[] pk
, ubyte[] sk
)
749 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
750 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
754 crypto_scalarmult_base(pk
, sk
);
758 * Function crypto_box_beforenm() computes a shared secret 's' from
759 * public key 'pk' and secret key 'sk'.
762 * skey = slice to put secret into
769 void crypto_box_beforenm() (ubyte[] skey
, const(ubyte)[] pk
, const(ubyte)[] sk
)
771 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
772 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
773 assert(skey
.length
>= crypto_box_BEFORENMBYTES
);
777 crypto_scalarmult(s
, sk
, pk
);
778 crypto_core_hsalsa20(skey
, zero_
[], s
[], sigma
[]);
782 * The crypto_box_afternm() function encrypts and authenticates
783 * a message 'msg' using a secret key 'key' and a nonce 'nonce'.
784 * The crypto_box_afternm() function returns the resulting ciphertext 'c'.
787 * c = resulting cyphertext
793 * success flag and cyphertext in 'c'
795 bool crypto_box_afternm() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] key
)
797 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
798 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
801 return crypto_secretbox(c
, msg
, nonce
, key
);
805 * The crypto_box_open_afternm() function verifies and decrypts
806 * a ciphertext 'c' using a secret key 'key' and a nonce 'nonce'.
807 * The crypto_box_open_afternm() function returns the resulting message 'msg'.
810 * msg = resulting message
816 * success flag and resulting message in 'msg'
818 bool crypto_box_open_afternm() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] key
)
820 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
821 assert(key
.length
>= crypto_box_BEFORENMBYTES
);
824 return crypto_secretbox_open(msg
, c
, nonce
, key
);
828 * The crypto_box() function encrypts and authenticates a message 'msg'
829 * using the sender's secret key 'sk', the receiver's public key 'pk',
830 * and a nonce 'nonce'. The crypto_box() function returns the resulting ciphertext 'c'.
833 * c = resulting cyphertext
836 * pk = receiver's public key
837 * sk = sender's secret key
840 * success flag and cyphertext in 'c'
842 bool crypto_box() (ubyte[] c
, const(ubyte)[] msg
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
)
844 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
845 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
846 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
850 crypto_box_beforenm(k
, pk
, sk
);
851 return crypto_box_afternm(c
, msg
, nonce
, k
);
855 * The crypto_box_open() function verifies and decrypts
856 * a ciphertext 'c' using the receiver's secret key 'sk',
857 * the sender's public key 'pk', and a nonce 'nonce'.
858 * The crypto_box_open() function returns the resulting message 'msg'.
861 * msg = resulting message
864 * pk = receiver's public key
865 * sk = sender's secret key
868 * success flag and message in 'msg'
870 bool crypto_box_open() (ubyte[] msg
, const(ubyte)[] c
, const(ubyte)[] nonce
, const(ubyte)[] pk
, const(ubyte)[] sk
)
872 assert(nonce
.length
>= crypto_box_NONCEBYTES
);
873 assert(pk
.length
>= crypto_box_PUBLICKEYBYTES
);
874 assert(sk
.length
>= crypto_box_SECRETKEYBYTES
);
878 crypto_box_beforenm(k
, pk
, sk
);
879 return crypto_box_open_afternm(msg
, c
, nonce
, k
);
883 ulong R() (ulong x
, int c
) { return (x
>>c
)|
(x
<<(64-c
)); }
884 ulong Ch() (ulong x
, ulong y
, ulong z
) { return (x
&y
)^
(~x
&z
); }
885 ulong Maj() (ulong x
, ulong y
, ulong z
) { return (x
&y
)^
(x
&z
)^
(y
&z
); }
886 ulong Sigma0() (ulong x
) { return R(x
, 28)^
R(x
, 34)^
R(x
, 39); }
887 ulong Sigma1() (ulong x
) { return R(x
, 14)^
R(x
, 18)^
R(x
, 41); }
888 ulong sigma0() (ulong x
) { return R(x
, 1)^
R(x
, 8)^
(x
>>7); }
889 ulong sigma1() (ulong x
) { return R(x
, 19)^
R(x
, 61)^
(x
>>6); }
891 immutable ulong[80] K
= [
892 0x428a2f98d728ae22UL
, 0x7137449123ef65cdUL
, 0xb5c0fbcfec4d3b2fUL
, 0xe9b5dba58189dbbcUL
,
893 0x3956c25bf348b538UL
, 0x59f111f1b605d019UL
, 0x923f82a4af194f9bUL
, 0xab1c5ed5da6d8118UL
,
894 0xd807aa98a3030242UL
, 0x12835b0145706fbeUL
, 0x243185be4ee4b28cUL
, 0x550c7dc3d5ffb4e2UL
,
895 0x72be5d74f27b896fUL
, 0x80deb1fe3b1696b1UL
, 0x9bdc06a725c71235UL
, 0xc19bf174cf692694UL
,
896 0xe49b69c19ef14ad2UL
, 0xefbe4786384f25e3UL
, 0x0fc19dc68b8cd5b5UL
, 0x240ca1cc77ac9c65UL
,
897 0x2de92c6f592b0275UL
, 0x4a7484aa6ea6e483UL
, 0x5cb0a9dcbd41fbd4UL
, 0x76f988da831153b5UL
,
898 0x983e5152ee66dfabUL
, 0xa831c66d2db43210UL
, 0xb00327c898fb213fUL
, 0xbf597fc7beef0ee4UL
,
899 0xc6e00bf33da88fc2UL
, 0xd5a79147930aa725UL
, 0x06ca6351e003826fUL
, 0x142929670a0e6e70UL
,
900 0x27b70a8546d22ffcUL
, 0x2e1b21385c26c926UL
, 0x4d2c6dfc5ac42aedUL
, 0x53380d139d95b3dfUL
,
901 0x650a73548baf63deUL
, 0x766a0abb3c77b2a8UL
, 0x81c2c92e47edaee6UL
, 0x92722c851482353bUL
,
902 0xa2bfe8a14cf10364UL
, 0xa81a664bbc423001UL
, 0xc24b8b70d0f89791UL
, 0xc76c51a30654be30UL
,
903 0xd192e819d6ef5218UL
, 0xd69906245565a910UL
, 0xf40e35855771202aUL
, 0x106aa07032bbd1b8UL
,
904 0x19a4c116b8d2d0c8UL
, 0x1e376c085141ab53UL
, 0x2748774cdf8eeb99UL
, 0x34b0bcb5e19b48a8UL
,
905 0x391c0cb3c5c95a63UL
, 0x4ed8aa4ae3418acbUL
, 0x5b9cca4f7763e373UL
, 0x682e6ff3d6b2b8a3UL
,
906 0x748f82ee5defb2fcUL
, 0x78a5636f43172f60UL
, 0x84c87814a1f0ab72UL
, 0x8cc702081a6439ecUL
,
907 0x90befffa23631e28UL
, 0xa4506cebde82bde9UL
, 0xbef9a3f7b2c67915UL
, 0xc67178f2e372532bUL
,
908 0xca273eceea26619cUL
, 0xd186b8c721c0c207UL
, 0xeada7dd6cde0eb1eUL
, 0xf57d4f7fee6ed178UL
,
909 0x06f067aa72176fbaUL
, 0x0a637dc5a2c898a6UL
, 0x113f9804bef90daeUL
, 0x1b710b35131c471bUL
,
910 0x28db77f523047d84UL
, 0x32caab7b40c72493UL
, 0x3c9ebe0a15c9bebcUL
, 0x431d67c49c100d4cUL
,
911 0x4cc5d4becb3e42b6UL
, 0x597f299cfc657e2aUL
, 0x5fcb6fab3ad6faecUL
, 0x6c44198c4a475817UL
914 void crypto_hashblocks (ubyte[] x
, const(ubyte)[] m
, ulong n
) @safe nothrow @nogc {
915 ulong[8] z
= void, b
= void, a
= void;
919 foreach (i
; 0..8) z
[i
] = a
[i
] = dl64(x
[8*i
..$]);
921 foreach (i
; 0..16) w
[i
] = dl64(m
[mpos
+8*i
..$]);
924 t
= a
[7]+Sigma1(a
[4])+Ch(a
[4], a
[5], a
[6])+K
[i
]+w
[i
%16];
925 b
[7] = t
+Sigma0(a
[0])+Maj(a
[0], a
[1], a
[2]);
927 //foreach (j; 0..8) a[(j+1)%8] = b[j];
931 foreach (j
; 0..16) w
[j
] += w
[(j
+9)%16]+sigma0(w
[(j
+1)%16])+sigma1(w
[(j
+14)%16]);
934 foreach (i
; 0..8) { a
[i
] += z
[i
]; z
[i
] = a
[i
]; }
938 foreach (i
; 0..8) ts64(x
[8*i
..$], z
[i
]);
941 immutable ubyte[64] iv
= [
942 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
943 0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
944 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
945 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
946 0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
947 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
948 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
949 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
953 * The crypto_hash() function hashes a message 'msg'.
954 * It returns a hash 'output'. The output length of 'output' should be at least crypto_hash_BYTES.
957 * output = resulting hash
963 public void crypto_hash() (ubyte[] output
, const(ubyte)[] msg
)
965 assert(output
.length
>= crypto_hash_BYTES
);
969 ubyte[256] x
; /*autoinit*/
970 size_t n
= msg
.length
;
976 crypto_hashblocks(h
, msg
, n
);
981 x
[0..n
] = msg
[mpos
..mpos
+n
];
986 ts64(x
[n
-8..$], b
<<3);
987 crypto_hashblocks(h
, x
, n
);
992 private void add() (ref long[16][4] p
, ref long[16][4] q
) {
993 long[16] a
= void, b
= void, c
= void, d
= void, t
= void, e
= void, f
= void, g
= void, h
= void;
1016 void cswap() (ref long[16][4] p
, ref long[16][4] q
, ubyte b
) {
1017 foreach (i
; 0..4) sel25519(p
[i
], q
[i
], b
);
1020 void pack() (ubyte[] r
, ref long[16][4] p
) {
1021 long[16] tx
= void, ty
= void, zi
= void;
1026 r
[31] ^
= par25519(tx
)<<7;
1029 void scalarmult() (ref long[16][4] p
, ref long[16][4] q
, const(ubyte)[] s
) {
1034 for (int i
= 255; i
>= 0; --i
) {
1035 ubyte b
= (s
[i
/8]>>(i
&7))&1;
1043 void scalarbase() (ref long[16][4] p
, const(ubyte)[] s
) {
1044 long[16][4] q
= void;
1049 scalarmult(p
, q
, s
);
1053 * The crypto_sign_keypair() function randomly generates a secret key and
1054 * a corresponding public key.
1057 * pk = slice to put generated public key into
1058 * sk = slice to put generated secret key into
1063 public void crypto_sign_keypair() (ubyte[] pk
, ubyte[] sk
)
1065 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1066 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1070 long[16][4] p
= void;
1072 randombytes(sk
, 32);
1073 crypto_hash(d
, sk
[0..32]);
1081 sk
[32..64] = pk
[0..32];
1084 immutable ulong[32] L
= [
1085 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
1088 void modL() (ubyte[] r
, long[] x
) {
1090 for (auto i
= 63; i
>= 32; --i
) {
1093 for (j
= i
-32; j
< i
-12; ++j
) {
1094 x
[j
] += carry
-16*x
[i
]*L
[j
-(i
-32)];
1095 carry
= (x
[j
]+128)>>8;
1102 foreach (j
; 0..32) {
1103 x
[j
] += carry
-(x
[31]>>4)*L
[j
];
1107 foreach (j
; 0..32) x
[j
] -= carry
*L
[j
];
1108 foreach (i
; 0..32) {
1114 void reduce() (ubyte[] r
) {
1116 foreach (i
; 0..64) x
[i
] = cast(ulong)r
[i
];
1124 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1125 * The crypto_sign() function returns the resulting signed message.
1128 * sm = buffer to receive signed message, must be of size at least msg.length+64
1130 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1135 void crypto_sign() (ubyte[] sm
, const(ubyte)[] msg
, const(ubyte)[] sk
)
1137 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1138 assert(sm
.length
>= msg
.length
+64);
1141 ubyte[64] d
= void, h
= void, r
= void;
1142 ulong[64] x
;/*autoinit*/
1143 long[16][4] p
= void;
1144 size_t n
= msg
.length
;
1145 size_t smlen
= n
+64;
1147 crypto_hash(d
, sk
[0..32]);
1152 sm
[64..64+n
] = msg
[];
1153 sm
[32..64] = d
[32..64];
1155 crypto_hash(r
, sm
[32..32+n
+32]);
1160 sm
[32..64] = sk
[32..64];
1161 crypto_hash(h
, sm
[0..n
+64]);
1164 foreach (i
; 0..32) x
[i
] = cast(ulong)r
[i
];
1165 foreach (i
; 0..32) foreach (j
; 0..32) x
[i
+j
] += h
[i
]*cast(ulong)d
[j
];
1166 modL(sm
[32..$], cast(long[])x
);
1170 * The crypto_sign() function signs a message 'msg' using the sender's secret key 'sk'.
1171 * The crypto_sign() function returns the resulting signed message.
1173 * WARNING! This function allocates!
1177 * sk == secret key, slice size must be at least crypto_sign_SECRETKEYBYTES, extra ignored
1182 ubyte[] crypto_sign() (const(ubyte)[] msg
, const(ubyte)[] sk
)
1184 assert(sk
.length
>= crypto_sign_SECRETKEYBYTES
);
1188 size_t n
= msg
.length
;
1189 size_t smlen
= n
+64;
1191 crypto_sign(sm
, msg
, sk
);
1195 private bool unpackneg() (ref long[16][4] r
, const(ubyte)[] p
) {
1196 long[16] t
= void, chk
= void, num
= void, den
= void, den2
= void, den4
= void, den6
= void;
1198 unpack25519(r
[1], p
);
1206 M(den6
, den4
, den2
);
1218 if (!neq25519(chk
, num
)) M(r
[0], r
[0], I
);
1222 if (!neq25519(chk
, num
)) return false;
1224 if (par25519(r
[0]) == (p
[31]>>7)) Z(r
[0], gf0
, r
[0]);
1226 M(r
[3], r
[0], r
[1]);
1231 * The crypto_sign_open() function verifies the signature in
1232 * 'sm' using the receiver's public key 'pk'.
1235 * msg = decrypted message, last 64 bytes are useless zeroes, must be of size at least sm.length
1236 * sm == signed message
1237 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1242 bool crypto_sign_open() (ubyte[] msg
, const(ubyte)[] sm
, const(ubyte)[] pk
)
1244 assert(pk
.length
>= crypto_sign_PUBLICKEYBYTES
);
1245 assert(msg
.length
>= sm
.length
);
1250 long[16][4] p
= void, q
= void;
1251 size_t n
= sm
.length
;
1253 if (n
< 64) return false;
1255 if (!unpackneg(q
, pk
)) return false;
1257 msg
[32..64] = pk
[0..32];
1258 crypto_hash(h
, msg
);
1260 scalarmult(p
, q
, h
);
1262 scalarbase(q
, sm
[32..$]);
1267 if (!crypto_verify_32(sm
, t
)) {
1272 msg
[0..n
] = sm
[64..64+n
];
1280 * The crypto_sign_open() function verifies the signature in
1281 * 'sm' using the receiver's public key 'pk'.
1282 * The crypto_sign_open() function returns the message.
1284 * WARNING! This function allocates!
1287 * sm == signed message
1288 * pk == public key, slice size must be at least crypto_sign_PUBLICKEYBYTES, extra ignored
1291 * decrypted message or null on error
1293 ubyte[] crypto_sign_open() (const(ubyte)[] sm
, const(ubyte)[] pk
) {
1295 msg
.length
= sm
.length
;
1296 if (!crypto_sign_open(msg
, sm
, pk
)) return null;
1297 return msg
[0..sm
.length
-64]; // remove signature
1302 import std
.exception
;
1308 private extern(C) int open(const(char)* filename, int flags, ...);
1309 void randombytes (ubyte[] dest, size_t len) {
1310 import core.sys.posix.unistd;
1314 fd = open("/dev/urandom", /*O_RDONLY*/0);
1315 if (fd != -1) break;
1321 ssize_t i = read(fd, cast(void*)(&dest[pos]), (len < 1048576 ? len : 1048576));
1332 static void rnd (ubyte[] dest, size_t len) {
1333 for (size_t f = 0; f < len; ++f) dest[f] = cast(ubyte)uniform(0, 256);
1338 randombytes
= (ubyte[] dest
, size_t len
) {
1339 for (size_t f
= 0; f
< len
; ++f
) dest
[f
] = cast(ubyte)uniform(0, 256);
1342 void dumpArray(T
) (T
[] arr
) {
1343 writefln("============================= (%s)", arr
.length
);
1344 for (auto f
= 0; f
< arr
.length
; ++f
) {
1345 if (f
&& f
%16 == 0) writeln();
1346 static if (T
.sizeof
== 1) writef(" 0x%02x", arr
[f
]);
1347 else static if (T
.sizeof
== 2) writef(" 0x%04x", arr
[f
]);
1348 else static if (T
.sizeof
== 4) writef(" 0x%08x", arr
[f
]);
1349 else writef(" 0x%08x", arr
[f
]);
1352 writeln("-----------------------------");
1355 string
hashToString (const(ubyte)[] hash
) {
1357 s
.length
= hash
.length
*2;
1358 char toHex(int a
) { return cast(char)(a
< 10 ? a
+'0' : a
+'a'-10); }
1359 for (int a
= 0; a
< hash
.length
; ++a
) {
1360 s
[a
*2] = toHex(hash
[a
]>>4);
1361 s
[a
*2+1] = toHex(hash
[a
]&0x0f);
1363 return assumeUnique(s
);
1366 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];
1367 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];
1368 static immutable ubyte[5] m
= [0x61,0x68,0x6f,0x6a,0x0a];
1369 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];
1372 writeln("crypto_sign");
1373 smres
= crypto_sign(m
, sk
);
1374 assert(smres
.length
== sm
.length
);
1375 assert(smres
== sm
);
1377 writeln("crypto_sign_open");
1378 t
= crypto_sign_open(smres
, pk
);
1380 assert(t
.length
== m
.length
);
1384 // based on the code by Adam D. Ruppe
1385 // 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
1386 template SHARange(T
) if (isInputRange
!(T
)) {
1390 bool empty () { return state
== 5; }
1402 bool hackforward
= false;
1406 if (((position
+length
+8)*8)%512 == 8) {
1412 } else if (state
== 2) {
1414 if (!(((position
+length
+8)*8)%512)) {
1418 if (hackforward
) goto proceedmoar
;
1422 } else if (state
== 3) {
1424 current
= (length
>>(position
*8))&0xff;
1425 if (position
== 0) state
= 4; else --position
;
1426 } else if (state
== 4) {
1434 if (state
== 0) return cast(ubyte)r
.front
;
1436 //writefln("%x", current);
1443 int state
= 0; // reading range, reading appended bit, reading padding, reading length, done
1448 immutable(ubyte)[] SHA256(T
) (T data
) if (isInputRange
!(T
)) {
1449 uint[8] h
= [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
1450 static immutable(uint[64]) k
= [
1451 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1452 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1453 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1454 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1455 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1456 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1457 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1458 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1463 static if (is(data
== SHARange
)) range
= data
; else range
.r
= data
;
1466 while(!range
.empty
) {
1469 for(int a
= 0; a
< 16; ++a
) {
1470 for(int b
= 3; b
>= 0; --b
) {
1471 words
[a
] |
= cast(uint)(range
.front())<<(b
*8);
1476 uint ror (uint n
, int cnt
) {
1477 return cast(uint)(n
>>cnt
)|
cast(uint)(n
<<(32-(cnt
)));
1480 uint xrot00 (uint reax
, int r0
, int r1
, int r2
) {
1481 uint rebx
= reax
, recx
= reax
;
1482 reax
= ror(reax
, r0
);
1483 rebx
= ror(rebx
, r1
);
1490 for(int a
= 16; a
< 64; ++a
) {
1491 uint t1
= xrot00(words
[a
-15], 7, 18, 3);
1492 uint t2
= xrot00(words
[a
-2], 17, 19, 10);
1493 words
[a
] = words
[a
-16]+t1
+words
[a
-7]+t2
;
1505 uint xrot01 (uint reax
, int r0
, int r1
, int r2
) {
1506 uint rebx
= reax
, recx
= reax
;
1507 reax
= ror(reax
, r0
);
1508 rebx
= ror(rebx
, r1
);
1509 recx
= ror(recx
, r2
);
1515 for(int i
= 0; i
< 64; ++i
) {
1516 uint s0
= xrot01(A
, 2, 13, 22);
1517 uint maj
= (A
&B
)^
(A
&C
)^
(B
&C
);
1519 uint s1
= xrot01(E
, 6, 11, 25);
1520 uint ch
= (E
&F
)^
((~E
)&G
);
1521 uint t1
= H
+s1
+ch
+k
[i
]+words
[i
];
1544 for(int j
= 0; j
< 8; ++j
)
1545 for(int i
= 3; i
>= 0; --i
) {
1546 hash
~= cast(ubyte)(h
[j
]>>(i
*8))&0xff;
1556 static immutable ubyte[32] alicesk
= [
1557 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
1558 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
1559 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
1560 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
1563 static immutable ubyte[32] bobpk
= [
1564 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
1565 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
1566 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
1567 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
1570 static immutable ubyte[24] nonce
= [
1571 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1572 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1573 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1576 // API requires first 32 bytes to be 0
1577 static immutable ubyte[163] m
= [
1578 0, 0, 0, 0, 0, 0, 0, 0
1579 , 0, 0, 0, 0, 0, 0, 0, 0
1580 , 0, 0, 0, 0, 0, 0, 0, 0
1581 , 0, 0, 0, 0, 0, 0, 0, 0
1582 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1583 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1584 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1585 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1586 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1587 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1588 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1589 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1590 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1591 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1592 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1593 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1594 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1595 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1596 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1597 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1604 static immutable ubyte[] res
= [
1605 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1606 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1607 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1608 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1609 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1610 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1611 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1612 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1613 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1614 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1615 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1616 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1617 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1618 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1619 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1620 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1621 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1622 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1624 /*crypto_box_curve25519xsalsa20poly1305*/crypto_box(c
,m
,nonce
,bobpk
,alicesk
);
1625 for (auto f
= 16; f
< 163; ++f
) assert(c
[f
] == res
[f
-16]);
1631 static immutable ubyte[32] bobsk
= [
1632 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
1633 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
1634 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
1635 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
1638 static immutable ubyte[32] alicepk
= [
1639 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
1640 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
1641 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
1642 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
1645 static immutable ubyte[24] nonce
= [
1646 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1647 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1648 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1651 // API requires first 16 bytes to be 0
1652 static immutable ubyte[163] c
= [
1653 0, 0, 0, 0, 0, 0, 0, 0
1654 , 0, 0, 0, 0, 0, 0, 0, 0
1655 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1656 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1657 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1658 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1659 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1660 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1661 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1662 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1663 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1664 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1665 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1666 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1667 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1668 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1669 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1670 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1671 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1672 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1678 static immutable ubyte[] res
= [
1679 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1680 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1681 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1682 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1683 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1684 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1685 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1686 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1687 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1688 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1689 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1690 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1691 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1692 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1693 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1694 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1698 assert(/*crypto_box_curve25519xsalsa20poly1305_open*/crypto_box_open(m
,c
,nonce
,alicepk
,bobsk
));
1699 for (auto f
= 32; f
< 163; ++f
) assert(m
[f
] == res
[f
-32]);
1705 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1706 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1707 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1708 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1709 ubyte[crypto_box_NONCEBYTES
] n
;
1710 ubyte[10000] m
, c
, m2
;
1711 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1712 crypto_box_keypair(alicepk
,alicesk
);
1713 crypto_box_keypair(bobpk
,bobsk
);
1714 randombytes(n
,crypto_box_NONCEBYTES
);
1715 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1716 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1717 assert(crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
));
1718 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1721 version(unittest_full
) box7(); // it's slow
1725 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1726 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1727 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1728 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1729 ubyte[crypto_box_NONCEBYTES
] n
;
1730 ubyte[10000] m
, c
, m2
;
1731 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1732 crypto_box_keypair(alicepk
,alicesk
);
1733 crypto_box_keypair(bobpk
,bobsk
);
1734 randombytes(n
,crypto_box_NONCEBYTES
);
1735 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1736 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1738 while (caught
< 10) {
1739 c
[uniform(0, mlen
+crypto_box_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
1740 if (crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
)) {
1741 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1746 assert(caught
== 10);
1749 version(unittest_full
) box8(); // it's slow
1753 static immutable ubyte[32] shared_
= [
1754 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
1755 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
1756 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
1757 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
1760 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];
1762 static immutable ubyte[16] c
= [
1763 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1764 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1769 static immutable ubyte[32] res
= [
1770 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1771 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1772 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1773 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1776 crypto_core_hsalsa20(firstkey
,zero
,shared_
,c
);
1777 assert(firstkey
== res
);
1783 static immutable ubyte[32]firstkey
= [
1784 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1785 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1786 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1787 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1790 static immutable ubyte[16]nonceprefix
= [
1791 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1792 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1795 static immutable ubyte[16] c
= [
1796 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1797 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1800 ubyte[32] secondkey
;
1802 static immutable ubyte[32] res
= [
1803 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1804 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1805 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1806 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1809 crypto_core_hsalsa20(secondkey
,nonceprefix
,firstkey
,c
);
1810 assert(secondkey
== res
);
1816 static immutable ubyte[32] secondkey
= [
1817 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1818 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1819 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1820 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1823 static immutable ubyte[8] noncesuffix
= [
1824 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1827 static immutable ubyte[16] c
= [
1828 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1829 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1832 static ubyte[16] input
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ;
1834 static ubyte[64*256*256] output
;
1838 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];
1841 for (auto i
= 0; i
< 8; ++i
) input
[i
] = noncesuffix
[i
];
1844 crypto_core_salsa20(output
[pos
..$],input
,secondkey
,c
);
1846 } while (++input
[8]);
1847 } while (++input
[9]);
1848 crypto_hash(h
,output
);
1851 version(unittest_full
) core3(); // it's slow
1855 static immutable ubyte[32] k
= [
1856 1, 2, 3, 4, 5, 6, 7, 8
1857 , 9, 10, 11, 12, 13, 14, 15, 16
1858 ,201,202,203,204,205,206,207,208
1859 ,209,210,211,212,213,214,215,216
1862 static immutable ubyte[16] input
= [
1863 101,102,103,104,105,106,107,108
1864 ,109,110,111,112,113,114,115,116
1867 static immutable ubyte[16] c
= [
1868 101,120,112, 97,110,100, 32, 51
1869 , 50, 45, 98,121,116,101, 32,107
1874 static immutable ubyte[64] res
= [
1875 69, 37, 68, 39, 41, 15,107,193
1876 ,255,139,122, 6,170,233,217, 98
1877 , 89,144,182,106, 21, 51,200, 65
1878 ,239, 49,222, 34,215,114, 40,126
1879 ,104,197, 7,225,197,153, 31, 2
1880 ,102, 78, 76,176, 84,245,246,184
1881 ,177,160,133,130, 6, 72,149,119
1882 ,192,195,132,236,234,103,246, 74
1885 crypto_core_salsa20(output
,input
,k
,c
);
1886 assert(output
== res
);
1892 static immutable ubyte[32] k
= [
1893 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1894 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1895 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1896 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1899 static immutable ubyte[16] input
= [
1900 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1901 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1904 static immutable ubyte[16] c
= [
1905 101,120,112, 97,110,100, 32, 51
1906 , 50, 45, 98,121,116,101, 32,107
1911 static immutable ubyte[32] res
= [
1912 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1913 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1914 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1915 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1918 crypto_core_hsalsa20(output
,input
,k
,c
);
1919 assert(output
== res
);
1925 static immutable ubyte[32] k
= [
1926 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1927 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1928 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1929 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1932 static immutable ubyte[16] input
= [
1933 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1934 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1937 static immutable ubyte[16] c
= [
1938 101,120,112, 97,110,100, 32, 51
1939 , 50, 45, 98,121,116,101, 32,107
1944 static immutable ubyte[32] res
= [
1945 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1946 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1947 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1948 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1954 void print(const(ubyte)[] x
, const(ubyte)[] y
)
1957 for (auto i
= 0; i
< 4; ++i
) {
1960 //printf(",0x%02x",255&(xi-yi-borrow));
1961 pp
[pppos
++] = cast(ubyte)(255&(xi
-yi
-borrow
));
1962 borrow
= (xi
< yi
+borrow
);
1966 crypto_core_salsa20(output
,input
,k
,c
);
1968 print(output
[20..$],c
[4..$]);
1969 print(output
[40..$],c
[8..$]);
1970 print(output
[60..$],c
[12..$]);
1971 print(output
[24..$],input
);
1972 print(output
[28..$],input
[4..$]);
1973 print(output
[32..$],input
[8..$]);
1974 print(output
[36..$],input
[12..$]);
1981 static immutable ubyte[8] x
= ['t','e','s','t','i','n','g','\n'];
1982 static ubyte[crypto_hash_BYTES
] h
;
1983 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];
1985 //for (auto f = 0; f < crypto_hash_BYTES; ++f) assert(h[f] == res[f]);
1990 void onetimeauth () {
1991 writeln("onetimeauth");
1992 static immutable ubyte[32] rs
= [
1993 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
1994 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
1995 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
1996 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
1999 static immutable ubyte[131] c
= [
2000 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2001 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2002 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2003 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2004 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2005 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2006 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2007 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2008 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2009 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2010 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2011 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2012 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2013 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2014 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2015 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2021 static immutable ubyte[16] res
= [0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9];
2023 /*crypto_onetimeauth_poly1305*/crypto_onetimeauth(a
,c
,rs
);
2028 void onetimeauth2 () {
2029 writeln("onetimeauth2");
2030 static immutable ubyte[32] rs
= [
2031 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2032 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2033 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2034 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2037 static immutable ubyte[131] c
= [
2038 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2039 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2040 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2041 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2042 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2043 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2044 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2045 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2046 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2047 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2048 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2049 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2050 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2051 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2052 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2053 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2057 static immutable ubyte[16] a
= [
2058 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2059 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2062 assert(/*crypto_onetimeauth_poly1305_verify*/crypto_onetimeauth_verify(a
,c
,rs
));
2066 void onetimeauth7 () {
2067 writeln("onetimeauth7");
2068 static ubyte[32] key
;
2069 static ubyte[10000] c
;
2072 for (auto clen
= 0; clen
< 10000; ++clen
) {
2073 //if (clen%512 == 0) { writef("\r%s", clen); stdout.flush(); }
2074 randombytes(key
, key
.length
);
2075 randombytes(c
, clen
);
2076 crypto_onetimeauth(a
,c
[0..clen
],key
);
2077 assert(crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2079 c
[uniform(0, clen
)] += 1+(uniform(0, 255));
2080 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2081 a
[uniform(0, a
.length
)] += 1+(uniform(0, 255));
2082 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2086 version(unittest_full
) onetimeauth7(); // it's slow
2088 void scalarmult () {
2089 writeln("scalarmult");
2090 static immutable ubyte[32] alicesk
= [
2091 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2092 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2093 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2094 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2099 static immutable ubyte[32] res
= [
2100 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2101 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2102 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2103 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2106 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(alicepk
,alicesk
);
2107 assert(alicepk
== res
);
2111 void scalarmult2 () {
2112 writeln("scalarmult2");
2113 static immutable ubyte[32] bobsk
= [
2114 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2115 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2116 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2117 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2122 static immutable ubyte[32] res
= [
2123 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2124 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2125 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2126 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2129 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(bobpk
,bobsk
);
2130 assert(bobpk
== res
);
2134 void scalarmult5 () {
2135 writeln("scalarmult5");
2136 static immutable ubyte[32] alicesk
= [
2137 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2138 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2139 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2140 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2143 static immutable ubyte[32] bobpk
= [
2144 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2145 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2146 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2147 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2152 static immutable ubyte[32] res
= [
2153 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2154 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2155 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2156 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2159 crypto_scalarmult(k
,alicesk
,bobpk
);
2164 void scalarmult6 () {
2165 writeln("scalarmult6");
2166 static immutable ubyte[32] bobsk
= [
2167 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2168 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2169 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2170 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2173 static immutable ubyte[32] alicepk
= [
2174 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2175 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2176 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2177 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2182 static immutable ubyte[32] res
= [
2183 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2184 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2185 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2186 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2189 crypto_scalarmult(k
,bobsk
,alicepk
);
2195 writeln("secretbox");
2196 static immutable ubyte[32] firstkey
= [
2197 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2198 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2199 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2200 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2203 static immutable ubyte[24] nonce
= [
2204 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2205 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2206 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2209 // API requires first 32 bytes to be 0
2210 static immutable ubyte[163] m
= [
2211 0, 0, 0, 0, 0, 0, 0, 0
2212 , 0, 0, 0, 0, 0, 0, 0, 0
2213 , 0, 0, 0, 0, 0, 0, 0, 0
2214 , 0, 0, 0, 0, 0, 0, 0, 0
2215 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2216 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2217 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2218 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2219 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2220 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2221 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2222 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2223 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2224 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2225 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2226 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2227 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2228 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2229 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2230 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2234 static immutable ubyte[] res
= [
2235 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2236 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2237 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2238 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2239 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2240 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2241 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2242 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2243 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2244 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2245 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2246 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2247 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2248 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2249 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2250 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2251 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2252 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2257 crypto_secretbox(c
,m
,nonce
,firstkey
);
2258 for (auto i
= 16; i
< 163; ++i
) assert(c
[i
] == res
[i
-16]);
2262 void secretbox2 () {
2263 writeln("secretbox2");
2264 static immutable ubyte[32] firstkey
= [
2265 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2266 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2267 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2268 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2271 static immutable ubyte[24] nonce
= [
2272 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2273 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2274 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2277 // API requires first 16 bytes to be 0
2278 static immutable ubyte[163] c
= [
2279 0, 0, 0, 0, 0, 0, 0, 0
2280 , 0, 0, 0, 0, 0, 0, 0, 0
2281 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2282 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2283 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2284 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2285 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2286 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2287 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2288 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2289 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2290 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2291 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2292 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2293 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2294 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2295 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2296 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2297 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2298 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2302 static immutable ubyte[] res
= [
2303 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2304 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2305 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2306 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2307 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2308 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2309 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2310 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2311 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2312 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2313 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2314 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2315 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2316 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2317 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2318 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2324 assert(crypto_secretbox_open(m
,c
,nonce
,firstkey
));
2325 for (auto i
= 32; i
< 163; ++i
) assert(m
[i
] == res
[i
-32]);
2329 void secretbox7 () {
2330 writeln("secretbox7");
2331 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2332 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2333 static ubyte[10000] m
, c
, m2
;
2334 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2335 randombytes(k
,crypto_secretbox_KEYBYTES
);
2336 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2337 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2338 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2339 assert(crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
));
2340 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2345 void secretbox8 () {
2346 writeln("secretbox8");
2347 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2348 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2349 static ubyte[10000] m
, c
, m2
;
2350 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2351 randombytes(k
,crypto_secretbox_KEYBYTES
);
2352 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2353 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2354 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2356 while (caught
< 10) {
2357 c
[uniform(0, mlen
+crypto_secretbox_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
2358 if (crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
)) {
2359 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2363 assert(caught
== 10);
2366 version(unittest_full
) secretbox8(); // it's slow
2370 static immutable ubyte[32] firstkey
= [
2371 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2372 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2373 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2374 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2377 static immutable ubyte[24] nonce
= [
2378 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2379 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2380 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2383 static ubyte[4194304] output
;
2386 //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];
2388 crypto_stream(output
,nonce
,firstkey
);
2389 //crypto_hash_sha256(h,output,sizeof output);
2390 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2396 static immutable ubyte[32] secondkey
= [
2397 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
2398 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
2399 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
2400 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
2403 static immutable ubyte[8] noncesuffix
= [
2404 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2407 static ubyte[4194304] output
;
2409 crypto_stream_salsa20(output
,noncesuffix
,secondkey
);
2410 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2416 static immutable ubyte[32] firstkey
= [
2417 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2418 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2419 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2420 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2423 static immutable ubyte[24] nonce
= [
2424 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2425 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2426 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2431 static immutable ubyte[32] res
= [
2432 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2433 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2434 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2435 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2438 crypto_stream
/*_xsalsa20*/(rs
,nonce
,firstkey
);
2445 static immutable ubyte[32] firstkey
= [
2446 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2447 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2448 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2449 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2452 static immutable ubyte[24] nonce
= [
2453 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2454 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2455 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2458 static immutable ubyte[163] m
= [
2459 0, 0, 0, 0, 0, 0, 0, 0
2460 , 0, 0, 0, 0, 0, 0, 0, 0
2461 , 0, 0, 0, 0, 0, 0, 0, 0
2462 , 0, 0, 0, 0, 0, 0, 0, 0
2463 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2464 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2465 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2466 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2467 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2468 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2469 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2470 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2471 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2472 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2473 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2474 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2475 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2476 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2477 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2478 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2484 static immutable ubyte[] res
= [
2485 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2486 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2487 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2488 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2489 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2490 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2491 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2492 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2493 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2494 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2495 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2496 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2497 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2498 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2499 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2500 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2504 /*crypto_stream_xsalsa20_xor*/crypto_stream_xor(c
,m
,nonce
,firstkey
);
2505 for (auto i
= 32; i
< 163; ++i
) assert(c
[i
] == res
[i
-32]);
2510 version(unittest_main
) {