1#![no_std]
2#![doc = include_str!("../README.md")]
3#![doc(
4 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
5 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
6)]
7
8pub use universal_hash;
9
10use core::fmt::{self, Debug};
11use universal_hash::{
12 KeyInit, UhfClosure, UniversalHash,
13 common::{BlockSizeUser, KeySizeUser},
14 consts::{U16, U32},
15};
16
17mod backend;
18
19#[cfg(all(
20 any(target_arch = "x86", target_arch = "x86_64"),
21 not(poly1305_backend = "soft"),
22 target_feature = "avx2", any(fuzzing, test)
24))]
25mod fuzz;
26
27#[cfg(all(
28 any(target_arch = "x86", target_arch = "x86_64"),
29 not(poly1305_backend = "soft")
30))]
31use crate::backend::autodetect::State;
32
33#[cfg(not(all(
34 any(target_arch = "x86", target_arch = "x86_64"),
35 not(poly1305_backend = "soft")
36)))]
37use crate::backend::soft::State;
38
39pub const KEY_SIZE: usize = 32;
41
42pub const BLOCK_SIZE: usize = 16;
44
45pub type Key = universal_hash::Key<Poly1305>;
47
48pub type Block = universal_hash::Block<Poly1305>;
50
51pub type Tag = universal_hash::Block<Poly1305>;
53
54#[derive(Clone)]
61pub struct Poly1305 {
62 state: State,
63}
64
65impl KeySizeUser for Poly1305 {
66 type KeySize = U32;
67}
68
69impl KeyInit for Poly1305 {
70 fn new(key: &Key) -> Poly1305 {
72 Poly1305 {
73 state: State::new(key),
74 }
75 }
76}
77
78impl BlockSizeUser for Poly1305 {
79 type BlockSize = U16;
80}
81
82impl UniversalHash for Poly1305 {
83 fn update_with_backend(&mut self, f: impl UhfClosure<BlockSize = Self::BlockSize>) {
84 self.state.update_with_backend(f);
85 }
86
87 fn finalize(self) -> Tag {
89 self.state.finalize()
90 }
91}
92
93impl Poly1305 {
94 #[must_use]
98 pub fn compute_unpadded(mut self, data: &[u8]) -> Tag {
99 let (blocks, remaining) = Block::slice_as_chunks(data);
100
101 for block in blocks {
102 self.state.compute_block(block, false);
103 }
104
105 if !remaining.is_empty() {
106 let mut block = Block::default();
107 block[..remaining.len()].copy_from_slice(remaining);
108 block[remaining.len()] = 1;
109 self.state.compute_block(&block, true);
110 }
111
112 self.state.finalize()
113 }
114}
115
116impl Debug for Poly1305 {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 f.debug_struct("Poly1305").finish_non_exhaustive()
119 }
120}
121
122#[cfg(all(
123 any(target_arch = "x86", target_arch = "x86_64"),
124 not(poly1305_backend = "soft"),
125 target_feature = "avx2", any(fuzzing, test)
127))]
128pub use crate::fuzz::fuzz_avx2;