authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-28 16:07:58-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-08-28 16:07:58-04:00
log9de0f900e1a80554ac72c8675fc2896977f4930b
treed6c87f8784c7a688defd200a1ea745896c62c6ce
parentb65cca37ceb2b4181a4e713c270c546682acea23
parent87eb95f816b01c0133de47eb3c94ac470f9d8bf2
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #1369 from shawnl/crypto

std/crypto: add chacha20

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

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