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
1301 version(tweetnacl_unittest
)
1303 import std
.exception
;
1309 private extern(C) int open(const(char)* filename, int flags, ...);
1310 void randombytes (ubyte[] dest, size_t len) {
1311 import core.sys.posix.unistd;
1315 fd = open("/dev/urandom", /*O_RDONLY*/0);
1316 if (fd != -1) break;
1322 ssize_t i = read(fd, cast(void*)(&dest[pos]), (len < 1048576 ? len : 1048576));
1333 static void rnd (ubyte[] dest, size_t len) {
1334 for (size_t f = 0; f < len; ++f) dest[f] = cast(ubyte)uniform(0, 256);
1339 randombytes
= (ubyte[] dest
, size_t len
) {
1340 for (size_t f
= 0; f
< len
; ++f
) dest
[f
] = cast(ubyte)uniform(0, 256);
1343 void dumpArray(T
) (T
[] arr
) {
1344 writefln("============================= (%s)", arr
.length
);
1345 for (auto f
= 0; f
< arr
.length
; ++f
) {
1346 if (f
&& f
%16 == 0) writeln();
1347 static if (T
.sizeof
== 1) writef(" 0x%02x", arr
[f
]);
1348 else static if (T
.sizeof
== 2) writef(" 0x%04x", arr
[f
]);
1349 else static if (T
.sizeof
== 4) writef(" 0x%08x", arr
[f
]);
1350 else writef(" 0x%08x", arr
[f
]);
1353 writeln("-----------------------------");
1356 string
hashToString (const(ubyte)[] hash
) {
1358 s
.length
= hash
.length
*2;
1359 char toHex(int a
) { return cast(char)(a
< 10 ? a
+'0' : a
+'a'-10); }
1360 for (int a
= 0; a
< hash
.length
; ++a
) {
1361 s
[a
*2] = toHex(hash
[a
]>>4);
1362 s
[a
*2+1] = toHex(hash
[a
]&0x0f);
1364 return assumeUnique(s
);
1367 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];
1368 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];
1369 static immutable ubyte[5] m
= [0x61,0x68,0x6f,0x6a,0x0a];
1370 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];
1373 writeln("crypto_sign");
1374 smres
= crypto_sign(m
, sk
);
1375 assert(smres
.length
== sm
.length
);
1376 assert(smres
== sm
);
1378 writeln("crypto_sign_open");
1379 t
= crypto_sign_open(smres
, pk
);
1381 assert(t
.length
== m
.length
);
1385 // based on the code by Adam D. Ruppe
1386 // 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
1387 template SHARange(T
) if (isInputRange
!(T
)) {
1391 bool empty () { return state
== 5; }
1403 bool hackforward
= false;
1407 if (((position
+length
+8)*8)%512 == 8) {
1413 } else if (state
== 2) {
1415 if (!(((position
+length
+8)*8)%512)) {
1419 if (hackforward
) goto proceedmoar
;
1423 } else if (state
== 3) {
1425 current
= (length
>>(position
*8))&0xff;
1426 if (position
== 0) state
= 4; else --position
;
1427 } else if (state
== 4) {
1435 if (state
== 0) return cast(ubyte)r
.front
;
1437 //writefln("%x", current);
1444 int state
= 0; // reading range, reading appended bit, reading padding, reading length, done
1449 immutable(ubyte)[] SHA256(T
) (T data
) if (isInputRange
!(T
)) {
1450 uint[8] h
= [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
1451 static immutable(uint[64]) k
= [
1452 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1453 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1454 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1455 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1456 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1457 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1458 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1459 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1464 static if (is(data
== SHARange
)) range
= data
; else range
.r
= data
;
1467 while(!range
.empty
) {
1470 for(int a
= 0; a
< 16; ++a
) {
1471 for(int b
= 3; b
>= 0; --b
) {
1472 words
[a
] |
= cast(uint)(range
.front())<<(b
*8);
1477 uint ror (uint n
, int cnt
) {
1478 return cast(uint)(n
>>cnt
)|
cast(uint)(n
<<(32-(cnt
)));
1481 uint xrot00 (uint reax
, int r0
, int r1
, int r2
) {
1482 uint rebx
= reax
, recx
= reax
;
1483 reax
= ror(reax
, r0
);
1484 rebx
= ror(rebx
, r1
);
1491 for(int a
= 16; a
< 64; ++a
) {
1492 uint t1
= xrot00(words
[a
-15], 7, 18, 3);
1493 uint t2
= xrot00(words
[a
-2], 17, 19, 10);
1494 words
[a
] = words
[a
-16]+t1
+words
[a
-7]+t2
;
1506 uint xrot01 (uint reax
, int r0
, int r1
, int r2
) {
1507 uint rebx
= reax
, recx
= reax
;
1508 reax
= ror(reax
, r0
);
1509 rebx
= ror(rebx
, r1
);
1510 recx
= ror(recx
, r2
);
1516 for(int i
= 0; i
< 64; ++i
) {
1517 uint s0
= xrot01(A
, 2, 13, 22);
1518 uint maj
= (A
&B
)^
(A
&C
)^
(B
&C
);
1520 uint s1
= xrot01(E
, 6, 11, 25);
1521 uint ch
= (E
&F
)^
((~E
)&G
);
1522 uint t1
= H
+s1
+ch
+k
[i
]+words
[i
];
1545 for(int j
= 0; j
< 8; ++j
)
1546 for(int i
= 3; i
>= 0; --i
) {
1547 hash
~= cast(ubyte)(h
[j
]>>(i
*8))&0xff;
1557 static immutable ubyte[32] alicesk
= [
1558 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
1559 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
1560 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
1561 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
1564 static immutable ubyte[32] bobpk
= [
1565 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
1566 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
1567 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
1568 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
1571 static immutable ubyte[24] nonce
= [
1572 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1573 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1574 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1577 // API requires first 32 bytes to be 0
1578 static immutable ubyte[163] m
= [
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 , 0, 0, 0, 0, 0, 0, 0, 0
1583 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1584 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1585 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1586 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1587 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1588 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1589 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1590 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1591 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1592 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1593 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1594 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1595 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1596 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1597 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1598 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1605 static immutable ubyte[] res
= [
1606 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1607 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1608 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1609 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1610 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1611 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1612 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1613 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1614 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1615 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1616 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1617 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1618 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1619 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1620 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1621 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1622 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1623 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1625 /*crypto_box_curve25519xsalsa20poly1305*/crypto_box(c
,m
,nonce
,bobpk
,alicesk
);
1626 for (auto f
= 16; f
< 163; ++f
) assert(c
[f
] == res
[f
-16]);
1632 static immutable ubyte[32] bobsk
= [
1633 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
1634 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
1635 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
1636 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
1639 static immutable ubyte[32] alicepk
= [
1640 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
1641 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
1642 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
1643 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
1646 static immutable ubyte[24] nonce
= [
1647 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1648 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1649 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1652 // API requires first 16 bytes to be 0
1653 static immutable ubyte[163] c
= [
1654 0, 0, 0, 0, 0, 0, 0, 0
1655 , 0, 0, 0, 0, 0, 0, 0, 0
1656 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
1657 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
1658 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
1659 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
1660 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
1661 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
1662 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
1663 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
1664 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
1665 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
1666 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
1667 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
1668 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
1669 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
1670 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
1671 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
1672 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
1673 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
1679 static immutable ubyte[] res
= [
1680 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
1681 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
1682 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
1683 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
1684 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
1685 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
1686 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
1687 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
1688 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
1689 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
1690 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
1691 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
1692 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
1693 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
1694 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
1695 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
1699 assert(/*crypto_box_curve25519xsalsa20poly1305_open*/crypto_box_open(m
,c
,nonce
,alicepk
,bobsk
));
1700 for (auto f
= 32; f
< 163; ++f
) assert(m
[f
] == res
[f
-32]);
1706 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1707 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1708 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1709 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1710 ubyte[crypto_box_NONCEBYTES
] n
;
1711 ubyte[10000] m
, c
, m2
;
1712 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1713 crypto_box_keypair(alicepk
,alicesk
);
1714 crypto_box_keypair(bobpk
,bobsk
);
1715 randombytes(n
,crypto_box_NONCEBYTES
);
1716 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1717 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1718 assert(crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
));
1719 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1722 version(unittest_full
) box7(); // it's slow
1726 ubyte[crypto_box_SECRETKEYBYTES
] alicesk
;
1727 ubyte[crypto_box_PUBLICKEYBYTES
] alicepk
;
1728 ubyte[crypto_box_SECRETKEYBYTES
] bobsk
;
1729 ubyte[crypto_box_PUBLICKEYBYTES
] bobpk
;
1730 ubyte[crypto_box_NONCEBYTES
] n
;
1731 ubyte[10000] m
, c
, m2
;
1732 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_box_ZEROBYTES
< m
.length
; ++mlen
) {
1733 crypto_box_keypair(alicepk
,alicesk
);
1734 crypto_box_keypair(bobpk
,bobsk
);
1735 randombytes(n
,crypto_box_NONCEBYTES
);
1736 randombytes(m
[crypto_box_ZEROBYTES
..$],mlen
);
1737 crypto_box(c
[0..mlen
+crypto_box_ZEROBYTES
],m
,n
,bobpk
,alicesk
);
1739 while (caught
< 10) {
1740 c
[uniform(0, mlen
+crypto_box_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
1741 if (crypto_box_open(m2
[0..mlen
+crypto_box_ZEROBYTES
],c
,n
,alicepk
,bobsk
)) {
1742 for (auto i
= 0; i
< mlen
+crypto_box_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
1747 assert(caught
== 10);
1750 version(unittest_full
) box8(); // it's slow
1754 static immutable ubyte[32] shared_
= [
1755 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
1756 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
1757 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
1758 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
1761 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];
1763 static immutable ubyte[16] c
= [
1764 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1765 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1770 static immutable ubyte[32] res
= [
1771 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1772 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1773 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1774 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1777 crypto_core_hsalsa20(firstkey
,zero
,shared_
,c
);
1778 assert(firstkey
== res
);
1784 static immutable ubyte[32]firstkey
= [
1785 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
1786 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
1787 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
1788 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
1791 static immutable ubyte[16]nonceprefix
= [
1792 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
1793 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
1796 static immutable ubyte[16] c
= [
1797 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1798 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1801 ubyte[32] secondkey
;
1803 static immutable ubyte[32] res
= [
1804 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1805 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1806 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1807 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1810 crypto_core_hsalsa20(secondkey
,nonceprefix
,firstkey
,c
);
1811 assert(secondkey
== res
);
1817 static immutable ubyte[32] secondkey
= [
1818 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
1819 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
1820 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
1821 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
1824 static immutable ubyte[8] noncesuffix
= [
1825 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
1828 static immutable ubyte[16] c
= [
1829 0x65,0x78,0x70,0x61,0x6e,0x64,0x20,0x33
1830 ,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b
1833 static ubyte[16] input
= [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ;
1835 static ubyte[64*256*256] output
;
1839 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];
1842 for (auto i
= 0; i
< 8; ++i
) input
[i
] = noncesuffix
[i
];
1845 crypto_core_salsa20(output
[pos
..$],input
,secondkey
,c
);
1847 } while (++input
[8]);
1848 } while (++input
[9]);
1849 crypto_hash(h
,output
);
1852 version(unittest_full
) core3(); // it's slow
1856 static immutable ubyte[32] k
= [
1857 1, 2, 3, 4, 5, 6, 7, 8
1858 , 9, 10, 11, 12, 13, 14, 15, 16
1859 ,201,202,203,204,205,206,207,208
1860 ,209,210,211,212,213,214,215,216
1863 static immutable ubyte[16] input
= [
1864 101,102,103,104,105,106,107,108
1865 ,109,110,111,112,113,114,115,116
1868 static immutable ubyte[16] c
= [
1869 101,120,112, 97,110,100, 32, 51
1870 , 50, 45, 98,121,116,101, 32,107
1875 static immutable ubyte[64] res
= [
1876 69, 37, 68, 39, 41, 15,107,193
1877 ,255,139,122, 6,170,233,217, 98
1878 , 89,144,182,106, 21, 51,200, 65
1879 ,239, 49,222, 34,215,114, 40,126
1880 ,104,197, 7,225,197,153, 31, 2
1881 ,102, 78, 76,176, 84,245,246,184
1882 ,177,160,133,130, 6, 72,149,119
1883 ,192,195,132,236,234,103,246, 74
1886 crypto_core_salsa20(output
,input
,k
,c
);
1887 assert(output
== res
);
1893 static immutable ubyte[32] k
= [
1894 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1895 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1896 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1897 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1900 static immutable ubyte[16] input
= [
1901 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1902 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1905 static immutable ubyte[16] c
= [
1906 101,120,112, 97,110,100, 32, 51
1907 , 50, 45, 98,121,116,101, 32,107
1912 static immutable ubyte[32] res
= [
1913 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1914 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1915 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1916 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1919 crypto_core_hsalsa20(output
,input
,k
,c
);
1920 assert(output
== res
);
1926 static immutable ubyte[32] k
= [
1927 0xee,0x30,0x4f,0xca,0x27,0x00,0x8d,0x8c
1928 ,0x12,0x6f,0x90,0x02,0x79,0x01,0xd8,0x0f
1929 ,0x7f,0x1d,0x8b,0x8d,0xc9,0x36,0xcf,0x3b
1930 ,0x9f,0x81,0x96,0x92,0x82,0x7e,0x57,0x77
1933 static immutable ubyte[16] input
= [
1934 0x81,0x91,0x8e,0xf2,0xa5,0xe0,0xda,0x9b
1935 ,0x3e,0x90,0x60,0x52,0x1e,0x4b,0xb3,0x52
1938 static immutable ubyte[16] c
= [
1939 101,120,112, 97,110,100, 32, 51
1940 , 50, 45, 98,121,116,101, 32,107
1945 static immutable ubyte[32] res
= [
1946 0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40
1947 ,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45
1948 ,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94
1949 ,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd
1955 void print(const(ubyte)[] x
, const(ubyte)[] y
)
1958 for (auto i
= 0; i
< 4; ++i
) {
1961 //printf(",0x%02x",255&(xi-yi-borrow));
1962 pp
[pppos
++] = cast(ubyte)(255&(xi
-yi
-borrow
));
1963 borrow
= (xi
< yi
+borrow
);
1967 crypto_core_salsa20(output
,input
,k
,c
);
1969 print(output
[20..$],c
[4..$]);
1970 print(output
[40..$],c
[8..$]);
1971 print(output
[60..$],c
[12..$]);
1972 print(output
[24..$],input
);
1973 print(output
[28..$],input
[4..$]);
1974 print(output
[32..$],input
[8..$]);
1975 print(output
[36..$],input
[12..$]);
1982 static immutable ubyte[8] x
= ['t','e','s','t','i','n','g','\n'];
1983 static ubyte[crypto_hash_BYTES
] h
;
1984 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];
1986 //for (auto f = 0; f < crypto_hash_BYTES; ++f) assert(h[f] == res[f]);
1991 void onetimeauth () {
1992 writeln("onetimeauth");
1993 static immutable ubyte[32] rs
= [
1994 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
1995 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
1996 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
1997 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2000 static immutable ubyte[131] c
= [
2001 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2002 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2003 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2004 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2005 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2006 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2007 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2008 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2009 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2010 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2011 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2012 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2013 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2014 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2015 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2016 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2022 static immutable ubyte[16] res
= [0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9];
2024 /*crypto_onetimeauth_poly1305*/crypto_onetimeauth(a
,c
,rs
);
2029 void onetimeauth2 () {
2030 writeln("onetimeauth2");
2031 static immutable ubyte[32] rs
= [
2032 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2033 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2034 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2035 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2038 static immutable ubyte[131] c
= [
2039 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2040 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2041 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2042 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2043 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2044 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2045 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2046 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2047 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2048 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2049 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2050 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2051 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2052 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2053 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2054 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2058 static immutable ubyte[16] a
= [
2059 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2060 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2063 assert(/*crypto_onetimeauth_poly1305_verify*/crypto_onetimeauth_verify(a
,c
,rs
));
2067 void onetimeauth7 () {
2068 writeln("onetimeauth7");
2069 static ubyte[32] key
;
2070 static ubyte[10000] c
;
2073 for (auto clen
= 0; clen
< 10000; ++clen
) {
2074 //if (clen%512 == 0) { writef("\r%s", clen); stdout.flush(); }
2075 randombytes(key
, key
.length
);
2076 randombytes(c
, clen
);
2077 crypto_onetimeauth(a
,c
[0..clen
],key
);
2078 assert(crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2080 c
[uniform(0, clen
)] += 1+(uniform(0, 255));
2081 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2082 a
[uniform(0, a
.length
)] += 1+(uniform(0, 255));
2083 assert(!crypto_onetimeauth_verify(a
,c
[0..clen
],key
));
2087 version(unittest_full
) onetimeauth7(); // it's slow
2089 void scalarmult () {
2090 writeln("scalarmult");
2091 static immutable ubyte[32] alicesk
= [
2092 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2093 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2094 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2095 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2100 static immutable ubyte[32] res
= [
2101 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2102 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2103 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2104 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2107 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(alicepk
,alicesk
);
2108 assert(alicepk
== res
);
2112 void scalarmult2 () {
2113 writeln("scalarmult2");
2114 static immutable ubyte[32] bobsk
= [
2115 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2116 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2117 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2118 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2123 static immutable ubyte[32] res
= [
2124 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2125 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2126 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2127 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2130 /*crypto_scalarmult_curve25519_base*/crypto_scalarmult_base(bobpk
,bobsk
);
2131 assert(bobpk
== res
);
2135 void scalarmult5 () {
2136 writeln("scalarmult5");
2137 static immutable ubyte[32] alicesk
= [
2138 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
2139 ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
2140 ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
2141 ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
2144 static immutable ubyte[32] bobpk
= [
2145 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
2146 ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
2147 ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
2148 ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
2153 static immutable ubyte[32] res
= [
2154 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2155 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2156 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2157 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2160 crypto_scalarmult(k
,alicesk
,bobpk
);
2165 void scalarmult6 () {
2166 writeln("scalarmult6");
2167 static immutable ubyte[32] bobsk
= [
2168 0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
2169 ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
2170 ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
2171 ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
2174 static immutable ubyte[32] alicepk
= [
2175 0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2176 ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2177 ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2178 ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
2183 static immutable ubyte[32] res
= [
2184 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1
2185 ,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25
2186 ,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33
2187 ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42
2190 crypto_scalarmult(k
,bobsk
,alicepk
);
2196 writeln("secretbox");
2197 static immutable ubyte[32] firstkey
= [
2198 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2199 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2200 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2201 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2204 static immutable ubyte[24] nonce
= [
2205 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2206 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2207 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2210 // API requires first 32 bytes to be 0
2211 static immutable ubyte[163] m
= [
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 , 0, 0, 0, 0, 0, 0, 0, 0
2216 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2217 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2218 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2219 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2220 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2221 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2222 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2223 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2224 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2225 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2226 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2227 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2228 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2229 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2230 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2231 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2235 static immutable ubyte[] res
= [
2236 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2237 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2238 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2239 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2240 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2241 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2242 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2243 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2244 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2245 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2246 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2247 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2248 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2249 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2250 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2251 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2252 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2253 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2258 crypto_secretbox(c
,m
,nonce
,firstkey
);
2259 for (auto i
= 16; i
< 163; ++i
) assert(c
[i
] == res
[i
-16]);
2263 void secretbox2 () {
2264 writeln("secretbox2");
2265 static immutable ubyte[32] firstkey
= [
2266 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2267 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2268 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2269 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2272 static immutable ubyte[24] nonce
= [
2273 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2274 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2275 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2278 // API requires first 16 bytes to be 0
2279 static immutable ubyte[163] c
= [
2280 0, 0, 0, 0, 0, 0, 0, 0
2281 , 0, 0, 0, 0, 0, 0, 0, 0
2282 ,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
2283 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
2284 ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2285 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2286 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2287 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2288 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2289 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2290 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2291 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2292 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2293 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2294 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2295 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2296 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2297 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2298 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2299 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2303 static immutable ubyte[] res
= [
2304 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2305 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2306 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2307 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2308 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2309 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2310 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2311 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2312 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2313 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2314 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2315 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2316 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2317 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2318 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2319 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2325 assert(crypto_secretbox_open(m
,c
,nonce
,firstkey
));
2326 for (auto i
= 32; i
< 163; ++i
) assert(m
[i
] == res
[i
-32]);
2330 void secretbox7 () {
2331 writeln("secretbox7");
2332 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2333 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2334 static ubyte[10000] m
, c
, m2
;
2335 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2336 randombytes(k
,crypto_secretbox_KEYBYTES
);
2337 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2338 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2339 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2340 assert(crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
));
2341 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2346 void secretbox8 () {
2347 writeln("secretbox8");
2348 static ubyte[crypto_secretbox_KEYBYTES
] k
;
2349 static ubyte[crypto_secretbox_NONCEBYTES
] n
;
2350 static ubyte[10000] m
, c
, m2
;
2351 for (auto mlen
= 0; mlen
< 1000 && mlen
+crypto_secretbox_ZEROBYTES
< m
.length
; ++mlen
) {
2352 randombytes(k
,crypto_secretbox_KEYBYTES
);
2353 randombytes(n
,crypto_secretbox_NONCEBYTES
);
2354 randombytes(m
[crypto_secretbox_ZEROBYTES
..$],mlen
);
2355 crypto_secretbox(c
[0..mlen
+crypto_secretbox_ZEROBYTES
],m
,n
,k
);
2357 while (caught
< 10) {
2358 c
[uniform(0, mlen
+crypto_secretbox_ZEROBYTES
)] = cast(ubyte)uniform(0, 256);
2359 if (crypto_secretbox_open(m2
[0..mlen
+crypto_secretbox_ZEROBYTES
],c
,n
,k
)) {
2360 for (auto i
= 0; i
< mlen
+crypto_secretbox_ZEROBYTES
; ++i
) assert(m2
[i
] == m
[i
]);
2364 assert(caught
== 10);
2367 version(unittest_full
) secretbox8(); // it's slow
2371 static immutable ubyte[32] firstkey
= [
2372 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2373 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2374 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2375 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2378 static immutable ubyte[24] nonce
= [
2379 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2380 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2381 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2384 static ubyte[4194304] output
;
2387 //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];
2389 crypto_stream(output
,nonce
,firstkey
);
2390 //crypto_hash_sha256(h,output,sizeof output);
2391 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2397 static immutable ubyte[32] secondkey
= [
2398 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9
2399 ,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88
2400 ,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9
2401 ,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4
2404 static immutable ubyte[8] noncesuffix
= [
2405 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2408 static ubyte[4194304] output
;
2410 crypto_stream_salsa20(output
,noncesuffix
,secondkey
);
2411 assert(hashToString(SHA256(output
[0..$])) == "662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2");
2417 static immutable ubyte[32] firstkey
= [
2418 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2419 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2420 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2421 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2424 static immutable ubyte[24] nonce
= [
2425 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2426 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2427 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2432 static immutable ubyte[32] res
= [
2433 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
2434 ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
2435 ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
2436 ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80
2439 crypto_stream
/*_xsalsa20*/(rs
,nonce
,firstkey
);
2446 static immutable ubyte[32] firstkey
= [
2447 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4
2448 ,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7
2449 ,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2
2450 ,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89
2453 static immutable ubyte[24] nonce
= [
2454 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
2455 ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
2456 ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
2459 static immutable ubyte[163] m
= [
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 , 0, 0, 0, 0, 0, 0, 0, 0
2464 ,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
2465 ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
2466 ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
2467 ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
2468 ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
2469 ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
2470 ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
2471 ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
2472 ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
2473 ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
2474 ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
2475 ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
2476 ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
2477 ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
2478 ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
2479 ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
2485 static immutable ubyte[] res
= [
2486 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
2487 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
2488 ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
2489 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
2490 ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
2491 ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
2492 ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
2493 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
2494 ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
2495 ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
2496 ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
2497 ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
2498 ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
2499 ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
2500 ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
2501 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
2505 /*crypto_stream_xsalsa20_xor*/crypto_stream_xor(c
,m
,nonce
,firstkey
);
2506 for (auto i
= 32; i
< 163; ++i
) assert(c
[i
] == res
[i
-32]);
2512 version(tweetnacl_unittest
)
2513 version(unittest_main
)