From 2ea332ad5d07ef6e0292d9136d609109e35d46b0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 20 Apr 2021 09:58:41 -0700 Subject: [PATCH] argon2: use Block::SIZE constant (#161) Also deprecates the previous `argon2::BLOCK_SIZE` constant. --- argon2/src/block.rs | 101 ++++++++++++++++++++--------------------- argon2/src/instance.rs | 7 ++- argon2/src/lib.rs | 7 +-- 3 files changed, 57 insertions(+), 58 deletions(-) diff --git a/argon2/src/block.rs b/argon2/src/block.rs index f7ee8ddb..96bc3065 100644 --- a/argon2/src/block.rs +++ b/argon2/src/block.rs @@ -1,6 +1,5 @@ //! Argon2 memory block functions -use crate::BLOCK_SIZE; use core::{ convert::TryInto, num::Wrapping, @@ -11,62 +10,23 @@ use core::{ #[cfg(feature = "zeroize")] use zeroize::Zeroize; -/// Quadwords in block -const QWORDS_IN_BLOCK: usize = BLOCK_SIZE / 8; - /// Structure for the (1KB) memory block implemented as 128 64-bit words. #[derive(Copy, Clone, Debug)] -pub(crate) struct Block([u64; QWORDS_IN_BLOCK]); +pub(crate) struct Block([u64; Self::SIZE / 8]); impl Default for Block { fn default() -> Self { - Self([0u64; QWORDS_IN_BLOCK]) - } -} - -impl BitXor for Block { - type Output = Self; - - fn bitxor(self, rhs: Self) -> Self::Output { - let mut res = self; - res ^= rhs; - res - } -} - -impl BitXorAssign for Block { - fn bitxor_assign(&mut self, rhs: Self) { - for (a, b) in self.iter_mut().zip(rhs.iter()) { - *a ^= *b; - } - } -} - -impl Index for Block { - type Output = u64; - - fn index(&self, index: usize) -> &u64 { - &self.0[index] - } -} - -impl IndexMut for Block { - fn index_mut(&mut self, index: usize) -> &mut u64 { - &mut self.0[index] - } -} - -#[cfg(feature = "zeroize")] -impl Zeroize for Block { - fn zeroize(&mut self) { - self.0.zeroize(); + Self([0u64; Self::SIZE / 8]) } } impl Block { + /// Memory block size in bytes + pub const SIZE: usize = 1024; + /// Load a block from a block-sized byte slice pub fn load(&mut self, input: &[u8]) { - debug_assert_eq!(input.len(), BLOCK_SIZE); + debug_assert_eq!(input.len(), Block::SIZE); for (i, chunk) in input.chunks(8).enumerate() { self[i] = u64::from_le_bytes(chunk.try_into().unwrap()); @@ -97,6 +57,13 @@ impl Block { // block_tmp = ref_block + prev_block + next_block } + /// Designed by the Lyra PHC team + fn blake2_mult(x: u64, y: u64) -> u64 { + let m = 0xFFFFFFFF; + let xy = Wrapping((x & m) * (y & m)) * Wrapping(2); + (Wrapping(x) + Wrapping(y) + xy).0 + } + /// Blake2 round function // TODO(tarcieri): use the `blake2` crate macro_rules! blake2_round { @@ -178,9 +145,41 @@ impl Block { } } -/// Designed by the Lyra PHC team -fn blake2_mult(x: u64, y: u64) -> u64 { - let m = 0xFFFFFFFF; - let xy = Wrapping((x & m) * (y & m)) * Wrapping(2); - (Wrapping(x) + Wrapping(y) + xy).0 +impl BitXor for Block { + type Output = Self; + + fn bitxor(self, rhs: Self) -> Self::Output { + let mut res = self; + res ^= rhs; + res + } +} + +impl BitXorAssign for Block { + fn bitxor_assign(&mut self, rhs: Self) { + for (a, b) in self.iter_mut().zip(rhs.iter()) { + *a ^= *b; + } + } +} + +impl Index for Block { + type Output = u64; + + fn index(&self, index: usize) -> &u64 { + &self.0[index] + } +} + +impl IndexMut for Block { + fn index_mut(&mut self, index: usize) -> &mut u64 { + &mut self.0[index] + } +} + +#[cfg(feature = "zeroize")] +impl Zeroize for Block { + fn zeroize(&mut self) { + self.0.zeroize(); + } } diff --git a/argon2/src/instance.rs b/argon2/src/instance.rs index b83fa5f8..0cd977fd 100644 --- a/argon2/src/instance.rs +++ b/argon2/src/instance.rs @@ -1,8 +1,7 @@ //! Argon2 instance (i.e. state) use crate::{ - Algorithm, Argon2, Block, Error, Memory, Version, BLOCK_SIZE, MAX_OUTLEN, MIN_OUTLEN, - SYNC_POINTS, + Algorithm, Argon2, Block, Error, Memory, Version, MAX_OUTLEN, MIN_OUTLEN, SYNC_POINTS, }; use blake2::{ digest::{self, VariableOutput}, @@ -201,7 +200,7 @@ impl<'a> Instance<'a> { } // Hash the result - let mut blockhash_bytes = [0u8; BLOCK_SIZE]; + let mut blockhash_bytes = [0u8; Block::SIZE]; for (chunk, v) in blockhash_bytes.chunks_mut(8).zip(blockhash.iter()) { chunk.copy_from_slice(&v.to_le_bytes()) @@ -220,7 +219,7 @@ impl<'a> Instance<'a> { /// Function creates first 2 blocks per lane fn fill_first_blocks(&mut self, blockhash: &[u8]) -> Result<(), Error> { - let mut hash = [0u8; BLOCK_SIZE]; + let mut hash = [0u8; Block::SIZE]; for l in 0..self.lanes { // Make the first and second block in each lane as G(H0||0||i) or diff --git a/argon2/src/lib.rs b/argon2/src/lib.rs index 933d8953..f2640187 100644 --- a/argon2/src/lib.rs +++ b/argon2/src/lib.rs @@ -123,10 +123,10 @@ pub const MIN_OUTLEN: usize = 4; /// Maximum digest size in bytes pub const MAX_OUTLEN: usize = 0xFFFFFFFF; -/// Minimum number of memory blocks (each of [`BLOCK_SIZE`] bytes) +/// Minimum number of memory blocks. pub const MIN_MEMORY: u32 = 2 * SYNC_POINTS; // 2 blocks per slice -/// Maximum number of memory blocks (each of [`BLOCK_SIZE`] bytes) +/// Maximum number of memory blocks. pub const MAX_MEMORY: u32 = 0x0FFFFFFF; /// Minimum number of passes @@ -151,7 +151,8 @@ pub const MAX_SALT_LENGTH: usize = 0xFFFFFFFF; pub const MAX_SECRET: usize = 0xFFFFFFFF; /// Memory block size in bytes -pub const BLOCK_SIZE: usize = 1024; +#[deprecated(since = "0.1.6", note = "use Block::SIZE instead")] +pub const BLOCK_SIZE: usize = Block::SIZE; /// Argon2d algorithm identifier #[cfg(feature = "password-hash")]