#![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)]
#[cfg(feature = "std")]
extern crate std;
pub use universal_hash;
use universal_hash::{
consts::{U16, U32},
crypto_common::{BlockSizeUser, KeySizeUser},
generic_array::GenericArray,
KeyInit, UniversalHash,
};
mod backend;
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft),
target_feature = "avx2", // Fuzz tests bypass AVX2 autodetection code
any(fuzzing, test)
))]
mod fuzz;
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft)
))]
use crate::backend::autodetect::State;
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft)
)))]
use crate::backend::soft::State;
pub const KEY_SIZE: usize = 32;
pub const BLOCK_SIZE: usize = 16;
pub type Key = universal_hash::Key<Poly1305>;
pub type Block = universal_hash::Block<Poly1305>;
pub type Tag = universal_hash::Block<Poly1305>;
#[derive(Clone)]
pub struct Poly1305 {
state: State,
}
impl KeySizeUser for Poly1305 {
type KeySize = U32;
}
impl KeyInit for Poly1305 {
fn new(key: &Key) -> Poly1305 {
Poly1305 {
state: State::new(key),
}
}
}
impl BlockSizeUser for Poly1305 {
type BlockSize = U16;
}
impl UniversalHash for Poly1305 {
fn update_with_backend(
&mut self,
f: impl universal_hash::UhfClosure<BlockSize = Self::BlockSize>,
) {
self.state.update_with_backend(f);
}
fn finalize(self) -> Tag {
self.state.finalize()
}
}
impl Poly1305 {
pub fn compute_unpadded(mut self, data: &[u8]) -> Tag {
for chunk in data.chunks(BLOCK_SIZE) {
if chunk.len() == BLOCK_SIZE {
let block = GenericArray::from_slice(chunk);
self.state.compute_block(block, false);
} else {
let mut block = Block::default();
block[..chunk.len()].copy_from_slice(chunk);
block[chunk.len()] = 1;
self.state.compute_block(&block, true)
}
}
self.state.finalize()
}
}
opaque_debug::implement!(Poly1305);
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft),
target_feature = "avx2", // Fuzz tests bypass AVX2 autodetection code
any(fuzzing, test)
))]
pub use crate::fuzz::fuzz_avx2;