Skip to content

Commit b1a4ac1

Browse files
committed
Calldata generator
1 parent aa28d4d commit b1a4ac1

File tree

3 files changed

+152
-5
lines changed

3 files changed

+152
-5
lines changed

runner/src/main.rs

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::vec252::VecFelt252;
55
use cairo_lang_runner::{Arg, ProfilingInfoCollectionConfig, RunResultValue, SierraCasmRunner};
66
use cairo_lang_sierra::program::VersionedProgram;
77
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
8+
use cairo_vm::Felt252;
89
use clap::Parser;
910
use itertools::{chain, Itertools};
1011
use runner::{CairoVersion, HasherBitLength, StoneVersion};
@@ -13,9 +14,9 @@ use std::{
1314
io::{stdin, Read},
1415
};
1516
use swiftness_proof_parser::parse;
16-
use transform::StarkProofExprs;
17+
use transform::{Expr, StarkProofExprs};
1718

18-
const ENTRYPOINT: &str = "main";
19+
const ENTRYPOINT: &str = "get_calldata";
1920

2021
#[derive(Parser)]
2122
#[command(author, version, about)]
@@ -45,6 +46,19 @@ fn main() -> anyhow::Result<()> {
4546
serde_json::from_str(&stark_proof.public_input.to_string()).unwrap();
4647
let unsent_commitment: VecFelt252 =
4748
serde_json::from_str(&stark_proof.unsent_commitment.to_string()).unwrap();
49+
let last_layer_commitment: VecFelt252 =
50+
serde_json::from_str(&stark_proof.unsent_commitment[5].to_string()).unwrap();
51+
52+
let fri_witness = stark_proof.witness.last().expect("No fri witness").clone();
53+
let fri_witness = split_array(fri_witness);
54+
let steps = fri_witness.chunks(2).map(|chunk| {
55+
chunk
56+
.into_iter()
57+
.flatten()
58+
.map(|s| Felt252::from_dec_str(s).unwrap().to_hex_string())
59+
.join(" ")
60+
}).collect_vec();
61+
4862
let witness: VecFelt252 = serde_json::from_str(&stark_proof.witness.to_string()).unwrap();
4963

5064
let proof = chain!(
@@ -84,7 +98,25 @@ fn main() -> anyhow::Result<()> {
8498

8599
match result.value {
86100
RunResultValue::Success(msg) => {
87-
println!("{:?}", msg);
101+
let (const_state, mut variable_state, fact_hash) = extract_calldata_from_memory(result.memory, &msg);
102+
103+
let const_state_str = const_state.iter().map(|x| x.to_hex_string()).join(" ");
104+
105+
let last_variable_state = variable_state.pop().unwrap();
106+
107+
for (var, step) in variable_state.iter().zip_eq(steps.iter()) {
108+
let v = var.iter().map(|x| x.to_hex_string()).join(" ");
109+
println!("\nSTEP");
110+
println!("{} {} {}", const_state_str, v, step);
111+
}
112+
113+
println!("\nFINAL");
114+
println!("{} {} 0x{:x} {}",
115+
const_state_str,
116+
last_variable_state.iter().map(|x| x.to_hex_string()).join(" "),
117+
last_layer_commitment.len(),
118+
last_layer_commitment.iter().map(|x| x.to_hex_string()).join(" ")
119+
);
88120
}
89121
RunResultValue::Panic(msg) => {
90122
panic!("{:?}", msg);
@@ -93,3 +125,75 @@ fn main() -> anyhow::Result<()> {
93125

94126
Ok(())
95127
}
128+
129+
fn extract_calldata_from_memory(memory: Vec<Option<Felt252>>, output: &Vec<Felt252>) -> (Vec<Felt252>, Vec<Vec<Felt252>>, Felt252) {
130+
let mut output_iter = output.iter();
131+
132+
let mut calldata_constant_state: Vec<Felt252> = vec![];
133+
calldata_constant_state.push(*output_iter.next().unwrap()); // n_layers
134+
append_memory_segment(&mut calldata_constant_state, &memory, output_iter.next_tuple().unwrap(), 6); // commitment
135+
append_memory_segment(&mut calldata_constant_state, &memory, output_iter.next_tuple().unwrap(), 1); // eval_points
136+
append_memory_segment(&mut calldata_constant_state, &memory, output_iter.next_tuple().unwrap(), 1); // step_sizes
137+
calldata_constant_state.push(*output_iter.next().unwrap()); // last_layer_coefficients_hash
138+
139+
let mut variable_state_ptr: Vec<Felt252> = vec![];
140+
append_memory_segment(&mut variable_state_ptr, &memory, output_iter.next_tuple().unwrap(), 1); // variable_state
141+
let variable_state_iter = variable_state_ptr.iter().skip(1);
142+
let mut calldata_variable_state: Vec<Vec<Felt252>> = vec![];
143+
for mut x in &variable_state_iter.chunks(3) {
144+
let (iteration, begin, end) = x.next_tuple().unwrap();
145+
let begin: usize = begin.to_biguint().try_into().unwrap();
146+
let end: usize = end.to_biguint().try_into().unwrap();
147+
let len = (end - begin) / 3;
148+
let mut calldata = vec![];
149+
calldata.push(*iteration);
150+
calldata.push(len.into());
151+
for x in memory[begin..end].iter() {
152+
calldata.push(x.unwrap());
153+
}
154+
calldata_variable_state.push(calldata);
155+
}
156+
157+
let fact_hash = *output_iter.next().unwrap();
158+
159+
(calldata_constant_state, calldata_variable_state, fact_hash)
160+
}
161+
162+
fn append_memory_segment(calldata: &mut Vec<Felt252>, memory: &Vec<Option<Felt252>>, (&start, &end): (&Felt252, &Felt252), size: usize) {
163+
let start: usize = start.to_biguint().try_into().unwrap();
164+
let end: usize = end.to_biguint().try_into().unwrap();
165+
let len = (end - start) / size;
166+
calldata.push(len.into());
167+
for addr in start..end {
168+
calldata.push(memory[addr].unwrap());
169+
}
170+
}
171+
172+
fn split_array(expr: Expr) -> Vec<Vec<String>> {
173+
match expr {
174+
Expr::Array(arr) => {
175+
let mut acc: Vec<Vec<String>> = vec![];
176+
let mut curr: Vec<String> = vec![];
177+
let mut it: u32 = 0;
178+
for elem in arr {
179+
if let Expr::Value(val) = elem {
180+
if it == 0 {
181+
if curr.len() > 0 {
182+
acc.push(curr);
183+
}
184+
it = val.parse().expect("Not a number");
185+
curr = vec![val];
186+
} else {
187+
curr.push(val);
188+
it -= 1;
189+
}
190+
}
191+
}
192+
if curr.len() > 0 {
193+
acc.push(curr);
194+
}
195+
acc
196+
}
197+
_ => panic!("Not an array"),
198+
}
199+
}

src/fri/fri.cairo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ fn hash_array(mut array: Span<felt252>) -> felt252 {
263263
// TODO: probably commitment can be moved to separate struct StateFinalize together with
264264
// last_layer_coefficients
265265

266-
#[derive(Drop, Serde)]
266+
#[derive(Drop, Serde, Clone)]
267267
struct FriVerificationStateConstant {
268268
n_layers: u32,
269269
commitment: Span<TableCommitment>,
@@ -295,7 +295,7 @@ fn hash_constant(state: @FriVerificationStateConstant) -> felt252 {
295295
}
296296
}
297297

298-
#[derive(Drop, Serde)]
298+
#[derive(Drop, Serde, Clone)]
299299
struct FriVerificationStateVariable {
300300
iter: u32,
301301
queries: Span<FriLayerQuery>,

src/lib.cairo

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,46 @@ fn main(mut serialized: Span<felt252>, settings: @VerifierSettings) -> (felt252,
5656

5757
(program_hash, output_hash)
5858
}
59+
60+
use cairo_verifier::fri::fri::{FriVerificationStateConstant, FriVerificationStateVariable};
61+
use core::poseidon::{Poseidon, PoseidonImpl, HashStateImpl};
62+
63+
struct Calldata {
64+
const_state: FriVerificationStateConstant,
65+
variable_state: Span<FriVerificationStateVariable>,
66+
fact_hash: felt252,
67+
}
68+
69+
fn get_calldata(mut serialized: Span<felt252>, settings: @VerifierSettings) -> Calldata {
70+
let stark_proof_serde = Serde::<StarkProofWithSerde>::deserialize(ref serialized).unwrap();
71+
let stark_proof: StarkProof = stark_proof_serde.into();
72+
let (program_hash, output_hash) = match settings.cairo_version {
73+
CairoVersion::Cairo0 => stark_proof.public_input.verify_cairo0(),
74+
CairoVersion::Cairo1 => stark_proof.public_input.verify_cairo1(),
75+
};
76+
77+
let mut variable_states = array![];
78+
79+
let fact_hash = PoseidonImpl::new().update(program_hash).update(output_hash).finalize();
80+
81+
let (mut const_state, mut variable_state, last_layer_coefficients, _) = stark_proof
82+
.verify_initial(0.try_into().unwrap(), 0.try_into().unwrap(), settings);
83+
84+
for witness in stark_proof.witness.fri_witness.layers {
85+
variable_states.append(variable_state.clone());
86+
let (new_const_state, new_variable_state) = StarkProofImpl::verify_step(
87+
const_state, variable_state, *witness, settings
88+
);
89+
variable_state = new_variable_state;
90+
const_state = new_const_state;
91+
};
92+
93+
variable_states.append(variable_state.clone());
94+
StarkProofImpl::verify_final(const_state.clone(), variable_state, last_layer_coefficients);
95+
96+
Calldata {
97+
const_state,
98+
variable_state: variable_states.span(),
99+
fact_hash,
100+
}
101+
}

0 commit comments

Comments
 (0)