Skip to content

Commit

Permalink
Merge pull request RustCrypto#128 from RustCrypto/universal-hash/key-…
Browse files Browse the repository at this point in the history
…and-block-type-aliases

universal-hash: add `Key` and `Block` type aliases
  • Loading branch information
tarcieri committed May 23, 2020
2 parents 0d72ab1 + af9c536 commit dcbdbbc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 39 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 46 additions & 38 deletions universal-hash/src/lib.rs
@@ -1,13 +1,15 @@
//! Traits for [Universal Hash Functions].
//!
//! Universal hash functions select from a "universal family" of possible
//! hash functions selected by a key. They are well suited to the purpose
//! of "one time authenticators" for a sequence of bytestring inputs,
//! as their construction has a number of desirable properties such as
//! pairwise independence as well as amenability to efficient implementations,
//! particularly when implemented using SIMD instructions.
//! Universal hash functions provide a "universal family" of possible
//! hash functions where a given member of a family is selected by a key.
//!
//! When combined with a cipher, such as in Galois/Counter Mode or the
//! They are well suited to the purpose of "one time authenticators" for a
//! sequence of bytestring inputs, as their construction has a number of
//! desirable properties such as pairwise independence as well as amenability
//! to efficient implementations, particularly when implemented using SIMD
//! instructions.
//!
//! When combined with a cipher, such as in Galois/Counter Mode (GCM) or the
//! Salsa20 family AEAD constructions, they can provide the core functionality
//! for a Message Authentication Code (MAC).
//!
Expand All @@ -27,6 +29,12 @@ use generic_array::typenum::Unsigned;
use generic_array::{ArrayLength, GenericArray};
use subtle::{Choice, ConstantTimeEq};

/// Keys to a [`UniversalHash`].
pub type Key<U> = GenericArray<u8, <U as UniversalHash>::KeySize>;

/// Blocks are inputs to a [`UniversalHash`].
pub type Block<U> = GenericArray<u8, <U as UniversalHash>::BlockSize>;

/// The `UniversalHash` trait defines a generic interface for universal hash
/// functions.
pub trait UniversalHash: Clone {
Expand All @@ -37,10 +45,10 @@ pub trait UniversalHash: Clone {
type BlockSize: ArrayLength<u8>;

/// Instantiate a universal hash function with the given key
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self;
fn new(key: &Key<Self>) -> Self;

/// Input a block into the universal hash function
fn update_block(&mut self, block: &GenericArray<u8, Self::BlockSize>);
fn update_block(&mut self, block: &Block<Self>);

/// Input data into the universal hash function. If the length of the
/// data is not a multiple of the block size, the remaining data is
Expand All @@ -64,24 +72,24 @@ pub trait UniversalHash: Clone {
}
}

/// Reset `UniversalHash` instance.
/// Reset [`UniversalHash`] instance.
fn reset(&mut self);

/// Obtain the [`Output`] of a `UniversalHash` function and consume it.
fn result(self) -> Output<Self::BlockSize>;
/// Obtain the [`Output`] of a [`UniversalHash`] function and consume it.
fn result(self) -> Output<Self>;

/// Obtain the [`Output`] of a `UniversalHash` computation and reset it back
/// Obtain the [`Output`] of a [`UniversalHash`] computation and reset it back
/// to its initial state.
fn result_reset(&mut self) -> Output<Self::BlockSize> {
fn result_reset(&mut self) -> Output<Self> {
let res = self.clone().result();
self.reset();
res
}

/// Verify the `UniversalHash` of the processed input matches a given [`Output`].
/// Verify the [`UniversalHash`] of the processed input matches a given [`Output`].
/// This is useful when constructing Message Authentication Codes (MACs)
/// from universal hash functions.
fn verify(self, other: &GenericArray<u8, Self::BlockSize>) -> Result<(), Error> {
fn verify(self, other: &Block<Self>) -> Result<(), Error> {
if self.result() == other.into() {
Ok(())
} else {
Expand All @@ -91,68 +99,68 @@ pub trait UniversalHash: Clone {
}

/// Outputs of universal hash functions which are a thin wrapper around a
/// byte array. Provides a safe `Eq` implementation that runs in constant time,
/// byte array. Provides a safe [`Eq`] implementation that runs in constant time,
/// which is useful for implementing Message Authentication Codes (MACs) based
/// on universal hashing.
#[derive(Clone)]
pub struct Output<N: ArrayLength<u8>> {
bytes: GenericArray<u8, N>,
pub struct Output<U: UniversalHash> {
bytes: GenericArray<u8, U::BlockSize>,
}

impl<N> Output<N>
impl<U> Output<U>
where
N: ArrayLength<u8>,
U: UniversalHash,
{
/// Create a new `Block`.
pub fn new(bytes: GenericArray<u8, N>) -> Output<N> {
/// Create a new [`Output`] block.
pub fn new(bytes: Block<U>) -> Output<U> {
Output { bytes }
}

/// Get the inner `GenericArray` this type wraps
pub fn into_bytes(self) -> GenericArray<u8, N> {
/// Get the inner [`GenericArray`] this type wraps
pub fn into_bytes(self) -> Block<U> {
self.bytes
}
}

impl<N> From<GenericArray<u8, N>> for Output<N>
impl<U> From<Block<U>> for Output<U>
where
N: ArrayLength<u8>,
U: UniversalHash,
{
fn from(bytes: GenericArray<u8, N>) -> Self {
fn from(bytes: Block<U>) -> Self {
Output { bytes }
}
}

impl<'a, N> From<&'a GenericArray<u8, N>> for Output<N>
impl<'a, U> From<&'a Block<U>> for Output<U>
where
N: ArrayLength<u8>,
U: UniversalHash,
{
fn from(bytes: &'a GenericArray<u8, N>) -> Self {
fn from(bytes: &'a Block<U>) -> Self {
bytes.clone().into()
}
}

impl<N> ConstantTimeEq for Output<N>
impl<U> ConstantTimeEq for Output<U>
where
N: ArrayLength<u8>,
U: UniversalHash,
{
fn ct_eq(&self, other: &Self) -> Choice {
self.bytes.ct_eq(&other.bytes)
}
}

impl<N> PartialEq for Output<N>
impl<U> PartialEq for Output<U>
where
N: ArrayLength<u8>,
U: UniversalHash,
{
fn eq(&self, x: &Output<N>) -> bool {
fn eq(&self, x: &Output<U>) -> bool {
self.ct_eq(x).unwrap_u8() == 1
}
}

impl<N: ArrayLength<u8>> Eq for Output<N> {}
impl<U: UniversalHash> Eq for Output<U> {}

/// Error type for when the `Output` of a `UniversalHash`
/// Error type for when the [`Output`] of a [`UniversalHash`]
/// is not equal to the expected value.
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub struct Error;
Expand Down

0 comments on commit dcbdbbc

Please sign in to comment.