hashes: Rename length field and use u64
The hash engine types have a `length` field that is used to cache the number of bytes hashed so far, as such it is an arbitrary number and could use a `u64` instead of `usize`. While we are at it rename `length` to `bytes_hashed` to remove any ambiguity of what this field is. Note this field is private, we already have the public getter `n_bytes_hashes` to get the value. Introduce a private function `incomplete_block_size`, the purpose of this function is to put all the casts in one place so they can be well documented and easily understood. Fix: #3016
This commit is contained in:
parent
e2ff08635e
commit
cbfddb0394
|
@ -34,7 +34,7 @@ impl Default for HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64; // Same as sha256::HashEngine::BLOCK_SIZE;
|
||||
fn input(&mut self, data: &[u8]) { self.0.input(data) }
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.0.n_bytes_hashed() }
|
||||
}
|
||||
|
||||
fn from_engine(e: HashEngine) -> Hash {
|
||||
|
|
|
@ -102,7 +102,7 @@ impl<T: GeneralHash> HmacEngine<T> {
|
|||
impl<T: GeneralHash> HashEngine for HmacEngine<T> {
|
||||
const BLOCK_SIZE: usize = T::Engine::BLOCK_SIZE;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.iengine.n_bytes_hashed() }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.iengine.n_bytes_hashed() }
|
||||
|
||||
fn input(&mut self, buf: &[u8]) { self.iengine.input(buf) }
|
||||
}
|
||||
|
|
|
@ -187,8 +187,8 @@ pub trait HashEngine: Clone {
|
|||
/// Add data to the hash engine.
|
||||
fn input(&mut self, data: &[u8]);
|
||||
|
||||
/// Return the number of bytes already n_bytes_hashed(inputted).
|
||||
fn n_bytes_hashed(&self) -> usize;
|
||||
/// Return the number of bytes already input into the engine.
|
||||
fn n_bytes_hashed(&self) -> u64;
|
||||
}
|
||||
|
||||
/// Trait describing hash digests which can be constructed by hashing arbitrary data.
|
||||
|
@ -314,6 +314,13 @@ mod sealed {
|
|||
impl<const N: usize> IsByteArray for [u8; N] { }
|
||||
}
|
||||
|
||||
fn incomplete_block_len<H: HashEngine>(eng: &H) -> usize {
|
||||
let block_size = <H as HashEngine>::BLOCK_SIZE as u64; // Cast usize to u64 is ok.
|
||||
|
||||
// After modulo operation we know cast u64 to usize as ok.
|
||||
(eng.n_bytes_hashed() % block_size) as usize
|
||||
}
|
||||
|
||||
/// Attempted to create a hash from an invalid length slice.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct FromSliceError {
|
||||
|
|
|
@ -6,7 +6,7 @@ use core::cmp;
|
|||
use core::ops::Index;
|
||||
use core::slice::SliceIndex;
|
||||
|
||||
use crate::HashEngine as _;
|
||||
use crate::{incomplete_block_len, HashEngine as _};
|
||||
|
||||
crate::internal_macros::hash_type! {
|
||||
160,
|
||||
|
@ -17,19 +17,19 @@ crate::internal_macros::hash_type! {
|
|||
#[cfg(not(hashes_fuzz))]
|
||||
fn from_engine(mut e: HashEngine) -> Hash {
|
||||
// pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
|
||||
let data_len = e.length as u64;
|
||||
let n_bytes_hashed = e.bytes_hashed;
|
||||
|
||||
let zeroes = [0; BLOCK_SIZE - 8];
|
||||
e.input(&[0x80]);
|
||||
if e.length % BLOCK_SIZE > zeroes.len() {
|
||||
if crate::incomplete_block_len(&e) > zeroes.len() {
|
||||
e.input(&zeroes);
|
||||
}
|
||||
let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
|
||||
let pad_length = zeroes.len() - incomplete_block_len(&e);
|
||||
e.input(&zeroes[..pad_length]);
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
|
||||
debug_assert_eq!(incomplete_block_len(&e), zeroes.len());
|
||||
|
||||
e.input(&(8 * data_len).to_le_bytes());
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, 0);
|
||||
e.input(&(8 * n_bytes_hashed).to_le_bytes());
|
||||
debug_assert_eq!(incomplete_block_len(&e), 0);
|
||||
|
||||
Hash(e.midstate())
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ const BLOCK_SIZE: usize = 64;
|
|||
pub struct HashEngine {
|
||||
buffer: [u8; BLOCK_SIZE],
|
||||
h: [u32; 5],
|
||||
length: usize,
|
||||
bytes_hashed: u64,
|
||||
}
|
||||
|
||||
impl HashEngine {
|
||||
|
@ -56,7 +56,7 @@ impl HashEngine {
|
|||
pub const fn new() -> Self {
|
||||
Self {
|
||||
h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0],
|
||||
length: 0,
|
||||
bytes_hashed: 0,
|
||||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl Default for HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
|
||||
|
||||
engine_input_impl!();
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use core::cmp;
|
|||
use core::ops::Index;
|
||||
use core::slice::SliceIndex;
|
||||
|
||||
use crate::HashEngine as _;
|
||||
use crate::{incomplete_block_len, HashEngine as _};
|
||||
|
||||
crate::internal_macros::hash_type! {
|
||||
160,
|
||||
|
@ -16,19 +16,19 @@ crate::internal_macros::hash_type! {
|
|||
|
||||
fn from_engine(mut e: HashEngine) -> Hash {
|
||||
// pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
|
||||
let data_len = e.length as u64;
|
||||
let n_bytes_hashed = e.bytes_hashed;
|
||||
|
||||
let zeroes = [0; BLOCK_SIZE - 8];
|
||||
e.input(&[0x80]);
|
||||
if e.length % BLOCK_SIZE > zeroes.len() {
|
||||
if incomplete_block_len(&e) > zeroes.len() {
|
||||
e.input(&zeroes);
|
||||
}
|
||||
let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
|
||||
let pad_length = zeroes.len() - incomplete_block_len(&e);
|
||||
e.input(&zeroes[..pad_length]);
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
|
||||
debug_assert_eq!(incomplete_block_len(&e), zeroes.len());
|
||||
|
||||
e.input(&(8 * data_len).to_be_bytes());
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, 0);
|
||||
e.input(&(8 * n_bytes_hashed).to_be_bytes());
|
||||
debug_assert_eq!(incomplete_block_len(&e), 0);
|
||||
|
||||
Hash(e.midstate())
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ const BLOCK_SIZE: usize = 64;
|
|||
pub struct HashEngine {
|
||||
buffer: [u8; BLOCK_SIZE],
|
||||
h: [u32; 5],
|
||||
length: usize,
|
||||
bytes_hashed: u64,
|
||||
}
|
||||
|
||||
impl HashEngine {
|
||||
|
@ -48,7 +48,7 @@ impl HashEngine {
|
|||
pub const fn new() -> Self {
|
||||
Self {
|
||||
h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0],
|
||||
length: 0,
|
||||
bytes_hashed: 0,
|
||||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ impl Default for HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
|
||||
|
||||
engine_input_impl!();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use core::{cmp, convert, fmt};
|
|||
|
||||
use hex::DisplayHex;
|
||||
|
||||
use crate::{sha256d, HashEngine as _};
|
||||
use crate::{incomplete_block_len, sha256d, HashEngine as _};
|
||||
#[cfg(doc)]
|
||||
use crate::{sha256t, sha256t_tag};
|
||||
|
||||
|
@ -25,19 +25,19 @@ crate::internal_macros::hash_type! {
|
|||
#[cfg(not(hashes_fuzz))]
|
||||
fn from_engine(mut e: HashEngine) -> Hash {
|
||||
// pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
|
||||
let data_len = e.length as u64;
|
||||
let n_bytes_hashed = e.bytes_hashed;
|
||||
|
||||
let zeroes = [0; BLOCK_SIZE - 8];
|
||||
e.input(&[0x80]);
|
||||
if e.length % BLOCK_SIZE > zeroes.len() {
|
||||
if incomplete_block_len(&e) > zeroes.len() {
|
||||
e.input(&zeroes);
|
||||
}
|
||||
let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
|
||||
let pad_length = zeroes.len() - incomplete_block_len(&e);
|
||||
e.input(&zeroes[..pad_length]);
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
|
||||
debug_assert_eq!(incomplete_block_len(&e), zeroes.len());
|
||||
|
||||
e.input(&(8 * data_len).to_be_bytes());
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, 0);
|
||||
e.input(&(8 * n_bytes_hashed).to_be_bytes());
|
||||
debug_assert_eq!(incomplete_block_len(&e), 0);
|
||||
|
||||
Hash(e.midstate_unchecked().bytes)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ const BLOCK_SIZE: usize = 64;
|
|||
pub struct HashEngine {
|
||||
buffer: [u8; BLOCK_SIZE],
|
||||
h: [u32; 8],
|
||||
length: usize,
|
||||
bytes_hashed: u64,
|
||||
}
|
||||
|
||||
impl HashEngine {
|
||||
|
@ -71,7 +71,7 @@ impl HashEngine {
|
|||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
|
||||
0x5be0cd19,
|
||||
],
|
||||
length: 0,
|
||||
bytes_hashed: 0,
|
||||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl HashEngine {
|
|||
*ret_val = u32::from_be_bytes(midstate_bytes.try_into().expect("4 byte slice"));
|
||||
}
|
||||
|
||||
HashEngine { buffer: [0; BLOCK_SIZE], h: ret, length: midstate.length }
|
||||
HashEngine { buffer: [0; BLOCK_SIZE], h: ret, bytes_hashed: midstate.bytes_hashed }
|
||||
}
|
||||
|
||||
/// Returns `true` if the midstate can be extracted from this engine.
|
||||
|
@ -94,14 +94,14 @@ impl HashEngine {
|
|||
/// the hash engine is a multiple of 64. See caveat on [`Self::midstate`].
|
||||
///
|
||||
/// Please see docs on [`Midstate`] before using this function.
|
||||
pub const fn can_extract_midstate(&self) -> bool { self.length % 64 == 0 }
|
||||
pub const fn can_extract_midstate(&self) -> bool { self.bytes_hashed % 64 == 0 }
|
||||
|
||||
/// Outputs the midstate of the hash engine.
|
||||
///
|
||||
/// Please see docs on [`Midstate`] before using this function.
|
||||
pub fn midstate(&self) -> Result<Midstate, MidstateError> {
|
||||
if !self.can_extract_midstate() {
|
||||
return Err(MidstateError { invalid_length: self.length });
|
||||
return Err(MidstateError { invalid_n_bytes_hashed: self.bytes_hashed });
|
||||
}
|
||||
Ok(self.midstate_unchecked())
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ impl HashEngine {
|
|||
for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(4)) {
|
||||
ret_bytes.copy_from_slice(&val.to_be_bytes());
|
||||
}
|
||||
Midstate { bytes: ret, length: self.length }
|
||||
Midstate { bytes: ret, bytes_hashed: self.bytes_hashed }
|
||||
}
|
||||
|
||||
// Does not check that `HashEngine::can_extract_midstate`.
|
||||
|
@ -121,7 +121,7 @@ impl HashEngine {
|
|||
fn midstate_unchecked(&self) -> Midstate {
|
||||
let mut ret = [0; 32];
|
||||
ret.copy_from_slice(&self.buffer[..32]);
|
||||
Midstate { bytes: ret, length: self.length }
|
||||
Midstate { bytes: ret, bytes_hashed: self.bytes_hashed }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ impl Default for HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
|
||||
|
||||
engine_input_impl!();
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ pub struct Midstate {
|
|||
bytes: [u8; 32],
|
||||
/// Number of bytes hashed to achieve this midstate.
|
||||
// INVARIANT must always be a multiple of 64.
|
||||
length: usize,
|
||||
bytes_hashed: u64,
|
||||
}
|
||||
|
||||
impl Midstate {
|
||||
|
@ -186,19 +186,19 @@ impl Midstate {
|
|||
/// # Panics
|
||||
///
|
||||
/// Panics if `bytes_hashed` is not a multiple of 64.
|
||||
pub const fn new(state: [u8; 32], bytes_hashed: usize) -> Self {
|
||||
pub const fn new(state: [u8; 32], bytes_hashed: u64) -> Self {
|
||||
if bytes_hashed % 64 != 0 {
|
||||
panic!("bytes hashed is not a multiple of 64");
|
||||
}
|
||||
|
||||
Midstate { bytes: state, length: bytes_hashed }
|
||||
Midstate { bytes: state, bytes_hashed }
|
||||
}
|
||||
|
||||
/// Deconstructs the [`Midstate`], returning the underlying byte array and number of bytes hashed.
|
||||
pub const fn as_parts(&self) -> (&[u8; 32], usize) { (&self.bytes, self.length) }
|
||||
pub const fn as_parts(&self) -> (&[u8; 32], u64) { (&self.bytes, self.bytes_hashed) }
|
||||
|
||||
/// Deconstructs the [`Midstate`], returning the underlying byte array and number of bytes hashed.
|
||||
pub const fn into_parts(self) -> ([u8; 32], usize) { (self.bytes, self.length) }
|
||||
pub const fn into_parts(self) -> ([u8; 32], u64) { (self.bytes, self.bytes_hashed) }
|
||||
|
||||
/// Creates midstate for tagged hashes.
|
||||
///
|
||||
|
@ -222,7 +222,7 @@ impl fmt::Debug for Midstate {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Midstate")
|
||||
.field("bytes", &self.bytes.as_hex())
|
||||
.field("length", &self.length)
|
||||
.field("length", &self.bytes_hashed)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ impl convert::AsRef<[u8]> for Midstate {
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MidstateError {
|
||||
/// The invalid number of bytes hashed.
|
||||
invalid_length: usize,
|
||||
invalid_n_bytes_hashed: u64,
|
||||
}
|
||||
|
||||
impl fmt::Display for MidstateError {
|
||||
|
@ -243,7 +243,7 @@ impl fmt::Display for MidstateError {
|
|||
write!(
|
||||
f,
|
||||
"invalid number of bytes hashed {} (should have been a multiple of 64)",
|
||||
self.invalid_length
|
||||
self.invalid_n_bytes_hashed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ impl Midstate {
|
|||
output[i * 4 + 3] = (state[i + 0] >> 0) as u8;
|
||||
i += 1;
|
||||
}
|
||||
Midstate { bytes: output, length: bytes.len() }
|
||||
Midstate { bytes: output, bytes_hashed: bytes.len() as u64 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -996,7 +996,7 @@ mod tests {
|
|||
let mut midstate_engine =
|
||||
sha256::HashEngine::from_midstate(engine.midstate_unchecked());
|
||||
assert_eq!(engine.h, midstate_engine.h);
|
||||
assert_eq!(engine.length, midstate_engine.length);
|
||||
assert_eq!(engine.bytes_hashed, midstate_engine.bytes_hashed);
|
||||
engine.input(data);
|
||||
midstate_engine.input(data);
|
||||
assert_eq!(engine.h, midstate_engine.h);
|
||||
|
@ -1037,7 +1037,7 @@ mod tests {
|
|||
assert_eq!(
|
||||
Hash::hash(bytes),
|
||||
Hash::hash_unoptimized(bytes),
|
||||
"hashes don't match for length {}",
|
||||
"hashes don't match for n_bytes_hashed {}",
|
||||
i + 1
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ impl Default for HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64; // Same as sha256::HashEngine::BLOCK_SIZE;
|
||||
fn input(&mut self, data: &[u8]) { self.0.input(data) }
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.0.n_bytes_hashed() }
|
||||
}
|
||||
|
||||
fn from_engine(e: HashEngine) -> Hash {
|
||||
|
|
|
@ -35,7 +35,7 @@ impl Default for HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = sha512::BLOCK_SIZE;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.0.n_bytes_hashed() }
|
||||
|
||||
fn input(&mut self, inp: &[u8]) { self.0.input(inp); }
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use core::cmp;
|
|||
use core::ops::Index;
|
||||
use core::slice::SliceIndex;
|
||||
|
||||
use crate::HashEngine as _;
|
||||
use crate::{incomplete_block_len, HashEngine as _};
|
||||
|
||||
crate::internal_macros::hash_type! {
|
||||
512,
|
||||
|
@ -17,20 +17,20 @@ crate::internal_macros::hash_type! {
|
|||
#[cfg(not(hashes_fuzz))]
|
||||
pub(crate) fn from_engine(mut e: HashEngine) -> Hash {
|
||||
// pad buffer with a single 1-bit then all 0s, until there are exactly 16 bytes remaining
|
||||
let data_len = e.length as u64;
|
||||
let n_bytes_hashed = e.bytes_hashed;
|
||||
|
||||
let zeroes = [0; BLOCK_SIZE - 16];
|
||||
e.input(&[0x80]);
|
||||
if e.length % BLOCK_SIZE > zeroes.len() {
|
||||
if incomplete_block_len(&e) > zeroes.len() {
|
||||
e.input(&zeroes);
|
||||
}
|
||||
let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
|
||||
let pad_length = zeroes.len() - incomplete_block_len(&e);
|
||||
e.input(&zeroes[..pad_length]);
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
|
||||
debug_assert_eq!(incomplete_block_len(&e), zeroes.len());
|
||||
|
||||
e.input(&[0; 8]);
|
||||
e.input(&(8 * data_len).to_be_bytes());
|
||||
debug_assert_eq!(e.length % BLOCK_SIZE, 0);
|
||||
e.input(&(8 * n_bytes_hashed).to_be_bytes());
|
||||
debug_assert_eq!(incomplete_block_len(&e), 0);
|
||||
|
||||
Hash(e.midstate())
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ pub(crate) const BLOCK_SIZE: usize = 128;
|
|||
#[derive(Clone)]
|
||||
pub struct HashEngine {
|
||||
h: [u64; 8],
|
||||
length: usize,
|
||||
bytes_hashed: u64,
|
||||
buffer: [u8; BLOCK_SIZE],
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ impl HashEngine {
|
|||
0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
|
||||
0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
|
||||
],
|
||||
length: 0,
|
||||
bytes_hashed: 0,
|
||||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ impl HashEngine {
|
|||
0x22312194fc2bf72c, 0x9f555fa3c84c64c2, 0x2393b86b6f53b151, 0x963877195940eabd,
|
||||
0x96283ee2a88effe3, 0xbe5e1e2553863992, 0x2b0199fc2c85b8aa, 0x0eb72ddc81c52ca2,
|
||||
],
|
||||
length: 0,
|
||||
bytes_hashed: 0,
|
||||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ impl HashEngine {
|
|||
0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
|
||||
0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
|
||||
],
|
||||
length: 0,
|
||||
bytes_hashed: 0,
|
||||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ impl HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 128;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
|
||||
|
||||
engine_input_impl!();
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ impl Default for HashEngine {
|
|||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = sha512::BLOCK_SIZE;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.0.n_bytes_hashed() }
|
||||
|
||||
fn input(&mut self, inp: &[u8]) { self.0.input(inp); }
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ pub struct State {
|
|||
pub struct HashEngine {
|
||||
k0: u64,
|
||||
k1: u64,
|
||||
length: usize, // how many bytes we've processed
|
||||
bytes_hashed: u64, // how many bytes we've processed
|
||||
state: State, // hash State
|
||||
tail: u64, // unprocessed bytes le
|
||||
ntail: usize, // how many bytes in tail are valid
|
||||
|
@ -94,7 +94,7 @@ impl HashEngine {
|
|||
HashEngine {
|
||||
k0,
|
||||
k1,
|
||||
length: 0,
|
||||
bytes_hashed: 0,
|
||||
state: State {
|
||||
v0: k0 ^ 0x736f6d6570736575,
|
||||
v1: k1 ^ 0x646f72616e646f6d,
|
||||
|
@ -129,16 +129,16 @@ impl crate::HashEngine for HashEngine {
|
|||
|
||||
#[inline]
|
||||
fn input(&mut self, msg: &[u8]) {
|
||||
let length = msg.len();
|
||||
self.length += length;
|
||||
let bytes_hashed = msg.len();
|
||||
self.bytes_hashed += bytes_hashed as u64; // Cast usize to u64 is ok.
|
||||
|
||||
let mut needed = 0;
|
||||
|
||||
if self.ntail != 0 {
|
||||
needed = 8 - self.ntail;
|
||||
self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
|
||||
if length < needed {
|
||||
self.ntail += length;
|
||||
self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(bytes_hashed, needed)) } << (8 * self.ntail);
|
||||
if bytes_hashed < needed {
|
||||
self.ntail += bytes_hashed;
|
||||
return;
|
||||
} else {
|
||||
self.state.v3 ^= self.tail;
|
||||
|
@ -149,7 +149,7 @@ impl crate::HashEngine for HashEngine {
|
|||
}
|
||||
|
||||
// Buffered tail is now flushed, process new input.
|
||||
let len = length - needed;
|
||||
let len = bytes_hashed - needed;
|
||||
let left = len & 0x7;
|
||||
|
||||
let mut i = needed;
|
||||
|
@ -167,7 +167,7 @@ impl crate::HashEngine for HashEngine {
|
|||
self.ntail = left;
|
||||
}
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
fn n_bytes_hashed(&self) -> u64 { self.bytes_hashed }
|
||||
}
|
||||
|
||||
impl Hash {
|
||||
|
@ -190,7 +190,7 @@ impl Hash {
|
|||
pub fn from_engine_to_u64(e: HashEngine) -> u64 {
|
||||
let mut state = e.state;
|
||||
|
||||
let b: u64 = ((e.length as u64 & 0xff) << 56) | e.tail;
|
||||
let b: u64 = ((e.bytes_hashed & 0xff) << 56) | e.tail;
|
||||
|
||||
state.v3 ^= b;
|
||||
HashEngine::c_rounds(&mut state);
|
||||
|
|
|
@ -70,15 +70,16 @@ macro_rules! engine_input_impl(
|
|||
() => (
|
||||
#[cfg(not(hashes_fuzz))]
|
||||
fn input(&mut self, mut inp: &[u8]) {
|
||||
|
||||
while !inp.is_empty() {
|
||||
let buf_idx = self.length % <Self as crate::HashEngine>::BLOCK_SIZE;
|
||||
let buf_idx = $crate::incomplete_block_len(self);
|
||||
let rem_len = <Self as crate::HashEngine>::BLOCK_SIZE - buf_idx;
|
||||
let write_len = cmp::min(rem_len, inp.len());
|
||||
|
||||
self.buffer[buf_idx..buf_idx + write_len]
|
||||
.copy_from_slice(&inp[..write_len]);
|
||||
self.length += write_len;
|
||||
if self.length % <Self as crate::HashEngine>::BLOCK_SIZE == 0 {
|
||||
self.bytes_hashed += write_len as u64;
|
||||
if $crate::incomplete_block_len(self) == 0 {
|
||||
self.process_block();
|
||||
}
|
||||
inp = &inp[write_len..];
|
||||
|
|
Loading…
Reference in New Issue