Skip to content

WASM and freestanding target support (browser, edge, embedded) #119

Description

@koko1123

Motivation

Compiling to WebAssembly is the thing Zig does that Rust does adequately and TypeScript cannot do at all, and it is the clearest technical differentiator eth.zig has over alloy.rs for application developers. A browser dApp that wants real signing today either ships a large JS bundle or a Rust/wasm-bindgen blob with a JS glue layer; a wasm32-freestanding eth.zig is a small, dependency-free .wasm with a plain C-shaped import surface.

The same work unlocks two other targets we get for free: wasm32-wasi for edge runtimes (Cloudflare Workers, Fastly, Deno Deploy), and bare-metal freestanding for hardware-wallet and secure-enclave firmware -- an audience that cannot use any existing Ethereum library because they all assume an allocator, a heap, and libc.

The actual blockers

This is not a "flip the target flag" change. Concretely, today:

  1. Vendored C is unconditional. build.zig calls addXkcp on every module and adds C source files for libsecp256k1, XKCP, blst, and c-kzg with no way to opt out. link_libc = true is set unconditionally.
  2. There is no backend selection. src/secp256k1.zig delegates sign, recover, and derivePublicKey straight to secp256k1_c (lines 140, 195, 256); src/keccak.zig imports keccak_xkcp.zig directly. Pure-Zig paths exist -- keccak_optimized.zig was fixed and vector-verified in keccak_optimized.zig: pure-Zig fallback produces wrong digests #80, and secp256k1.zig already carries the GLV endomorphism scaffolding -- but nothing selects them.
  3. Transports assume a hosted OS. http_transport, ws_transport, and sse_transport need std.Io, sockets, and TLS. On wasm32-freestanding there is no socket; the host provides fetch.

Scope

  • Build options: -Dcrypto-backend=c|zig (default c on hosted targets, forced zig on freestanding) and -Dtransports=true|false. Gate addXkcp and the C source additions behind the backend option, and set link_libc accordingly.
  • Backend indirection: a comptime switch in secp256k1.zig and keccak.zig choosing the C or pure-Zig implementation. No behavior change on the default path -- the existing benchmarks must be byte-identical and speed-identical after this refactor, which is the main review criterion.
  • Freestanding module set: root.zig should compile with transports excluded, exposing primitives, hex, RLP, ABI, keccak, secp256k1, transaction signing, EIP-712, HD wallets, and keystore. KZG (blst) stays out of the freestanding build -- it is C-only and blob transactions are not a browser use case.
  • Allocator discipline: audit for hidden std.heap.page_allocator / libc-allocator assumptions on the freestanding paths; the caller supplies the allocator, and a fixed-buffer allocator must work.
  • CI: build legs for wasm32-freestanding, wasm32-wasi, and one bare aarch64-freestanding to keep the no-libc path honest. Run the unit suite under wasm32-wasi where the test runner supports it.
  • Demo: examples/wasm/ -- an HTML page that loads the .wasm and signs a transaction in-browser with no JS crypto dependency. This is the artifact that makes the case; ship it with the issue.

Relationship to #118

The C ABI issue and this one converge: the export fn surface from src/c_api.zig is exactly the right wasm export surface, and both need the same caller-allocates discipline. Land the backend selection here first, since the C ABI work can otherwise proceed independently.

Pointers

build.zig (addXkcp at line 14 and the addCSourceFile calls from line 201), src/secp256k1.zig, src/keccak.zig, src/keccak_optimized.zig (the verified pure-Zig Keccak from #80). Zig's std.crypto.ecc.Secp256k1 is already imported in secp256k1.zig and is a correct-but-slower fallback -- document the expected performance delta of the pure-Zig backend in bench/RESULTS.md rather than hiding it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions