Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ is_aggregator_set:
fi

start_proof_aggregator_dev: is_aggregator_set ## Starts proof aggregator with mock proofs (DEV mode)
AGGREGATOR=$(AGGREGATOR) RISC0_DEV_MODE=1 cargo run --manifest-path ./aggregation_mode/Cargo.toml --release -- config-files/config-proof-aggregator-mock.yaml
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

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

start_proof_aggregator_gpu: is_aggregator_set ## Starts proof aggregator with proving + GPU acceleration (CUDA)
AGGREGATOR=$(AGGREGATOR) SP1_PROVER=cuda cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove,gpu -- config-files/config-proof-aggregator.yaml
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

verify_aggregated_proof_sp1_holesky_stage:
@echo "Verifying SP1 in aggregated proofs on holesky..."
Expand Down Expand Up @@ -202,6 +202,9 @@ verify_aggregated_proof_risc0_holesky_stage:
install_aggregation_mode: ## Install the aggregation mode with proving enabled
cargo install --path aggregation_mode --features prove
Comment thread
MarcosNicolau marked this conversation as resolved.
Outdated

agg_mode_write_program_ids: ## Write proof aggregator zkvm programs ids
cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --bin write_program_image_id_vk_hash

_AGGREGATOR_:

build_aggregator:
Expand Down
9 changes: 8 additions & 1 deletion aggregation_mode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name = "proof_aggregator"
version = "0.1.0"
edition = "2021"


[dependencies]
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
Expand Down Expand Up @@ -41,3 +40,11 @@ opt-level = 3
default = []
prove = []
gpu = ["risc0-zkvm/cuda"]

[[bin]]
name = "proof_aggregator"
path = "./src/main.rs"

[[bin]]
name = "write_program_image_id_vk_hash"
path = "./bin/write_program_image_id_vk_hash.rs"
2 changes: 1 addition & 1 deletion aggregation_mode/abi/AlignedProofAggregationService.json

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions aggregation_mode/bin/write_program_image_id_vk_hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use alloy::hex::hex;
use proof_aggregator::aggregators::{
risc0_aggregator::RISC0_AGGREGATOR_PROGRAM_ID_BYTES, sp1_aggregator,
};
use serde_json::json;
use sp1_sdk::HashableKey;
use std::{env, fs, path::Path};
use tracing::info;
use tracing_subscriber::FmtSubscriber;

const SP1_PROGRAM_ELF: &[u8] =
include_bytes!("../aggregation_programs/sp1/elf/sp1_aggregator_program");

include!(concat!(env!("OUT_DIR"), "/methods.rs"));

fn main() {
let subscriber = FmtSubscriber::builder().finish();
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");

info!("About to write sp1 programs vk hash bytes + risc0 programs image id bytes");
let sp1_vk_hash = sp1_aggregator::vk_from_elf(SP1_PROGRAM_ELF).bytes32_raw();
let risc0_image_id_bytes = RISC0_AGGREGATOR_PROGRAM_ID_BYTES;

let sp1_vk_hash_hex = hex::encode(sp1_vk_hash);
let risc0_image_id_hex = hex::encode(risc0_image_id_bytes);

let dest_path = Path::new("programs_ids.json");

let json_data = json!({
"sp1_vk_hash": format!("0x{}", sp1_vk_hash_hex),
"risc0_image_id": format!("0x{}", risc0_image_id_hex),
});

// Write to the file
fs::write(
&dest_path,
serde_json::to_string_pretty(&json_data).unwrap(),
)
.unwrap();
Copy link
Copy Markdown
Member Author

@MarcosNicolau MarcosNicolau Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also considered printing it to the console instead of writing it to a file, as this is only available in the contracts deployment configs.


info!("Program ids written to {:?}", dest_path);
}
4 changes: 4 additions & 0 deletions aggregation_mode/programs_ids.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"risc0_image_id": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86",
"sp1_vk_hash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39"
}
2 changes: 1 addition & 1 deletion aggregation_mode/src/aggregators/risc0_aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use risc0_zkvm::{default_prover, ExecutorEnv, ProverOpts, Receipt};
use sha3::{Digest, Keccak256};

/// Byte representation of the aggregator image_id, converted from `[u32; 8]` to `[u8; 32]`.
const RISC0_AGGREGATOR_PROGRAM_ID_BYTES: [u8; 32] = {
pub const RISC0_AGGREGATOR_PROGRAM_ID_BYTES: [u8; 32] = {
let mut res = [0u8; 32];
let mut i = 0;
while i < 8 {
Expand Down
3 changes: 0 additions & 3 deletions aggregation_mode/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use config::Config;
use fetcher::{ProofsFetcher, ProofsFetcherError};
use merkle_tree::compute_proofs_merkle_root;
use risc0_ethereum_contracts::encode_seal;
use sp1_sdk::HashableKey;
use std::str::FromStr;
use tracing::{error, info, warn};
use types::{AlignedProofAggregationService, AlignedProofAggregationServiceContract};
Expand Down Expand Up @@ -154,7 +153,6 @@ impl ProofAggregator {
self.proof_aggregation_service
.verifySP1(
blob_versioned_hash.into(),
proof.vk().bytes32_raw().into(),
proof.proof_with_pub_values.public_values.to_vec().into(),
proof.proof_with_pub_values.bytes().into(),
)
Expand All @@ -170,7 +168,6 @@ impl ProofAggregator {
.verifyRisc0(
blob_versioned_hash.into(),
encoded_seal.into(),
proof.image_id.into(),
proof.receipt.journal.bytes.into(),
)
.sidecar(blob)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ contract AlignedProofAggregationServiceDeployer is Script {

address alignedAggregatorAddress = stdJson.readAddress(config_data, ".address.alignedAggregatorAddress");
address sp1VerifierAddress = stdJson.readAddress(config_data, ".address.sp1VerifierAddress");
bytes32 sp1AggregationProgramVKHash =
stdJson.readBytes32(config_data, ".programs_id.sp1AggregationProgramVKHash");
address risc0VerifierAddress = stdJson.readAddress(config_data, ".address.risc0VerifierAddress");
bytes32 risc0AggregationProgramImageId =
stdJson.readBytes32(config_data, ".programs_id.risc0AggregationProgramImageId");

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

Expand All @@ -23,11 +27,13 @@ contract AlignedProofAggregationServiceDeployer is Script {
ERC1967Proxy proxy = new ERC1967Proxy(
address(alignedProofAggregationService),
abi.encodeWithSignature(
"initialize(address,address,address,address)",
"initialize(address,address,address,address,bytes32,bytes32)",
ownerAddress,
alignedAggregatorAddress,
sp1VerifierAddress,
risc0VerifierAddress
risc0VerifierAddress,
risc0AggregationProgramImageId,
sp1AggregationProgramVKHash
)
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"address": {
"sp1VerifierAddress": "0xB146FbFdFeC2a5182b3Cef9becE03290224256D5",
"risc0VerifierAddress": "0x663F3ad617193148711d28f5334eE4Ed07016602",
"alignedAggregatorAddress": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"alignedAggregatorAddressPrivateKey": "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"
},
"permissions": {
"owner": "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955"
}
"address": {
"sp1VerifierAddress": "0xB146FbFdFeC2a5182b3Cef9becE03290224256D5",
"risc0VerifierAddress": "0x663F3ad617193148711d28f5334eE4Ed07016602",
"alignedAggregatorAddress": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"alignedAggregatorAddressPrivateKey": "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"
},
"programs_id": {
"sp1AggregationProgramVKHash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39",
"risc0AggregationProgramImageId": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86"
},
"permissions": {
"owner": "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
"alignedAggregatorAddress": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"alignedAggregatorAddressPrivateKey": "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"
},
"programs_id": {
"sp1AggregationProgramVKHash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39",
"risc0AggregationProgramImageId": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86"
},
"permissions": {
"owner": "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"risc0VerifierAddress": "0xf70aBAb028Eb6F4100A24B203E113D94E87DE93C",
"alignedAggregatorAddress": "0x9403dF48130621f87974a5A1d1d11d3aF1222A82"
},
"programs_id": {
"sp1AggregationProgramVKHash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39",
"risc0AggregationProgramImageId": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86"
},
"permissions": {
"owner": "0x97aEC5F28181abe5d2aD40dBe7FbaEe014529b7D"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"risc0VerifierAddress": "0xf70aBAb028Eb6F4100A24B203E113D94E87DE93C",
"alignedAggregatorAddress": "0x3595aa7d30f89f65933e7421dec77e4478d9fb01"
},
"programs_id": {
"sp1AggregationProgramVKHash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39",
"risc0AggregationProgramImageId": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86"
},
"permissions": {
"owner": "0xE3C695b73dbe27106aF4530b152de3e57456B385"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"risc0VerifierAddress": "0x8EaB2D97Dfce405A1692a21b3ff3A172d593D319",
"alignedAggregatorAddress": "<aligned_aggregator_address>"
},
"programs_id": {
"sp1AggregationProgramVKHash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39",
"risc0AggregationProgramImageId": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86"
},
"permissions": {
"owner": "<owner_address>"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"risc0VerifierAddress": "0x8EaB2D97Dfce405A1692a21b3ff3A172d593D319",
"alignedAggregatorAddress": "<aligned_aggregator_address>"
},
"programs_id": {
"sp1AggregationProgramVKHash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39",
"risc0AggregationProgramImageId": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86"
},
"permissions": {
"owner": "<owner_address>"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"risc0VerifierAddress": "0x925d8331ddc0a1F0d96E68CF073DFE1d92b69187",
"alignedAggregatorAddress": "<aligned_aggregator_address>"
},
"programs_id": {
"sp1AggregationProgramVKHash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39",
"risc0AggregationProgramImageId": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86"
},
"permissions": {
"owner": "<owner_address>"
}
Expand Down

Large diffs are not rendered by default.

52 changes: 37 additions & 15 deletions contracts/src/core/AlignedProofAggregationService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ contract AlignedProofAggregationService is
/// 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();
}
Expand All @@ -44,45 +52,47 @@ contract AlignedProofAggregationService is
address newOwner,
address _alignedAggregatorAddress,
address _sp1VerifierAddress,
address _risc0VerifierAddress
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,
bytes32 sp1ProgramVKey,
bytes calldata sp1PublicValues,
bytes calldata sp1ProofBytes
) public onlyAlignedAggregator {
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(sp1ProgramVKey, sp1PublicValues, sp1ProofBytes);
ISP1Verifier(sp1VerifierAddress).verifyProof(sp1AggregatorProgramVKHash, sp1PublicValues, sp1ProofBytes);
}

aggregatedProofs[merkleRoot] = true;
emit AggregatedProofVerified(merkleRoot, blobVersionedHash);
}

function verifyRisc0(
bytes32 blobVersionedHash,
bytes calldata risc0ReceiptSeal,
bytes32 risc0ImageId,
bytes calldata risc0JournalBytes
) public onlyAlignedAggregator {
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, risc0ImageId, risc0JournalDigest);
IRiscZeroVerifier(risc0VerifierAddress).verify(
risc0ReceiptSeal, risc0AggregatorProgramImageId, risc0JournalDigest
);
}

aggregatedProofs[merkleRoot] = true;
Expand Down Expand Up @@ -115,4 +125,16 @@ contract AlignedProofAggregationService is
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;
}
Comment thread
MauroToscano marked this conversation as resolved.
}
17 changes: 4 additions & 13 deletions contracts/src/core/IAlignedProofAggregationService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,13 @@ interface IAlignedProofAggregationService {
/// @dev This function is called by the aligned proof aggregator after collecting the proofs and aggregating them
/// to be verified on-chain. We expect the blobTransactionHash to be called before
/// @param blobVersionedHash the versioned hash of the blob transaction that contains the leaves that compose the merkle root.
/// @param sp1ProgramVKey Public verifying key
/// @param sp1PublicValues Values used to perform the execution
/// @param sp1ProofBytes Groth16 proof
function verifySP1(
bytes32 blobVersionedHash,
bytes32 sp1ProgramVKey,
bytes calldata sp1PublicValues,
bytes calldata sp1ProofBytes
) external;
function verifySP1(bytes32 blobVersionedHash, bytes calldata sp1PublicValues, bytes calldata sp1ProofBytes)
external;

function verifyRisc0(
bytes32 blobVersionedHash,
bytes calldata risc0ReceiptSeal,
bytes32 risc0ImageId,
bytes calldata risc0JournalBytes
) external;
function verifyRisc0(bytes32 blobVersionedHash, bytes calldata risc0ReceiptSeal, bytes calldata risc0JournalBytes)
external;

/// @notice event that gets emitted after a successful aggregated proof verification
event AggregatedProofVerified(bytes32 indexed merkleRoot, bytes32 blobVersionedHash);
Expand Down
4 changes: 4 additions & 0 deletions programs_ids.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"risc0_image_id": "0x616eccca41e741062c79481078c0cbaa034da436c2ba254b09de8c2cf20bdd86",
"sp1_vk_hash": "0x00964e05feb8c81d33714c9a9d66d0941210996853b8886d40e8c85ed3a4fa39"
}