Skip to content

Commit 129e7ea

Browse files
committed
Admit AVX2 encode backend
1 parent 022213c commit 129e7ea

23 files changed

Lines changed: 502 additions & 369 deletions

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ Implemented now:
7171
- Bounded Kani proof harnesses that run on Rust `1.90.0` with
7272
`cargo-kani 0.67.0`.
7373
- Constant-time assembly evidence generation for reviewer inspection.
74-
- Runtime-dispatched std `x86`/`x86_64` SSSE3/SSE4.1 fixed-block encode for
75-
Standard and URL-safe alphabets behind the SIMD admission boundary, with
76-
scalar fallback for unsupported CPUs, `no_std`, custom alphabets, tails,
77-
padding, in-place encode, and decode.
74+
- Runtime-dispatched std `x86`/`x86_64` AVX2 fixed-block encode, falling back
75+
to SSSE3/SSE4.1 and then scalar, for Standard and URL-safe alphabets behind
76+
the SIMD admission boundary. Unsupported CPUs, `no_std`, custom alphabets,
77+
tails, padding, in-place encode, and decode stay scalar.
7878
- Optional `base64-ng-sanitization` companion crate for applications that
7979
already admit `sanitization` and want direct CT decode helpers into
8080
clear-on-drop secret containers.
@@ -87,7 +87,7 @@ Implemented now:
8787

8888
Planned behind admission evidence:
8989

90-
- Additional admitted AVX2, AVX-512, ARM NEON, wasm `simd128`, custom alphabet,
90+
- Additional admitted AVX-512, ARM NEON, wasm `simd128`, custom alphabet,
9191
in-place, and decode fast paths after the SIMD admission evidence is
9292
complete. Default builds and unsupported runtime CPUs remain scalar.
9393
- Full async streaming wrappers only after the `tokio` feature passes the
@@ -107,7 +107,7 @@ Planned behind admission evidence:
107107
| MSRV | Rust `1.90.0` |
108108
| Runtime dependencies | Zero external crates |
109109
| Unsafe policy | Scalar encode/decode remains safe Rust; audited unsafe is limited to volatile wiping, CT comparison/barrier helpers, and the reviewed SIMD boundary |
110-
| Active backend | Scalar by default; std x86/x86_64 SSSE3/SSE4.1 encode when `simd` is enabled and runtime CPU probing passes |
110+
| Active backend | Scalar by default; std x86/x86_64 AVX2 encode preferred, then SSSE3/SSE4.1 encode, when `simd` is enabled and runtime CPU probing passes |
111111
| Strict decoding | Default, canonical, no whitespace |
112112
| Legacy compatibility | Explicit opt-in APIs |
113113
| Constant-time posture | Constant-time-oriented scalar validation/decode with isolated dudect-style timing evidence; no formal cryptographic guarantee |
@@ -949,9 +949,9 @@ Security commitments:
949949
dead-store elimination and are ordered before the cleanup boundary on
950950
supported native architectures. Constant-time comparison, byte accumulation,
951951
CT scan, and CT result-gate hardening remain audited in `src/ct/`.
952-
- Unsafe SIMD remains isolated under `src/simd/`; the admitted SSSE3/SSE4.1
953-
encode path is std runtime-probed and all non-admitted backends remain
954-
prototype-only.
952+
- Unsafe SIMD remains isolated under `src/simd/`; the admitted AVX2 and
953+
SSSE3/SSE4.1 encode paths are std runtime-probed and all non-admitted
954+
backends remain prototype-only.
955955
- Local checks verify that `allow(unsafe_code)` is confined to the volatile
956956
wipe helpers and SIMD boundary, every unsafe function is inventoried, and
957957
every unsafe block has a nearby `SAFETY:` explanation. Architecture intrinsics,

docs/PLAN.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -680,12 +680,14 @@ Current `1.1.x` checkpoint state:
680680
unsupported CPUs, `no_std`, custom alphabets, tails, padding, in-place encode,
681681
and decode. Runtime reports and admission evidence now identify
682682
SSSE3/SSE4.1 encode as the admitted backend.
683+
- `1.1.7`: admitted std-only x86/x86_64 AVX2 encode dispatch above the existing
684+
SSSE3/SSE4.1 encode path for Standard and URL-safe alphabet families. The
685+
active path uses runtime CPU probing, fixed 24-byte vector blocks, YMM/XMM
686+
cleanup, and scalar fallback for unsupported CPUs, `no_std`, custom
687+
alphabets, tails, padding, in-place encode, and decode.
683688

684689
Planned checkpoints to reach `1.2.0` fully working encode acceleration:
685690

686-
- `1.1.7`: admit std-only x86/x86_64 AVX2 encode dispatch with the same public
687-
API coverage and fallback requirements. Runtime priority must be explicit
688-
and tested, for example AVX2 above SSSE3/SSE4.1 when both are available.
689691
- `1.1.8`: admit AVX-512 VBMI encode dispatch only if hardware evidence,
690692
generated assembly, register cleanup, fallback behavior, and benchmark data
691693
are complete. If AVX-512 evidence is incomplete, keep AVX-512 as a real

docs/RELEASE_EVIDENCE.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,13 @@ The release gate runs:
113113
- reserved SIMD feature-bundle compile checks for AVX2, AVX-512 VBMI,
114114
SSSE3/SSE4.1, NEON, and wasm `simd128` under `no_std` when the corresponding
115115
Rust targets are installed
116-
- backend evidence capture for runtime backend reporting, admitted SSSE3/SSE4.1
117-
encode dispatch when supported, and inactive SIMD prototype scalar-equivalence
118-
output for remaining candidates
119-
- SIMD admission policy for the current release series, with SSSE3/SSE4.1
120-
encode admitted only for std x86/x86_64 Standard and URL-safe alphabets, no
121-
decode acceleration, and no SIMD performance claims without complete local
122-
benchmark evidence
116+
- backend evidence capture for runtime backend reporting, admitted AVX2 or
117+
SSSE3/SSE4.1 encode dispatch when supported, and inactive SIMD prototype
118+
scalar-equivalence output for remaining candidates
119+
- SIMD admission policy for the current release series, with AVX2 and
120+
SSSE3/SSE4.1 encode admitted only for std x86/x86_64 Standard and URL-safe
121+
alphabets, no decode acceleration, and no SIMD performance claims without
122+
complete local benchmark evidence
123123
- unsafe-boundary validation that confines `allow(unsafe_code)` to the audited
124124
cleanup helpers in `src/cleanup.rs`, CT barrier/comparison helpers in
125125
`src/ct/`, and the SIMD boundary in `src/simd/`
@@ -280,9 +280,9 @@ The script runs the runtime backend-report test and the gated SIMD
280280
scalar-equivalence tests with `--nocapture`. The runtime report records
281281
`candidate_detection_mode`, which distinguishes x86/x86_64 `std` runtime CPU
282282
probing from compile-time target-feature reporting used by `no_std` and other
283-
compile-time-only targets. On CPUs with SSSE3/SSE4.1, the admitted encode path
284-
may be active for Standard and URL-safe alphabets. AVX2 and AVX-512 tests still
285-
execute inactive prototype bodies and compare them against scalar output. On
283+
compile-time-only targets. On CPUs with AVX2 or SSSE3/SSE4.1, an admitted
284+
encode path may be active for Standard and URL-safe alphabets. AVX-512 tests
285+
still execute inactive prototype bodies and compare them against scalar output. On
286286
AArch64 NEON-capable hosts, the NEON test exercises the inactive fixed-block
287287
vector prototype for Standard and URL-safe alphabets; 32-bit ARM remains
288288
scaffold evidence. Wasm `simd128` evidence is kept in
@@ -292,7 +292,7 @@ script writes
292292
`target/release-evidence/backend/MANIFEST.txt`, `runtime-backend-report.txt`,
293293
and `simd-prototype-equivalence.txt` so local CPU evidence can be archived. The
294294
manifest labels prototype-only evidence as `real-non-dispatchable` and
295-
separately records `active_backend_admitted=ssse3-sse4.1-encode`, so audit logs
295+
separately records `active_backend_admitted=avx2-or-ssse3-sse4.1-encode`, so audit logs
296296
do not confuse remaining fixed-block prototype execution with active dispatch
297297
admission.
298298

@@ -376,12 +376,12 @@ scripts/generate_simd_asm_evidence.sh
376376
```
377377

378378
On x86/x86_64 hosts, the script emits release test-harness assembly for the
379-
admitted SSSE3/SSE4.1 encode path and the AVX2 and AVX-512 VBMI prototype
380-
feature bundles, then checks for the expected byte-shuffle, byte-permute,
379+
admitted AVX2 and SSSE3/SSE4.1 encode paths and the AVX-512 VBMI prototype
380+
feature bundle, then checks for the expected byte-shuffle, byte-permute,
381381
vector-register, and cleanup instructions. On non-x86 hosts it records a skip
382382
manifest. The generated files are written to
383-
`target/release-evidence/simd-asm/`. AVX2 and AVX-512 remain inactive prototype
384-
evidence until the SIMD admission manifest names them as admitted backends.
383+
`target/release-evidence/simd-asm/`. AVX-512 remains inactive prototype
384+
evidence until the SIMD admission manifest names it as an admitted backend.
385385

386386
## Performance Evidence
387387

docs/SIMD.md

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# SIMD Admission Policy
22

3-
`base64-ng` is scalar by default and admits only one conservative accelerated
4-
path in the `1.1.x` line: std `x86`/`x86_64` SSSE3/SSE4.1 encode for Standard
5-
and URL-safe alphabet families. Future SIMD dispatch remains gated unless a
6-
complete SIMD admission evidence package lands in the same release commit as
7-
the active backend change. The crate uses `#![deny(unsafe_code)]` and permits
3+
`base64-ng` is scalar by default and admits conservative accelerated encode
4+
paths in the `1.1.x` line: std `x86`/`x86_64` AVX2 first, then SSSE3/SSE4.1,
5+
for Standard and URL-safe alphabet families. Future SIMD dispatch remains gated
6+
unless a complete SIMD admission evidence package lands in the same release
7+
commit as the active backend change. The crate uses `#![deny(unsafe_code)]` and permits
88
reviewed `allow(unsafe_code)` exceptions only for audited cleanup in
99
`src/cleanup.rs`, CT comparison, byte accumulation, CT scan, and CT result-gate
1010
helpers in `src/ct/`, and the private `src/simd/` boundary.
@@ -37,6 +37,12 @@ The SIMD roadmap separates implementation evidence from active acceleration:
3737
code after runtime CPU probing. Scalar remains the fallback for unsupported
3838
CPUs, `no_std`, custom alphabets, tails, padding, in-place encode, wrapped
3939
encode paths that select scalar fallback, and every decode path.
40+
- `1.1.7` admits std `x86`/`x86_64` AVX2 encode dispatch for Standard and
41+
URL-safe alphabet families. AVX2 is selected before SSSE3/SSE4.1 when runtime
42+
CPU probing proves `avx2`; otherwise the existing SSSE3/SSE4.1 or scalar
43+
fallback path is used. Tails, padding, custom alphabets, `no_std`, in-place
44+
encode, wrapped encode paths that select scalar fallback, and every decode
45+
path remain scalar.
4046
- `1.2.0` is the release where encode acceleration must be fully working for
4147
the admitted encode scope. Public encode APIs must dispatch to admitted
4248
encode backends when runtime policy and CPU features allow it, and must fall
@@ -71,8 +77,8 @@ runtime behavior for that line.
7177
Decode and in-place encode are still backed only by the scalar implementation.
7278
- With the `simd` feature enabled, the private dispatch scaffold detects
7379
AVX-512 VBMI, AVX2, SSSE3/SSE4.1, NEON, and wasm `simd128` candidates.
74-
Only std `x86`/`x86_64` SSSE3/SSE4.1 encode can become active; all other
75-
candidates still execute scalar code.
80+
Only std `x86`/`x86_64` AVX2 and SSSE3/SSE4.1 encode can become active; all
81+
other candidates still execute scalar code.
7682
- AVX-512 VBMI detection is reporting-only until the implementation has full
7783
admission evidence. Detection requires the planned feature bundle:
7884
`avx512f`, `avx512bw`, `avx512vl`, and `avx512vbmi`.
@@ -99,12 +105,12 @@ runtime behavior for that line.
99105
`std::is_x86_feature_detected!`; unsupported CPUs execute scalar code.
100106
Custom alphabets, tails, padding, `no_std`, in-place encode, and decode stay
101107
scalar.
102-
- An inactive AVX2 fixed-block encode prototype exists behind the SIMD boundary
103-
as real non-dispatchable vector encode evidence for Standard and URL-safe
104-
alphabets. It uses AVX2 lane-local byte shuffling, vector shifts/masks, and
108+
- AVX2 encode is admitted for std `x86`/`x86_64` Standard and URL-safe alphabet
109+
families. It uses AVX2 lane-local byte shuffling, vector shifts/masks, and
105110
byte blending for fixed 24-byte input blocks, then clears XMM/YMM state
106-
before returning. It is tested against scalar output only when AVX2 is
107-
available and is not reachable from runtime backend selection.
111+
before returning. Runtime dispatch uses `std::is_x86_feature_detected!`;
112+
unsupported CPUs fall back to SSSE3/SSE4.1 or scalar. Custom alphabets, tails,
113+
padding, `no_std`, in-place encode, and decode stay scalar.
108114
- An inactive AArch64 NEON fixed-block encode prototype exists behind the same
109115
boundary as real non-dispatchable vector encode evidence for Standard and
110116
URL-safe alphabets. It uses NEON table lookup, vector shifts/masks, and
@@ -132,8 +138,8 @@ runtime behavior for that line.
132138
current ARM builds, candidate detection is compile-time target-feature
133139
reporting. A binary compiled with `-C target-feature=+avx2` can therefore
134140
report an AVX2 candidate even if it is deployed on a CPU that cannot execute
135-
AVX2 instructions. Active SSSE3/SSE4.1 encode dispatch is std runtime-probed
136-
only; any future `no_std` SIMD activation must require an explicit
141+
AVX2 instructions. Active AVX2 and SSSE3/SSE4.1 encode dispatch is std
142+
runtime-probed only; any future `no_std` SIMD activation must require an explicit
137143
caller-side CPU contract or remain disabled where runtime probing is
138144
unavailable.
139145
- `runtime::require_backend_policy()` allows deployments to enforce scalar
@@ -157,8 +163,8 @@ runtime behavior for that line.
157163
strings suitable for CI and audit logs.
158164
- Unit tests compare dispatch behavior against the scalar reference for
159165
canonical inputs, malformed inputs, and undersized output buffers.
160-
- The `simd` feature enables only the admitted std x86/x86_64 SSSE3/SSE4.1
161-
encode path where runtime CPU probing succeeds.
166+
- The `simd` feature enables only the admitted std x86/x86_64 AVX2 and
167+
SSSE3/SSE4.1 encode paths where runtime CPU probing succeeds.
162168
- Current `1.1` development keeps every non-admitted backend scalar or
163169
prototype-only unless the SIMD admission manifest, scalar differential tests,
164170
fuzz evidence, unsafe inventory, architecture evidence, benchmark evidence,
@@ -200,31 +206,32 @@ scripts/check_backend_evidence.sh
200206

201207
This prints the runtime backend-report test and runs the gated SIMD
202208
scalar-equivalence tests with `--nocapture`, so local CPU evidence is easy to
203-
copy into release notes or issue discussion. On x86/x86_64 hosts with
209+
copy into release notes or issue discussion. On x86/x86_64 hosts with AVX2 or
204210
SSSE3/SSE4.1, the runtime report may show admitted encode acceleration as
205-
active. AVX2 and AVX-512 tests still exercise inactive fixed-block vector
206-
encode prototypes against scalar output. On AArch64 NEON-capable hosts, the
211+
active. AVX-512 tests still exercise inactive fixed-block vector encode
212+
prototypes against scalar output. On AArch64 NEON-capable hosts, the
207213
NEON test exercises the inactive fixed-block vector prototype for Standard and
208214
URL-safe alphabets; 32-bit ARM remains scaffold evidence. The script also writes
209215
`target/release-evidence/backend/MANIFEST.txt` with toolchain metadata,
210216
commands, status values, artifact checksums, and explicit
211217
`prototype_state=real-non-dispatchable` labels for prototype-only backends and
212-
`active_backend_admitted=ssse3-sse4.1-encode` for the admitted encode backend.
218+
`active_backend_admitted=avx2-or-ssse3-sse4.1-encode` for admitted encode
219+
backends.
213220

214221
Capture generated assembly evidence for x86 encode paths:
215222

216223
```sh
217224
scripts/generate_simd_asm_evidence.sh
218225
```
219226

220-
The script emits release test-harness assembly for the admitted SSSE3/SSE4.1
221-
encode path plus AVX2 and AVX-512 VBMI prototype feature bundles, then checks
222-
for expected vector and cleanup instructions. AVX2 and AVX-512 remain review
223-
evidence only; they do not activate runtime dispatch.
227+
The script emits release test-harness assembly for the admitted AVX2 and
228+
SSSE3/SSE4.1 encode paths plus the AVX-512 VBMI prototype feature bundle, then
229+
checks for expected vector and cleanup instructions. AVX-512 remains review
230+
evidence only; it does not activate runtime dispatch.
224231

225232
## Required Before SIMD Code Lands
226233

227-
Any AVX2, NEON, AVX-512, wasm `simd128`, decode, custom alphabet, in-place, or
234+
Any NEON, AVX-512, wasm `simd128`, decode, custom alphabet, in-place, or
228235
additional runtime-dispatch implementation
229236
must include:
230237

@@ -251,13 +258,13 @@ must include:
251258
backends. The gate currently requires:
252259

253260
- `ActiveBackend` to expose only `Scalar` plus the std x86/x86_64
254-
SSSE3/SSE4.1 encode variant.
255-
- `active_backend()` to return SSSE3/SSE4.1 only after std runtime CPU probing,
256-
and scalar otherwise.
257-
- No accelerated `ActiveBackend::Avx*`, `ActiveBackend::Neon`,
261+
AVX2 and SSSE3/SSE4.1 encode variants.
262+
- `active_backend()` to return AVX2 before SSSE3/SSE4.1 only after std runtime
263+
CPU probing, and scalar otherwise.
264+
- No accelerated `ActiveBackend::Avx512*`, `ActiveBackend::Neon`,
258265
`ActiveBackend::Wasm*`, or generic SIMD dispatch variants in source.
259-
- `docs/SIMD_ADMISSION.md` to record the admitted SSSE3/SSE4.1 encode scope
260-
and keep all other backends prototype-only.
266+
- `docs/SIMD_ADMISSION.md` to record the admitted AVX2 and SSSE3/SSE4.1 encode
267+
scope and keep all other backends prototype-only.
261268
- Documentation for benchmark evidence, release-note restrictions, and
262269
vector-register retention cleanup strategy to remain packaged.
263270
- The encode admission draft to remain packaged and validated before any
@@ -278,7 +285,7 @@ remain pending.
278285
- Scalar remains the fallback for every build.
279286
- Candidate detection must not imply activation; a detected candidate may still
280287
execute scalar until the accelerated backend is admitted.
281-
- The only active non-scalar backend in `1.1.6` is std x86/x86_64
288+
- The active non-scalar backends in `1.1.7` are std x86/x86_64 AVX2 encode and
282289
SSSE3/SSE4.1 encode for Standard and URL-safe alphabet families.
283290
- Prototype functions may exercise target-feature and unsafe plumbing without
284291
being eligible for dispatch.

docs/SIMD_ACTIVATION_CHECKLIST.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# SIMD Activation Checklist
22

33
This checklist is mandatory before any additional SIMD code becomes
4-
dispatchable. SSSE3/SSE4.1 encode is admitted only for std x86/x86_64 Standard
5-
and URL-safe alphabet families. AVX2, AVX-512, NEON, wasm, custom-alphabet,
6-
in-place, and decode SIMD paths remain prototype-only or scalar until their own
7-
checklist evidence is complete.
4+
dispatchable. AVX2 and SSSE3/SSE4.1 encode are admitted only for std
5+
x86/x86_64 Standard and URL-safe alphabet families. AVX-512, NEON, wasm,
6+
custom-alphabet, in-place, and decode SIMD paths remain prototype-only or
7+
scalar until their own checklist evidence is complete.
88

99
## Non-Negotiable Rule
1010

0 commit comments

Comments
 (0)