Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add chacha counter initialization #51

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/crypto/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn chacha_block<const ROUNDS: u8>(input: [u32; 16]) -> [u32; 16] {
}

/// Initialize the ChaCha internal state, with a 256-bit key and 64-bit nonce.
pub const fn chacha_init(key: [u8; 32], nonce: [u8; 8]) -> [u32; 16] {
pub const fn chacha_init(key: [u8; 32], counter: [u8; 8], nonce: [u8; 8]) -> [u32; 16] {
let mut state = [0u32; 16];
state[0] = chacha_pack(CHACHA_TAU, 0);
state[1] = chacha_pack(CHACHA_TAU, 4);
Expand All @@ -65,8 +65,8 @@ pub const fn chacha_init(key: [u8; 32], nonce: [u8; 8]) -> [u32; 16] {
state[11] = chacha_pack(&key, 28);

// 64-bit counter
state[12] = 0;
state[13] = 0;
state[12] = chacha_pack(&counter, 0);
state[13] = chacha_pack(&counter, 4);
// Nonce
state[14] = chacha_pack(&nonce, 0);
state[15] = chacha_pack(&nonce, 4);
Expand Down Expand Up @@ -95,10 +95,11 @@ mod tests {
macro_rules! ietf_test_vector {
($key_hex: tt, $nonce_hex: tt, $keystream_hex: tt) => {
let key: [u8; 32] = hex::decode($key_hex).unwrap().try_into().unwrap();
let counter = [0u8; 8];
let nonce: [u8; 8] = hex::decode($nonce_hex).unwrap().try_into().unwrap();
let expected_keystream: Vec<u8> = hex::decode($keystream_hex).unwrap();

let mut state = chacha_init(key, nonce);
let mut state = chacha_init(key, counter, nonce);
let mut keystream: Vec<u8> = Vec::with_capacity(expected_keystream.len());

while expected_keystream.len() > keystream.len() {
Expand Down
13 changes: 8 additions & 5 deletions src/rand/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,17 @@ impl<const ROUNDS: u8> ChaCha<ROUNDS> {
pub fn new() -> Self {
let mut key: [u8; 32] = Default::default();
crate::entropy::system(&mut key);
let counter = [0u8; 8];
let mut nonce: [u8; 8] = Default::default();
crate::entropy::system(&mut nonce);
let state = chacha::chacha_init(key, nonce);
let state = chacha::chacha_init(key, counter, nonce);
Self { state }
}

/// Create a new [`ChaCha`] instance, using the provided key and nonce.
#[must_use]
pub const fn new_key(key: [u8; 32], nonce: [u8; 8]) -> Self {
let state = chacha::chacha_init(key, nonce);
pub const fn new_key(key: [u8; 32], counter: [u8; 8], nonce: [u8; 8]) -> Self {
let state = chacha::chacha_init(key, counter, nonce);
Self { state }
}
}
Expand All @@ -50,9 +51,10 @@ impl<const ROUNDS: u8> Default for ChaCha<ROUNDS> {
fn default() -> Self {
let mut key: [u8; 32] = Default::default();
crate::entropy::system(&mut key);
let counter = [0u8; 8];
let mut nonce: [u8; 8] = Default::default();
crate::entropy::system(&mut nonce);
let state = chacha::chacha_init(key, nonce);
let state = chacha::chacha_init(key, counter, nonce);
Self { state }
}
}
Expand Down Expand Up @@ -97,8 +99,9 @@ impl<const ROUNDS: u8> SeedableRng<40, 64> for ChaCha<ROUNDS> {
let mut key = [0_u8; 32];
let mut nonce = [0_u8; 8];
key.copy_from_slice(&seed[..32]);
let counter = [0u8; 8];
nonce.copy_from_slice(&seed[32..]);
self.state = chacha::chacha_init(key, nonce);
self.state = chacha::chacha_init(key, counter, nonce);
}
}

Expand Down