authorgravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2018-08-10 19:01:37-07:00
committergravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2018-08-27 19:44:11-07:00
log444edd9aed84ebfd9153817259e2a4e1228b7120
treea8d83cd54dbe8ca4bfdfe20ed310bffa784b36b7
parent526338b00fbe1cac19f64832176af3bdf2108a56

std.crypto: add chaCha20

v3

3 files changed, 437 insertions(+), 0 deletions(-)

CMakeLists.txt+1
...@@ -451,6 +451,7 @@ set(ZIG_STD_FILES...@@ -451,6 +451,7 @@ set(ZIG_STD_FILES
451 "crypto/sha1.zig"451 "crypto/sha1.zig"
452 "crypto/sha2.zig"452 "crypto/sha2.zig"
453 "crypto/sha3.zig"453 "crypto/sha3.zig"
454 "crypto/chacha20.zig"
454 "cstr.zig"455 "cstr.zig"
455 "debug/failing_allocator.zig"456 "debug/failing_allocator.zig"
456 "debug/index.zig"457 "debug/index.zig"
std/crypto/chacha20.zig created+431
...@@ -0,0 +1,431 @@
1// Based on public domain Supercop by Daniel J. Bernstein
2
3const std = @import("../index.zig");
4const mem = std.mem;
5const endian = std.endian;
6const assert = std.debug.assert;
7const builtin = @import("builtin");
8
9const QuarterRound = struct {
10 a: usize,
11 b: usize,
12 c: usize,
13 d: usize,
14};
15
16fn Rp(a: usize, b: usize, c: usize, d: usize) QuarterRound {
17 return QuarterRound{
18 .a = a,
19 .b = b,
20 .c = c,
21 .d = d,
22 };
23}
24
25fn rotate(a: u32, b: u5) u32 {
26 return ((a << b) |
27 (a >> @intCast(u5, (32 - @intCast(u6, b))))
28 );
29}
30
31// The chacha family of ciphers are based on the salsa family.
32fn salsa20_wordtobyte(input: [16]u32) [64]u8 {
33 var x: [16]u32 = undefined;
34 var out: [64]u8 = undefined;
35
36 for (x) |_, i|
37 x[i] = input[i];
38 const rounds = comptime []QuarterRound{
39 Rp( 0, 4, 8,12),
40 Rp( 1, 5, 9,13),
41 Rp( 2, 6,10,14),
42 Rp( 3, 7,11,15),
43 Rp( 0, 5,10,15),
44 Rp( 1, 6,11,12),
45 Rp( 2, 7, 8,13),
46 Rp( 3, 4, 9,14),
47 };
48 comptime var j: usize = 20;
49 inline while (j > 0) : (j -=2) {
50 for (rounds) |r| {
51 x[r.a] +%= x[r.b]; x[r.d] = rotate(x[r.d] ^ x[r.a], 16);
52 x[r.c] +%= x[r.d]; x[r.b] = rotate(x[r.b] ^ x[r.c], 12);
53 x[r.a] +%= x[r.b]; x[r.d] = rotate(x[r.d] ^ x[r.a], 8);
54 x[r.c] +%= x[r.d]; x[r.b] = rotate(x[r.b] ^ x[r.c], 7);
55 }
56 }
57 for (x) |_, i|
58 x[i] +%= input[i];
59 for (x) |_, i|
60 mem.writeInt(out[4 * i .. 4 * i + 4], x[i], builtin.Endian.Little);
61 return out;
62}
63
64fn chaCha20_internal(out: []u8, in: []const u8, key: [8]u32, counter: [4]u32) void {
65 var ctx: [16]u32 = undefined;
66 var remaining: usize = if (in.len > out.len) in.len else out.len;
67 var cursor: usize = 0;
68
69 const c = "expand 32-byte k";
70 const constant_le = []u32{
71 mem.readIntLE(u32, c[0..4]),
72 mem.readIntLE(u32, c[4..8]),
73 mem.readIntLE(u32, c[8..12]),
74 mem.readIntLE(u32, c[12..16]),
75 };
76
77 mem.copy(u32, ctx[0..], constant_le[0..4]);
78 mem.copy(u32, ctx[4..12], key[0..8]);
79 mem.copy(u32, ctx[12..16], counter[0..4]);
80
81 while (true) {
82 var buf = salsa20_wordtobyte(ctx);
83
84 if (remaining < 64) {
85 var i: usize = 0;
86 while (i < remaining) : (i += 1)
87 out[cursor + i] = in[cursor + i] ^ buf[i];
88 return;
89 }
90
91 comptime var i: usize = 0;
92 inline while (i < 64) : (i += 1)
93 out[cursor + i] = in[cursor + i] ^ buf[i];
94
95 cursor += 64;
96 remaining -= 64;
97
98 ctx[12] += 1;
99 }
100}
101
102/// ChaCha20 avoids the possibility of timing attacks, as there are no branches
103/// on secret key data.
104///
105/// in and out should be the same length.
106/// counter should generally be 0 or 1
107///
108/// ChaCha20 is self-reversing. To decrypt just run the cipher with the same
109/// counter, nonce, and key.
110pub fn chaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [12]u8) void {
111 assert(in.len >= out.len);
112 assert((in.len >> 6) + counter <= @maxValue(u32));
113
114 var k: [8]u32 = undefined;
115 var c: [4]u32 = undefined;
116
117 k[0] = mem.readIntLE(u32, key[0..4]);
118 k[1] = mem.readIntLE(u32, key[4..8]);
119 k[2] = mem.readIntLE(u32, key[8..12]);
120 k[3] = mem.readIntLE(u32, key[12..16]);
121 k[4] = mem.readIntLE(u32, key[16..20]);
122 k[5] = mem.readIntLE(u32, key[20..24]);
123 k[6] = mem.readIntLE(u32, key[24..28]);
124 k[7] = mem.readIntLE(u32, key[28..32]);
125
126 c[0] = counter;
127 c[1] = mem.readIntLE(u32, nonce[0..4]);
128 c[2] = mem.readIntLE(u32, nonce[4..8]);
129 c[3] = mem.readIntLE(u32, nonce[8..12]);
130 chaCha20_internal(out, in, k, c);
131}
132
133/// This is the original ChaCha20 before RFC 7539, which recommends using the
134/// orgininal version on applications such as disk or file encryption that might
135/// exceed the 256 GiB limit of the 96-bit nonce version.
136pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32]u8, nonce: [8]u8) void {
137 assert(in.len >= out.len);
138 assert(counter +% (in.len >> 6) >= counter);
139
140 var cursor: u64 = 0;
141 var k: [8]u32 = undefined;
142 var c: [4]u32 = undefined;
143
144 k[0] = mem.readIntLE(u32, key[0..4]);
145 k[1] = mem.readIntLE(u32, key[4..8]);
146 k[2] = mem.readIntLE(u32, key[8..12]);
147 k[3] = mem.readIntLE(u32, key[12..16]);
148 k[4] = mem.readIntLE(u32, key[16..20]);
149 k[5] = mem.readIntLE(u32, key[20..24]);
150 k[6] = mem.readIntLE(u32, key[24..28]);
151 k[7] = mem.readIntLE(u32, key[28..32]);
152
153 c[0] = @truncate(u32, counter);
154 c[1] = @truncate(u32, counter >> 32);
155 c[2] = mem.readIntLE(u32, nonce[0..4]);
156 c[3] = mem.readIntLE(u32, nonce[4..8]);
157
158 const block_size = (1 << 6);
159 const big_block = (block_size << 32);
160
161 // first partial big block
162 if (((@intCast(u64, @maxValue(u32) - @truncate(u32, counter)) + 1) << 6) < in.len) {
163 chaCha20_internal(out[cursor..big_block], in[cursor..big_block], k, c);
164 cursor = big_block - cursor;
165 c[1] += 1;
166 if (comptime @sizeOf(usize) > 4) {
167 // A big block is giant: 256 GiB, but we can avoid this limitation
168 var remaining_blocks: u32 = @intCast(u32, (in.len / big_block));
169 var i: u32 = 0;
170 while (remaining_blocks > 0) : (remaining_blocks -= 1) {
171 chaCha20_internal(out[cursor..cursor + big_block], in[cursor..cursor + big_block], k, c);
172 c[1] += 1; // upper 32-bit of counter, generic chaCha20_internal() doesn't
173 // know about this.
174 cursor += big_block;
175 }
176 }
177 }
178
179 chaCha20_internal(out[cursor..], in[cursor..], k, c);
180}
181
182// https://tools.ietf.org/html/rfc7539#section-2.4.2
183test "crypto.chacha20 test vector sunscreen" {
184 const expected_result = []u8{
185 0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80,
186 0x41, 0xba, 0x07, 0x28, 0xdd, 0x0d, 0x69, 0x81,
187 0xe9, 0x7e, 0x7a, 0xec, 0x1d, 0x43, 0x60, 0xc2,
188 0x0a, 0x27, 0xaf, 0xcc, 0xfd, 0x9f, 0xae, 0x0b,
189 0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab,
190 0x8f, 0x59, 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57,
191 0x16, 0x39, 0xd6, 0x24, 0xe6, 0x51, 0x52, 0xab,
192 0x8f, 0x53, 0x0c, 0x35, 0x9f, 0x08, 0x61, 0xd8,
193 0x07, 0xca, 0x0d, 0xbf, 0x50, 0x0d, 0x6a, 0x61,
194 0x56, 0xa3, 0x8e, 0x08, 0x8a, 0x22, 0xb6, 0x5e,
195 0x52, 0xbc, 0x51, 0x4d, 0x16, 0xcc, 0xf8, 0x06,
196 0x81, 0x8c, 0xe9, 0x1a, 0xb7, 0x79, 0x37, 0x36,
197 0x5a, 0xf9, 0x0b, 0xbf, 0x74, 0xa3, 0x5b, 0xe6,
198 0xb4, 0x0b, 0x8e, 0xed, 0xf2, 0x78, 0x5e, 0x42,
199 0x87, 0x4d,
200 };
201 const input = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
202 var result: [114]u8 = undefined;
203 const key = []u8{
204 0, 1, 2, 3, 4, 5, 6, 7,
205 8, 9,10,11,12,13,14,15,
206 16,17,18,19,20,21,22,23,
207 24,25,26,27,28,29,30,31,
208 };
209 const nonce = []u8{
210 0, 0, 0, 0,
211 0, 0, 0, 0x4a,
212 0, 0, 0, 0,
213 };
214
215 chaCha20IETF(result[0..], input[0..], 1, key, nonce);
216 assert(mem.eql(u8, expected_result, result));
217
218 // Chacha20 is self-reversing.
219 var plaintext: [114]u8 = undefined;
220 chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);
221 assert(mem.compare(u8, input, plaintext) == mem.Compare.Equal);
222}
223
224// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
225test "crypto.chacha20 test vector 1" {
226 const expected_result = []u8{
227 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
228 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
229 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
230 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
231 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
232 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
233 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
234 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
235 };
236 const input = []u8{
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 };
246 var result: [64]u8 = undefined;
247 const key = []u8{
248 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0,
251 0, 0, 0, 0, 0, 0, 0, 0,
252 };
253 const nonce = []u8{0, 0, 0, 0, 0, 0, 0, 0};
254
255 chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
256 assert(mem.eql(u8, expected_result, result));
257}
258
259test "crypto.chacha20 test vector 2" {
260 const expected_result = []u8{
261 0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96,
262 0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96,
263 0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 0xd2, 0x60,
264 0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41,
265 0xbb, 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2,
266 0xa5, 0xd1, 0xe7, 0xe2, 0x0d, 0x42, 0xaf, 0x2c,
267 0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 0x81,
268 0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63,
269 };
270 const input = []u8{
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 };
280 var result: [64]u8 = undefined;
281 const key = []u8{
282 0, 0, 0, 0, 0, 0, 0, 0,
283 0, 0, 0, 0, 0, 0, 0, 0,
284 0, 0, 0, 0, 0, 0, 0, 0,
285 0, 0, 0, 0, 0, 0, 0, 1,
286 };
287 const nonce = []u8{0, 0, 0, 0, 0, 0, 0, 0};
288
289 chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
290 assert(mem.eql(u8, expected_result, result));
291}
292
293test "crypto.chacha20 test vector 3" {
294 const expected_result = []u8{
295 0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5,
296 0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a,
297 0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13,
298 0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31,
299 0xe8, 0x5a, 0x05, 0x02, 0x78, 0xa7, 0x08, 0x45,
300 0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b,
301 0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e,
302 0x44, 0x5f, 0x41, 0xe3,
303 };
304 const input = []u8{
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00,
313 };
314 var result: [60]u8 = undefined;
315 const key = []u8{
316 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0,
320 };
321 const nonce = []u8{0, 0, 0, 0, 0, 0, 0, 1};
322
323 chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
324 assert(mem.eql(u8, expected_result, result));
325}
326
327test "crypto.chacha20 test vector 4" {
328 const expected_result = []u8{
329 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb,
330 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80,
331 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 0x42, 0xac,
332 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32,
333 0x11, 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c,
334 0xa8, 0xad, 0x64, 0x26, 0x19, 0x4a, 0x88, 0x54,
335 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 0x7d,
336 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b,
337 };
338 const input = []u8{
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 };
348 var result: [64]u8 = undefined;
349 const key = []u8{
350 0, 0, 0, 0, 0, 0, 0, 0,
351 0, 0, 0, 0, 0, 0, 0, 0,
352 0, 0, 0, 0, 0, 0, 0, 0,
353 0, 0, 0, 0, 0, 0, 0, 0,
354 };
355 const nonce = []u8{1, 0, 0, 0, 0, 0, 0, 0};
356
357 chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
358 assert(mem.eql(u8, expected_result, result));
359}
360
361test "crypto.chacha20 test vector 5" {
362 const expected_result = []u8{
363 0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69,
364 0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75,
365 0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93,
366 0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1,
367 0x34, 0xa4, 0x54, 0x7b, 0x73, 0x3b, 0x46, 0x41,
368 0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69,
369 0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1,
370 0x59, 0x16, 0x15, 0x5c, 0x2b, 0xe8, 0x24, 0x1a,
371
372 0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94,
373 0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66,
374 0x89, 0xde, 0x95, 0x26, 0x49, 0x86, 0xd9, 0x58,
375 0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd,
376 0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56,
377 0x3e, 0xb9, 0xb3, 0xa4, 0xa4, 0x72, 0xf8, 0x2e,
378 0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e,
379 0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7,
380
381 0x9d, 0xb9, 0xd4, 0xf7, 0xc7, 0xa8, 0x99, 0x15,
382 0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3,
383 0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a,
384 0x97, 0xa5, 0xf5, 0x76, 0xfe, 0x06, 0x40, 0x25,
385 0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5,
386 0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69,
387 0x59, 0x66, 0x09, 0x96, 0x54, 0x6c, 0xc9, 0xc4,
388 0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7,
389
390 0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79,
391 0xe5, 0xc5, 0x36, 0x0c, 0x33, 0x17, 0x16, 0x6a,
392 0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a,
393 0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2,
394 0xcc, 0xb2, 0x7d, 0x5a, 0xaa, 0xe0, 0xad, 0x7a,
395 0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09,
396 0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a,
397 0x6d, 0xeb, 0x3a, 0xb7, 0x8f, 0xab, 0x78, 0xc9,
398 };
399 const input = []u8{
400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
401 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
402 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
403 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
405 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
406 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
407 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
408
409 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
410 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
411 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
415 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
416 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
417 };
418 var result: [256]u8 = undefined;
419 const key = []u8{
420 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
421 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
422 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
423 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
424 };
425 const nonce = []u8{
426 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
427 };
428
429 chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
430 assert(mem.eql(u8, expected_result, result));
431}
std/crypto/index.zig+5
...@@ -24,6 +24,10 @@ pub const HmacMd5 = hmac.HmacMd5;...@@ -24,6 +24,10 @@ pub const HmacMd5 = hmac.HmacMd5;
24pub const HmacSha1 = hmac.Sha1;24pub const HmacSha1 = hmac.Sha1;
25pub const HmacSha256 = hmac.Sha256;25pub const HmacSha256 = hmac.Sha256;
2626
27const import_chaCha20 = @import("chacha20.zig");
28pub const chaCha20IETF = import_chaCha20.chaCha20IETF;
29pub const chaCha20With64BitNonce = import_chaCha20.chaCha20With64BitNonce;
30
27test "crypto" {31test "crypto" {
28 _ = @import("md5.zig");32 _ = @import("md5.zig");
29 _ = @import("sha1.zig");33 _ = @import("sha1.zig");
...@@ -31,4 +35,5 @@ test "crypto" {...@@ -31,4 +35,5 @@ test "crypto" {
31 _ = @import("sha3.zig");35 _ = @import("sha3.zig");
32 _ = @import("blake2.zig");36 _ = @import("blake2.zig");
33 _ = @import("hmac.zig");37 _ = @import("hmac.zig");
38 _ = @import("chacha20.zig");
34}39}