Skip to content

Commit 6111e83

Browse files
committed
Admit AVX-512 strict decode dispatch
1 parent 8aace53 commit 6111e83

14 files changed

Lines changed: 173 additions & 73 deletions

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ Implemented now:
8484
encode helpers can use admitted fixed-block encode for their unwrapped
8585
encoding step; unsupported CPUs, `no_std`, custom alphabets, tails, padding,
8686
in-place encode, and line-ending insertion stay scalar.
87-
- Runtime-dispatched std `x86`/`x86_64` AVX2 fixed-block strict decode,
88-
falling back to SSSE3/SSE4.1 and then scalar, in the `1.3.0` working line,
89-
limited to Standard and URL-safe alphabets after whole-input scalar
90-
validation. Unsupported CPUs, `no_std`, custom alphabets, short inputs,
91-
tails, wrapped decode, legacy decode, in-place decode, and CT secret decode
92-
stay scalar.
87+
- Runtime-dispatched std `x86`/`x86_64` AVX-512 VBMI fixed-block strict
88+
decode, falling back to AVX2, then SSSE3/SSE4.1, and then scalar, in the
89+
`1.3.0` working line, limited to Standard and URL-safe alphabets after
90+
whole-input scalar validation. Unsupported CPUs, `no_std`, custom alphabets,
91+
short inputs, tails, wrapped decode, legacy decode, in-place decode, and CT
92+
secret decode stay scalar.
9393
- Optional `base64-ng-sanitization` companion crate for applications that
9494
already admit `sanitization` and want direct CT decode helpers into
9595
clear-on-drop secret containers.
@@ -102,13 +102,13 @@ Implemented now:
102102

103103
Planned behind admission evidence:
104104

105-
- Additional SIMD decode acceleration beyond AVX2 and SSSE3/SSE4.1 strict
106-
Standard and URL-safe decode only after separate `1.3.0` admission evidence
107-
is complete. The frozen first scope remains padded and unpadded strict
108-
decode only: no line wrapping, no legacy whitespace, no custom alphabets, no
109-
bcrypt/crypt profiles, and no constant-time-oriented secret decode. Default
110-
builds, unsupported runtime CPUs, `no_std`, and all out-of-scope decode
111-
surfaces remain scalar.
105+
- Additional SIMD decode acceleration beyond AVX-512 VBMI, AVX2, and
106+
SSSE3/SSE4.1 strict Standard and URL-safe decode only after separate
107+
`1.3.0` admission evidence is complete. The frozen first scope remains
108+
padded and unpadded strict decode only: no line wrapping, no legacy
109+
whitespace, no custom alphabets, no bcrypt/crypt profiles, and no
110+
constant-time-oriented secret decode. Default builds, unsupported runtime
111+
CPUs, `no_std`, and all out-of-scope decode surfaces remain scalar.
112112
- Additional admitted wasm `simd128`, custom alphabet, and in-place encode
113113
fast paths only after separate SIMD admission evidence is complete. Default
114114
builds and unsupported runtime CPUs remain scalar.

docs/RELEASE_EVIDENCE.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,10 @@ The release gate runs:
124124
prototypes
125125
- SIMD admission policy for the current release series, with AVX-512 VBMI,
126126
AVX2, SSSE3/SSE4.1, and NEON encode admitted only for std x86/x86_64 or std
127-
aarch64 Standard and URL-safe alphabets, AVX2 and SSSE3/SSE4.1 strict decode
128-
admitted only for std x86/x86_64 Standard and URL-safe alphabets, and no
129-
SIMD performance claims without complete local benchmark evidence
127+
aarch64 Standard and URL-safe alphabets, AVX-512 VBMI, AVX2, and
128+
SSSE3/SSE4.1 strict decode admitted only for std x86/x86_64 Standard and
129+
URL-safe alphabets, and no SIMD performance claims without complete local
130+
benchmark evidence
130131
- unsafe-boundary validation that confines `allow(unsafe_code)` to the audited
131132
cleanup helpers in `src/cleanup.rs`, CT barrier/comparison helpers in
132133
`src/ct/`, and the SIMD boundary in `src/simd/`

docs/SECURITY_CONTROLS.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,12 @@ buffering unbounded frames. For secrets, collect one complete protocol frame
271271
under an application size limit and decode it with `ct::CtEngine`.
272272
Normal SIMD decode admission is not a secret-decoding claim. The `1.3.0`
273273
decode acceleration scope is limited to strict Standard and URL-safe
274-
interoperability decode. The admitted decode backends are std x86/x86_64 AVX2
275-
for full 32-byte encoded blocks and SSSE3/SSE4.1 for full 16-byte encoded
276-
blocks after scalar whole-input validation; every other decode backend and the
277-
`base64_ng::ct` constant-time-oriented decode path remain scalar unless a
278-
separate formal side-channel evidence package admits otherwise.
274+
interoperability decode. The admitted decode backends are std x86/x86_64
275+
AVX-512 VBMI for full 64-byte encoded blocks, AVX2 for full 32-byte encoded
276+
blocks, and SSSE3/SSE4.1 for full 16-byte encoded blocks after scalar
277+
whole-input validation; every other decode backend and the `base64_ng::ct`
278+
constant-time-oriented decode path remain scalar unless a separate formal
279+
side-channel evidence package admits otherwise.
279280
Deployments that require the most conservative side-channel posture should
280281
combine `base64_ng::ct` with
281282
`runtime::BackendPolicy::HighAssuranceScalarOnly` so sensitive decode paths

docs/SIMD.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,13 @@ The SIMD roadmap separates implementation evidence from active acceleration:
7373
- `1.3.0` is the first release that may activate SIMD decode acceleration if
7474
the `1.2.x` decode evidence line is complete and the encode acceleration line
7575
has remained stable.
76-
- The admitted `1.3.0` decode backends are std `x86`/`x86_64` AVX2 first,
77-
then SSSE3/SSE4.1 strict decode for Standard and URL-safe alphabet families.
78-
They validate the complete input with the scalar decoder first so public
79-
error shape and indexes remain scalar-compatible, then use fixed 32-byte
80-
AVX2 or fixed 16-byte SSSE3/SSE4.1 encoded blocks where possible. Tails and
81-
every unsupported decode surface remain scalar.
76+
- The admitted `1.3.0` decode backends are std `x86`/`x86_64` AVX-512 VBMI
77+
first, then AVX2, then SSSE3/SSE4.1 strict decode for Standard and URL-safe
78+
alphabet families. They validate the complete input with the scalar decoder
79+
first so public error shape and indexes remain scalar-compatible, then use
80+
fixed 64-byte AVX-512 VBMI, fixed 32-byte AVX2, or fixed 16-byte
81+
SSSE3/SSE4.1 encoded blocks where possible. Tails and every unsupported
82+
decode surface remain scalar.
8283

8384
The `1.3.0` decode scope is frozen before implementation starts: strict
8485
Standard and URL-safe decode only, padded and unpadded, through the normal
@@ -108,8 +109,9 @@ runtime behavior for that line.
108109
- The scalar implementation is the reference behavior.
109110
- Encode and normal strict decode entry points pass through internal backend
110111
boundaries. In-place encode remains scalar-only. Strict decode may use the
111-
admitted AVX2 or SSSE3/SSE4.1 backend on std x86/x86_64 builds with the
112-
`simd` feature; every unsupported decode surface still falls back to scalar.
112+
admitted AVX-512 VBMI, AVX2, or SSSE3/SSE4.1 backend on std x86/x86_64
113+
builds with the `simd` feature; every unsupported decode surface still falls
114+
back to scalar.
113115
- With the `simd` feature enabled, the private dispatch scaffold detects
114116
AVX-512 VBMI, AVX2, SSSE3/SSE4.1, NEON, and wasm `simd128` candidates.
115117
Only std `x86`/`x86_64` AVX-512 VBMI, AVX2, SSSE3/SSE4.1, and std
@@ -123,11 +125,11 @@ runtime behavior for that line.
123125
admitted encode boundary. For wrapped encode, SIMD applies only to the
124126
unwrapped Base64 staging step; line-ending insertion remains scalar.
125127
- Public strict `decode_slice`, `decode_slice_clear_tail`, `decode_buffer`, and
126-
alloc strict decode helpers route through the decode boundary. AVX2 decode
127-
applies only to full 32-byte encoded blocks after scalar whole-input
128-
validation and falls back to SSSE3/SSE4.1 or scalar for shorter inputs.
129-
Legacy decode, wrapped decode, in-place decode, CT secret decode, custom
130-
alphabets, short inputs, and tails remain scalar.
128+
alloc strict decode helpers route through the decode boundary. AVX-512 VBMI
129+
decode applies only to full 64-byte encoded blocks after scalar whole-input
130+
validation and falls back to AVX2, SSSE3/SSE4.1, or scalar for shorter
131+
inputs. Legacy decode, wrapped decode, in-place decode, CT secret decode,
132+
custom alphabets, short inputs, and tails remain scalar.
131133
- AVX-512 VBMI encode is admitted for std `x86`/`x86_64` Standard and URL-safe
132134
alphabet families. It uses AVX-512 lane-local byte shuffling, vector
133135
shifts/masks, and VBMI byte permutes over the alphabet table for fixed
@@ -136,7 +138,7 @@ runtime behavior for that line.
136138
`avx512bw`, `avx512vl`, and `avx512vbmi`; unsupported CPUs fall back to
137139
AVX2, SSSE3/SSE4.1, or scalar. Custom alphabets, tails, padding, `no_std`,
138140
in-place encode, line-ending insertion, and every decode surface outside the
139-
separate AVX2/SSSE3/SSE4.1 strict decode admission stay scalar.
141+
separate AVX-512/AVX2/SSSE3/SSE4.1 strict decode admission stay scalar.
140142
- Runtime backend identifiers expose their required CPU feature bundles through
141143
`runtime::Backend::required_cpu_features()`.
142144
- Runtime backend reports include `candidate_required_cpu_features=[...]` in
@@ -152,23 +154,23 @@ runtime behavior for that line.
152154
clears XMM registers before returning. Runtime dispatch uses
153155
`std::is_x86_feature_detected!`; unsupported CPUs execute scalar code.
154156
Custom alphabets, tails, padding, `no_std`, in-place encode, line-ending
155-
insertion, and every decode surface outside the separate AVX2/SSSE3/SSE4.1
156-
strict decode admission stay scalar.
157+
insertion, and every decode surface outside the separate
158+
AVX-512/AVX2/SSSE3/SSE4.1 strict decode admission stay scalar.
157159
- AVX2 encode is admitted for std `x86`/`x86_64` Standard and URL-safe alphabet
158160
families. It uses AVX2 lane-local byte shuffling, vector shifts/masks, and
159161
byte blending for fixed 24-byte input blocks, then clears XMM/YMM state
160162
before returning. Runtime dispatch uses `std::is_x86_feature_detected!`;
161163
unsupported CPUs fall back to SSSE3/SSE4.1 or scalar. Custom alphabets, tails,
162164
padding, `no_std`, in-place encode, line-ending insertion, and every decode
163-
surface outside the separate AVX2/SSSE3/SSE4.1 strict decode admission stay
164-
scalar.
165+
surface outside the separate AVX-512/AVX2/SSSE3/SSE4.1 strict decode
166+
admission stay scalar.
165167
- AArch64 NEON encode is admitted for std `aarch64` Standard and URL-safe
166168
alphabet families. It uses NEON table lookup, vector shifts/masks, and
167169
byte-select alphabet mapping for fixed 12-byte input blocks, then clears used
168170
NEON registers before returning. NEON is mandatory for the admitted AArch64
169171
target. Custom alphabets, tails, padding, 32-bit `arm+neon`, `no_std`,
170172
in-place encode, line-ending insertion, and every decode surface outside the
171-
separate AVX2/SSSE3/SSE4.1 strict decode admission stay scalar.
173+
separate AVX-512/AVX2/SSSE3/SSE4.1 strict decode admission stay scalar.
172174
- An inactive wasm `simd128` fixed-block encode prototype exists behind the
173175
same boundary as real non-dispatchable vector encode evidence for Standard
174176
and URL-safe alphabets. It uses wasm byte shuffling, vector shifts/masks, and
@@ -277,7 +279,7 @@ fixed-block decode prototypes, and
277279
`active_backend_admitted=avx512-vbmi-or-avx2-or-ssse3-sse4.1-or-neon-encode`
278280
for admitted encode backends. The runtime report also exposes
279281
`BackendReport::active_decode_backend()` so release evidence can distinguish
280-
the narrower AVX2/SSSE3/SSE4.1 strict decode admission from the active encode
282+
the narrower AVX-512/AVX2/SSSE3/SSE4.1 strict decode admission from the active encode
281283
backend.
282284

283285
Capture generated assembly evidence for x86 encode paths:
@@ -354,8 +356,8 @@ remain pending.
354356
- The active non-scalar backends in the `1.2.x` encode line are std
355357
x86/x86_64 AVX-512 VBMI encode, AVX2 encode, SSSE3/SSE4.1 encode, and std
356358
aarch64 NEON encode for Standard and URL-safe alphabet families. The
357-
`1.3.0` decode admission is separate: std x86/x86_64 AVX2 first, then
358-
SSSE3/SSE4.1 strict decode only.
359+
`1.3.0` decode admission is separate: std x86/x86_64 AVX-512 VBMI first,
360+
then AVX2, then SSSE3/SSE4.1 strict decode only.
359361
- Prototype functions may exercise target-feature and unsafe plumbing without
360362
being eligible for dispatch.
361363
- Runtime CPU detection may be used only behind `std`.

docs/SIMD_ADMISSION.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,27 @@ only for backends named in this file and the release gate.
77
## Current Admission State
88

99
- Admitted backends: AVX-512 VBMI encode, AVX2 encode, SSSE3/SSE4.1 encode,
10-
NEON encode, AVX2 strict decode, and SSSE3/SSE4.1 strict decode for std
11-
`x86`/`x86_64` or std `aarch64` where applicable.
10+
NEON encode, AVX-512 VBMI strict decode, AVX2 strict decode, and
11+
SSSE3/SSE4.1 strict decode for std `x86`/`x86_64` or std `aarch64` where
12+
applicable.
1213
- Active backend priority: AVX-512 VBMI, then AVX2, then SSSE3/SSE4.1 on
1314
x86/x86_64; NEON on aarch64; scalar otherwise.
1415
- Runtime activation scope: std x86/x86_64 and std aarch64 dispatch only.
15-
- Gate summary: Admitted backends: AVX-512 VBMI encode, AVX2 encode, SSSE3/SSE4.1 encode, NEON encode, AVX2 strict decode, and SSSE3/SSE4.1 strict decode.
16+
- Gate summary: Admitted backends: AVX-512 VBMI encode, AVX2 encode, SSSE3/SSE4.1 encode, NEON encode, AVX-512 VBMI strict decode, AVX2 strict decode, and SSSE3/SSE4.1 strict decode.
1617
- Gate priority: Active backend priority: AVX-512 VBMI, then AVX2, then SSSE3/SSE4.1 on x86/x86_64; NEON on aarch64.
1718
- Public performance claims: none without local benchmark evidence.
1819
- Release status: `1.2.3`; `1.2.0` admitted conservative active encode
1920
dispatch, and `1.2.3` is a dependency-sync patch for the optional
2021
sanitization companion. Active encode dispatch admits AVX-512 VBMI above
2122
AVX2 above SSSE3/SSE4.1 on x86/x86_64 and NEON on aarch64 for Standard and
22-
URL-safe alphabet families. In the `1.3.0` working line, AVX2 strict decode
23-
is admitted above SSSE3/SSE4.1 strict decode for std `x86`/`x86_64`
24-
Standard and URL-safe alphabet families when a full 32-byte encoded block is
25-
present; SSSE3/SSE4.1 covers full 16-byte encoded blocks. AVX-512 VBMI,
26-
NEON, custom alphabets, in-place decode, wrapped decode, legacy decode, CT
27-
secret decode, `no_std`, and wasm `simd128` decode remain scalar or
28-
prototype-only. Wrapped encode may use admitted fixed-block encode for its
23+
URL-safe alphabet families. In the `1.3.0` working line, AVX-512 VBMI strict
24+
decode is admitted above AVX2 and SSSE3/SSE4.1 strict decode for std
25+
`x86`/`x86_64` Standard and URL-safe alphabet families when a full 64-byte
26+
encoded block is present; AVX2 covers full 32-byte encoded blocks and
27+
SSSE3/SSE4.1 covers full 16-byte encoded blocks. NEON, custom alphabets,
28+
in-place decode, wrapped decode, legacy decode, CT secret decode, `no_std`,
29+
and wasm `simd128` decode remain scalar or prototype-only. Wrapped encode
30+
may use admitted fixed-block encode for its
2931
unwrapped staging step; line-ending insertion remains scalar.
3032

3133
## `1.3.0` Decode Admission Scope Freeze
@@ -91,7 +93,7 @@ State labels are intentionally strict:
9193

9294
| Backend | State | Required CPU features | Evidence |
9395
| --- | --- | --- | --- |
94-
| AVX-512 VBMI | admitted backend | `avx512f`, `avx512bw`, `avx512vl`, `avx512vbmi` | std x86/x86_64 runtime-dispatched encode for Standard and URL-safe alphabet families; fixed 48-byte encode blocks use vector code only when at least one full block is present; a fixed 64-byte decode block prototype exists for tests and evidence only; public decode through AVX-512 remains prototype-only, while shorter inputs, tails, unsupported alphabets, in-place encode, line-ending insertion, and `no_std` use scalar fallback |
96+
| AVX-512 VBMI | admitted backend | `avx512f`, `avx512bw`, `avx512vl`, `avx512vbmi` | std x86/x86_64 runtime-dispatched encode and strict decode for Standard and URL-safe alphabet families; encode uses fixed 48-byte input blocks, and decode uses fixed 64-byte encoded blocks only after whole-input scalar validation preserves public error shape; shorter inputs fall back to AVX2, SSSE3/SSE4.1, or scalar, tails use scalar, and unsupported alphabets, in-place encode/decode, wrapped decode, legacy decode, CT secret decode, line-ending insertion, and `no_std` use scalar fallback |
9597
| AVX2 | admitted backend | `avx2` | std x86/x86_64 runtime-dispatched encode and strict decode for Standard and URL-safe alphabet families; encode uses fixed 24-byte input blocks, and decode uses fixed 32-byte encoded blocks only after whole-input scalar validation preserves public error shape; shorter inputs fall back to SSSE3/SSE4.1 or scalar, tails use scalar, and unsupported alphabets, in-place encode/decode, wrapped decode, legacy decode, CT secret decode, line-ending insertion, and `no_std` use scalar fallback |
9698
| SSSE3/SSE4.1 | admitted backend | `ssse3`, `sse4.1` | std x86/x86_64 runtime-dispatched encode and strict decode for Standard and URL-safe alphabet families; encode uses fixed 12-byte input blocks, and decode uses fixed 16-byte encoded blocks only after whole-input scalar validation preserves public error shape; shorter inputs, tails, unsupported alphabets, in-place encode/decode, wrapped decode, legacy decode, CT secret decode, line-ending insertion, and `no_std` use scalar fallback |
9799
| NEON | admitted backend | `neon` | std aarch64 runtime-dispatched encode for Standard and URL-safe alphabet families; fixed 12-byte encode blocks use vector code only when at least one full block is present; a fixed 16-byte decode block prototype exists for tests and evidence only; public decode through NEON remains prototype-only, while shorter inputs, tails, unsupported alphabets, 32-bit ARM, in-place encode, line-ending insertion, and `no_std` use scalar fallback |
@@ -100,7 +102,7 @@ State labels are intentionally strict:
100102
## Release Rule
101103

102104
Advertise SIMD acceleration only with the admitted backend name and scope. Do
103-
not claim wasm `simd128`, custom alphabet, in-place, AVX-512/NEON decode, or
104-
any broader decode acceleration until this manifest names those backends or API
105+
not claim wasm `simd128`, custom alphabet, in-place, NEON decode, or any
106+
broader decode acceleration until this manifest names those backends or API
105107
surfaces and links to the matching differential, fuzz, unsafe, benchmark, and
106108
release-note evidence.

0 commit comments

Comments
 (0)