Security and Transparency
UPA Security and Transparency
NEBRA's Universal Proof Aggregation (UPA) protocol enables applications on Ethereum to outsource the task of verifying zero-knowledge proofs (ZKPs) to an off-chain aggregator. The UPA verifies ZKPs at a lower cost than direct verification in a smart contract, while maintaining the same security and soundness guarantees.
NEBRA is committed to security and transparency, and we believe that users of the UPA have a right to examine the code and read the audit reports themselves before entrusting us with their proofs. This page serves as a security-oriented guide to the UPA protocol and its current implementation. We begin with an overview of the UPA's guarantees and potential concerns, then provide details on the on- and off-chain components of the UPA.
UPA Guarantees
At a high level, the security guarantees of the UPA are:
Proof validity: If the UPA marks a given proof ID as "verified" then the user must have submitted a valid proof to the UPA.
Equal privacy: the UPA does not require additional information beyond the proof and public inputs. It therefore maintains the existing level of privacy offered by each application.
Additionally, the UPA offers a censorship-resistance guarantee via on-chain proof submission:
Proofs submitted on-chain are indexed by the UPA contract and must be verified in this order (assuming they are valid). Failure to include valid proofs or failure to respect the ordering of proofs exposes the aggregator to a penalty.
Application Developer Responsibilities
The UPA cannot address the following security concerns. It is the application developer's responsibility to prevent:
Replay attacks: once a proof has been verified by the UPA, its inputs are forever marked as "verified." Application developers must decide whether it should be possible to reuse these inputs for multiple transactions. When reuse is undesirable the application itself must prevent this with some mechanism such as a nullifier. (This should already be the case, because even without the UPA it is possible to generate multiple valid proofs for the same set of inputs!)
Under-constrained circuits: it is the application developer's responsibility to write circuits that correctly enforce the in-circuit portion of their application logic.
Liveness and Redundancy
Developers should understand that the UPA protocol has an off-chain component, and therefore cannot guarantee liveness equal to that of Ethereum. NEBRA will strive to match Ethereum's liveness by building redundancy into the prover network that powers the UPA's off-chain component. Nonetheless, we recommend that application developers build in resilience to any potential outages the UPA may experience.
This simply means that application smart contracts should maintain the ability to directly verify users' proofs, as they would in the absence of the UPA. Then, in the event of UPA downtime, users can choose to submit their transaction with "direct verification" rather than "UPA verification," albeit at a higher cost.
UPA On-Chain Component
The UPA's on-chain component is a collection of smart contracts on Ethereum. Its responsibilities include
Verifying Key Registration: the UPA records verifying keys submitted by developers and assigns to each key a unique circuit ID.
Proof Submission: the UPA accepts (circuit ID, proof, inputs) tuples and
Ensures that the circuit ID belongs to a previously-registered VK
Computes a proof ID from the circuit ID and inputs
Indexes submissions, determining the order in which the aggregator must verify them
Records a "proof digest," identifying the proof for potential censorship challenges
Aggregated Proof Verification: the UPA checks proofs submitted by the aggregator, ensuring that only valid application proofs will be marked as verified
Verification Queries: allowing applications to query whether a given proof ID has been marked as verified
Fee Collection: determining and collecting the fee due for proof aggregation
Fee Disbursement: ensuring that the aggregator can collect the fee only after aggregating proofs
Censorship resistance: handling censorship challenges and punishing the aggregator for censoring valid proofs
UPA Off-Chain Component
The UPA's off-chain component is a collection of zero-knowledge circuits that ensure that only valid application proofs will be marked as verified by the UPA. More precisely, the soundness guarantee is that if a given proof ID is an input to a valid aggregated proof, then the aggregator has knowledge of a valid application proof for the verifying key and public inputs corresponding to that proof ID.
Applications using the UPA therefore receive a cryptographic guarantee that their users submitted valid application proofs for any inputs that the UPA marks as verified.
Proofs for these circuits are produced by a permissioned off-chain aggregator. This aggregator is operated by NEBRA (though the protocol allows for the role to eventually be shared or even decentralized). We emphasize that although the aggregator is centralized, it is not trusted. Even a malicious aggregator cannot aggregate invalid application proofs, thanks to the cryptographic soundness guarantee of the circuits. We explain below how the UPA smart contracts verify the work done by the aggregator.
AggregatedProofVerifier
Contract
AggregatedProofVerifier
ContractThe AggregatedProofVerifier
contract is the on-chain component of the UPA that is responsible for verifying the aggregated proofs produced by the aggregator. This contract links the on- and off-chain parts of the protocol, allowing the UPA contract to verify the aggregator's claim that a list of application inputs have valid proofs. It plays an essential role in the overall soundness of the UPA.
Auditing the AggregatedProofVerifier
contract is therefore more challenging than the main UPA contracts, but not impossible. Because the contract is generated deterministically using open-source tools and data, any third party is free to repeat the procedure and check that the resulting bytecode matches the actual deployment. This is similar to how ordinary smart contracts written in Solidity can have their source code verified by blockchain explorers like Etherscan; the blockchain explorer compiles the provided Solidity code and checks that it matches the contract's EVM bytecode.
Compile to EVM bytecode. Finally,
solc
compiles the Yul verifier generated in the previous step to EVM bytecode. For the sake of comparison to the deployed contract code, it is important to use the samesolc
version (v0.8.17
) used by NEBRA during deployment.
Last updated
Was this helpful?