Skip to content

Commit a7872e7

Browse files
committed
Const-evaluate runtime alphabet mapping
1 parent f50f567 commit a7872e7

12 files changed

Lines changed: 41 additions & 21 deletions

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
from the static smoke-test document.
1414
- Made `Alphabet::ENCODE` the sole encoding definition used by `Engine`, so
1515
hand-written, inconsistent, or stateful `Alphabet::encode` overrides cannot
16-
produce API-, input-length-, or backend-dependent output.
16+
produce API-, input-length-, or backend-dependent output. Standard-family
17+
mapper selection is an associated compile-time constant rather than a
18+
repeated scalar-call prefix scan.
19+
- Made the API-audit policy gate check stable semantic fragments instead of a
20+
Markdown line-wrapping-sensitive sentence.
1721
- Added daily and manually dispatchable RustSec and cargo-deny advisory checks
1822
for the workspace and isolated dudect, fuzz, and performance lockfiles.
1923
- Updated async cleanup and release-evidence documentation.

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ the Chromium wasm smoke gate requires a success attribute created only by
6161
runtime execution rather than matching a token present in static HTML.
6262
Runtime encoding also treats `Alphabet::ENCODE` as its sole output definition,
6363
so custom `Alphabet::encode` overrides cannot create API-, input-length-, or
64-
backend-dependent output. A dedicated daily workflow checks all maintained
65-
lockfiles for newly published advisories.
64+
backend-dependent output. Standard-family mapper selection is compile-time and
65+
does not add a repeated prefix scan to scalar calls. A dedicated daily workflow
66+
checks all maintained lockfiles for newly published advisories.
6667
The stronger RISC-V RVV proof and admission review is scheduled for `1.3.9`;
6768
until then, RISC-V remains QEMU-tested scalar/fallback-only. The workspace
6869
crate family stays version-aligned at `1.3.8`.
@@ -708,8 +709,9 @@ assert_eq!(DotSlash::decode(b'.'), Some(0));
708709
For custom tables, `Engine` uses a deliberately conservative fixed 64-entry
709710
scan for every emitted Base64 byte to avoid secret-indexed table lookups.
710711
Standard and URL-safe table families use crate-owned optimized arithmetic
711-
mappers. For very large payloads and custom alphabets, benchmark this tradeoff
712-
before using them on untrusted high-volume traffic.
712+
mappers selected as an associated compile-time constant. For very large
713+
payloads and custom alphabets, benchmark this tradeoff before using them on
714+
untrusted high-volume traffic.
713715

714716
If you implement `Alphabet` manually, `Engine` still treats `ENCODE` as the
715717
sole encoding definition and does not call an overridden `encode` method.

docs/API_AUDIT.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ Decision rationale:
252252
`Engine` APIs read that table through crate-owned mappers and never invoke a
253253
hand-written `Alphabet::encode` override. The method remains available as a
254254
low-level direct-call helper for API compatibility, but it cannot alter
255-
`Engine` output.
255+
`Engine` output. Standard-family mapper classification is evaluated as an
256+
associated compile-time constant, not repeated for each scalar call.
256257
- Manual `Alphabet` implementations can override `encode` or `decode`. An
257258
`encode` override affects only direct calls to that low-level helper; a
258259
`decode` override affects the normal strict `Engine` path. The `ct` module

docs/CRATE_VERSION_MATRIX.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ guarded read-all vector growth and wipes every replaced allocation before
1313
deallocation. The Chromium-family wasm evidence gate now requires a
1414
runtime-created DOM success attribute that is proven absent from the static
1515
HTML source. Runtime encoding now uses `Alphabet::ENCODE` as its sole output
16-
definition, so custom overrides cannot create backend-dependent output, and
17-
scheduled advisory monitoring covers all maintained lockfiles. SIMD admission
18-
scope, unsafe boundaries, and the zero-dependency core posture remain
19-
unchanged. The stronger RISC-V RVV proof and backend-admission review moves to
20-
`1.3.9`.
16+
definition, so custom overrides cannot create backend-dependent output;
17+
standard-family mapper selection is compile-time rather than repeated per
18+
scalar call. Scheduled advisory monitoring covers all maintained lockfiles.
19+
SIMD admission scope, unsafe boundaries, and the zero-dependency core posture
20+
remain unchanged. The stronger RISC-V RVV proof and backend-admission review
21+
moves to `1.3.9`.
2122

2223
| Crate | Version | Publish In 1.3.8 | Cargo |
2324
| --- | --- | --- | --- |

docs/PLAN.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,10 @@ inside the `1.3.x` line if they remain evidence-gated and do not weaken the
11781178
- Require Chromium-family wasm smoke evidence to contain a runtime-created DOM
11791179
success attribute that is absent from the static test document.
11801180
- Make `Alphabet::ENCODE` the sole encoding definition used by runtime and
1181-
const `Engine` APIs so custom overrides cannot affect output.
1181+
const `Engine` APIs so custom overrides cannot affect output, with
1182+
standard-family mapper selection evaluated at compile time.
1183+
- Keep API-audit policy checks semantic and insensitive to Markdown line
1184+
wrapping.
11821185
- Add daily and manually dispatchable advisory monitoring for workspace and
11831186
isolated tool lockfiles.
11841187
- Preserve core encode/decode behavior, SIMD admission scope, unsafe

release-crates.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ previous_version = "1.3.7"
77
version = "1.3.8"
88
change = "code"
99
publish = true
10-
reason = "Publishes the 1.3.8 security-hardening patch with guarded Tokio read-all growth, runtime-only browser wasm evidence, table-authoritative custom alphabet encoding, and scheduled advisory monitoring; the stronger RISC-V RVV review moves to 1.3.9."
10+
reason = "Publishes the 1.3.8 security-hardening patch with guarded Tokio read-all growth, runtime-only browser wasm evidence, compile-time-selected table-authoritative custom alphabet encoding, and scheduled advisory monitoring; the stronger RISC-V RVV review moves to 1.3.9."
1111

1212
[crates."base64-ng-sanitization"]
1313
previous_version = "1.3.7"

release-notes/RELEASE_NOTES_1.3.8.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ the `base64-ng` workspace.
1313
- Hardened Chromium-family wasm runtime evidence so success requires a
1414
runtime-created DOM attribute that is absent from the static HTML source.
1515
- Made `Alphabet::ENCODE` the sole output definition used by `Engine`, so
16-
hand-written or stateful `Alphabet::encode` overrides cannot alter output.
16+
hand-written or stateful `Alphabet::encode` overrides cannot alter output;
17+
standard-family mapper selection is evaluated at compile time.
18+
- Hardened the API-audit policy gate against harmless Markdown line wrapping.
1719
- Added daily and manually dispatchable RustSec and cargo-deny monitoring for
1820
the workspace and isolated tool lockfiles.
1921
- Updated async cleanup, release evidence, migration, and dependency examples.

scripts/validate-api-audit.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ for required_text in \
3535
"try_into_exposed_string" \
3636
"Encode-to-back and decode-to-front contracts" \
3737
"define_alphabet!" \
38-
"The \`ct\` module scans" \
38+
"\`encode\` override affects only direct calls" \
39+
"\`decode\` override affects the normal strict \`Engine\` path" \
3940
"\`Alphabet::ENCODE\` directly" \
4041
"Keep the custom-alphabet timing contract documented" \
4142
"Padded \`DecoderReader\` stops after terminal padding" \

src/alphabet.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ pub(crate) enum RuntimeEncodeMapper {
361361
}
362362

363363
impl RuntimeEncodeMapper {
364-
pub(crate) fn for_alphabet<A: Alphabet>() -> Self {
364+
pub(crate) const fn for_alphabet<A: Alphabet>() -> Self {
365365
const STANDARD_PREFIX: [u8; 62] =
366366
*b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
367367

@@ -393,6 +393,12 @@ impl RuntimeEncodeMapper {
393393
}
394394
}
395395

396+
pub(crate) struct RuntimeEncodeMapperFor<A: Alphabet>(core::marker::PhantomData<A>);
397+
398+
impl<A: Alphabet> RuntimeEncodeMapperFor<A> {
399+
pub(crate) const VALUE: RuntimeEncodeMapper = RuntimeEncodeMapper::for_alphabet::<A>();
400+
}
401+
396402
#[inline]
397403
const fn encode_alphabet_value(value: u8, encode: &[u8; 64]) -> u8 {
398404
let mut output = 0;

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pub use alphabet::{
155155
Alphabet, AlphabetError, Bcrypt, Crypt, Standard, UrlSafe, decode_alphabet_byte,
156156
validate_alphabet,
157157
};
158-
pub(crate) use alphabet::{RuntimeEncodeMapper, encode_base64_value};
158+
pub(crate) use alphabet::{RuntimeEncodeMapperFor, encode_base64_value};
159159
pub use buffers::{DecodedBuffer, EncodedBuffer, ExposedDecodedArray, ExposedEncodedArray};
160160
#[cfg(feature = "alloc")]
161161
pub use buffers::{ExposedSecretString, ExposedSecretVec, SecretBuffer};

0 commit comments

Comments
 (0)