@@ -37,13 +37,16 @@ contract AlignedProofAggregationService is
3737 /// if the sp1 verifier address is set to this address, then we skip verification
3838 address public constant VERIFIER_MOCK_ADDRESS = address (0xFF );
3939
40- /// The unique identifier (image ID) of the RISC Zero aggregator program.
41- /// This ensures that only proofs generated by a trusted Risc0 program can be verified.
42- bytes32 public risc0AggregatorProgramImageId;
43-
44- /// The verification key hash for the SP1 aggregator program.
45- /// This ensures that only proofs generated by a trusted SP1 program can be verified.
46- bytes32 public sp1AggregatorProgramVKHash;
40+ /// @notice A mapping to track valid program IDs (image IDs for RISC Zero or vk hashes for SP1)
41+ /// to their corresponding verifier types. These program IDs are used to ensure that proofs are
42+ /// verified against known and registered programs.
43+ mapping (bytes32 => uint8 ) public programIds;
44+
45+ enum VerifierType {
46+ INVALID, // This to prevent default value being considered valid (when mapping returns 0 for non-existing keys)
47+ SP1,
48+ RISC0
49+ }
4750
4851 constructor () {
4952 _disableInitializers ();
@@ -54,45 +57,50 @@ contract AlignedProofAggregationService is
5457 address _alignedAggregatorAddress ,
5558 address _sp1VerifierAddress ,
5659 address _risc0VerifierAddress ,
57- bytes32 _risc0AggregatorProgramImageId ,
58- bytes32 _sp1AggregatorProgramVKHash
60+ bytes32 [] memory _programIds ,
61+ uint8 [] memory _verifierTypes
5962 ) public initializer {
6063 __Ownable_init ();
6164 __UUPSUpgradeable_init ();
6265 _transferOwnership (newOwner);
6366 alignedAggregatorAddress = _alignedAggregatorAddress;
6467 sp1VerifierAddress = _sp1VerifierAddress;
6568 risc0VerifierAddress = _risc0VerifierAddress;
66- risc0AggregatorProgramImageId = _risc0AggregatorProgramImageId;
67- sp1AggregatorProgramVKHash = _sp1AggregatorProgramVKHash;
69+ for (uint256 i = 0 ; i < _programIds.length ; i++ ) {
70+ programIds[_programIds[i]] = _verifierTypes[i];
71+ }
6872 }
6973
70- function verifySP1 (bytes32 blobVersionedHash , bytes calldata sp1PublicValues , bytes calldata sp1ProofBytes )
74+ function verifySP1 (bytes32 blobVersionedHash , bytes calldata sp1PublicValues , bytes calldata sp1ProofBytes , bytes32 programId )
7175 public
7276 onlyAlignedAggregator
7377 {
7478 (bytes32 merkleRoot ) = abi.decode (sp1PublicValues, (bytes32 ));
7579
80+ require (programIds[programId] == uint8 (VerifierType.SP1), "Invalid program ID " );
81+
7682 // In dev mode, poofs are mocked, so we skip the verification part
7783 if (_isSP1VerificationEnabled ()) {
78- ISP1Verifier (sp1VerifierAddress).verifyProof (sp1AggregatorProgramVKHash , sp1PublicValues, sp1ProofBytes);
84+ ISP1Verifier (sp1VerifierAddress).verifyProof (programId , sp1PublicValues, sp1ProofBytes);
7985 }
8086
8187 aggregatedProofs[merkleRoot] = true ;
8288 emit AggregatedProofVerified (merkleRoot, blobVersionedHash);
8389 }
8490
85- function verifyRisc0 (bytes32 blobVersionedHash , bytes calldata risc0ReceiptSeal , bytes calldata risc0JournalBytes )
91+ function verifyRisc0 (bytes32 blobVersionedHash , bytes calldata risc0ReceiptSeal , bytes calldata risc0JournalBytes , bytes32 programId )
8692 public
8793 onlyAlignedAggregator
8894 {
8995 (bytes32 merkleRoot ) = abi.decode (risc0JournalBytes, (bytes32 ));
9096
97+ require (programIds[programId] == uint8 (VerifierType.RISC0), "Invalid program ID " );
98+
9199 // In dev mode, poofs are mocked, so we skip the verification part
92100 if (_isRisc0VerificationEnabled ()) {
93101 bytes32 risc0JournalDigest = sha256 (risc0JournalBytes);
94102 IRiscZeroVerifier (risc0VerifierAddress).verify (
95- risc0ReceiptSeal, risc0AggregatorProgramImageId , risc0JournalDigest
103+ risc0ReceiptSeal, programId , risc0JournalDigest
96104 );
97105 }
98106
@@ -113,13 +121,17 @@ contract AlignedProofAggregationService is
113121 /// @param merklePath The Merkle proof (sibling hashes) needed to reconstruct the Merkle root.
114122 /// @param programId The identifier for the ZK program (image_id in RISC0 or vk hash in SP1).
115123 /// @param publicInputs The public inputs bytes of the proof.
124+ /// @param verifierType The type of verifier (SP1 or RISC0).
116125 ///
117126 /// @return bool Returns true if the computed Merkle root is a recognized valid aggregated proof.
118- function verifyProofInclusion (bytes32 [] calldata merklePath , bytes32 programId , bytes calldata publicInputs )
127+ function verifyProofInclusion (bytes32 [] calldata merklePath , bytes32 programId , bytes calldata publicInputs , VerifierType verifierType )
119128 public
120129 view
121130 returns (bool )
122131 {
132+ require (programIds[programId] == uint8 (verifierType), "Program ID not registered for the received verifier type " );
133+
134+ // TODO: consider adding the verifierType to the proof commitment to avoid potential collisions
123135 bytes32 proofCommitment = keccak256 (abi.encodePacked (programId, publicInputs));
124136 bytes32 merkleRoot = MerkleProof.processProofCalldata (merklePath, proofCommitment);
125137 return aggregatedProofs[merkleRoot];
@@ -153,24 +165,19 @@ contract AlignedProofAggregationService is
153165 emit Risc0VerifierAddressUpdated (_risc0VerifierAddress);
154166 }
155167
156- /// @notice Sets the image id of the Risc0 program
157- /// @param _risc0AggregatorProgramImageId The new imageid for the Risc0 aggregator program
158- function setRisc0AggregatorProgramImageId (bytes32 _risc0AggregatorProgramImageId ) external onlyOwner {
159- risc0AggregatorProgramImageId = _risc0AggregatorProgramImageId;
160- emit Risc0AggregatorProgramImageIdUpdated (_risc0AggregatorProgramImageId);
161- }
162-
163168 /// @notice Sets the address of the SP1 verifier contract
164169 /// @param _sp1VerifierAddress The new address for the SP1 verifier contract
165170 function setSP1VerifierAddress (address _sp1VerifierAddress ) external onlyOwner {
166171 sp1VerifierAddress = _sp1VerifierAddress;
167172 emit SP1VerifierAddressUpdated (_sp1VerifierAddress);
168173 }
169174
170- /// @notice Sets the vk hash of the sp1 program
171- /// @param _sp1AggregatorProgramVKHash The new vk hash for the sp1 aggregator program
172- function setSP1AggregatorProgramVKHash (bytes32 _sp1AggregatorProgramVKHash ) external onlyOwner {
173- sp1AggregatorProgramVKHash = _sp1AggregatorProgramVKHash;
174- emit SP1AggregatorProgramVKHashUpdated (_sp1AggregatorProgramVKHash);
175+ function addProgramId (bytes32 programId , VerifierType verifierType ) external onlyOwner {
176+ programIds[programId] = uint8 (verifierType);
177+ }
178+
179+ function deleteProgramId (bytes32 programId ) external onlyOwner {
180+ // Check if we should verify its existence before deleting
181+ delete programIds[programId];
175182 }
176183}
0 commit comments