Skip to content

fix(serdes): decode usize as u64 on 32-bit targets (wasm32 verifier)#328

Open
pauldelucia wants to merge 1 commit into
PolyhedraZK:mainfrom
pauldelucia:serdes-wasm32-fix
Open

fix(serdes): decode usize as u64 on 32-bit targets (wasm32 verifier)#328
pauldelucia wants to merge 1 commit into
PolyhedraZK:mainfrom
pauldelucia:serdes-wasm32-fix

Conversation

@pauldelucia
Copy link
Copy Markdown

Problem

exp_serde_for_number!(usize, 8) expands to a usize::from_le_bytes([u8; 8]) call. On 32-bit targets (wasm32-unknown-unknown, wasm32-wasi) usize::from_le_bytes takes [u8; 4], so the macro fails to compile.

Fix

Replace the macro call for usize with a hand-written ExpSerde impl that:

  • Serializes as a fixed-width 8 bytes (matches current 64-bit behavior — wire format unchanged).
  • Deserializes by reading 8 bytes into a u64, then try_from-ing to usize. Values above usize::MAX on 32-bit (4 GiB) return SerdeError::DeserializeError.

Why

Proofs are produced on 64-bit hosts; the wire format already stores usize as 8 bytes. This is purely a 32-bit-decode fix — no change to what 64-bit consumers see.

Motivation: unblocks browser / mobile WASM verifier builds that need to deserialize Circuit<C> and Proof on wasm32-unknown-unknown.

Scope

  • 18 lines in serdes/src/serdes.rs.
  • No wire-format change.
  • No test fixtures need regenerating.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the macro-based serialization for usize with a manual implementation to ensure it always serializes as a fixed-width 64-bit integer, which enables cross-platform compatibility between 64-bit provers and 32-bit WASM verifiers. A review comment suggests simplifying this manual implementation by delegating to the existing u64 serialization logic to improve idiomaticity and reduce code duplication.

Comment thread serdes/src/serdes.rs Outdated
Comment on lines +41 to +50
fn serialize_into<W: Write>(&self, mut writer: W) -> SerdeResult<()> {
writer.write_all(&(*self as u64).to_le_bytes())?;
Ok(())
}
fn deserialize_from<R: Read>(mut reader: R) -> SerdeResult<Self> {
let mut buffer = [0u8; 8];
reader.read_exact(&mut buffer)?;
let v = u64::from_le_bytes(buffer);
usize::try_from(v).map_err(|_| SerdeError::DeserializeError)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The manual implementation of ExpSerde for usize can be simplified by delegating to the u64 implementation. This is more idiomatic, reduces code duplication, and matches the pattern used for the bool implementation later in this file. It correctly preserves the 8-byte wire format and the try_from check for 32-bit targets.

    fn serialize_into<W: Write>(&self, writer: W) -> SerdeResult<()> {
        (*self as u64).serialize_into(writer)
    }
    fn deserialize_from<R: Read>(reader: R) -> SerdeResult<Self> {
        let v = u64::deserialize_from(reader)?;
        usize::try_from(v).map_err(|_| SerdeError::DeserializeError)
    }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — delegated to u64::ExpSerde in 6a9e39e.

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<C>` and `Proof` on wasm32-unknown-unknown for browser/mobile full-GKR verification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant