Coverage Report

Created: 2026-02-14 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}