Balazs Komuves e4fdbccca6
concatenating all the remaining MSMs into one (that's always a bit faster)
currently we have 4 of them:
- 1 for the "rho term"
- 1 for the unified C1 + "projection terms"
- 2 for the cross-terms

i hope the cross-terms can be also reduced to just 1 later
2026-06-16 14:49:40 +02:00
2026-06-15 14:13:56 +02:00
2026-06-15 14:13:56 +02:00
2024-01-18 13:04:26 +01:00
2023-11-09 15:21:21 +01:00
2023-11-09 15:21:21 +01:00

Groth16 prover written in Nim

This is a Groth16 prover implementation in Nim, using the constantine library as an arithmetic / curve backend.

The implementation is compatible with the circom + snarkjs ecosystem.

At the moment only the BN254 (aka. alt-bn128) curve is supported.

Partial proofs

Groth16 has an interesting internal structure in that most of the proof computation is linear in the witness.

This implies that if you have to generate a lot of proofs where a large part of the witness is unchanged, then you can precalculate quite a lot, making subsequent proofs faster. A situation where this happens is when you have a long-term identity, which however you don't want to reveal (eg. anonymous credentials).

As splitting the proof into two has negligible overhead in practice, this is an essentially free win in such situations. However the speedup potential is limited, because the single nonlinear term depends on the full witness. In practice we've seen 2x-3x speedups when 10% of the witness changes.

This is implemented under groth16/partial/.

Semi-dynamic proofs

In a recent paper "Dynark: Making Groth16 Dynamic" (2025), a solution was proposed for also speeding up the computation of the nonlinear term. This results in an asymptotic speedup, however, unlike the previous (essentially trivial) solution, this one is not for free: There is a somewhat heavy precalculation when the full witness changes.

Whether that's worth it depends on the particular use-case.

A version of this idea is implemented under groth16/dynamic/.

License

Licensed and distributed under either of the MIT license or Apache License, v2.0, at your choice.

TODO

  • clean up the code
  • more comprehensive testing
  • compare .r1cs to the "coeffs" section of .zkey
  • generate fake circuit-specific setup ourselves
  • make a CLI interface
  • multithreading support (MSM, and possibly also FFT)
  • add Groth16 explanatory notes
  • document the snarkjs circuit-specific setup H points convention
  • precalculate stuff for "partial" proofs
  • implement Dynark style "dynamic proofs" too
  • benchmarks
  • make it work for different curves
Description
circom-compatible Groth16 prover in Nim
Readme
Languages
Nim 98.4%
Shell 1.1%
Circom 0.5%