/// Creates a new context with the full set of sequential-mode parameters. pubfn new_with_params(
salt: &[u8],
persona: &[u8],
key_size: usize,
output_size: usize,
) -> Self {
assert!(key_size <= $bytes::to_usize());
assert!(output_size <= $bytes::to_usize());
// The number of bytes needed to express two words. let length = $bytes::to_usize() / 4;
assert!(salt.len() <= length);
assert!(persona.len() <= length);
// Build a parameter block letmut p = [0as $word; 8];
p[0] = 0x0101_0000 ^ ((key_size as $word) << 8) ^ (output_size as $word);
// salt is two words long if salt.len() < length { letmut padded_salt =
GenericArray::<u8, <$bytes as Div<U4>>::Output>::default(); for i in0..salt.len() {
padded_salt[i] = salt[i];
}
p[4] = $word::from_le_bytes(padded_salt[0..length / 2].try_into().unwrap());
p[5] = $word::from_le_bytes(
padded_salt[length / 2..padded_salt.len()]
.try_into()
.unwrap(),
);
} else {
p[4] = $word::from_le_bytes(salt[0..salt.len() / 2].try_into().unwrap());
p[5] =
$word::from_le_bytes(salt[salt.len() / 2..salt.len()].try_into().unwrap());
}
// persona is also two words long if persona.len() < length { letmut padded_persona =
GenericArray::<u8, <$bytes as Div<U4>>::Output>::default(); for i in0..persona.len() {
padded_persona[i] = persona[i];
}
p[6] = $word::from_le_bytes(padded_persona[0..length / 2].try_into().unwrap());
p[7] = $word::from_le_bytes(
padded_persona[length / 2..padded_persona.len()]
.try_into()
.unwrap(),
);
} else {
p[6] = $word::from_le_bytes(persona[0..length / 2].try_into().unwrap());
p[7] = $word::from_le_bytes(
persona[length / 2..persona.len()].try_into().unwrap(),
);
}
letmut m: [$word; 16] = Default::default(); let n = core::mem::size_of::<$word>(); for (v, chunk) in m.iter_mut().zip(block.chunks_exact(n)) {
*v = $word::from_ne_bytes(chunk.try_into().unwrap());
} let h = &mutself.h;
let t0 = self.t as $word; let t1 = match $bytes::to_u8() { 64 => 0, 32 => (self.t >> 32) as $word,
_ => unreachable!(),
};
impl<OutSize> $name<OutSize> where
OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
LeEq<OutSize, $max_size>: NonZero,
{ /// Create new instance using provided key, salt, and persona. /// /// Setting key to `None` indicates unkeyed usage. /// /// # Errors /// /// If key is `Some`, then its length should not be zero or bigger /// than the block size. The salt and persona length should not be /// bigger than quarter of block size. If any of those conditions is /// false the method will return an error. #[inline] pubfn new_with_salt_and_personal(
key: Option<&[u8]>,
salt: &[u8],
persona: &[u8],
) -> Result<Self, InvalidLength> { let kl = key.map_or(0, |k| k.len()); let bs = <$hash as BlockSizeUser>::BlockSize::USIZE; let qbs = bs / 4; if key.is_some() && kl == 0 || kl > bs || salt.len() > qbs || persona.len() > qbs { return Err(InvalidLength);
} let buffer = iflet Some(k) = key { letmut padded_key = Block::<$hash>::default();
padded_key[..kl].copy_from_slice(k);
LazyBuffer::new(&padded_key)
} else {
LazyBuffer::default()
};
Ok(Self {
core: <$hash>::new_with_params(salt, persona, kl, OutSize::USIZE),
buffer, #[cfg(feature = "reset")]
key_block: key.map(|k| { letmut t = Key::<Self>::default();
t[..kl].copy_from_slice(k);
t
}),
_out: PhantomData,
})
}
}
impl<OutSize> KeySizeUser for $name<OutSize> where
OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
LeEq<OutSize, $max_size>: NonZero,
{ type KeySize = $max_size;
}
impl<OutSize> KeyInit for $name<OutSize> where
OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
LeEq<OutSize, $max_size>: NonZero,
{ #[inline] fn new(key: &Key<Self>) -> Self { Self::new_from_slice(key).expect("Key has correct length")
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.