Skip to content

Commit 1d516a6

Browse files
Add get_single_block to chacha20 module
In the next commit, we'll want to get a single block from a chacha stream that takes a 16-byte nonce.
1 parent 063b758 commit 1d516a6

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

lightning/src/util/chacha20.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ mod real_chacha {
151151
ChaCha20{ state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 }
152152
}
153153

154+
/// Get one block from a ChaCha stream.
155+
pub fn get_single_block(key: &[u8; 32], nonce: &[u8; 16]) -> [u8; 32] {
156+
let mut chacha = ChaCha20 { state: ChaCha20::expand(key, nonce), output: [0u8; BLOCK_SIZE], offset: 64 };
157+
let mut chacha_bytes = [0; 32];
158+
chacha.process_in_place(&mut chacha_bytes);
159+
chacha_bytes
160+
}
161+
154162
fn expand(key: &[u8], nonce: &[u8]) -> ChaChaState {
155163
let constant = match key.len() {
156164
16 => b"expand 16-byte k",
@@ -256,6 +264,12 @@ mod real_chacha {
256264
self.offset += count;
257265
}
258266
}
267+
268+
#[cfg(test)]
269+
pub fn seek_to_block(&mut self, block_offset: u32) {
270+
self.state.d.0 = block_offset;
271+
self.update();
272+
}
259273
}
260274
}
261275
#[cfg(not(feature = "fuzztarget"))]
@@ -272,6 +286,10 @@ mod fuzzy_chacha {
272286
Self {}
273287
}
274288

289+
pub fn get_single_block(_key: &[u8; 32], _nonce: &[u8; 16]) -> [u8; 32] {
290+
[0; 32]
291+
}
292+
275293
pub fn process(&mut self, input: &[u8], output: &mut [u8]) {
276294
output.copy_from_slice(input);
277295
}
@@ -302,6 +320,7 @@ mod test {
302320
use core::iter::repeat;
303321

304322
use super::ChaCha20;
323+
use std::convert::TryInto;
305324

306325
#[test]
307326
fn test_chacha20_256_tls_vectors() {
@@ -572,4 +591,31 @@ mod test {
572591
assert_eq!(output, tv.keystream);
573592
}
574593
}
594+
595+
#[test]
596+
fn get_single_block() {
597+
// Test that `get_single_block` (which takes a 16-byte nonce) is equivalent to getting a block
598+
// using a 12-byte nonce, with the block starting at the counter offset given by the remaining 4
599+
// bytes.
600+
let key = [
601+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
602+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
603+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
604+
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
605+
];
606+
let nonce_16bytes = [
607+
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b
608+
];
609+
let counter_pos = &nonce_16bytes[..4];
610+
let nonce_12bytes = &nonce_16bytes[4..];
611+
612+
// Initialize a ChaCha20 instance with its counter starting at 0.
613+
let mut chacha20 = ChaCha20::new(&key, nonce_12bytes);
614+
// Seek its counter to the block at counter_pos.
615+
chacha20.seek_to_block(u32::from_le_bytes(counter_pos.try_into().unwrap()));
616+
let mut block_bytes = [0; 32];
617+
chacha20.process_in_place(&mut block_bytes);
618+
619+
assert_eq!(ChaCha20::get_single_block(&key, &nonce_16bytes), block_bytes);
620+
}
575621
}

0 commit comments

Comments
 (0)