Skip to main content

base64_ng/simd/
static_token.rs

1//! Static SIMD capability for deployments without runtime CPU probing.
2
3use core::marker::PhantomData;
4
5use crate::runtime::{Backend, OperationKind};
6use crate::{Alphabet, DecodeError, EncodeError, Standard, UrlSafe};
7
8/// Non-forgeable, thread-bound proof that a static SIMD backend passed its KAT.
9///
10/// The token bypasses runtime CPU probing only. It does not bypass bounds,
11/// canonicality, backend health, quarantine, or reporting. Kernel operations
12/// are added to this contract by the architecture admission commits that
13/// follow Commit 24.
14///
15/// The raw-pointer marker deliberately makes this value neither `Send` nor
16/// `Sync`; deployment evidence applies to the thread that constructed it.
17///
18/// ```compile_fail
19/// let token = base64_ng::StaticBackendToken::for_compiled_target().unwrap();
20/// std::thread::spawn(move || drop(token));
21/// ```
22#[derive(Debug)]
23pub struct StaticBackendToken {
24    backend: Backend,
25    generation: usize,
26    _thread_bound: PhantomData<*mut ()>,
27}
28
29impl StaticBackendToken {
30    /// Selects the strongest backend proven by compile-time target features.
31    ///
32    /// Returns `None` when the build lacks a complete feature bundle,
33    /// pointer-width atomics, or a passing known-answer test.
34    #[must_use]
35    pub fn for_compiled_target() -> Option<Self> {
36        let backend = compiled_backend()?;
37        Self::admit(backend, false)
38    }
39
40    /// Constructs a token from deployment-supplied backend evidence.
41    ///
42    /// # Safety
43    ///
44    /// Before calling, the deployment must prove that this thread's CPU and OS
45    /// vector state support every feature returned by
46    /// [`Backend::required_cpu_features`], that the ABI preserves the required
47    /// vector state, and that migration cannot move this thread to an
48    /// incompatible CPU. A false attestation can execute an unsupported
49    /// instruction during the mandatory KAT and terminate the process.
50    #[must_use]
51    pub unsafe fn assume_supported(backend: Backend) -> Option<Self> {
52        if backend_matches_target(backend) {
53            Self::admit(backend, true)
54        } else {
55            None
56        }
57    }
58
59    /// Returns the exact backend represented by this token.
60    #[must_use]
61    pub const fn backend(&self) -> Backend {
62        self.backend
63    }
64
65    /// Returns the health generation borrowed by this token.
66    #[must_use]
67    pub const fn health_generation(&self) -> usize {
68        self.generation
69    }
70
71    /// Returns whether quarantine and generation state still validate it.
72    ///
73    /// This is an admission snapshot, not synchronous cancellation. An
74    /// invocation that already observed a healthy generation may finish while
75    /// another thread quarantines that backend.
76    #[must_use]
77    pub fn is_valid(&self) -> bool {
78        let encode = crate::v2::backend_health::snapshot(OperationKind::Encode, self.backend);
79        let decode = crate::v2::backend_health::snapshot(OperationKind::StrictDecode, self.backend);
80        encode.state == crate::BackendHealthState::Healthy
81            && decode.state == crate::BackendHealthState::Healthy
82            && encode.generation == self.generation
83            && decode.generation == self.generation
84    }
85
86    /// Encodes with the statically admitted Standard-alphabet backend.
87    ///
88    /// Commits 25, 26, and 29 enable direct SSSE3/SSE4.1, AVX2, AVX-512 VBMI,
89    /// and little-endian `AArch64` NEON execution. Other token backends, or a
90    /// token invalidated by quarantine, use the scalar encoder.
91    /// The `checked-backend` feature applies the same per-call redundant
92    /// scalar comparison and quarantine policy as automatic dispatch.
93    pub fn encode_standard<const PAD: bool>(
94        &self,
95        input: &[u8],
96        output: &mut [u8],
97    ) -> Result<usize, EncodeError> {
98        self.encode::<Standard, PAD>(input, output)
99    }
100
101    /// Encodes with the statically admitted URL-safe-alphabet backend.
102    ///
103    /// Commits 25, 26, and 29 enable direct SSSE3/SSE4.1, AVX2, AVX-512 VBMI,
104    /// and little-endian `AArch64` NEON execution. Other token backends, or a
105    /// token invalidated by quarantine, use the scalar encoder.
106    /// The `checked-backend` feature applies the same per-call redundant
107    /// scalar comparison and quarantine policy as automatic dispatch.
108    pub fn encode_url_safe<const PAD: bool>(
109        &self,
110        input: &[u8],
111        output: &mut [u8],
112    ) -> Result<usize, EncodeError> {
113        self.encode::<UrlSafe, PAD>(input, output)
114    }
115
116    /// Decodes strict Standard Base64 with the statically admitted backend.
117    ///
118    /// Commits 27, 28, and 29 enable direct SSSE3/SSE4.1, AVX2, AVX-512 VBMI,
119    /// and little-endian `AArch64` NEON execution. Invalid input retains the
120    /// ordinary strict decoder's exact diagnostics. Direct SIMD blocks are
121    /// whole-input prevalidated, but short scalar fallbacks retain the ordinary
122    /// decoder's partial-output-on-error behavior.
123    pub fn decode_standard<const PAD: bool>(
124        &self,
125        input: &[u8],
126        output: &mut [u8],
127    ) -> Result<usize, DecodeError> {
128        self.decode::<Standard, PAD>(input, output)
129    }
130
131    /// Decodes strict URL-safe Base64 with the statically admitted backend.
132    ///
133    /// Commits 27, 28, and 29 enable direct SSSE3/SSE4.1, AVX2, AVX-512 VBMI,
134    /// and little-endian `AArch64` NEON execution. Invalid input retains the
135    /// ordinary strict decoder's exact diagnostics. Direct SIMD blocks are
136    /// whole-input prevalidated, but short scalar fallbacks retain the ordinary
137    /// decoder's partial-output-on-error behavior.
138    pub fn decode_url_safe<const PAD: bool>(
139        &self,
140        input: &[u8],
141        output: &mut [u8],
142    ) -> Result<usize, DecodeError> {
143        self.decode::<UrlSafe, PAD>(input, output)
144    }
145
146    fn encode<A: Alphabet, const PAD: bool>(
147        &self,
148        input: &[u8],
149        output: &mut [u8],
150    ) -> Result<usize, EncodeError> {
151        if !self.is_valid() {
152            return crate::scalar::encode_slice::<A, PAD>(input, output);
153        }
154        #[cfg(all(
155            feature = "checked-backend",
156            any(
157                target_arch = "x86",
158                target_arch = "x86_64",
159                all(target_arch = "aarch64", target_endian = "little")
160            )
161        ))]
162        match self.backend {
163            Backend::Avx512Vbmi | Backend::Avx2 | Backend::Ssse3Sse41 => {
164                return crate::encode_backend::encode_checked::<A, PAD>(
165                    self.backend,
166                    input,
167                    output,
168                );
169            }
170            #[cfg(all(target_arch = "aarch64", target_endian = "little"))]
171            Backend::Neon => {
172                return crate::encode_backend::encode_checked::<A, PAD>(
173                    self.backend,
174                    input,
175                    output,
176                );
177            }
178            _ => {}
179        }
180        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
181        match self.backend {
182            Backend::Avx512Vbmi => {
183                return crate::simd::encode_slice_avx512::<A, PAD>(input, output);
184            }
185            Backend::Avx2 => return crate::simd::encode_slice_avx2::<A, PAD>(input, output),
186            Backend::Ssse3Sse41 => {
187                return crate::simd::encode_slice_ssse3_sse41::<A, PAD>(input, output);
188            }
189            _ => {}
190        }
191        #[cfg(all(target_arch = "aarch64", target_endian = "little"))]
192        if self.backend == Backend::Neon {
193            return crate::simd::encode_slice_neon::<A, PAD>(input, output);
194        }
195        crate::scalar::encode_slice::<A, PAD>(input, output)
196    }
197
198    fn decode<A: Alphabet, const PAD: bool>(
199        &self,
200        input: &[u8],
201        output: &mut [u8],
202    ) -> Result<usize, DecodeError> {
203        if !self.is_valid() {
204            return crate::scalar::decode_slice::<A, PAD>(input, output);
205        }
206        #[cfg(all(
207            feature = "checked-backend",
208            any(
209                target_arch = "x86",
210                target_arch = "x86_64",
211                all(target_arch = "aarch64", target_endian = "little")
212            )
213        ))]
214        match self.backend {
215            Backend::Avx512Vbmi | Backend::Avx2 | Backend::Ssse3Sse41 => {
216                return crate::decode_backend::decode_checked::<A, PAD>(
217                    self.backend,
218                    input,
219                    output,
220                );
221            }
222            #[cfg(all(target_arch = "aarch64", target_endian = "little"))]
223            Backend::Neon => {
224                return crate::decode_backend::decode_checked::<A, PAD>(
225                    self.backend,
226                    input,
227                    output,
228                );
229            }
230            _ => {}
231        }
232        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
233        match self.backend {
234            Backend::Avx512Vbmi => {
235                return crate::simd::decode_slice_avx512::<A, PAD>(input, output);
236            }
237            Backend::Avx2 => return crate::simd::decode_slice_avx2::<A, PAD>(input, output),
238            Backend::Ssse3Sse41 => {
239                return crate::simd::decode_slice_ssse3_sse41::<A, PAD>(input, output);
240            }
241            _ => {}
242        }
243        #[cfg(all(target_arch = "aarch64", target_endian = "little"))]
244        if self.backend == Backend::Neon {
245            return crate::simd::decode_slice_neon::<A, PAD>(input, output);
246        }
247        crate::scalar::decode_slice::<A, PAD>(input, output)
248    }
249
250    fn admit(backend: Backend, deployment_attested: bool) -> Option<Self> {
251        let admit_operation = |operation| {
252            if deployment_attested {
253                crate::v2::backend_health::admit_deployment_attested(operation, backend)
254            } else {
255                crate::v2::backend_health::admit(operation, backend)
256            }
257        };
258        if !cfg!(target_has_atomic = "ptr")
259            || !admit_operation(OperationKind::Encode)
260            || !admit_operation(OperationKind::StrictDecode)
261        {
262            return None;
263        }
264        let encode = crate::v2::backend_health::snapshot(OperationKind::Encode, backend);
265        let decode = crate::v2::backend_health::snapshot(OperationKind::StrictDecode, backend);
266        if encode.generation != decode.generation {
267            return None;
268        }
269        Some(Self {
270            backend,
271            generation: encode.generation,
272            _thread_bound: PhantomData,
273        })
274    }
275}
276
277fn compiled_backend() -> Option<Backend> {
278    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
279    {
280        if cfg!(all(
281            target_feature = "avx512f",
282            target_feature = "avx512bw",
283            target_feature = "avx512vl",
284            target_feature = "avx512vbmi"
285        )) {
286            return Some(Backend::Avx512Vbmi);
287        }
288        if cfg!(target_feature = "avx2") {
289            return Some(Backend::Avx2);
290        }
291        if cfg!(all(target_feature = "ssse3", target_feature = "sse4.1")) {
292            return Some(Backend::Ssse3Sse41);
293        }
294    }
295    #[cfg(all(target_arch = "aarch64", target_endian = "little"))]
296    if cfg!(target_feature = "neon") {
297        return Some(Backend::Neon);
298    }
299    #[cfg(target_arch = "wasm32")]
300    if cfg!(target_feature = "simd128") {
301        return Some(Backend::WasmSimd128);
302    }
303    None
304}
305
306const fn backend_matches_target(backend: Backend) -> bool {
307    match backend {
308        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
309        Backend::Avx512Vbmi | Backend::Avx2 | Backend::Ssse3Sse41 => true,
310        #[cfg(all(target_arch = "aarch64", target_endian = "little"))]
311        Backend::Neon => true,
312        #[cfg(target_arch = "wasm32")]
313        Backend::WasmSimd128 => true,
314        _ => false,
315    }
316}