Skip to content

Commit 0c24e26

Browse files
committed
pi logic
1 parent a85aad8 commit 0c24e26

File tree

1 file changed

+73
-4
lines changed
  • ceno_recursion/src/aggregation

1 file changed

+73
-4
lines changed

ceno_recursion/src/aggregation/mod.rs

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ use openvm_circuit::{
4747
},
4848
system::{memory::CHUNK, program::trace::compute_exe_commit},
4949
};
50+
use openvm_continuations::{
51+
verifier::{
52+
common::{
53+
assert_or_assign_connector_pvs, assert_or_assign_memory_pvs,
54+
assert_required_air_for_app_vm_present, get_connector_pvs, get_memory_pvs,
55+
get_program_commit,
56+
},
57+
leaf::types::UserPublicValuesRootProof,
58+
},
59+
};
5060

5161
const LEAF_LOG_BLOWUP: usize = 1;
5262
const INTERNAL_LOG_BLOWUP: usize = 2;
@@ -63,18 +73,76 @@ impl CenoLeafVmVerifierConfig {
6373
pub fn build_program(&self) -> Program<F> {
6474
let mut builder = Builder::<C>::default();
6575

76+
let pvs = VmVerifierPvs::<Felt<F>>::uninit(&mut builder);
77+
6678
{
6779
builder.cycle_tracker_start("VerifyCenoProof");
6880

6981
let zkvm_proof_input_variables = ZKVMProofInput::read(&mut builder);
7082
verify_zkvm_proof(&mut builder, zkvm_proof_input_variables, &self.vk);
7183

84+
{
85+
let commit = get_program_commit(builder, &proof);
86+
builder.if_eq(i, RVar::zero()).then_or_else(
87+
|builder| {
88+
builder.assign(&pvs.app_commit, commit);
89+
},
90+
|builder| builder.assert_eq::<[_; DIGEST_SIZE]>(pvs.app_commit, commit),
91+
);
92+
}
93+
94+
let proof_connector_pvs = get_connector_pvs(builder, &proof);
95+
assert_or_assign_connector_pvs(builder, &pvs.connector, i, &proof_connector_pvs);
96+
97+
let proof_memory_pvs = get_memory_pvs(builder, &proof);
98+
assert_or_assign_memory_pvs(builder, &pvs.memory, i, &proof_memory_pvs);
99+
100+
let is_terminate = builder.cast_felt_to_var(pvs.connector.is_terminate);
101+
builder.if_eq(is_terminate, F::ONE).then(|builder| {
102+
let (pv_commit, expected_memory_root) =
103+
self.verify_user_public_values_root(builder);
104+
builder.assert_eq::<[_; DIGEST_SIZE]>(pvs.memory.final_root, expected_memory_root);
105+
builder.assign(&pvs.public_values_commit, pv_commit);
106+
});
107+
for pv in pvs.flatten() {
108+
builder.commit_public_value(pv);
109+
}
110+
72111
builder.cycle_tracker_end("VerifyCenoProof");
73112
builder.halt();
74113
}
75114

76115
builder.compile_isa_with_options(self.compiler_options)
77116
}
117+
118+
fn verify_user_public_values_root(
119+
&self,
120+
builder: &mut Builder<C>,
121+
) -> ([Felt<F>; DIGEST_SIZE], [Felt<F>; DIGEST_SIZE]) {
122+
let memory_dimensions = self.app_system_config.memory_config.memory_dimensions();
123+
let pv_as = PUBLIC_VALUES_ADDRESS_SPACE_OFFSET + memory_dimensions.as_offset;
124+
let pv_start_idx = memory_dimensions.label_to_index((pv_as, 0));
125+
let pv_height = log2_strict_usize(self.app_system_config.num_public_values / DIGEST_SIZE);
126+
let proof_len = memory_dimensions.overall_height() - pv_height;
127+
let idx_prefix = pv_start_idx >> pv_height;
128+
129+
// Read the public values root proof from the input stream.
130+
let root_proof = UserPublicValuesRootProof::<F>::read(builder);
131+
builder.assert_eq::<Usize<_>>(root_proof.sibling_hashes.len(), Usize::from(proof_len));
132+
let mut curr_commit = root_proof.public_values_commit;
133+
// Share the same state array to avoid unnecessary allocations.
134+
let compressor = VariableP2Compressor::new(builder);
135+
for i in 0..proof_len {
136+
let sibling_hash = builder.get(&root_proof.sibling_hashes, i);
137+
let (l_hash, r_hash) = if idx_prefix & (1 << i) != 0 {
138+
(sibling_hash, curr_commit)
139+
} else {
140+
(curr_commit, sibling_hash)
141+
};
142+
curr_commit = compressor.compress(builder, &l_hash, &r_hash);
143+
}
144+
(root_proof.public_values_commit, curr_commit)
145+
}
78146
}
79147

80148
#[derive(Clone, Serialize, Deserialize)]
@@ -96,6 +164,10 @@ pub fn compress_to_root_proof(
96164
.enumerate()
97165
.map(|(shard_id, p)| ZKVMProofInput::from((shard_id, p)))
98166
.collect();
167+
let user_public_values = zkvm_proof_inputs
168+
.iter()
169+
.flat_map(|p| p.raw_pi.iter().flat_map(|v| v.clone()).collect::<Vec<F>>())
170+
.collect();
99171

100172
let aggregation_start_timestamp = Instant::now();
101173

@@ -273,10 +345,7 @@ pub fn compress_to_root_proof(
273345
// Export e2e stark proof (used in verify_e2e_stark_proof)
274346
let root_stark_proof = VmStarkProof {
275347
proof: proofs.pop().unwrap(),
276-
user_public_values: zkvm_proof_inputs
277-
.iter()
278-
.flat_map(|p| p.raw_pi.iter().flat_map(|v| v.clone()).collect::<Vec<F>>())
279-
.collect(),
348+
user_public_values,
280349
};
281350
let file = File::create("root_stark_proof.bin").expect("Create export proof file");
282351
bincode::serialize_into(file, &root_stark_proof).expect("failed to serialize internal proof");

0 commit comments

Comments
 (0)