1#![no_std]
47
48mod utils;
49use core::fmt;
50use crate::utils::{u8_to_u32, xor_from_slice};
51
52fn quarterround(y0: u32, y1: u32, y2: u32, y3: u32) -> [u32; 4] {
53 let y1 = y1 ^ y0.wrapping_add(y3).rotate_left(7);
54 let y2 = y2 ^ y1.wrapping_add(y0).rotate_left(9);
55 let y3 = y3 ^ y2.wrapping_add(y1).rotate_left(13);
56 let y0 = y0 ^ y3.wrapping_add(y2).rotate_left(18);
57
58 [y0, y1, y2, y3]
59}
60
61fn columnround(y: [u32; 16]) -> [u32; 16] {
62 let [
63 [z0, z4, z8, z12],
64 [z5, z9, z13, z1],
65 [z10, z14, z2, z6],
66 [z15, z3, z7, z11]
67 ] = [
68 quarterround(y[0], y[4], y[8], y[12]),
69 quarterround(y[5], y[9], y[13], y[1]),
70 quarterround(y[10], y[14], y[2], y[6]),
71 quarterround(y[15], y[3], y[7], y[11]),
72 ];
73
74 [z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, z15]
75}
76
77fn rowround(y: [u32; 16]) -> [u32; 16] {
78 let [
79 [z0, z1, z2, z3],
80 [z5, z6, z7, z4],
81 [z10, z11, z8, z9],
82 [z15, z12, z13, z14]
83 ] = [
84 quarterround(y[0], y[1], y[2], y[3]),
85 quarterround(y[5], y[6], y[7], y[4]),
86 quarterround(y[10], y[11], y[8], y[9]),
87 quarterround(y[15], y[12], y[13], y[14])
88 ];
89
90 [z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, z15]
91}
92
93fn doubleround(y: [u32; 16]) -> [u32; 16] {
94 rowround(columnround(y))
95}
96
97#[derive(Clone, Copy)]
98struct Overflow {
99 buffer: [u8; 64],
100 offset: usize
101}
102
103impl Overflow {
104 fn new(buffer: [u8; 64], offset: usize) -> Overflow {
105 Overflow { buffer, offset }
106 }
107
108 fn modify<F>(&mut self, buffer: &mut [u8], modifier: F)
109 where F: Fn(&mut [u8], &[u8])
110 {
111 let offset = self.offset;
112 self.offset += buffer.len();
113 modifier(buffer, &self.buffer[offset..self.offset]);
114 }
115}
116
117impl fmt::Debug for Overflow {
118 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
119 formatter
120 .debug_struct("Overflow")
121 .field("buffer", &&self.buffer[..])
122 .field("offset", &self.offset)
123 .finish()
124 }
125}
126
127#[derive(Clone, Copy, Debug)]
129pub enum Key {
130 Key16([u8; 16]),
131 Key32([u8; 32])
132}
133
134#[derive(Clone, Copy, Debug)]
135struct Generator {
136 init_matrix: [u32; 16],
137 cround_matrix: [u32; 16],
138 dround_values: [u32; 4],
139 counter: u64
140}
141
142impl Generator {
143 fn new(key: Key, nonce: [u8; 8], counter: u64) -> Generator {
144 let mut init_matrix = [0; 16];
145 init_matrix[0] = 1634760805;
146 init_matrix[15] = 1797285236;
147 init_matrix[8] = counter as u32;
148 init_matrix[9] = (counter >> 32) as u32;
149 u8_to_u32(&nonce[..], &mut init_matrix[6..8]);
150
151 match key {
152 Key::Key16(key) => {
153 u8_to_u32(&key[..], &mut init_matrix[1..5]);
154 u8_to_u32(&key[..], &mut init_matrix[11..15]);
155 init_matrix[5] = 824206446;
156 init_matrix[10] = 2036477238;
157 }
158 Key::Key32(key) => {
159 u8_to_u32(&key[..16], &mut init_matrix[1..5]);
160 u8_to_u32(&key[16..], &mut init_matrix[11..15]);
161 init_matrix[5] = 857760878;
162 init_matrix[10] = 2036477234;
163 }
164 }
165
166 let cround_matrix = columnround(init_matrix);
167 let dround_values = quarterround(
168 cround_matrix[5],
169 cround_matrix[6],
170 cround_matrix[7],
171 cround_matrix[4]
172 );
173
174 Generator { init_matrix, cround_matrix, dround_values, counter }
175 }
176
177 fn first_doubleround(&self) -> [u32; 16] {
178 let [r5, r6, r7, r4] = self.dround_values;
179 let [
180 [r0, r1, r2, r3],
181 [r10, r11, r8, r9],
182 [r15, r12, r13, r14]
183 ] = [
184 quarterround(
185 self.cround_matrix[0],
186 self.cround_matrix[1],
187 self.cround_matrix[2],
188 self.cround_matrix[3]
189 ),
190 quarterround(
191 self.cround_matrix[10],
192 self.cround_matrix[11],
193 self.cround_matrix[8],
194 self.cround_matrix[9]
195 ),
196 quarterround(
197 self.cround_matrix[15],
198 self.cround_matrix[12],
199 self.cround_matrix[13],
200 self.cround_matrix[14]
201 )
202 ];
203
204 [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15]
205 }
206
207 fn set_counter(&mut self, counter: u64) {
208 self.counter = counter;
209 self.init_matrix[8] = counter as u32;
210 let [z0, z4, z8, z12] = quarterround(
211 self.init_matrix[0],
212 self.init_matrix[4],
213 self.init_matrix[8],
214 self.init_matrix[12]
215 );
216 self.cround_matrix[0] = z0;
217 self.cround_matrix[8] = z8;
218 self.cround_matrix[12] = z12;
219
220 if counter > 0xffffffff_u64 {
221 self.init_matrix[9] = (counter >> 32) as u32;
222 let [z5, z9, z13, z1] = quarterround(
223 self.init_matrix[5],
224 self.init_matrix[9],
225 self.init_matrix[13],
226 self.init_matrix[1]
227 );
228
229 self.cround_matrix[1] = z1;
230 self.cround_matrix[9] = z9;
231 self.cround_matrix[13] = z13;
232
233 self.dround_values = quarterround(
234 z5,
235 self.cround_matrix[6],
236 self.cround_matrix[7],
237 z4
238 );
239 }
240 }
241
242 fn next(&mut self) -> [u8; 64] {
243 let mut buffer = [0; 64];
244 (0..9)
245 .fold(self.first_doubleround(), |block, _| doubleround(block))
246 .iter()
247 .zip(self.init_matrix.iter())
248 .enumerate()
249 .for_each(|(index, (drounds_value, &init_value))| {
250 let offset = index * 4;
251 let sum = drounds_value.wrapping_add(init_value);
252 buffer[offset..offset + 4].copy_from_slice(&sum.to_le_bytes());
253 });
254
255 self.set_counter(self.counter.wrapping_add(1));
256 buffer
257 }
258}
259
260#[derive(Clone, Copy, Debug)]
262pub struct Salsa20 {
263 generator: Generator,
264 overflow: Overflow
265}
266
267impl Salsa20 {
268 pub fn new(key: Key, nonce: [u8; 8], counter: u64) -> Salsa20 {
274 let overflow = Overflow::new([0; 64], 64);
275 let generator = Generator::new(key, nonce, counter);
276 Salsa20 { generator, overflow }
277 }
278
279 fn modify<F>(&mut self, buffer: &mut [u8], modifier: &F)
280 where F: Fn(&mut [u8], &[u8])
281 {
282 let buffer_len = buffer.len();
283 let overflow_len = 64 - self.overflow.offset;
284
285 if overflow_len != 0 {
286 if buffer_len >= overflow_len {
287 self.overflow.modify(&mut buffer[..overflow_len], modifier);
288 } else {
289 self.overflow.modify(&mut buffer[..], modifier);
290 return;
291 }
292 }
293
294 let last_block_offset = buffer_len - (buffer_len - overflow_len) % 64;
295
296 for offset in (overflow_len..last_block_offset).step_by(64) {
297 modifier(&mut buffer[offset..offset + 64], &self.generator.next());
298 }
299
300 if last_block_offset != buffer_len {
301 self.overflow = Overflow::new(self.generator.next(), 0);
302 self.overflow.modify(&mut buffer[last_block_offset..], modifier);
303 }
304 }
305
306 pub fn set_counter(&mut self, counter: u64) {
308 if counter != self.generator.counter {
309 self.generator.set_counter(counter);
310 }
311 self.overflow = Overflow::new([0; 64], 64);
312 }
313
314 pub fn generate(&mut self, buffer: &mut [u8]) {
316 self.modify(buffer, &<[u8]>::copy_from_slice);
317 }
318
319 pub fn encrypt(&mut self, buffer: &mut [u8]) {
321 self.modify(buffer, &xor_from_slice);
322 }
323}
324
325#[cfg(test)]
326mod tests {
327 use super::*;
328
329 #[test]
330 fn quarterround_test() {
331 assert_eq!(
332 quarterround(0x00000000, 0x00000000, 0x00000000, 0x00000000),
333 [0x00000000, 0x00000000, 0x00000000, 0x00000000]
334 );
335 assert_eq!(
336 quarterround(0xe7e8c006, 0xc4f9417d, 0x6479b4b2, 0x68c67137),
337 [0xe876d72b, 0x9361dfd5, 0xf1460244, 0x948541a3]
338 );
339 }
340
341 #[test]
342 fn rowround_test() {
343 test([
344 0x00000001, 0x00000000, 0x00000000, 0x00000000,
345 0x00000001, 0x00000000, 0x00000000, 0x00000000,
346 0x00000001, 0x00000000, 0x00000000, 0x00000000,
347 0x00000001, 0x00000000, 0x00000000, 0x00000000
348 ], [
349 0x08008145, 0x00000080, 0x00010200, 0x20500000,
350 0x20100001, 0x00048044, 0x00000080, 0x00010000,
351 0x00000001, 0x00002000, 0x80040000, 0x00000000,
352 0x00000001, 0x00000200, 0x00402000, 0x88000100
353 ]);
354
355 test([
356 0x08521bd6, 0x1fe88837, 0xbb2aa576, 0x3aa26365,
357 0xc54c6a5b, 0x2fc74c2f, 0x6dd39cc3, 0xda0a64f6,
358 0x90a2f23d, 0x067f95a6, 0x06b35f61, 0x41e4732e,
359 0xe859c100, 0xea4d84b7, 0x0f619bff, 0xbc6e965a
360 ], [
361 0xa890d39d, 0x65d71596, 0xe9487daa, 0xc8ca6a86,
362 0x949d2192, 0x764b7754, 0xe408d9b9, 0x7a41b4d1,
363 0x3402e183, 0x3c3af432, 0x50669f96, 0xd89ef0a8,
364 0x0040ede5, 0xb545fbce, 0xd257ed4f, 0x1818882d
365 ]);
366
367 fn test(input_data: [u32; 16], expected_data: [u32; 16]) {
368 assert_eq!(rowround(input_data), expected_data);
369 }
370 }
371
372 #[test]
373 fn columnround_test() {
374 test([
375 0x00000001, 0x00000000, 0x00000000, 0x00000000,
376 0x00000001, 0x00000000, 0x00000000, 0x00000000,
377 0x00000001, 0x00000000, 0x00000000, 0x00000000,
378 0x00000001, 0x00000000, 0x00000000, 0x00000000
379 ], [
380 0x10090288, 0x00000000, 0x00000000, 0x00000000,
381 0x00000101, 0x00000000, 0x00000000, 0x00000000,
382 0x00020401, 0x00000000, 0x00000000, 0x00000000,
383 0x40a04001, 0x00000000, 0x00000000, 0x00000000
384 ]);
385
386 test([
387 0x08521bd6, 0x1fe88837, 0xbb2aa576, 0x3aa26365,
388 0xc54c6a5b, 0x2fc74c2f, 0x6dd39cc3, 0xda0a64f6,
389 0x90a2f23d, 0x067f95a6, 0x06b35f61, 0x41e4732e,
390 0xe859c100, 0xea4d84b7, 0x0f619bff, 0xbc6e965a
391 ], [
392 0x8c9d190a, 0xce8e4c90, 0x1ef8e9d3, 0x1326a71a,
393 0x90a20123, 0xead3c4f3, 0x63a091a0, 0xf0708d69,
394 0x789b010c, 0xd195a681, 0xeb7d5504, 0xa774135c,
395 0x481c2027, 0x53a8e4b5, 0x4c1f89c5, 0x3f78c9c8
396 ]);
397
398 fn test(input_data: [u32; 16], expected_data: [u32; 16]) {
399 assert_eq!(columnround(input_data), expected_data);
400 }
401 }
402
403 #[test]
404 fn doubleround_test() {
405 test([
406 0x00000001, 0x00000000, 0x00000000, 0x00000000,
407 0x00000000, 0x00000000, 0x00000000, 0x00000000,
408 0x00000000, 0x00000000, 0x00000000, 0x00000000,
409 0x00000000, 0x00000000, 0x00000000, 0x00000000
410 ], [
411 0x8186a22d, 0x0040a284, 0x82479210, 0x06929051,
412 0x08000090, 0x02402200, 0x00004000, 0x00800000,
413 0x00010200, 0x20400000, 0x08008104, 0x00000000,
414 0x20500000, 0xa0000040, 0x0008180a, 0x612a8020
415 ]);
416
417 test([
418 0xde501066, 0x6f9eb8f7, 0xe4fbbd9b, 0x454e3f57,
419 0xb75540d3, 0x43e93a4c, 0x3a6f2aa0, 0x726d6b36,
420 0x9243f484, 0x9145d1e8, 0x4fa9d247, 0xdc8dee11,
421 0x054bf545, 0x254dd653, 0xd9421b6d, 0x67b276c1
422 ], [
423 0xccaaf672, 0x23d960f7, 0x9153e63a, 0xcd9a60d0,
424 0x50440492, 0xf07cad19, 0xae344aa0, 0xdf4cfdfc,
425 0xca531c29, 0x8e7943db, 0xac1680cd, 0xd503ca00,
426 0xa74b2ad6, 0xbc331c5c, 0x1dda24c7, 0xee928277
427 ]);
428
429 fn test(input_data: [u32; 16], expected_data: [u32; 16]) {
430 assert_eq!(doubleround(input_data), expected_data);
431 }
432 }
433
434 #[test]
435 fn create_init_matrix_test() {
436 test(Key::Key16([
437 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
438 ]), [
439 101, 120, 112, 97, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
440 15, 16, 110, 100, 32, 49, 101, 102, 103, 104, 105, 106, 107, 108,
441 109, 110, 111, 112, 113, 114, 115, 116, 54, 45, 98, 121, 1, 2, 3,
442 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 116, 101, 32, 107
443 ]);
444
445 test(Key::Key32([
446 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 201, 202,
447 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216
448 ]), [
449 101, 120, 112, 97, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
450 15, 16, 110, 100, 32, 51, 101, 102, 103, 104, 105, 106, 107, 108,
451 109, 110, 111, 112, 113, 114, 115, 116, 50, 45, 98, 121, 201, 202,
452 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
453 216, 116, 101, 32, 107
454 ]);
455
456 fn test(key: Key, expected_data: [u8; 64]) {
457 let nonce = [101, 102, 103, 104, 105, 106, 107, 108];
458 let counter = u64::from_le_bytes(
459 [109, 110, 111, 112, 113, 114, 115, 116]
460 );
461 let generator = Generator::new(key, nonce, counter);
462
463 let mut expected_data_u32 = [0; 16];
464 u8_to_u32(&expected_data, &mut expected_data_u32);
465 assert_eq!(generator.init_matrix, expected_data_u32);
466 }
467 }
468
469 #[test]
470 fn first_doubleround_test() {
471 test(0x00000000, [0x00000000, 0x00000000]);
472 test(0x00000001, [0x00000001, 0x00000000]);
473 test(0x1234567f, [0x1234567f, 0x00000000]);
474 test(0xffffffff, [0xffffffff, 0x00000000]);
475 test(0x100000000, [0x00000000, 0x00000001]);
476 test(0x012345678abcdef, [0x78abcdef, 0x123456]);
477
478 fn test(counter: u64, counter_as_u32: [u32; 2]) {
479 let key = Key::Key16([0; 16]);
480 let mut generator = Generator::new(key, [0; 8], 0);
481 generator.set_counter(counter);
482 assert_eq!(generator.init_matrix[8..10], counter_as_u32);
483 assert_eq!(
484 generator.first_doubleround(),
485 doubleround(generator.init_matrix)
486 );
487 };
488 }
489
490 #[test]
491 fn generate_test() {
492 test(Key::Key16([
493 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
494 ]), [
495 39, 173, 46, 248, 30, 200, 82, 17, 48, 67, 254, 239, 37, 18, 13,
496 247, 241, 200, 61, 144, 10, 55, 50, 185, 6, 47, 246, 253, 143, 86,
497 187, 225, 134, 85, 110, 246, 161, 163, 43, 235, 231, 94, 171, 51,
498 145, 214, 112, 29, 14, 232, 5, 16, 151, 140, 183, 141, 171, 9, 122,
499 181, 104, 182, 177, 193
500 ]);
501
502 test(Key::Key32([
503 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 201, 202,
504 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216
505 ]), [
506 69, 37, 68, 39, 41, 15, 107, 193, 255, 139, 122, 6, 170, 233, 217,
507 98, 89, 144, 182, 106, 21, 51, 200, 65, 239, 49, 222, 34, 215, 114,
508 40, 126, 104, 197, 7, 225, 197, 153, 31, 2, 102, 78, 76, 176, 84,
509 245, 246, 184, 177, 160, 133, 130, 6, 72, 149, 119, 192, 195, 132,
510 236, 234, 103, 246, 74
511 ]);
512
513 fn test(key: Key, expected_data: [u8; 64]) {
514 let nonce = [101, 102, 103, 104, 105, 106, 107, 108];
515 let counter = u64::from_le_bytes(
516 [109, 110, 111, 112, 113, 114, 115, 116]
517 );
518 let mut generator = Generator::new(key, nonce, counter);
519
520 let buffer = generator.next();
521 assert_eq!(buffer.to_vec(), expected_data.to_vec());
522 }
523 }
524}