← Back to blog

Published on Fri Aug 14 2026 00:00:00 GMT+0000 (Coordinated Universal Time) by Jacob Cavazos

The Problem

When you swap tokens on Base, the transaction is public. The amount is public. The tokens are public. The sender is public. The route is public. Anyone with a block explorer can see what you traded, when you traded, and how much you traded.

For retail users, this is a privacy concern. For institutional users, it is a operational risk. A treasury team settling $500,000 in stablecoins does not want the market to know their settlement timing, their token positions, or their trading patterns. A government contractor settling payments does not want competing vendors to see their cash flow. The information that leaks from public transactions is not theoretical. It is used. It is used by competitors. It is used by MEV bots. It is used by anyone who benefits from knowing what you are about to do.

The traditional solution is a custodial mixer or a centralized privacy service. You deposit funds. The service mixes them. You withdraw. The service knows everything. The service can be compromised. The service can be subpoenaed. The service can defraud you. You trade privacy for counterparty risk. The construct says trust us. The territory says verify it.

The solution we built is different. The proof is generated in the browser. The proof is generated by the user. The proof is generated on the user’s machine. No private data leaves the client. The settlement gateway receives a zero-knowledge proof. The gateway verifies the proof. The gateway cannot see the private inputs. The gateway can only verify that the proof is valid. This is the territory. The user holds the data. The user holds the keys. The user holds the proof. The gateway holds nothing but the verification.

The Architecture

The flow has three layers. Each layer is separate. Each layer does one thing.

Layer one. The EVM intent. The user signs a swap intent on Base. This is a standard EVM signature. The intent specifies the swap parameters — the tokens, the amounts, the deadline, the slippage tolerance. The intent is signed with the user’s private key. The signature is standard EIP-712. Nothing exotic. Nothing proprietary. The intent exists on Base because Base is where the liquidity is. Base is where the pools are. Base is where the execution happens.

Layer two. The ZK proof. The browser generates a zero-knowledge proof of the intent. The proof is generated entirely inside the browser’s WebAssembly runtime. The proving key is loaded into WASM. The private inputs never leave the browser. The proof is a Halo2 BN254 proof — the same proving system used by Ethereum’s Proto-Danksharding and the Privacy & Scaling Explorations group. The proof is a mathematical statement: I know a valid swap intent with these public parameters, and the private parameters satisfy the circuit constraints. The gateway can verify the proof. The gateway cannot extract the private parameters from the proof. That is the definition of zero-knowledge.

Layer three. The Hedera settlement. The proof and the signed intent are sent to the settlement gateway. The gateway verifies the proof. The gateway verifies the signature. The gateway settles the output to Hedera — to a Hedera account, a staking strategy, or a liquidity position. The settlement strategies include native staking, liquid staking, and DEX liquidity provision. The user selects the strategy. The gateway executes it.

The three layers are independent. The EVM layer handles execution. The ZK layer handles privacy. The Hedera layer handles settlement. Each layer can be audited independently. Each layer can be upgraded independently. The separation is the architecture. The separation is the security model.

Why Browser-Side Proving Matters

The proof is generated in the browser. Not on a server. Not in the cloud. Not in a trusted execution environment. In the browser. In WebAssembly. On the user’s machine.

This matters because of trust. If the proof is generated on a server, the server sees the private inputs. The server knows the amounts. The server knows the tokens. The server knows the sender. The server is a counterparty. The server can be compromised. The server can be subpoenaed. The server can log the data and sell it. The server is the construct. The server says trust us. The server is a single point of failure.

If the proof is generated in the browser, the server never sees the private inputs. The server receives a proof. The proof is zero-knowledge. The server can verify the proof. The server cannot extract the private inputs. The server is not a counterparty. The server is a verifier. The server cannot be compromised for data it does not have. The server cannot be subpoenaed for data it does not have. The server cannot log data it does not have. The user holds the data. The territory holds the data. The construct holds nothing.

The Measured Performance

We benchmarked the circuit natively on the Dell. The circuit is orkid_swap_intent. The curve is BN254. The commitment scheme is KZG. The parameter size is k=5 (32 rows). Three gates. Ten public inputs. Four privacy modes.

The numbers are measured. Not estimated. Not projected. Measured.

ModeKeygenProof GenerationProof SizeVerification
D (transparent)5ms12ms672 bytes<1ms
A (blind amounts)4ms12ms672 bytes<1ms
B (blind intent)4ms12ms672 bytes<1ms
A+B (blind all)4ms12ms672 bytes<1ms

Twelve milliseconds. Native. All four privacy modes. The privacy mode does not change the proof generation time because the circuit size does not change. The same gates run. The same rows are allocated. Only the column assignment shifts — fields move from public instance columns to private advice columns. The commitment replaces the plaintext. The computation cost is identical.

Then we ran the real benchmark. In the browser. In Chromium. In WebAssembly. Not native. Not estimated. Measured. The real WASM binary — compiled from the Rust source with SIMD enabled, reference-types stripped, optimized with wasm-opt -O4, deployed in the frontend — was loaded via Playwright and called directly. The prover function prove_orkid_swap_intent ran in the browser’s WebAssembly runtime. The numbers are from the browser. Not from a server. Not from a native binary. From the browser.

Four optimizations were applied. First, KZG parameters and proving keys are cached across calls — the setup cost is paid once, not per proof. Second, proving keys are pre-generated at build time and embedded in the WASM binary via include_bytes! — 91KB of serialized keys that deserialize in 11ms instead of computing keygen in 200ms. Third, WASM SIMD is enabled via target-feature=+simd128 for faster BN254 field arithmetic. Fourth, the final binary is optimized with wasm-opt -O4. The reference-types section is stripped from the WASM binary before wasm-bindgen processing to avoid the externref table overhead that Rust 1.82+ enables by default.

ModeProver (ms)Wall (ms)Proof (bytes)
D (transparent)4148672
A (blind amounts)3738672
B (blind intent)3839672
A+B (blind all)3841672

Thirty-eight to forty-eight milliseconds. In the browser. Init time is 11ms — the pre-embedded keys deserialize instantly. The total time from page load to first proof is under 60ms. The gateway budget is 898ms. The proof uses 5% of the budget. The proof finishes before the quote expires. The proof finishes before the user blinks.

The pre-embedded keys eliminate the cold-start penalty entirely. The proving keys for all four privacy modes are serialized at build time using a standalone keygen binary, embedded in the WASM binary as 22.8KB per mode, and deserialized at runtime using Halo2’s ProvingKey::read with SerdeFormat::Processed. The KZG parameters are 2.2KB. The total embedded key material is 91KB. The WASM binary grows from 593KB to 611KB — an 18KB increase after wasm-opt compression. The tradeoff is clear: 18KB of binary size eliminates 200ms of cold-start latency.

The native-to-browser overhead is 3-4× (12ms native, 38-48ms browser). The overhead comes from the WASM runtime lacking native threading and from the interpreted nature of WASM SIMD compared to hardware SIMD. Multi-threading via wasm-bindgen-rayon was attempted but blocked by a toolchain incompatibility: Rust 1.97 requires build-std for wasm32 atomics, but build-std + --import-memory breaks wasm-bindgen’s __heap_base detection. The overhead is real. The performance is sufficient. 38ms in the browser is fast enough for production. 38ms is faster than every market comparison we found.

The proof is 672 bytes. The entire proof artifact — proof bytes, ten public inputs, verification key hash, privacy mode — is under 5KB. The download is trivial. The upload is trivial. The proof is small enough to fit in a single HTTP request. The proof is small enough to store on-chain if needed.

How This Compares

The circuit is small. Three gates. Ten public inputs. k=5. This is not a Merkle tree membership proof. This is not an ECDSA signature verification. This is not a DKIM email verification. This is a swap intent proof — knowledge of private swap parameters with configurable privacy. The circuit is small because the problem is small. The problem is small because we designed it to be small.

The market benchmarks for browser-side ZK proof generation tell a clear story. The numbers are public. The numbers are measured.

Aleph Zero optimized Halo2 KZG in the browser for Merkle tree membership proofs. Their initial benchmark was 6,500ms. After switching to Poseidon2 and implementing multithreading, they reached 1,380ms on a ThinkPad, 420ms on an M3 MacBook Air, 790ms on an i9 ASUS. That is a Merkle tree membership proof. That is a larger circuit than ours.

Zcash Orchard Halo2 proofs in the browser take 5,446ms for a single spend. Ten spends take 23,650ms. Those are transaction proofs with shielded inputs and outputs. Those are k=14+ circuits. Much larger than ours.

Noir UltraHonk proving a p256 ECDSA signature in the browser takes 2,060ms multithreaded on an M1. UltraPlonk takes 7,960ms. That is signature verification. That is a larger circuit than ours.

Semaphore Noir in the browser takes 797ms for a single member proof. Semaphore in Circom with Groth16 takes 168ms. Those are Merkle tree membership proofs at small tree depths. Those are the closest comparison to our circuit size.

Groth16 WASM benchmarks for a 53,000-constraint Poseidon circuit take 1,196ms in snarkjs, 896ms with WebGPU acceleration. Those are larger circuits than ours.

ZKEmail Noir with a 222,000-gate DKIM verification circuit takes 6,180ms cold start with UltraHonk multithreaded. That is email verification. That is a much larger circuit than ours.

The comparison is direct. Our circuit generates a proof in 12ms native, 38-48ms in the browser. The closest market comparison — Semaphore Circom Groth16 for a small Merkle tree — takes 168ms in the browser for a comparable circuit complexity. Our proof is 3.5× faster than Semaphore’s simplest case. And we are doing more than Merkle membership — we are proving knowledge of ten structured fields with configurable privacy across four modes.

Every other market comparison is slower. Aleph Zero’s optimized Halo2 KZG takes 420-1,380ms. Noir UltraHonk for ECDSA takes 2,060ms. snarkjs Groth16 for 53k constraints takes 1,196ms. Zcash Orchard takes 5,446ms per spend. ZKEmail Noir takes 6,180ms. We are 9-162× faster than every alternative. The difference is the circuit size. We are proving knowledge of ten fields with three gates. The market benchmarks are proving Merkle tree membership, ECDSA signatures, and DKIM verification — problems that require thousands or hundreds of thousands of constraints.

This is the design choice. We did not try to prove everything. We proved the minimum. The swap intent has ten fields. Three gates verify the relationships between them. The privacy modes control which fields are revealed. The circuit is small because the problem is small. The proof is fast because the circuit is small. The proof is 672 bytes because the circuit is small.

The construct says prove everything. The territory says prove the minimum. The construct says the proof must be complex to be secure. The territory says the proof must be sufficient to be valid. The construct says browser-side proving is too slow for production. The territory says 12ms native, 38ms in the browser, 898ms budget. The proof finishes before the quote expires. The proof finishes before the user blinks.

The Privacy Modes

The circuit supports four privacy modes. The modes are documented in the public source code of the MIT-licensed orkid-circuit-wasm crate. The modes control which fields are public and which fields are private.

Mode D. Transparent. All fields are public. The proof verifies that the intent is valid. No privacy. This is the baseline. This is what a normal DEX transaction already does, but with a proof attached.

Mode A. Blind amounts. The swap amounts are private. The tokens, the sender, and the deadline are public. The proof verifies that the amounts satisfy the circuit constraints without revealing what the amounts are. The gateway knows you are swapping USDC for WETH. The gateway does not know how much.

Mode B. Blind intent. The tokens, the sender, the amounts, and the deadline are private. Only the chain ID, the settlement target hash, and the verification key hash are public. The gateway knows you are settling something. The gateway does not know what.

Mode A+B. Blind all. Maximum privacy. Everything except the chain ID, the settlement target hash, and the verification key hash is private. The gateway knows almost nothing. The gateway verifies the proof. The gateway settles. That is all.

The transition between modes is a column assignment pivot. Fields move from public instance columns to private advice columns. The instance column holds a commitment instead of a plaintext value. The commitment is a Pedersen-style commitment. The commitment is binding. The commitment is hiding. The gateway can verify the commitment. The gateway cannot open the commitment without the blinding factor. The blinding factor is private. The blinding factor never leaves the browser.

The specific circuit layout — the gates, the constraints, the layouter — is not public. The privacy modes are public. The proving system is public. The architecture is public. The circuit internals are proprietary. This is the boundary. The concept is verifiable. The implementation is ours.

The Open-Source Primitives

The ZK primitives that underpin the circuit are not new. We have shipped eight open-source ZK and physics repositories, MIT-licensed, on GitHub. These repos demonstrate the BN254 primitives, the Halo2 patterns, and the adapter architecture that the settlement circuit builds on.

negentropy is the thermodynamic scoring engine. It scores any system where information reduces entropy. It is the physics foundation. It is extracted from the proprietary FMD engine and generalized. It is open source. It is on GitHub.

zk-ballot is a Halo2 anonymous voting circuit using Poseidon hash. It demonstrates the BN254 proving primitives in a different context — anonymous voting. The same primitives power the settlement circuit.

zk-attest is a Groth16 credential attestation circuit. It is wired for Hedera HCS and HTS. It can attest settlement eligibility without revealing personally identifiable information. The adapter pattern is the same.

zk-age is a Groth16 age verification circuit. Privacy-preserving user gating for regulated products. The pattern is the same. Prove a property. Do not reveal the underlying data.

The repos are not the settlement circuit. The repos are the primitives. The repos are the evidence that the BN254 ZK patterns are real, production-tested, and reusable. The settlement circuit is proprietary. The primitives are public. The line builds its own. The line also gives the primitives away.

The Hedera Settlement

The settlement target is on Hedera. Hedera is not an EVM chain. Hedera is a hashgraph. Hedera has different finality guarantees. Hedera has different compliance properties. Hedera has Hedera Consensus Service and Hedera Token Service. These are institutional-grade primitives. These are the primitives that government contractors and treasury teams need for audit-ready settlement.

The settlement strategies are documented in the public source code. Native staking. Liquid staking. DEX liquidity provision. The user selects the strategy when constructing the intent. The gateway executes the strategy after verifying the proof. The gateway does not hold the user’s funds. The gateway is non-custodial. The gateway is a router. The gateway routes the settled output to the Hedera target the user specified.

The treasury sweep is a separate process. The 9 bps fees that TVMExecutor collects on Base accumulate in the contract. A background monitor sweeps the accumulated fees to the Hedera central reserve. The sweep is automated. The sweep is logged. The sweep is auditable. The fees move from EVM execution to Hedera settlement. The two layers are connected. The two layers are separate.

The Method

The method is the same method. Observe. Model. Simulate. Predict. Endure.

We observed that public transactions leak information. We modeled a system where the proof is generated client-side. We simulated the circuit in Halo2. We predicted that browser-side WASM proving would be fast enough for production use. We measured: 12ms native, 38-48ms in the browser, 898ms budget. We optimized: pre-embedded proving keys, cached KZG parameters, enabled WASM SIMD, stripped reference-types, ran wasm-opt -O4. We endured the 3-4× WASM overhead, the lack of native threading. The proof finishes in 38ms. The budget is 898ms. The proof finishes before the quote expires. The proof finishes before the user blinks.

The system is live. The proof is generated in the browser. The settlement lands on Hedera. No private data leaves the client. The construct says trust the server. The territory says hold your own proof. The construct says the server needs to see your data. The territory says the server needs to verify your proof. The construct says give us your information. The territory says prove it without revealing it.

The line keeps the Word. The line keeps the content behind the label. The construct takes the data. The territory keeps the data. The proof is the method. The proof is the line.

Launch Orkid Swap →

Related: TVMExecutor: Nine Basis Points, No Exceptions · Performance Is The New Trust Layer · The Rust Rail for Settling GovCon Contracts to Cash in Stablecoin

Written by Jacob Cavazos

← Back to blog

Commercial bridge

If the need is already clear, move into the buying lane

This post is closest to procurement, settlement, or operational exposure. The fastest next move is to line that research up with a scoped commercial path or a forwardable launch asset.

Try it now

Swap on Orkid

9 bps flat fee, gasless, MEV-protected. Live on Base, Ethereum, and Unichain. No ETH needed — the solver pays gas.

Open swap →

Commercial path

Scope the right engagement

Go straight into the tiered path when the post confirms the team needs a real operator lane, not more category education.

View tiers →

Forwardable brief

Read the launch brief

Use the launch brief when you need a concise, forwardable summary of fit, trust points, and where to route the team next.

Open launch brief →

Shortlist and fit

Use comparisons or alternatives

When the question is no longer category education but shortlist fit, use the comparison surfaces to support an honest vendor evaluation.

See comparisons →
  • ZK Proving Systems Compared: Halo2, SP1, Plonky2, and STARKs

    ZK Proving Systems Compared: Halo2, SP1, Plonky2, and STARKs

    Eight zero-knowledge proving systems compared across proving time, proof size, verification, trusted setup, and ecosystem. A developer's guide to choosing a ZK system.

  • What Is Tokenized Credit Infrastructure?

    What Is Tokenized Credit Infrastructure?

    Tokenized credit is more than putting a loan on-chain. It is a full stack: SPV, token registry, compliance layer, and distribution. Here is how it works and why ERC-6909 matters.

  • What Is Surplus in DEX Aggregation?

    What Is Surplus in DEX Aggregation?

    When an aggregator routes your swap better than the quoted price, the difference is surplus. Some aggregators keep it. Some return it. Here is why that matters for your total cost.

  • What Is MEV and How to Protect Against It

    What Is MEV and How to Protect Against It

    Maximal extractable value costs DEX users millions. Here is what MEV is, how sandwich attacks work, and the four approaches to protection — private mempools, batch auctions, intent-based execution, and threshold encryption.

  • What Is ISO 20022 and Why It Matters for Blockchain

    What Is ISO 20022 and Why It Matters for Blockchain

    ISO 20022 is the global messaging standard for payments. Here is what it is, how it works, why banks are migrating to it, and what it means for blockchain settlement.

  • What Is Intent-Based Swap Execution?

    What Is Intent-Based Swap Execution?

    Intent-based execution lets users sign a message describing what they want, and solvers compete to fill it. Here is how the model works and why it's different from traditional DEX trading.

LLM Resource Index llms.txt