Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 401
feat(aggregation-mode): turn program IDs into a mapping#2175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
421e6219af1ee0b833ecd36379846ce5d48a81b73fc14107e4898009c88ec93bb3786d7048c1bd50427b6cdc1a02c1df1eb938200d4fe4beba099a5aceefe1e634e589320f76a90843a349684bdcb80e323c295f6b54e1e23919e20c9ec6e09e01ce970a7532dc6f93ae78925f8f6d45ea248710724970e9a40141369e881e61ec5062bdf4d5b88f6d68ece072e0568File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -44,6 +44,8 @@ pub struct ProofAggregator { | ||
| proof_aggregation_service: AlignedProofAggregationServiceContract, | ||
| fetcher: ProofsFetcher, | ||
| config: Config, | ||
| sp1_chunk_aggregator_vk_hash_bytes: [u8; 32], | ||
| risc0_chunk_aggregator_image_id_bytes: [u8; 32], | ||
| } | ||
| impl ProofAggregator { | ||
| @@ -66,11 +68,25 @@ impl ProofAggregator { | ||
| ZKVMEngine::from_env().expect("AGGREGATOR env variable to be set to one of sp1|risc0"); | ||
| let fetcher = ProofsFetcher::new(&config); | ||
| let sp1_chunk_aggregator_vk_hash_bytes: [u8; 32] = | ||
| hex::decode(&config.sp1_chunk_aggregator_vk_hash) | ||
| .expect("Failed to decode SP1 chunk aggregator VK hash") | ||
| .try_into() | ||
| .expect("SP1 chunk aggregator VK hash must be 32 bytes"); | ||
| let risc0_chunk_aggregator_image_id_bytes: [u8; 32] = | ||
| hex::decode(&config.risc0_chunk_aggregator_image_id) | ||
| .expect("Failed to decode Risc0 chunk aggregator image id") | ||
| .try_into() | ||
| .expect("Risc0 chunk aggregator image id must be 32 bytes"); | ||
MarcosNicolau marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| Self { | ||
| engine, | ||
| proof_aggregation_service, | ||
| fetcher, | ||
| config, | ||
| sp1_chunk_aggregator_vk_hash_bytes, | ||
| risc0_chunk_aggregator_image_id_bytes, | ||
| } | ||
| } | ||
| @@ -157,10 +173,11 @@ impl ProofAggregator { | ||
| let tx_req = match aggregated_proof { | ||
| AlignedProof::SP1(proof) => self | ||
| .proof_aggregation_service | ||
| .verifySP1( | ||
| .verifyAggregationSP1( | ||
| blob_versioned_hash.into(), | ||
| proof.proof_with_pub_values.public_values.to_vec().into(), | ||
| proof.proof_with_pub_values.bytes().into(), | ||
| self.sp1_chunk_aggregator_vk_hash_bytes.into(), | ||
| ) | ||
| .sidecar(blob) | ||
| .into_transaction_request(), | ||
| @@ -169,10 +186,11 @@ impl ProofAggregator { | ||
| AggregatedProofSubmissionError::Risc0EncodingSeal(e.to_string()) | ||
| })?; | ||
| self.proof_aggregation_service | ||
| .verifyRisc0( | ||
| .verifyAggregationRisc0( | ||
| blob_versioned_hash.into(), | ||
| encoded_seal.into(), | ||
| proof.receipt.journal.bytes.into(), | ||
| self.risc0_chunk_aggregator_image_id_bytes.into(), | ||
| ) | ||
| .sidecar(blob) | ||
| .into_transaction_request() | ||
Large diffs are not rendered by default.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -15,8 +15,8 @@ contract AlignedProofAggregationService is | ||
| OwnableUpgradeable, | ||
| UUPSUpgradeable | ||
| { | ||
| /// @notice Map the merkle root to a boolean to indicate it was verified | ||
| mapping(bytes32 => bool) public aggregatedProofs; | ||
| /// @notice true if merkle root is verified | ||
| mapping(bytes32 => bool) public isMerkleRootVerified; | ||
| /// @notice The address of the SP1 verifier contract. | ||
| /// @dev This can either be a specific SP1Verifier for a specific version, or the | ||
| @@ -33,13 +33,14 @@ contract AlignedProofAggregationService is | ||
| /// https://dev.risczero.com/api/blockchain-integration/contracts/verifier#contract-addresses | ||
| address public risc0VerifierAddress; | ||
| /// The unique identifier (image ID) of the RISC Zero aggregator program. | ||
| /// This ensures that only proofs generated by a trusted Risc0 program can be verified. | ||
| bytes32 public risc0AggregatorProgramImageId; | ||
| /// @notice Proving system ID for SP1 | ||
| uint8 public constant SP1_ID = 1; | ||
| /// The verification key hash for the SP1 aggregator program. | ||
| /// This ensures that only proofs generated by a trusted SP1 program can be verified. | ||
| bytes32 public sp1AggregatorProgramVKHash; | ||
| /// @notice Proving system ID for RISC0 | ||
| uint8 public constant RISC0_ID = 2; | ||
| /// @notice Maps allowed verifiers commitments to their proving system. If the verifier is not a valid one, it returns 0 and is considered invalid | ||
| mapping(bytes32 => uint8) public allowedVerifiersProvingSystem; | ||
MarcosNicolau marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| constructor() { | ||
| _disableInitializers(); | ||
| @@ -59,62 +60,70 @@ contract AlignedProofAggregationService is | ||
| alignedAggregatorAddress = _alignedAggregatorAddress; | ||
| sp1VerifierAddress = _sp1VerifierAddress; | ||
| risc0VerifierAddress = _risc0VerifierAddress; | ||
| risc0AggregatorProgramImageId = _risc0AggregatorProgramImageId; | ||
| sp1AggregatorProgramVKHash = _sp1AggregatorProgramVKHash; | ||
| allowedVerifiersProvingSystem[_risc0AggregatorProgramImageId] = RISC0_ID; | ||
| allowedVerifiersProvingSystem[_sp1AggregatorProgramVKHash] = SP1_ID; | ||
| } | ||
| function verifySP1(bytes32 blobVersionedHash, bytes calldata sp1PublicValues, bytes calldata sp1ProofBytes) | ||
| function verifyAggregationSP1(bytes32 blobVersionedHash, bytes calldata sp1PublicValues, bytes calldata sp1ProofBytes, bytes32 verifierProgramCommitment) | ||
| public | ||
| onlyAlignedAggregator | ||
| { | ||
| (bytes32 merkleRoot) = abi.decode(sp1PublicValues, (bytes32)); | ||
| ISP1Verifier(sp1VerifierAddress).verifyProof(sp1AggregatorProgramVKHash, sp1PublicValues, sp1ProofBytes); | ||
| if (allowedVerifiersProvingSystem[verifierProgramCommitment] != SP1_ID) { | ||
| revert InvalidVerifyingProgram(verifierProgramCommitment, SP1_ID, allowedVerifiersProvingSystem[verifierProgramCommitment]); | ||
| } | ||
| ISP1Verifier(sp1VerifierAddress).verifyProof(verifierProgramCommitment, sp1PublicValues, sp1ProofBytes); | ||
| aggregatedProofs[merkleRoot] = true; | ||
| isMerkleRootVerified[merkleRoot] = true; | ||
| emit AggregatedProofVerified(merkleRoot, blobVersionedHash); | ||
| } | ||
| function verifyRisc0(bytes32 blobVersionedHash, bytes calldata risc0ReceiptSeal, bytes calldata risc0JournalBytes) | ||
| function verifyAggregationRisc0(bytes32 blobVersionedHash, bytes calldata risc0ReceiptSeal, bytes calldata risc0JournalBytes, bytes32 verifierProgramCommitment) | ||
| public | ||
| onlyAlignedAggregator | ||
| { | ||
| (bytes32 merkleRoot) = abi.decode(risc0JournalBytes, (bytes32)); | ||
| if (allowedVerifiersProvingSystem[verifierProgramCommitment] != RISC0_ID) { | ||
| revert InvalidVerifyingProgram(verifierProgramCommitment, RISC0_ID, allowedVerifiersProvingSystem[verifierProgramCommitment]); | ||
| } | ||
| bytes32 risc0JournalDigest = sha256(risc0JournalBytes); | ||
| IRiscZeroVerifier(risc0VerifierAddress).verify( | ||
| risc0ReceiptSeal, risc0AggregatorProgramImageId, risc0JournalDigest | ||
| risc0ReceiptSeal, verifierProgramCommitment, risc0JournalDigest | ||
| ); | ||
| aggregatedProofs[merkleRoot] = true; | ||
| isMerkleRootVerified[merkleRoot] = true; | ||
| emit AggregatedProofVerified(merkleRoot, blobVersionedHash); | ||
| } | ||
| /// @notice Verifies the inclusion of proof in an aggregated proof via Merkle tree proof. | ||
| /// | ||
| /// @dev | ||
| /// - The `programId` parameter represents the unique identifier for the vm program: | ||
| /// - The `programCommitment` parameter represents the unique identifier for the vm program: | ||
| /// - In RISC Zero, this corresponds to the `image_id`. | ||
| /// - In SP1, this corresponds to the `vk` (verification key) hash. | ||
| /// - The proof commitment is derived by hashing together the `programId` and the `publicInputs`. | ||
| /// - The proof commitment is derived by hashing together the `programCommitment` and the `publicInputs`. | ||
| /// - The `merklePath` is then used to compute the Merkle root from this commitment. | ||
| /// - The function returns `true` if this Merkle root is known to correspond to a valid aggregated proof. | ||
| /// | ||
| /// @param merklePath The Merkle proof (sibling hashes) needed to reconstruct the Merkle root. | ||
| /// @param provingSystemId The id of the proving system (1 for SP1, 2 for RISC0). | ||
| /// @param programId The identifier for the ZK program (image_id in RISC0 or vk hash in SP1). | ||
| /// @param publicInputs The public inputs bytes of the proof. | ||
| /// @param programCommitment The commitment of the program sent to Aligned (image_id in RISC0 or vk hash in SP1). | ||
| /// @param publicInputs The public inputs bytes of the proof sent to Aligned. | ||
| /// | ||
| /// @return bool Returns true if the computed Merkle root is a recognized valid aggregated proof. | ||
| function verifyProofInclusion( | ||
| function isProofVerified( | ||
MarcosNicolau marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| bytes32[] calldata merklePath, | ||
| uint16 provingSystemId, | ||
| bytes32 programId, | ||
| bytes32 programCommitment, | ||
| bytes calldata publicInputs | ||
| ) public view returns (bool) { | ||
| bytes32 proofCommitment = keccak256(abi.encodePacked(provingSystemId, programId, publicInputs)); | ||
| bytes32 proofCommitment = keccak256(abi.encodePacked(provingSystemId, programCommitment, publicInputs)); | ||
| bytes32 merkleRoot = MerkleProof.processProofCalldata(merklePath, proofCommitment); | ||
| return aggregatedProofs[merkleRoot]; | ||
| return isMerkleRootVerified[merkleRoot]; | ||
| } | ||
| function _authorizeUpgrade(address newImplementation) | ||
| @@ -130,31 +139,54 @@ contract AlignedProofAggregationService is | ||
| _; | ||
| } | ||
| /// @notice Modifier to ensure the provided proving system ID is one of the valid values. | ||
| modifier onValidProvingSystemId(uint8 provingSystemId) { | ||
| if (provingSystemId != SP1_ID && | ||
| provingSystemId != RISC0_ID){ | ||
| revert IAlignedProofAggregationService.InvalidProvingSystemId(provingSystemId); | ||
| } | ||
| _; | ||
| } | ||
| /// @notice Sets the address of the Risc0 verifier contract | ||
| /// @param _risc0VerifierAddress The new address for the Risc0 verifier contract | ||
| function setRisc0VerifierAddress(address _risc0VerifierAddress) external onlyOwner { | ||
| risc0VerifierAddress = _risc0VerifierAddress; | ||
| emit Risc0VerifierAddressUpdated(_risc0VerifierAddress); | ||
| } | ||
| /// @notice Sets the image id of the Risc0 program | ||
| /// @param _risc0AggregatorProgramImageId The new imageid for the Risc0 aggregator program | ||
| function setRisc0AggregatorProgramImageId(bytes32 _risc0AggregatorProgramImageId) external onlyOwner { | ||
| risc0AggregatorProgramImageId = _risc0AggregatorProgramImageId; | ||
| emit Risc0AggregatorProgramImageIdUpdated(_risc0AggregatorProgramImageId); | ||
| } | ||
| /// @notice Sets the address of the SP1 verifier contract | ||
| /// @param _sp1VerifierAddress The new address for the SP1 verifier contract | ||
| function setSP1VerifierAddress(address _sp1VerifierAddress) external onlyOwner { | ||
| sp1VerifierAddress = _sp1VerifierAddress; | ||
| emit SP1VerifierAddressUpdated(_sp1VerifierAddress); | ||
| } | ||
| /// @notice Sets the vk hash of the sp1 program | ||
| /// @param _sp1AggregatorProgramVKHash The new vk hash for the sp1 aggregator program | ||
| function setSP1AggregatorProgramVKHash(bytes32 _sp1AggregatorProgramVKHash) external onlyOwner { | ||
| sp1AggregatorProgramVKHash = _sp1AggregatorProgramVKHash; | ||
| emit SP1AggregatorProgramVKHashUpdated(_sp1AggregatorProgramVKHash); | ||
| /// @notice Allows a new verifying program commitment to the list of valid verifying programs. | ||
| /// @param verifierProgramCommitment The verifying program commitment to allow (image ID for RISC0 or vk hash for SP1). | ||
| /// @param provingSystemId The proving system ID associated with the verifying program. | ||
| function allowVerifyingProgram(bytes32 verifierProgramCommitment, uint8 provingSystemId) | ||
| external | ||
| onlyOwner | ||
| onValidProvingSystemId(provingSystemId) | ||
| { | ||
| allowedVerifiersProvingSystem[verifierProgramCommitment] = provingSystemId; | ||
| emit VerifierProgramAllowed(verifierProgramCommitment, provingSystemId); | ||
| } | ||
| /// @notice Disallows a verifying program commitment from the list of valid verifying programs. | ||
| /// @param verifierProgramCommitment The verifying program commitment to disallow (image ID for RISC0 or vk hash for SP1). | ||
| function disallowVerifyingProgram(bytes32 verifierProgramCommitment, uint8 provingSystemId) external onlyOwner onValidProvingSystemId(provingSystemId) { | ||
| // Preserve the proving system ID so we can emit it with the event | ||
| uint8 provingSystemIdRaw = allowedVerifiersProvingSystem[verifierProgramCommitment]; | ||
| // Check if the obtained proving system ID matches the one received by param | ||
| if (provingSystemIdRaw != provingSystemId) { | ||
| revert IAlignedProofAggregationService.ProvingSystemIdMismatch(provingSystemIdRaw, provingSystemId); | ||
| } | ||
| delete allowedVerifiersProvingSystem[verifierProgramCommitment]; | ||
| emit VerifierProgramDisallowed(verifierProgramCommitment, provingSystemIdRaw); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.