From 6a9e39e4852c1781903a6bd0dd3f849b87a58ed4 Mon Sep 17 00:00:00 2001 From: Paul DeLucia <69597248+pauldelucia@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:16:35 +0700 Subject: [PATCH] fix(serdes): usize serializes as fixed-width u64 on 32-bit targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `exp_serde_for_number!(usize, 8)` macro expands to a `usize::from_le_bytes([u8; 8])` call that fails on wasm32 (and any other 32-bit target) where `usize::from_le_bytes` takes `[u8; 4]`. Proofs are produced on 64-bit hosts, so the wire format already stores usize as 8 bytes; this change just makes the verifier decode them correctly on 32-bit targets by reading a u64 and try_from-ing to usize. Values above `usize::MAX` on 32-bit (4 GiB) decode to `SerdeError::DeserializeError`. Unblocks WASM verifier builds — the verifier needs to deserialize `Circuit` and `Proof` on wasm32-unknown-unknown for browser/mobile full-GKR verification. --- serdes/src/serdes.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/serdes/src/serdes.rs b/serdes/src/serdes.rs index 0de383403..cbf903311 100644 --- a/serdes/src/serdes.rs +++ b/serdes/src/serdes.rs @@ -32,7 +32,20 @@ impl ExpSerde for () { } exp_serde_for_number!(u64, 8); -exp_serde_for_number!(usize, 8); +// `usize` serializes as a fixed-width u64 so proofs produced on 64-bit +// hosts (prover) decode on 32-bit targets too (wasm32-unknown-unknown +// consumers — mobile, browser, any WASM verifier). The generic +// `exp_serde_for_number!(usize, 8)` macro hits an 8-vs-4 byte mismatch +// on 32-bit targets where `usize::from_le_bytes` takes `[u8; 4]`. +impl ExpSerde for usize { + fn serialize_into(&self, writer: W) -> SerdeResult<()> { + (*self as u64).serialize_into(writer) + } + fn deserialize_from(mut reader: R) -> SerdeResult { + let v = u64::deserialize_from(&mut reader)?; + usize::try_from(v).map_err(|_| SerdeError::DeserializeError) + } +} exp_serde_for_number!(u8, 1); exp_serde_for_number!(f64, 8); exp_serde_for_number!(u128, 16);