Skip to content

Commit a06d4e2

Browse files
Merge 451d400 into 3b38eb5
2 parents 3b38eb5 + 451d400 commit a06d4e2

19 files changed

+155
-41
lines changed

Makefile

+8-4
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,13 @@ reset_last_aggregated_block:
171171
@echo '{"last_aggregated_block":0}' > config-files/proof-aggregator.last_aggregated_block.json
172172

173173
start_proof_aggregator_dev: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with mock proofs (DEV mode)
174-
AGGREGATOR=$(AGGREGATOR) RISC0_DEV_MODE=1 cargo run --manifest-path ./aggregation_mode/Cargo.toml --release -- config-files/config-proof-aggregator-mock.yaml
174+
AGGREGATOR=$(AGGREGATOR) RISC0_DEV_MODE=1 cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --bin proof_aggregator -- config-files/config-proof-aggregator-mock.yaml
175175

176176
start_proof_aggregator: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with proving activated
177-
AGGREGATOR=$(AGGREGATOR) cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove -- config-files/config-proof-aggregator.yaml
177+
AGGREGATOR=$(AGGREGATOR) cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove --bin proof_aggregator -- config-files/config-proof-aggregator.yaml
178178

179179
start_proof_aggregator_gpu: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with proving + GPU acceleration (CUDA)
180-
AGGREGATOR=$(AGGREGATOR) SP1_PROVER=cuda cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove,gpu -- config-files/config-proof-aggregator.yaml
180+
AGGREGATOR=$(AGGREGATOR) SP1_PROVER=cuda cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove,gpu --bin proof_aggregator -- config-files/config-proof-aggregator.yaml
181181

182182
verify_aggregated_proof_sp1_holesky_stage:
183183
@echo "Verifying SP1 in aggregated proofs on holesky..."
@@ -204,7 +204,11 @@ verify_aggregated_proof_risc0_holesky_stage:
204204
--rpc_url https://ethereum-holesky-rpc.publicnode.com
205205

206206
install_aggregation_mode: ## Install the aggregation mode with proving enabled
207-
cargo install --path aggregation_mode --features prove,gpu
207+
cargo install --path aggregation_mode --features prove,gpu --bin proof_aggregator
208+
209+
agg_mode_write_program_ids: ## Write proof aggregator zkvm programs ids
210+
@cd aggregation_mode && \
211+
cargo run --release --bin write_program_image_id_vk_hash
208212

209213
_AGGREGATOR_:
210214

aggregation_mode/Cargo.toml

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ name = "proof_aggregator"
33
version = "0.1.0"
44
edition = "2021"
55

6-
76
[dependencies]
87
serde = { version = "1.0.203", features = ["derive"] }
98
serde_json = "1.0.117"
@@ -41,3 +40,11 @@ opt-level = 3
4140
default = []
4241
prove = []
4342
gpu = ["risc0-zkvm/cuda"]
43+
44+
[[bin]]
45+
name = "proof_aggregator"
46+
path = "./src/main.rs"
47+
48+
[[bin]]
49+
name = "write_program_image_id_vk_hash"
50+
path = "./bin/write_program_image_id_vk_hash.rs"

aggregation_mode/abi/AlignedProofAggregationService.json

+1-1
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use alloy::hex::hex;
2+
use proof_aggregator::aggregators::{
3+
risc0_aggregator::RISC0_AGGREGATOR_PROGRAM_ID_BYTES, sp1_aggregator,
4+
};
5+
use serde_json::json;
6+
use sp1_sdk::HashableKey;
7+
use std::{env, fs, path::Path};
8+
use tracing::info;
9+
use tracing_subscriber::FmtSubscriber;
10+
11+
const SP1_PROGRAM_ELF: &[u8] =
12+
include_bytes!("../aggregation_programs/sp1/elf/sp1_aggregator_program");
13+
14+
include!(concat!(env!("OUT_DIR"), "/methods.rs"));
15+
16+
fn main() {
17+
let subscriber = FmtSubscriber::builder().finish();
18+
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
19+
20+
info!("About to write sp1 programs vk hash bytes + risc0 programs image id bytes");
21+
let sp1_vk_hash = sp1_aggregator::vk_from_elf(SP1_PROGRAM_ELF).bytes32_raw();
22+
let risc0_image_id_bytes = RISC0_AGGREGATOR_PROGRAM_ID_BYTES;
23+
24+
let sp1_vk_hash_hex = hex::encode(sp1_vk_hash);
25+
let risc0_image_id_hex = hex::encode(risc0_image_id_bytes);
26+
27+
let dest_path = Path::new("programs_ids.json");
28+
29+
let json_data = json!({
30+
"sp1_vk_hash": format!("0x{}", sp1_vk_hash_hex),
31+
"risc0_image_id": format!("0x{}", risc0_image_id_hex),
32+
});
33+
34+
// Write to the file
35+
fs::write(dest_path, serde_json::to_string_pretty(&json_data).unwrap()).unwrap();
36+
37+
info!("Program ids written to {:?}", dest_path);
38+
}

aggregation_mode/programs_ids.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"risc0_image_id": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd",
3+
"sp1_vk_hash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6"
4+
}

aggregation_mode/src/aggregators/risc0_aggregator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use risc0_zkvm::{default_prover, ExecutorEnv, ProverOpts, Receipt};
44
use sha3::{Digest, Keccak256};
55

66
/// Byte representation of the aggregator image_id, converted from `[u32; 8]` to `[u8; 32]`.
7-
const RISC0_AGGREGATOR_PROGRAM_ID_BYTES: [u8; 32] = {
7+
pub const RISC0_AGGREGATOR_PROGRAM_ID_BYTES: [u8; 32] = {
88
let mut res = [0u8; 32];
99
let mut i = 0;
1010
while i < 8 {

aggregation_mode/src/backend/mod.rs

-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use config::Config;
2020
use fetcher::{ProofsFetcher, ProofsFetcherError};
2121
use merkle_tree::compute_proofs_merkle_root;
2222
use risc0_ethereum_contracts::encode_seal;
23-
use sp1_sdk::HashableKey;
2423
use std::str::FromStr;
2524
use tracing::{error, info, warn};
2625
use types::{AlignedProofAggregationService, AlignedProofAggregationServiceContract};
@@ -154,7 +153,6 @@ impl ProofAggregator {
154153
self.proof_aggregation_service
155154
.verifySP1(
156155
blob_versioned_hash.into(),
157-
proof.vk().bytes32_raw().into(),
158156
proof.proof_with_pub_values.public_values.to_vec().into(),
159157
proof.proof_with_pub_values.bytes().into(),
160158
)
@@ -170,7 +168,6 @@ impl ProofAggregator {
170168
.verifyRisc0(
171169
blob_versioned_hash.into(),
172170
encoded_seal.into(),
173-
proof.image_id.into(),
174171
proof.receipt.journal.bytes.into(),
175172
)
176173
.sidecar(blob)

contracts/script/deploy/AlignedProofAggregationServiceDeployer.s.sol

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ contract AlignedProofAggregationServiceDeployer is Script {
1212

1313
address alignedAggregatorAddress = stdJson.readAddress(config_data, ".address.alignedAggregatorAddress");
1414
address sp1VerifierAddress = stdJson.readAddress(config_data, ".address.sp1VerifierAddress");
15+
bytes32 sp1AggregationProgramVKHash =
16+
stdJson.readBytes32(config_data, ".programs_id.sp1AggregationProgramVKHash");
1517
address risc0VerifierAddress = stdJson.readAddress(config_data, ".address.risc0VerifierAddress");
18+
bytes32 risc0AggregationProgramImageId =
19+
stdJson.readBytes32(config_data, ".programs_id.risc0AggregationProgramImageId");
1620

1721
address ownerAddress = stdJson.readAddress(config_data, ".permissions.owner");
1822

@@ -23,11 +27,13 @@ contract AlignedProofAggregationServiceDeployer is Script {
2327
ERC1967Proxy proxy = new ERC1967Proxy(
2428
address(alignedProofAggregationService),
2529
abi.encodeWithSignature(
26-
"initialize(address,address,address,address)",
30+
"initialize(address,address,address,address,bytes32,bytes32)",
2731
ownerAddress,
2832
alignedAggregatorAddress,
2933
sp1VerifierAddress,
30-
risc0VerifierAddress
34+
risc0VerifierAddress,
35+
risc0AggregationProgramImageId,
36+
sp1AggregationProgramVKHash
3137
)
3238
);
3339

contracts/script/deploy/config/devnet/proof-aggregator-service.devnet.config.json

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
"alignedAggregatorAddress": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
66
"alignedAggregatorAddressPrivateKey": "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"
77
},
8+
"programs_id": {
9+
"sp1AggregationProgramVKHash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6",
10+
"risc0AggregationProgramImageId": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd"
11+
},
812
"permissions": {
913
"owner": "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955"
1014
}

contracts/script/deploy/config/devnet/proof-aggregator-service.devnet.mock.config.json

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
"alignedAggregatorAddress": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
66
"alignedAggregatorAddressPrivateKey": "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"
77
},
8+
"programs_id": {
9+
"sp1AggregationProgramVKHash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6",
10+
"risc0AggregationProgramImageId": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd"
11+
},
812
"permissions": {
913
"owner": "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955"
1014
}

contracts/script/deploy/config/holesky/proof-aggregator-service.holesky.config.json

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"risc0VerifierAddress": "0xf70aBAb028Eb6F4100A24B203E113D94E87DE93C",
55
"alignedAggregatorAddress": "0x9403dF48130621f87974a5A1d1d11d3aF1222A82"
66
},
7+
"programs_id": {
8+
"sp1AggregationProgramVKHash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6",
9+
"risc0AggregationProgramImageId": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd"
10+
},
711
"permissions": {
812
"owner": "0x97aEC5F28181abe5d2aD40dBe7FbaEe014529b7D"
913
}

contracts/script/deploy/config/holesky/proof-aggregator-service.holesky.config.stage.json

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"risc0VerifierAddress": "0xf70aBAb028Eb6F4100A24B203E113D94E87DE93C",
55
"alignedAggregatorAddress": "0x3595aa7d30f89f65933e7421dec77e4478d9fb01"
66
},
7+
"programs_id": {
8+
"sp1AggregationProgramVKHash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6",
9+
"risc0AggregationProgramImageId": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd"
10+
},
711
"permissions": {
812
"owner": "0xE3C695b73dbe27106aF4530b152de3e57456B385"
913
}

contracts/script/deploy/config/mainnet/proof-aggregator-service.mainnet.config.json

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"risc0VerifierAddress": "0x8EaB2D97Dfce405A1692a21b3ff3A172d593D319",
55
"alignedAggregatorAddress": "<aligned_aggregator_address>"
66
},
7+
"programs_id": {
8+
"sp1AggregationProgramVKHash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6",
9+
"risc0AggregationProgramImageId": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd"
10+
},
711
"permissions": {
812
"owner": "<owner_address>"
913
}

contracts/script/deploy/config/mainnet_staging/proof-aggregator-service.mainnet.config.json

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"risc0VerifierAddress": "0x8EaB2D97Dfce405A1692a21b3ff3A172d593D319",
55
"alignedAggregatorAddress": "<aligned_aggregator_address>"
66
},
7+
"programs_id": {
8+
"sp1AggregationProgramVKHash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6",
9+
"risc0AggregationProgramImageId": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd"
10+
},
711
"permissions": {
812
"owner": "<owner_address>"
913
}

contracts/script/deploy/config/sepolia/proof-aggregator-service.sepolia.config.json

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"risc0VerifierAddress": "0x925d8331ddc0a1F0d96E68CF073DFE1d92b69187",
55
"alignedAggregatorAddress": "<aligned_aggregator_address>"
66
},
7+
"programs_id": {
8+
"sp1AggregationProgramVKHash": "0x00eb8139c8360fc371b9a6decdec55ba01aaae0f4739f68139e0b3d40397d1d6",
9+
"risc0AggregationProgramImageId": "0xa2966b3e63b5e73848dd3fb8ff1e03ac68ca10fa961ca0c0d8dbbb0a85b60acd"
10+
},
711
"permissions": {
812
"owner": "<owner_address>"
913
}

contracts/scripts/anvil/deploy_aligned_contracts.sh

+17
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,23 @@ rm -f "script/output/devnet/alignedlayer_deployment_output.temp1.json"
6565
rm -f "script/output/devnet/alignedlayer_deployment_output.temp2.json"
6666

6767

68+
# Update Program IDs in anvil deployment
69+
cd ..
70+
make agg_mode_write_program_ids
71+
72+
# Copy new values to config file
73+
jq '.programs_id.risc0AggregationProgramImageId = $input[0].risc0_image_id | .programs_id.sp1AggregationProgramVKHash = $input[0].sp1_vk_hash' \
74+
--slurpfile input aggregation_mode/programs_ids.json \
75+
contracts/script/deploy/config/devnet/proof-aggregator-service.devnet.config.json \
76+
> temp.json && mv temp.json contracts/script/deploy/config/devnet/proof-aggregator-service.devnet.config.json
77+
78+
jq '.programs_id.risc0AggregationProgramImageId = $input[0].risc0_image_id | .programs_id.sp1AggregationProgramVKHash = $input[0].sp1_vk_hash' \
79+
--slurpfile input aggregation_mode/programs_ids.json \
80+
contracts/script/deploy/config/devnet/proof-aggregator-service.devnet.mock.config.json \
81+
> temp.json && mv temp.json contracts/script/deploy/config/devnet/proof-aggregator-service.devnet.mock.config.json
82+
83+
cd contracts
84+
6885
# Deploy proof aggregation service contract with SP1 Verifier
6986
forge script script/deploy/AlignedProofAggregationServiceDeployer.s.sol \
7087
./script/deploy/config/devnet/proof-aggregator-service.devnet.config.json \

contracts/scripts/anvil/state/alignedlayer-deployed-anvil-state.json

+1-1
Large diffs are not rendered by default.

contracts/src/core/AlignedProofAggregationService.sol

+37-15
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ contract AlignedProofAggregationService is
3636
/// if the sp1 verifier address is set to this address, then we skip verification
3737
address public constant VERIFIER_MOCK_ADDRESS = address(0xFF);
3838

39+
/// The unique identifier (image ID) of the RISC Zero aggregator program.
40+
/// This ensures that only proofs generated by a trusted Risc0 program can be verified.
41+
bytes32 public risc0AggregatorProgramImageId;
42+
43+
/// The verification key hash for the SP1 aggregator program.
44+
/// This ensures that only proofs generated by a trusted SP1 program can be verified.
45+
bytes32 public sp1AggregatorProgramVKHash;
46+
3947
constructor() {
4048
_disableInitializers();
4149
}
@@ -44,45 +52,47 @@ contract AlignedProofAggregationService is
4452
address newOwner,
4553
address _alignedAggregatorAddress,
4654
address _sp1VerifierAddress,
47-
address _risc0VerifierAddress
55+
address _risc0VerifierAddress,
56+
bytes32 _risc0AggregatorProgramImageId,
57+
bytes32 _sp1AggregatorProgramVKHash
4858
) public initializer {
4959
__Ownable_init();
5060
__UUPSUpgradeable_init();
5161
_transferOwnership(newOwner);
5262
alignedAggregatorAddress = _alignedAggregatorAddress;
5363
sp1VerifierAddress = _sp1VerifierAddress;
5464
risc0VerifierAddress = _risc0VerifierAddress;
65+
risc0AggregatorProgramImageId = _risc0AggregatorProgramImageId;
66+
sp1AggregatorProgramVKHash = _sp1AggregatorProgramVKHash;
5567
}
5668

57-
function verifySP1(
58-
bytes32 blobVersionedHash,
59-
bytes32 sp1ProgramVKey,
60-
bytes calldata sp1PublicValues,
61-
bytes calldata sp1ProofBytes
62-
) public onlyAlignedAggregator {
69+
function verifySP1(bytes32 blobVersionedHash, bytes calldata sp1PublicValues, bytes calldata sp1ProofBytes)
70+
public
71+
onlyAlignedAggregator
72+
{
6373
(bytes32 merkleRoot) = abi.decode(sp1PublicValues, (bytes32));
6474

6575
// In dev mode, poofs are mocked, so we skip the verification part
6676
if (_isSP1VerificationEnabled()) {
67-
ISP1Verifier(sp1VerifierAddress).verifyProof(sp1ProgramVKey, sp1PublicValues, sp1ProofBytes);
77+
ISP1Verifier(sp1VerifierAddress).verifyProof(sp1AggregatorProgramVKHash, sp1PublicValues, sp1ProofBytes);
6878
}
6979

7080
aggregatedProofs[merkleRoot] = true;
7181
emit AggregatedProofVerified(merkleRoot, blobVersionedHash);
7282
}
7383

74-
function verifyRisc0(
75-
bytes32 blobVersionedHash,
76-
bytes calldata risc0ReceiptSeal,
77-
bytes32 risc0ImageId,
78-
bytes calldata risc0JournalBytes
79-
) public onlyAlignedAggregator {
84+
function verifyRisc0(bytes32 blobVersionedHash, bytes calldata risc0ReceiptSeal, bytes calldata risc0JournalBytes)
85+
public
86+
onlyAlignedAggregator
87+
{
8088
(bytes32 merkleRoot) = abi.decode(risc0JournalBytes, (bytes32));
8189

8290
// In dev mode, poofs are mocked, so we skip the verification part
8391
if (_isRisc0VerificationEnabled()) {
8492
bytes32 risc0JournalDigest = sha256(risc0JournalBytes);
85-
IRiscZeroVerifier(risc0VerifierAddress).verify(risc0ReceiptSeal, risc0ImageId, risc0JournalDigest);
93+
IRiscZeroVerifier(risc0VerifierAddress).verify(
94+
risc0ReceiptSeal, risc0AggregatorProgramImageId, risc0JournalDigest
95+
);
8696
}
8797

8898
aggregatedProofs[merkleRoot] = true;
@@ -115,4 +125,16 @@ contract AlignedProofAggregationService is
115125
function setRisc0VerifierAddress(address _risc0VerifierAddress) external onlyOwner {
116126
risc0VerifierAddress = _risc0VerifierAddress;
117127
}
128+
129+
/// @notice Sets the image id of the Risc0 program
130+
/// @param _risc0AggregatorProgramImageId The new imageid for the Risc0 aggregator program
131+
function setRisc0AggregatorProgramImageId(bytes32 _risc0AggregatorProgramImageId) external onlyOwner {
132+
risc0AggregatorProgramImageId = _risc0AggregatorProgramImageId;
133+
}
134+
135+
/// @notice Sets the vk hash of the sp1 program
136+
/// @param _sp1AggregatorProgramVKHash The new vk hash for the sp1 aggregator program
137+
function setSP1AggregatorProgramVKHash(bytes32 _sp1AggregatorProgramVKHash) external onlyOwner {
138+
sp1AggregatorProgramVKHash = _sp1AggregatorProgramVKHash;
139+
}
118140
}

contracts/src/core/IAlignedProofAggregationService.sol

+4-13
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,13 @@ interface IAlignedProofAggregationService {
55
/// @dev This function is called by the aligned proof aggregator after collecting the proofs and aggregating them
66
/// to be verified on-chain. We expect the blobTransactionHash to be called before
77
/// @param blobVersionedHash the versioned hash of the blob transaction that contains the leaves that compose the merkle root.
8-
/// @param sp1ProgramVKey Public verifying key
98
/// @param sp1PublicValues Values used to perform the execution
109
/// @param sp1ProofBytes Groth16 proof
11-
function verifySP1(
12-
bytes32 blobVersionedHash,
13-
bytes32 sp1ProgramVKey,
14-
bytes calldata sp1PublicValues,
15-
bytes calldata sp1ProofBytes
16-
) external;
10+
function verifySP1(bytes32 blobVersionedHash, bytes calldata sp1PublicValues, bytes calldata sp1ProofBytes)
11+
external;
1712

18-
function verifyRisc0(
19-
bytes32 blobVersionedHash,
20-
bytes calldata risc0ReceiptSeal,
21-
bytes32 risc0ImageId,
22-
bytes calldata risc0JournalBytes
23-
) external;
13+
function verifyRisc0(bytes32 blobVersionedHash, bytes calldata risc0ReceiptSeal, bytes calldata risc0JournalBytes)
14+
external;
2415

2516
/// @notice event that gets emitted after a successful aggregated proof verification
2617
event AggregatedProofVerified(bytes32 indexed merkleRoot, bytes32 blobVersionedHash);

0 commit comments

Comments
 (0)