I’ve published noir-rlwe-gadgets, a Noir library that proves a BFV ciphertext is a well-formed encryption of a bounded message — both secret-key (the Greco statement) and public-key (the fhEVM-style input statement, where the prover holds only the recipient’s public key). It targets the Noir / Barretenberg / UltraHonk stack and emits a standard auto-generated Solidity verifier.
Approach. Schwartz-Zippel random-evaluation over R_q = Z_q[X]/(X^N+1) — not in-circuit NTT. Polynomial products are verified at a single Fiat-Shamir challenge with a committed quotient polynomial, turning an O(N log N) problem into an O(N) circuit. Two further optimizations (coefficient packing before the FS hash; a single-digest public input) cut the circuit ~5× and on-chain gas ~2.35×.
Measured (M2 Air 8 GB, n=1024, q≈2²⁷, digest variant):
| circuit | gates | prove | on-chain gas | public inputs |
|---|---|---|---|---|
| secret-key | 48,270 | 0.65 s | 2.45M | 1 |
| public-key | 80,262 | 0.89 s | 2.51M | 1 |
Verifier deployed + verified on Anvil; tampered inputs rejected on-chain; 50 library tests incl. soundness negative tests. Generic over ring degree, validated for N ≤ 4096.
Security. The Schwartz-Zippel soundness is worked out, not assumed: the no-wraparound and quotient-completeness lemmas are proven (‖D‖∞ < p/2), the in-circuit Fiat-Shamir has a ROM reduction (≤ Q·2N/p), knowledge-soundness and ZK reduce to UltraHonk, and the parameters are validated with the lattice-estimator (the 27-bit preset is ~126-bit; the 56-bit preset is insecure at n=1024 and ships test-vector-only). Still UNAUDITED — an independent audit is required before production; feedback and review very welcome.
The public-key path is the relevant primitive for proving validity of encrypted inputs to an FHE coprocessor. Would love to hear from anyone working on FHE-on-Aztec / threshold-FHE rollups about the statement and parameters that would be most useful.