-
Notifications
You must be signed in to change notification settings - Fork 396
Expand file tree
/
Copy pathAlignedProofAggregationService.sol
More file actions
140 lines (117 loc) · 5.8 KB
/
AlignedProofAggregationService.sol
File metadata and controls
140 lines (117 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol";
import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin-upgrades/contracts/proxy/utils/UUPSUpgradeable.sol";
import {IAlignedProofAggregationService} from "./IAlignedProofAggregationService.sol";
import {ISP1Verifier} from "@sp1-contracts/ISP1Verifier.sol";
import {IRiscZeroVerifier} from "@risc0-contracts/IRiscZeroVerifier.sol";
contract AlignedProofAggregationService is
IAlignedProofAggregationService,
Initializable,
OwnableUpgradeable,
UUPSUpgradeable
{
/// @notice Map the merkle root to a boolean to indicate it was verified
mapping(bytes32 => bool) public aggregatedProofs;
/// @notice The address of the SP1 verifier contract.
/// @dev This can either be a specific SP1Verifier for a specific version, or the
/// SP1VerifierGateway which can be used to verify proofs for any version of SP1.
/// For the list of supported verifiers on each chain, see:
/// https://docs.succinct.xyz/onchain-verification/contract-addresses
address public sp1VerifierAddress;
/// @notice The address of the Wallet that is allowed to call the verify function.
address public alignedAggregatorAddress;
/// @notice The address of the Risc0 verifier contract
/// @dev See supported verifier here:
/// https://dev.risczero.com/api/blockchain-integration/contracts/verifier#contract-addresses
address public risc0VerifierAddress;
/// @notice whether we are in dev mode or not
/// if the sp1 verifier address is set to this address, then we skip verification
address public constant VERIFIER_MOCK_ADDRESS = address(0xFF);
/// 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;
/// 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;
constructor() {
_disableInitializers();
}
function initialize(
address newOwner,
address _alignedAggregatorAddress,
address _sp1VerifierAddress,
address _risc0VerifierAddress,
bytes32 _risc0AggregatorProgramImageId,
bytes32 _sp1AggregatorProgramVKHash
) public initializer {
__Ownable_init();
__UUPSUpgradeable_init();
_transferOwnership(newOwner);
alignedAggregatorAddress = _alignedAggregatorAddress;
sp1VerifierAddress = _sp1VerifierAddress;
risc0VerifierAddress = _risc0VerifierAddress;
risc0AggregatorProgramImageId = _risc0AggregatorProgramImageId;
sp1AggregatorProgramVKHash = _sp1AggregatorProgramVKHash;
}
function verifySP1(bytes32 blobVersionedHash, bytes calldata sp1PublicValues, bytes calldata sp1ProofBytes)
public
onlyAlignedAggregator
{
(bytes32 merkleRoot) = abi.decode(sp1PublicValues, (bytes32));
// In dev mode, poofs are mocked, so we skip the verification part
if (_isSP1VerificationEnabled()) {
ISP1Verifier(sp1VerifierAddress).verifyProof(sp1AggregatorProgramVKHash, sp1PublicValues, sp1ProofBytes);
}
aggregatedProofs[merkleRoot] = true;
emit AggregatedProofVerified(merkleRoot, blobVersionedHash);
}
function verifyRisc0(bytes32 blobVersionedHash, bytes calldata risc0ReceiptSeal, bytes calldata risc0JournalBytes)
public
onlyAlignedAggregator
{
(bytes32 merkleRoot) = abi.decode(risc0JournalBytes, (bytes32));
// In dev mode, poofs are mocked, so we skip the verification part
if (_isRisc0VerificationEnabled()) {
bytes32 risc0JournalDigest = sha256(risc0JournalBytes);
IRiscZeroVerifier(risc0VerifierAddress).verify(
risc0ReceiptSeal, risc0AggregatorProgramImageId, risc0JournalDigest
);
}
aggregatedProofs[merkleRoot] = true;
emit AggregatedProofVerified(merkleRoot, blobVersionedHash);
}
function _isSP1VerificationEnabled() internal view returns (bool) {
return sp1VerifierAddress != VERIFIER_MOCK_ADDRESS;
}
function _isRisc0VerificationEnabled() internal view returns (bool) {
return risc0VerifierAddress != VERIFIER_MOCK_ADDRESS;
}
function _authorizeUpgrade(address newImplementation)
internal
override
onlyOwner // solhint-disable-next-line no-empty-blocks
{}
modifier onlyAlignedAggregator() {
if (msg.sender != alignedAggregatorAddress) {
revert OnlyAlignedAggregator(msg.sender);
}
_;
}
/// @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;
}
/// @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;
}
/// @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;
}
}