Skip to content

Commit 6ec3c81

Browse files
fix: change the program ids to be a mapping program id =>verifier type
1 parent 47aaa56 commit 6ec3c81

1 file changed

Lines changed: 35 additions & 28 deletions

File tree

contracts/src/core/AlignedProofAggregationService.sol

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)