/rust/registry/src/index.crates.io-1949cf8c6b5b557f/polyval-0.6.2/src/backend/autodetect.rs
Line | Count | Source |
1 | | //! Autodetection for CPU intrinsics, with fallback to the "soft" backend when |
2 | | //! they are unavailable. |
3 | | |
4 | | use crate::{backend::soft, Key, Tag}; |
5 | | use core::mem::ManuallyDrop; |
6 | | use universal_hash::{ |
7 | | consts::U16, |
8 | | crypto_common::{BlockSizeUser, KeySizeUser}, |
9 | | KeyInit, Reset, UniversalHash, |
10 | | }; |
11 | | |
12 | | #[cfg(all(target_arch = "aarch64", polyval_armv8))] |
13 | | use super::pmull as intrinsics; |
14 | | |
15 | | #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] |
16 | | use super::clmul as intrinsics; |
17 | | |
18 | | #[cfg(all(target_arch = "aarch64", polyval_armv8))] |
19 | | cpufeatures::new!(mul_intrinsics, "aes"); // `aes` implies PMULL |
20 | | |
21 | | #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] |
22 | | cpufeatures::new!(mul_intrinsics, "pclmulqdq"); |
23 | | |
24 | | /// **POLYVAL**: GHASH-like universal hash over GF(2^128). |
25 | | pub struct Polyval { |
26 | | inner: Inner, |
27 | | token: mul_intrinsics::InitToken, |
28 | | } |
29 | | |
30 | | union Inner { |
31 | | intrinsics: ManuallyDrop<intrinsics::Polyval>, |
32 | | soft: ManuallyDrop<soft::Polyval>, |
33 | | } |
34 | | |
35 | | impl KeySizeUser for Polyval { |
36 | | type KeySize = U16; |
37 | | } |
38 | | |
39 | | impl Polyval { |
40 | | /// Initialize POLYVAL with the given `H` field element and initial block |
41 | 1.59k | pub fn new_with_init_block(h: &Key, init_block: u128) -> Self { |
42 | 1.59k | let (token, has_intrinsics) = mul_intrinsics::init_get(); |
43 | | |
44 | 1.59k | let inner = if has_intrinsics { |
45 | 1.59k | Inner { |
46 | 1.59k | intrinsics: ManuallyDrop::new(intrinsics::Polyval::new_with_init_block( |
47 | 1.59k | h, init_block, |
48 | 1.59k | )), |
49 | 1.59k | } |
50 | | } else { |
51 | 0 | Inner { |
52 | 0 | soft: ManuallyDrop::new(soft::Polyval::new_with_init_block(h, init_block)), |
53 | 0 | } |
54 | | }; |
55 | | |
56 | 1.59k | Self { inner, token } |
57 | 1.59k | } |
58 | | } |
59 | | |
60 | | impl KeyInit for Polyval { |
61 | | /// Initialize POLYVAL with the given `H` field element |
62 | 0 | fn new(h: &Key) -> Self { |
63 | 0 | Self::new_with_init_block(h, 0) |
64 | 0 | } |
65 | | } |
66 | | |
67 | | impl BlockSizeUser for Polyval { |
68 | | type BlockSize = U16; |
69 | | } |
70 | | |
71 | | impl UniversalHash for Polyval { |
72 | 6.31k | fn update_with_backend( |
73 | 6.31k | &mut self, |
74 | 6.31k | f: impl universal_hash::UhfClosure<BlockSize = Self::BlockSize>, |
75 | 6.31k | ) { |
76 | | unsafe { |
77 | 6.31k | if self.token.get() { |
78 | 6.31k | f.call(&mut *self.inner.intrinsics) |
79 | | } else { |
80 | 0 | f.call(&mut *self.inner.soft) |
81 | | } |
82 | | } |
83 | 6.31k | } <polyval::backend::autodetect::Polyval as universal_hash::UniversalHash>::update_with_backend::<<ghash::GHash as universal_hash::UniversalHash>::update_with_backend::GHashClosure<universal_hash::UniversalHash::update::Ctx<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>> Line | Count | Source | 72 | 6.31k | fn update_with_backend( | 73 | 6.31k | &mut self, | 74 | 6.31k | f: impl universal_hash::UhfClosure<BlockSize = Self::BlockSize>, | 75 | 6.31k | ) { | 76 | | unsafe { | 77 | 6.31k | if self.token.get() { | 78 | 6.31k | f.call(&mut *self.inner.intrinsics) | 79 | | } else { | 80 | 0 | f.call(&mut *self.inner.soft) | 81 | | } | 82 | | } | 83 | 6.31k | } |
Unexecuted instantiation: <polyval::backend::autodetect::Polyval as universal_hash::UniversalHash>::update_with_backend::<_> |
84 | | |
85 | | /// Get POLYVAL result (i.e. computed `S` field element) |
86 | 1.28k | fn finalize(self) -> Tag { |
87 | | unsafe { |
88 | 1.28k | if self.token.get() { |
89 | 1.28k | ManuallyDrop::into_inner(self.inner.intrinsics).finalize() |
90 | | } else { |
91 | 0 | ManuallyDrop::into_inner(self.inner.soft).finalize() |
92 | | } |
93 | | } |
94 | 1.28k | } |
95 | | } |
96 | | |
97 | | impl Clone for Polyval { |
98 | 1.28k | fn clone(&self) -> Self { |
99 | 1.28k | let inner = if self.token.get() { |
100 | 1.28k | Inner { |
101 | 1.28k | intrinsics: ManuallyDrop::new(unsafe { (*self.inner.intrinsics).clone() }), |
102 | 1.28k | } |
103 | | } else { |
104 | 0 | Inner { |
105 | 0 | soft: ManuallyDrop::new(unsafe { (*self.inner.soft).clone() }), |
106 | 0 | } |
107 | | }; |
108 | | |
109 | 1.28k | Self { |
110 | 1.28k | inner, |
111 | 1.28k | token: self.token, |
112 | 1.28k | } |
113 | 1.28k | } |
114 | | } |
115 | | |
116 | | impl Reset for Polyval { |
117 | 0 | fn reset(&mut self) { |
118 | 0 | if self.token.get() { |
119 | 0 | unsafe { (*self.inner.intrinsics).reset() } |
120 | | } else { |
121 | 0 | unsafe { (*self.inner.soft).reset() } |
122 | | } |
123 | 0 | } |
124 | | } |