Skip to content

Commit c5974e6

Browse files
committed
Prove strict decode error surfaces
1 parent a25a8aa commit c5974e6

4 files changed

Lines changed: 84 additions & 0 deletions

File tree

docs/RELEASE_EVIDENCE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ The release gate runs:
7474
when installed, requiring `wasm-simd128` active encode/decode reporting and
7575
Standard plus URL-safe deterministic length sweeps, independent scalar
7676
reference encode checks, malformed-input rejection, and round trips
77+
- strict decode public-surface evidence through
78+
`standard_family_decode_surfaces_cover_tails_and_padding` and
79+
`standard_family_decode_error_surfaces_match_scalar`, proving Standard and
80+
URL-safe padded/unpadded slice, clear-tail, stack-buffer, vec, and secret
81+
helpers match the scalar reference for accepted input and rejected input
82+
while clear-tail APIs wipe caller buffers on errors
7783
- wasm simd128 browser smoke evidence through
7884
`scripts/check_wasm_browser_dispatch.sh`, which executes the same wasm32
7985
smoke module in a Chromium-family browser when installed or when

docs/SIMD_ADMISSION.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ encoded length: `standard_family_decode_surfaces_cover_tails_and_padding`
6666
checks `decode_slice`, `decode_slice_clear_tail`, stack buffers, and alloc
6767
helpers against the scalar reference across fixed-block thresholds, short
6868
inputs, non-block tails, and padded or unpadded input.
69+
Malformed Standard and URL-safe strict decode inputs are pinned by
70+
`standard_family_decode_error_surfaces_match_scalar`, which checks the same
71+
public surfaces against scalar error shapes and verifies clear-tail buffer
72+
wiping on rejected input.
6973

7074
## Wasm Posture Decision
7175

scripts/validate-simd-admission.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,9 @@ if ! grep -F -q "fn standard_family_decode_surfaces_cover_tails_and_padding()" s
174174
exit 1
175175
fi
176176

177+
if ! grep -F -q "fn standard_family_decode_error_surfaces_match_scalar()" src/decode_surface_tests.rs; then
178+
echo "simd admission: missing Standard-family malformed decode surface evidence" >&2
179+
exit 1
180+
fi
181+
177182
echo "simd admission: AVX-512 VBMI, AVX2, SSSE3/SSE4.1, NEON, and wasm simd128 encode/decode admission gate ok"

src/decode_surface_tests.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,49 @@ where
5454
}
5555
}
5656

57+
fn assert_standard_family_decode_error_surface_matches_scalar<A, const PAD: bool>(input: &[u8])
58+
where
59+
A: Alphabet,
60+
{
61+
let engine = Engine::<A, PAD>::new();
62+
let mut slice_output = [0x55; 512];
63+
let mut clear_tail_output = [0xaa; 512];
64+
let mut scalar_output = [0xcc; 512];
65+
66+
let scalar_err = scalar::scalar_reference_decode_slice::<A, PAD>(input, &mut scalar_output)
67+
.expect_err("malformed fixture must fail through the scalar reference");
68+
let slice_err = engine
69+
.decode_slice(input, &mut slice_output)
70+
.expect_err("malformed fixture must fail through decode_slice");
71+
let clear_tail_err = engine
72+
.decode_slice_clear_tail(input, &mut clear_tail_output)
73+
.expect_err("malformed fixture must fail through decode_slice_clear_tail");
74+
let buffer_err = engine
75+
.decode_buffer::<512>(input)
76+
.expect_err("malformed fixture must fail through decode_buffer");
77+
78+
assert_eq!(slice_err, scalar_err);
79+
assert_eq!(clear_tail_err, scalar_err);
80+
assert_eq!(buffer_err, scalar_err);
81+
assert!(
82+
clear_tail_output.iter().all(|byte| *byte == 0),
83+
"decode_slice_clear_tail must wipe the caller buffer on error"
84+
);
85+
86+
#[cfg(feature = "alloc")]
87+
{
88+
let vec_err = engine
89+
.decode_vec(input)
90+
.expect_err("malformed fixture must fail through decode_vec");
91+
let secret_err = engine
92+
.decode_secret(input)
93+
.expect_err("malformed fixture must fail through decode_secret");
94+
95+
assert_eq!(vec_err, scalar_err);
96+
assert_eq!(secret_err, scalar_err);
97+
}
98+
}
99+
57100
#[test]
58101
fn standard_family_decode_surfaces_cover_tails_and_padding() {
59102
let mut input = [0; 193];
@@ -68,3 +111,29 @@ fn standard_family_decode_surfaces_cover_tails_and_padding() {
68111
assert_standard_family_decode_surface_matches_scalar::<UrlSafe, false>(input);
69112
}
70113
}
114+
115+
#[test]
116+
fn standard_family_decode_error_surfaces_match_scalar() {
117+
for input in [
118+
b"!!!!".as_slice(),
119+
b"AAAA!",
120+
b"AA=A",
121+
b"Zh==",
122+
b"Zm9v$g==",
123+
b"AAAA====",
124+
] {
125+
assert_standard_family_decode_error_surface_matches_scalar::<Standard, true>(input);
126+
}
127+
128+
for input in [b"Z".as_slice(), b"Zg=", b"Zg==", b"Zm9v$g", b"Zh"] {
129+
assert_standard_family_decode_error_surface_matches_scalar::<Standard, false>(input);
130+
}
131+
132+
for input in [b"AA+A".as_slice(), b"AA/A", b"AA=A", b"Zh==", b"AAAA!"] {
133+
assert_standard_family_decode_error_surface_matches_scalar::<UrlSafe, true>(input);
134+
}
135+
136+
for input in [b"Z".as_slice(), b"AA+A", b"AA/A", b"Zg=", b"Zh"] {
137+
assert_standard_family_decode_error_surface_matches_scalar::<UrlSafe, false>(input);
138+
}
139+
}

0 commit comments

Comments
 (0)