Research & Primitives

ZK primitives benchmarked on real hardware. Architecture patterns from real systems. Numbers that protocol designers can actually use.

Why Flow? Flow's cross-VM architecture is unique: a single Cadence transaction can call an EVM contract atomically, combining Cadence resource safety with EVM precompile access (BN254, BLS12-381, Poseidon). No other production chain offers this pattern. It enables confidential token designs that aren't feasible on Ethereum alone. The research here is Flow-specific because that's where the unsolved problems live — not because the other chains don't matter.

openjanus/primitives

Public · npm

A public library of production-grade cryptographic primitives for Flow cross-VM, published via @claucondor/sdk on npm and sourced from claucondor/primitives and claucondor/sdk. All measurements are from Flow testnet, not emulator.

Public primitive inventory

BabyJubJub public
Elliptic Curve
PedersenBabyJub public
Commitments
Groth16Verifier public
SNARKs · CrossVM
ECIES AES-GCM public
Encryption
Stealth Addresses (ERC-5564) public
Privacy
BeaconBound VRF public
Randomness
Merkle Inclusion Proofs public
ZK
HKDF-SHA256 key derive public
Key Management

Benchmark measurements

Measured on Flow testnet. CU = Cadence computation units. Gas = EVM gas on Flow EVM. Cross-VM calls incur both CU cost (Cadence side) and gas cost (EVM side).

Module / Operation CU Cost EVM Gas Layer
PedersenBabyJub — addCommits~16 CUCadence native
PedersenBabyJub — createCommit~18 CUCadence native
BabyJub field arithmetic<10 CUCadence native
BeaconBound commit (VRF)~25 CUCadence native
Poseidon 2-input (Cadence native)~45 CUCadence native
Poseidon 2-input (EVM Yul bridge)~120 CU~35k gasCrossVM
Groth16 verify (EVM verifier)~200 CU~270k gasCrossVM
ConfidentialToken transfer (full)~350 CU~327k gasCrossVM
Mixer deposit (Poseidon Merkle)~280 CU~210k gasCrossVM
Mixer withdraw (nullifier + proof)~320 CU~290k gasCrossVM

Note: CU budget per transaction is 9,999 for Cross-VM scheduled transactions. Full benchmark methodology documented in openjanus/primitives.

What informed these primitives

The primitives in openjanus/primitives emerged from real application needs, not just academic exploration. PrivateTip needed a Groth16 verifier callable from Cadence — so CrossVMVerifier was built and benchmarked. Amount-hiding needed Pedersen commitments on BabyJubJub (compatible with Circom circuits) — so PedersenBabyJub was built native in Cadence. Stealth address generation needed ECC on the same curve — so BabyJubJub came first.

The research also explored directions that didn't make it into public libraries yet: FROST BLS12-381 threshold signatures via EIP-2537, MiMC hashing, and RISC0 Groth16 receipt verification. These remain active areas. The 9,999 CU ceiling for Cross-VM scheduled transactions was discovered empirically across 40+ benchmark runs — not documented anywhere, found by running FlowOracle's indexer into resource exhaustion.

The core insight driving everything: Flow's cross-VM model makes ZK economically feasible where Ethereum mainnet is prohibitive. A Groth16 verify that costs ~$0.50–5.00 on Ethereum mainnet costs ~$0.002–0.008 on Flow EVM. That's a 1-2 order-of-magnitude cost reduction — enough to make private tipping, sealed-bid auctions, and stealth transfers economically practical for real users, not just whales.

ZK-on-Flow Layered Lab (zk-prop)

Lab · Research

Seven-level progressive ZK curriculum built on real deployed contracts — from commit-reveal with Flow VRF beacon to a full confidential transfer circuit.

L1

Commit-Reveal with Flow VRF Beacon

deployed

Anti-frontrun commit-reveal using RandomBeaconHistory. Beacon block 324,226,714 as Phase 2 entropy for Groth16 ceremony.

L2

Groth16 Cubic Circuit Verifier on Flow EVM

deployed

Simple x^3 + x + 5 circuit in circom, compiled to Groth16, deployed verifier on Flow EVM. First EVM Groth16 deployment on Flow.

L3

Cross-VM Cadence → EVM Groth16

deployed

Single Cadence transaction calls the L2 EVM verifier atomically. Production pattern used in PrivateTip.

L4

Tornado-Style Mixer (Poseidon-EVM hash strategy)

deployed

Full mixer with Poseidon Merkle depth-2, historicalRoots replay protection, nullifier scheme. circom circuit included.

L5

Confidential Transfer Circuit Track

in progress

amount_disclose.circom — ZK proof that transferred amount matches commitment without revealing value.

L6

Full Confidential Transfer with Range Proofs

in progress

confidential_transfer.circom — end-to-end: wrap, shielded transfer, unwrap with amount privacy.

L7+

Privacy Wallet (roadmap)

roadmap

Cross-VM privacy wallet combining all L1-L6 primitives. Post-L7 roadmap candidate.

Trusted Setup Ceremony

The OpenJanus Groth16 ceremony follows a two-phase model to avoid single-contributor trapdoor risk.

Phase 1 — Powers of Tau

  • Source: Hermez pot18 transcript
  • Contributors: 200+ independent parties
  • Max degree: 2^18 constraints
  • Publicly verifiable transcript

Phase 2 — Circuit-Specific

  • Entropy: openssl rand -hex 32
  • Beacon: Flow VRF RandomBeaconHistory
  • Block: 324,226,714
  • Final zkey: reproducibly verifiable

Why the Hermez beacon constraint matters: snarkjs requires the Phase 2 beacon to be applied BEFORE circuit-specific setup contributions. A common misconfiguration applies it after — producing a verifier that accepts proofs but has a weakened security bound. The openjanus ceremony was run in the correct order.

Cross-VM ZK Pattern Reference

The core pattern that makes PrivateTip and the Janus stack work — a single Cadence transaction orchestrating EVM Groth16 verification atomically.

// Cadence transaction (single atomic block)
transaction(proof: [UInt8], publicSignals: [UInt8]) {
prepare(signer: AuthAccount) { ... }
execute {
// 1. Call EVM Groth16Verifier.verifyProof()
let result = EVM.call(verifierAddr, calldata)
// 2. Assert on result — fail entire tx if proof invalid
assert(result.data == true, message: "invalid proof")
// 3. Update Cadence state (vault, commitment, nullifier)
self.vault.withdraw(amount: amount)
}
}
Atomicity
If EVM call fails, Cadence state reverts
CU budget
~200-350 CU for full cross-VM ZK flow
Gas on EVM
~270-327k gas for Groth16 verify + state

What's next

The current primitives enable the first generation of applications. These are the next targets — some already in progress:

Sealed-bid auctions

Near

Bidders commit to encrypted amounts; winner proven via ZK without revealing losing bids. Groth16 circuit + BeaconBound reveal.

Hidden pack opens (NFT)

Near

Provably fair randomness for pack reveals — commit before mint, reveal with Flow VRF beacon. No house advantage by design.

Cross-VM privacy wallet

Mid

Combines amount-hiding (Pedersen), stealth addressing, and ECIES encryption in a single wallet UX on Flow. The natural L7 of zk-prop.

OFAC compliance integration

Pre-mainnet

Chainalysis Oracle hook at the wrap/unwrap boundary — screen before funds enter the shielded pool. 'Privacy, not impunity' at the protocol level.

ERC-7984 confidential token standard

Research

Full implementation of the amount-hiding ERC-7984 token standard on Flow cross-VM, with interoperability hooks for Ethereum bridging.

Available for contracts