|
47 | 47 | #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
|
48 | 48 | #![warn(missing_docs, rust_2018_idioms)]
|
49 | 49 |
|
50 |
| -pub use subtle; |
51 |
| - |
52 | 50 | pub mod field;
|
53 |
| -pub mod tag; |
54 |
| - |
55 |
| -use self::field::Element; |
56 |
| -pub use self::tag::Tag; |
57 | 51 |
|
58 |
| -// TODO(tarcieri): runtime selection of CLMUL vs soft backend when both are available |
59 |
| -use self::field::backend::M128i; |
| 52 | +pub use universal_hash; |
60 | 53 |
|
61 |
| -/// Size of a POLYVAL block (128-bits) |
62 |
| -pub const BLOCK_SIZE: usize = 16; |
| 54 | +use core::convert::TryInto; |
| 55 | +use universal_hash::generic_array::{typenum::U16, GenericArray}; |
| 56 | +use universal_hash::{Output, UniversalHash}; |
63 | 57 |
|
64 |
| -/// POLYVAL blocks (16-bytes) |
65 |
| -pub type Block = [u8; BLOCK_SIZE]; |
| 58 | +// TODO(tarcieri): runtime selection of CLMUL vs soft backend when both are available |
| 59 | +use field::backend::M128i; |
66 | 60 |
|
67 | 61 | /// **POLYVAL**: GHASH-like universal hash over GF(2^128).
|
68 | 62 | #[allow(non_snake_case)]
|
69 | 63 | #[derive(Clone)]
|
70 | 64 | #[repr(align(16))]
|
71 | 65 | pub struct Polyval {
|
72 | 66 | /// GF(2^128) field element input blocks are multiplied by
|
73 |
| - H: Element<M128i>, |
| 67 | + H: field::Element<M128i>, |
74 | 68 |
|
75 | 69 | /// Field element representing the computed universal hash
|
76 |
| - S: Element<M128i>, |
| 70 | + S: field::Element<M128i>, |
77 | 71 | }
|
78 | 72 |
|
79 |
| -impl Polyval { |
| 73 | +impl UniversalHash for Polyval { |
| 74 | + type KeySize = U16; |
| 75 | + type OutputSize = U16; |
| 76 | + |
80 | 77 | /// Initialize POLYVAL with the given `H` field element
|
81 |
| - pub fn new(h: Block) -> Self { |
| 78 | + fn new(h: &GenericArray<u8, U16>) -> Self { |
82 | 79 | Self {
|
83 |
| - H: Element::from_bytes(h), |
84 |
| - S: Element::from_bytes(Block::default()), |
| 80 | + H: field::Element::from_bytes(h.as_slice().try_into().unwrap()), |
| 81 | + S: field::Element::default(), |
85 | 82 | }
|
86 | 83 | }
|
87 | 84 |
|
88 | 85 | /// Input a field element `X` to be authenticated into POLYVAL.
|
89 |
| - pub fn input_block(&mut self, x: Block) { |
90 |
| - // "The sum of any two elements in the field is the result of XORing them." |
91 |
| - // -- RFC 8452 Section 3 |
92 |
| - let sum = self.S + Element::from_bytes(x); |
93 |
| - self.S = sum * self.H; |
94 |
| - } |
95 |
| - |
96 |
| - /// Input data into POLYVAL, first padding it to the block size |
97 |
| - /// ala the `right_pad_to_multiple_of_16_bytes()` function described in |
98 |
| - /// RFC 8452 Section 4: |
99 |
| - /// <https://tools.ietf.org/html/rfc8452#section-4> |
100 |
| - pub fn input_padded(&mut self, data: &[u8]) { |
101 |
| - for chunk in data.chunks(BLOCK_SIZE) { |
102 |
| - if chunk.len() == BLOCK_SIZE { |
103 |
| - // TODO(tarcieri): replace with `TryInto` in Rust 1.34+ |
104 |
| - self.input_block(unsafe { *(chunk.as_ptr() as *const Block) }); |
105 |
| - } else { |
106 |
| - let mut padded_block = [0u8; BLOCK_SIZE]; |
107 |
| - padded_block[..chunk.len()].copy_from_slice(chunk); |
108 |
| - self.input_block(padded_block); |
109 |
| - } |
110 |
| - } |
| 86 | + fn update_block(&mut self, x: &GenericArray<u8, U16>) { |
| 87 | + let x = field::Element::from_bytes(x.as_slice().try_into().unwrap()); |
| 88 | + self.S = (self.S + x) * self.H; |
111 | 89 | }
|
112 | 90 |
|
113 |
| - /// Process input blocks in a chained manner |
114 |
| - pub fn chain_block(mut self, x: Block) -> Self { |
115 |
| - self.input_block(x); |
116 |
| - self |
| 91 | + /// Reset internal state |
| 92 | + fn reset(&mut self) { |
| 93 | + self.S = field::Element::default(); |
117 | 94 | }
|
118 | 95 |
|
119 | 96 | /// Get POLYVAL result (i.e. computed `S` field element)
|
120 |
| - pub fn result(self) -> Tag { |
121 |
| - Tag::new(self.S.to_bytes()) |
| 97 | + fn result(self) -> Output<U16> { |
| 98 | + Output::new(GenericArray::from(self.S.to_bytes())) |
122 | 99 | }
|
123 | 100 | }
|
0 commit comments