iVF: ink! Verifier Contract Generator for Noir Circuits

Cecilia and I just shipped iVF, a tool that generates ink! v6 smart contract verifiers from Noir zero-knowledge circuits for PolkaVM. iVF (ink! Verifier Factory) automatically generates native PolkaVM verifier contracts from Noir ZKP circuits. Think of it as a compiler that takes zero-knowledge proof verification keys and outputs production-ready smart contracts. The generated contracts perform complex cryptographic operations, including elliptic curve arithmetic, polynomial evaluations, and pairing checks on-chain.

ZKP verification involves intricate field arithmetic, precise memory management, and direct interaction with cryptographic precompiles.

Why I Chose ink! Over Solidity

This project was born out of need as I was building a ZK anonymous poll application in July 2025, and eventually realised that it wasn’t possible for my ink! smart contract to interact with my deployed Solidity verifier. Of course, this is now possible since October when the ink! team released the update that ink! now supports Solidity ABI.

I have tried out this method and had my ink! Smart contract calling the verify function from the Solidity smart contract(https://www.youtube.com/live/eSjFekm36GA). This has allowed me to compare the experience of deploying verifiers on PolkaVM using each of the languages, and these are the reasons I prefer ink!:

Cohesive Developer Experience

Noir, the language used to write circuits, is based on Rust and uses a similar syntax. This means that most developers using Noir are familiar and/or comfortable with Rust and would lean more towards building their entire privacy-preserving dApp using Rust or Rust-like languages. On Polkadot, that happens to be ink!. This also means cross-contract calls between the main smart contracts and the verifier will be smoother if the verifier is also written in ink!.

Type Safety

Cryptographic code is very sensitive. A single bit flip can invalidate a proof or create a security vulnerability. Rust’s type system catches errors at compile time that would have been runtime failures in Solidity:

  • Field element operations that could overflow

  • Invalid point representations on elliptic curves

  • Buffer underflows when parsing proof bytes

  • Incorrect handling of 32-byte field elements

The borrow checker prevents a lot of memory safety issues that are common in cryptographic implementations.

Real Performance Gains

Based on our comparisons of both the ink! and Solidity verifiers, the ink! Verifier provided a 45% smaller binary size(57.97 kb), which is critical for on-chain deployment costs. For ZKP applications that verify hundreds or thousands of proofs, this directly translates to lower operational costs and better user experience.

Seamless Polkadot Integration

ink! v6’s PolkaVM support meant I was building for a native RISC-V target from day one. So far, my experience with Solidity verifiers on Polkadot has not been smooth. As expected, the verifiers are large contracts that need to be optimised before compiling. However, with Hardhat, I am unable to compile and deploy the verifier on Passet Hub, even when I enable viair. The pipeline that worked was using Remix IDE and turning on optimisation.

With ink!, the process is straightforward even for the verifier. The generated .contract files are deployed directly to Passet Hub smoothly.

Error Handling

Being able to use Rust’s Result<T, E> types for the verifier methods has made error handling explicit:

#[ink(message)]

pub fn verify(

    &self,

    proof: Vec<u8>,

    public_inputs: Vec<Vec<u8>>

) -> Result<bool, VerifierError>

Comparing this to Solidity’s require() statements that throw generic errors, with ink!, every possible failure in the verifier has a specific, typed error that clients can handle programmatically.

Challenges I Encountered

Precompile Documentation: Since I am using Pallet-Revive’s BN128 precompiles, I have to thoroughly understand their exact input/output formats. Better precompile documentation would help future builders. I do have to appreciate the ink! team though, since they have also been very helpful when it comes to understanding how to call these precompiles using ink!, and have provided me with direct guidance.

Ecosystem Maturity: The Solidity ecosystem has more libraries and examples for cryptographic primitives. But this hasn’t been a blocker this far; it just highlights areas where continued investment would accelerate adoption and improve the developer experience.

I’m happy to discuss the technical details of building with ink! V6, the performance comparisons with Solidity and any specific challenges in ZKP verification.

The code for iVF is fully open source: github.com/Lynette7/ivf

19 Likes

Keep the good job guys ! This sounds awesome.

2 Likes

Awesome post Lynette! Excited to play around with Noir + ink! myself

1 Like