diff --git a/README.md b/README.md index 35ec04a1..163636b5 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Orbinum is built using Substrate's FRAME framework and implements Clean Architec - **Pallets**: Modular runtime components (`pallet-shielded-pool`, `pallet-zk-verifier`, `pallet-relayer`) - **Primitives**: Core cryptographic libraries (`zk-core`, `zk-verifier`, `zk-circuits`) - **Client**: RPC layer and blockchain infrastructure -- **Circuits**: Circom zero-knowledge circuits (`value_proof`, `transfer`, `unshield`) +- **Circuits**: Circom zero-knowledge circuits (`value_proof`, `transfer`, `unshield`), maintained in [orbinum/circuits](https://github.com/orbinum/circuits) and the source of the verification keys registered on chain ## License diff --git a/primitives/zk-circuits/README.md b/primitives/zk-circuits/README.md index fea1bbda..81a28381 100644 --- a/primitives/zk-circuits/README.md +++ b/primitives/zk-circuits/README.md @@ -8,6 +8,29 @@ R1CS circuits and constraint gadgets for off-chain ZK proof generation. Intended for off-chain use (proof generation, testing). The runtime only needs `orbinum-zk-verifier` for on-chain proof verification. +> **These are not the circuits Orbinum runs.** +> +> The verification keys registered on chain are generated from the Circom +> sources in [orbinum/circuits](https://github.com/orbinum/circuits). This crate +> is a separate arkworks implementation of the same ideas, and the two have +> drifted apart. Do not run a trusted setup against it, and do not treat it as a +> specification of the protocol. +> +> Known divergences from the deployed circuits, as of this writing: +> +> | | This crate | `orbinum/circuits` | +> |---|---|---| +> | Unshield public signals | 6 | 7, including `change_commitment` | +> | Unshield change note | not modelled | supported | +> | Range checks on note values | none | `Num2Bits(128)` | +> +> The missing range checks matter most. Balance conservation here is enforced as +> field arithmetic with no bound on any value, so `sum(inputs) == sum(outputs) + +> fee` can be satisfied by wrapping modulo the BN254 scalar field. A setup run +> against `TransferCircuit` or `UnshieldCircuit` would produce a verifier that +> accepts inflated notes. The deployed Circom circuits constrain every value to +> 128 bits and are not affected. + ## Modules | Module | Contents | diff --git a/primitives/zk-circuits/src/lib.rs b/primitives/zk-circuits/src/lib.rs index a5bbf514..3915713d 100644 --- a/primitives/zk-circuits/src/lib.rs +++ b/primitives/zk-circuits/src/lib.rs @@ -6,6 +6,17 @@ //! Intended for off-chain use (proof generation, testing). The runtime only //! needs `orbinum-zk-verifier` for on-chain proof verification. //! +//! # These are not the circuits Orbinum runs +//! +//! The verification keys registered on chain come from the Circom sources in +//! [orbinum/circuits](https://github.com/orbinum/circuits). This crate is a +//! separate arkworks implementation that has drifted from them: `UnshieldCircuit` +//! exposes 6 public signals against the deployed circuit's 7 and does not model +//! the change note, and neither circuit here range-constrains note values, so +//! balance conservation can be satisfied by wrapping modulo the BN254 scalar +//! field. Do not run a trusted setup against these circuits. See the crate +//! README for the full comparison. +//! //! ## Modules //! //! - [`types`]: Core data types (Note, MerklePath, TreeDepth, CircuitValidator)