# noir-rlwe-gadgets — verifiable BFV encryption (RLWE) in Noir, with an on-chain UltraHonk verifier

**URL:** <https://forum.aztec.network/t/noir-rlwe-gadgets-verifiable-bfv-encryption-rlwe-in-noir-with-an-on-chain-ultrahonk-verifier/8591>\
**Category:** Noir\
**Tags:** noir\
**Created:** [June 15, 2026, 12:39pm UTC](https://forum.aztec.network/t/noir-rlwe-gadgets-verifiable-bfv-encryption-rlwe-in-noir-with-an-on-chain-ultrahonk-verifier/8591 "2026-06-15T12:39:50Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![aryaethn](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.aztec.network/aryaethn/32/2991_2.png) [@aryaethn](https://forum.aztec.network/u/aryaethn)\
**Post date:** [June 15, 2026, 12:39pm UTC](https://forum.aztec.network/t/noir-rlwe-gadgets-verifiable-bfv-encryption-rlwe-in-noir-with-an-on-chain-ultrahonk-verifier/8591/1 "2026-06-15T12:39:50Z")

</div>

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.

- Repo: [GitHub - aryaethn/noir-rlwe-gadgets · GitHub](https://github.com/aryaethn/noir-rlwe-gadgets)
- Concepts: [noir-rlwe-gadgets/docs/concepts.md at main · aryaethn/noir-rlwe-gadgets · GitHub](https://github.com/aryaethn/noir-rlwe-gadgets/blob/main/docs/concepts.md)
- Benchmarks: [noir-rlwe-gadgets/BENCHMARKS.md at main · aryaethn/noir-rlwe-gadgets · GitHub](https://github.com/aryaethn/noir-rlwe-gadgets/blob/main/BENCHMARKS.md)
