-
Notifications
You must be signed in to change notification settings - Fork 396
Expand file tree
/
Copy pathmod.rs
More file actions
145 lines (126 loc) · 4.7 KB
/
mod.rs
File metadata and controls
145 lines (126 loc) · 4.7 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
141
142
143
144
145
pub mod risc0_aggregator;
pub mod sp1_aggregator;
use std::fmt::Display;
use risc0_aggregator::{
AlignedRisc0VerificationError, Risc0AggregationError, Risc0ProofReceiptAndImageId,
};
use sp1_aggregator::{
AlignedSP1VerificationError, SP1AggregationError, SP1ProofWithPubValuesAndElf,
};
#[derive(Clone, Debug)]
pub enum ZKVMEngine {
SP1,
RISC0,
}
impl Display for ZKVMEngine {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::SP1 => write!(f, "SP1"),
Self::RISC0 => write!(f, "Risc0"),
}
}
}
#[derive(Debug)]
pub enum ProofAggregationError {
SP1Aggregation(SP1AggregationError),
Risc0Aggregation(Risc0AggregationError),
PublicInputsDeserialization,
}
impl ZKVMEngine {
pub fn from_env() -> Option<Self> {
let key = "AGGREGATOR";
let value = std::env::var(key).ok()?;
let engine = match value.as_str() {
"sp1" => ZKVMEngine::SP1,
"risc0" => ZKVMEngine::RISC0,
_ => panic!("Invalid AGGREGATOR, possible options are: sp1|risc0"),
};
Some(engine)
}
/// Aggregates a list of [`AlignedProof`]s into a single [`AlignedProof`].
///
/// Returns a tuple containing:
/// - The aggregated [`AlignedProof`], representing the combined proof
/// - The Merkle root computed within the ZKVM, exposed as a public input
///
/// This function performs proof aggregation and ensures the resulting Merkle root
/// can be independently verified by external systems.
pub fn aggregate_proofs(
&self,
proofs: Vec<AlignedProof>,
) -> Result<(AlignedProof, [u8; 32]), ProofAggregationError> {
let res = match self {
ZKVMEngine::SP1 => {
let proofs = proofs
.into_iter()
// Fetcher already filtered for SP1
// We do this for type casting, as to avoid using generics
// or macros in this function
.filter_map(|proof| match proof {
AlignedProof::SP1(proof) => Some(*proof),
_ => None,
})
.collect();
let mut agg_proof = sp1_aggregator::aggregate_proofs(proofs)
.map_err(ProofAggregationError::SP1Aggregation)?;
let merkle_root: [u8; 32] = agg_proof
.proof_with_pub_values
.public_values
.read::<[u8; 32]>();
(AlignedProof::SP1(agg_proof.into()), merkle_root)
}
ZKVMEngine::RISC0 => {
let proofs = proofs
.into_iter()
// Fetcher already filtered for Risc0
// We do this for type casting, as to avoid using generics
// or macros in this function
.filter_map(|proof| match proof {
AlignedProof::Risc0(proof) => Some(*proof),
_ => None,
})
.collect();
let agg_proof = risc0_aggregator::aggregate_proofs(proofs)
.map_err(ProofAggregationError::Risc0Aggregation)?;
// Note: journal.decode() won't work here as risc0 deserializer works under u32 words
let public_input_bytes = agg_proof.receipt.journal.as_ref();
let merkle_root: [u8; 32] = public_input_bytes
.try_into()
.map_err(|_| ProofAggregationError::PublicInputsDeserialization)?;
(AlignedProof::Risc0(agg_proof.into()), merkle_root)
}
};
Ok(res)
}
}
pub enum AlignedProof {
SP1(Box<SP1ProofWithPubValuesAndElf>),
Risc0(Box<Risc0ProofReceiptAndImageId>),
}
impl AlignedProof {
pub fn commitment(&self) -> [u8; 32] {
match self {
AlignedProof::SP1(proof) => proof.hash_vk_and_pub_inputs(),
AlignedProof::Risc0(proof) => proof.hash_image_id_and_public_inputs(),
}
}
}
#[derive(Debug)]
pub enum AlignedVerificationError {
Sp1(AlignedSP1VerificationError),
Risc0(AlignedRisc0VerificationError),
}
impl AlignedProof {
pub fn verify(&self) -> Result<(), AlignedVerificationError> {
match self {
AlignedProof::SP1(proof) => sp1_aggregator::verify(proof).map_err(
|arg0: sp1_aggregator::AlignedSP1VerificationError| {
AlignedVerificationError::Sp1(arg0)
},
),
AlignedProof::Risc0(proof) => {
risc0_aggregator::verify(proof).map_err(AlignedVerificationError::Risc0)
}
}
}
}