#![no_std]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
)]
#![warn(missing_docs, rust_2018_idioms)]
pub use polyval::universal_hash;
use polyval::Polyval;
use universal_hash::{
consts::U16,
crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser},
KeyInit, UhfBackend, UhfClosure, UniversalHash,
};
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
pub type Key = universal_hash::Key<GHash>;
pub type Block = universal_hash::Block<GHash>;
pub type Tag = universal_hash::Block<GHash>;
#[derive(Clone)]
pub struct GHash(Polyval);
impl KeySizeUser for GHash {
type KeySize = U16;
}
impl KeyInit for GHash {
#[inline]
fn new(h: &Key) -> Self {
let mut h = *h;
h.reverse();
#[allow(unused_mut)]
let mut h_polyval = polyval::mulx(&h);
#[cfg(feature = "zeroize")]
h.zeroize();
#[allow(clippy::let_and_return)]
let result = GHash(Polyval::new(&h_polyval));
#[cfg(feature = "zeroize")]
h_polyval.zeroize();
result
}
}
struct GHashBackend<'b, B: UhfBackend>(&'b mut B);
impl<'b, B: UhfBackend> BlockSizeUser for GHashBackend<'b, B> {
type BlockSize = B::BlockSize;
}
impl<'b, B: UhfBackend> ParBlocksSizeUser for GHashBackend<'b, B> {
type ParBlocksSize = B::ParBlocksSize;
}
impl<'b, B: UhfBackend> UhfBackend for GHashBackend<'b, B> {
fn proc_block(&mut self, x: &universal_hash::Block<B>) {
let mut x = x.clone();
x.reverse();
self.0.proc_block(&x);
}
}
impl BlockSizeUser for GHash {
type BlockSize = U16;
}
impl UniversalHash for GHash {
fn update_with_backend(&mut self, f: impl UhfClosure<BlockSize = Self::BlockSize>) {
struct GHashClosure<C: UhfClosure>(C);
impl<C: UhfClosure> BlockSizeUser for GHashClosure<C> {
type BlockSize = C::BlockSize;
}
impl<C: UhfClosure> UhfClosure for GHashClosure<C> {
fn call<B: UhfBackend<BlockSize = Self::BlockSize>>(self, backend: &mut B) {
self.0.call(&mut GHashBackend(backend));
}
}
self.0.update_with_backend(GHashClosure(f));
}
#[inline]
fn finalize(self) -> Tag {
let mut output = self.0.finalize();
output.reverse();
output
}
}
opaque_debug::implement!(GHash);