Skip to content

Commit ddeb0a2

Browse files
authored
feat: allow passing custom binary to the wrapper (#12)
1 parent 7de7d80 commit ddeb0a2

File tree

6 files changed

+145
-33
lines changed

6 files changed

+145
-33
lines changed

Cargo.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@ name = "cli"
1414
path = "src/main.rs"
1515

1616
[dependencies]
17-
boojum = { git = "https://github.com/matter-labs/zksync-crypto.git", package="boojum", branch = "mmzk_0418_without_field" , features = ["log_tracing"]}
17+
boojum = { git = "https://github.com/matter-labs/zksync-crypto.git", package="boojum", branch = "main" , features = ["log_tracing"]}
1818
# boojum = { path = "../zksync-crypto/crates/boojum"}
19-
bellman = { git = "https://github.com/matter-labs/zksync-crypto.git", package="zksync_bellman", branch = "mmzk_0418_without_field" }
19+
bellman = { git = "https://github.com/matter-labs/zksync-crypto.git", package="zksync_bellman", branch = "main" }
2020
# bellman = { path = "../zksync-crypto/crates/bellman", package="zksync_bellman"}
21-
rescue_poseidon = { git = "https://github.com/matter-labs/zksync-crypto.git", package="rescue_poseidon", branch = "mmzk_0418_without_field" }
21+
rescue_poseidon = { git = "https://github.com/matter-labs/zksync-crypto.git", package="rescue_poseidon", branch = "main" }
2222
# rescue_poseidon = { path = "../zksync-crypto/crates/rescue-poseidon"}
23-
snark_wrapper = { git = "https://github.com/matter-labs/zksync-crypto.git", package="snark_wrapper", branch = "mmzk_0418_without_field" }
23+
snark_wrapper = { git = "https://github.com/matter-labs/zksync-crypto.git", package="snark_wrapper", branch = "main" }
2424
# snark_wrapper = { path = "../zksync-crypto/crates/snark-wrapper"}
2525
risc_verifier = {git="https://github.com/matter-labs/air_compiler.git", package="final_reduced_risc_v_machine_verifier", features=["proof_utils"], branch="main"}
2626
# risc_verifier = {path="../air_compiler/circuit_defs/final_reduced_risc_v_machine/verifier", package="final_reduced_risc_v_machine_verifier", features=["proof_utils"]}
2727
execution_utils = {git="https://github.com/matter-labs/air_compiler.git", package="execution_utils", branch="main"}
2828
# execution_utils = {path="../air_compiler/execution_utils"}
29+
setups = {git="https://github.com/matter-labs/air_compiler.git", package="setups", branch="main"}
30+
# setups = {path="../../air_compiler/circuit_defs/setups"}
2931
circuit_mersenne_field = {path="circuit_mersenne_field"}
3032
serde_json = { version = "*" }
3133
serde = { version = "1", default-features = false, features = ["derive", "alloc"]}

circuit_mersenne_field/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
boojum = { git = "https://github.com/matter-labs/zksync-crypto.git", package="boojum", branch = "mmzk_0418_without_field" }
7+
boojum = { git = "https://github.com/matter-labs/zksync-crypto.git", package="boojum", branch = "main" }
88
# boojum = { path = "../../zksync-crypto/crates/boojum"}
99
mersenne_field = {git="https://github.com/matter-labs/air_compiler.git", package="field", branch="main"}
1010
# mersenne_field = {path="../../air_compiler/field", package="field"}

src/circuits/risc_wrapper.rs

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,11 @@ use circuit_mersenne_field::{
2727
};
2828
use std::mem::MaybeUninit;
2929

30-
use crate::wrapper_inner_verifier::imports::{
31-
FINAL_RISC_CIRCUIT_AUX_REGISTERS_VALUES, FINAL_RISC_CIRCUIT_END_PARAMS,
32-
};
33-
use crate::wrapper_inner_verifier::skeleton::{
34-
WrappedProofSkeletonInstance, WrappedQueryValuesInstance,
35-
};
3630
use crate::wrapper_inner_verifier::*;
31+
use crate::wrapper_inner_verifier::{
32+
imports::{FINAL_RISC_CIRCUIT_AUX_REGISTERS_VALUES, FINAL_RISC_CIRCUIT_END_PARAMS},
33+
skeleton::{WrappedProofSkeletonInstance, WrappedQueryValuesInstance},
34+
};
3735
use crate::wrapper_utils::prover_structs::*;
3836
use crate::wrapper_utils::verifier_traits::{CircuitLeafInclusionVerifier, PlaceholderSource};
3937
use risc_verifier::blake2s_u32::*;
@@ -62,8 +60,28 @@ pub struct RiscWrapperWitness {
6260
pub proof: RiscProof,
6361
}
6462

63+
#[derive(Clone, Debug)]
64+
pub struct BinaryCommitment {
65+
pub end_params: [u32; 8],
66+
pub aux_params: [u32; 8],
67+
}
68+
69+
impl BinaryCommitment {
70+
// Uses the binary information that was provided by wrapper generator.
71+
// In future, this will be the 'active' boojumos binary, but for now this is an example fibonacci code.
72+
pub fn from_default_binary() -> Self {
73+
Self {
74+
end_params: FINAL_RISC_CIRCUIT_END_PARAMS,
75+
aux_params: FINAL_RISC_CIRCUIT_AUX_REGISTERS_VALUES,
76+
}
77+
}
78+
}
79+
6580
impl RiscWrapperWitness {
66-
pub fn from_full_proof(full_proof: execution_utils::ProgramProof) -> Self {
81+
pub fn from_full_proof(
82+
full_proof: execution_utils::ProgramProof,
83+
binary_commitment: &BinaryCommitment,
84+
) -> Self {
6785
let execution_utils::ProgramProof {
6886
base_layer_proofs,
6987
delegation_proofs,
@@ -76,7 +94,7 @@ impl RiscWrapperWitness {
7694
assert!(base_layer_proofs.len() == 1);
7795
assert!(delegation_proofs.is_empty());
7896
assert!(register_final_values.len() == NUM_REGISTERS);
79-
assert_eq!(end_params, FINAL_RISC_CIRCUIT_END_PARAMS);
97+
assert_eq!(end_params, binary_commitment.end_params);
8098

8199
assert!(recursion_chain_preimage.is_some());
82100
let mut result_hasher = Blake2sBufferingTranscript::new();
@@ -87,10 +105,7 @@ impl RiscWrapperWitness {
87105
recursion_chain_hash.unwrap(),
88106
result_hasher.finalize_reset().0
89107
);
90-
assert_eq!(
91-
recursion_chain_hash.unwrap(),
92-
FINAL_RISC_CIRCUIT_AUX_REGISTERS_VALUES
93-
);
108+
assert_eq!(recursion_chain_hash.unwrap(), binary_commitment.aux_params);
94109

95110
let final_registers_state: Vec<_> = register_final_values
96111
.into_iter()
@@ -113,6 +128,7 @@ impl RiscWrapperWitness {
113128

114129
pub struct RiscWrapperCircuit<F: SmallField, V: CircuitLeafInclusionVerifier<F>> {
115130
pub witness: Option<RiscWrapperWitness>,
131+
pub binary_commitment: BinaryCommitment,
116132
_phantom: std::marker::PhantomData<(F, V)>,
117133
}
118134

@@ -199,7 +215,11 @@ impl<F: SmallField, V: CircuitLeafInclusionVerifier<F>> CircuitBuilder<F>
199215
}
200216

201217
impl<F: SmallField, V: CircuitLeafInclusionVerifier<F>> RiscWrapperCircuit<F, V> {
202-
pub fn new(witness: Option<RiscWrapperWitness>, verify_inner_proof: bool) -> Self {
218+
pub fn new(
219+
witness: Option<RiscWrapperWitness>,
220+
verify_inner_proof: bool,
221+
binary_commitment: BinaryCommitment,
222+
) -> Self {
203223
if verify_inner_proof {
204224
if let Some(witness) = &witness {
205225
verify_risc_proof::<V::OutOfCircuitImpl>(&witness.proof);
@@ -210,6 +230,7 @@ impl<F: SmallField, V: CircuitLeafInclusionVerifier<F>> RiscWrapperCircuit<F, V>
210230

211231
Self {
212232
witness,
233+
binary_commitment,
213234
_phantom: std::marker::PhantomData,
214235
}
215236
}
@@ -283,7 +304,13 @@ impl<F: SmallField, V: CircuitLeafInclusionVerifier<F>> RiscWrapperCircuit<F, V>
283304
let (proof_state, proof_input) =
284305
crate::wrapper_inner_verifier::verify(cs, skeleton, queries);
285306

286-
check_proof_state(cs, final_registers_state, &proof_state, &proof_input);
307+
check_proof_state(
308+
cs,
309+
final_registers_state,
310+
&proof_state,
311+
&proof_input,
312+
&self.binary_commitment,
313+
);
287314

288315
// we carry registers 10-17 to the next layer - those are the output of the base program
289316
let output_registers_values: Vec<_> = final_registers_state
@@ -405,6 +432,7 @@ pub(crate) fn check_proof_state<F: SmallField, CS: ConstraintSystem<F>>(
405432
NUM_AUX_BOUNDARY_VALUES,
406433
>,
407434
public_input: &WrappedProofPublicInputs<F, NUM_STATE_ELEMENTS>,
435+
binary_commitment: &BinaryCommitment,
408436
) {
409437
let mut transcript = Blake2sWrappedBufferingTranscript::new(cs);
410438

@@ -502,7 +530,7 @@ pub(crate) fn check_proof_state<F: SmallField, CS: ConstraintSystem<F>>(
502530

503531
for i in 0..8 {
504532
let end_params_word = UInt32::from_le_bytes(cs, end_params_output.0[i].inner);
505-
let expected_word = UInt32::allocate_constant(cs, FINAL_RISC_CIRCUIT_END_PARAMS[i]);
533+
let expected_word = UInt32::allocate_constant(cs, binary_commitment.end_params[i]);
506534
Num::enforce_equal(cs, &expected_word.into_num(), &end_params_word.into_num());
507535
}
508536

@@ -512,8 +540,7 @@ pub(crate) fn check_proof_state<F: SmallField, CS: ConstraintSystem<F>>(
512540
for i in 0..8 {
513541
let aux_register_idx = (i + 18) * 3;
514542
let aux_register = final_registers_state[aux_register_idx];
515-
let expected_word =
516-
UInt32::allocate_constant(cs, FINAL_RISC_CIRCUIT_AUX_REGISTERS_VALUES[i]);
543+
let expected_word = UInt32::allocate_constant(cs, binary_commitment.aux_params[i]);
517544
Num::enforce_equal(cs, &expected_word.into_num(), &aux_register.into_num());
518545
}
519546
}

src/lib.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use boojum::cs::traits::circuit::CircuitBuilderProxy;
3131
use boojum::gadgets::recursion::recursive_transcript::CircuitAlgebraicSpongeBasedTranscript;
3232
use boojum::gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge;
3333
use boojum::implementations::poseidon2::Poseidon2Goldilocks;
34+
pub use boojum::worker::Worker as BoojumWorker;
3435
use boojum::worker::*;
3536
use circuits::*;
3637
use wrapper_utils::verifier_traits::CircuitBlake2sForEverythingVerifier;
@@ -52,8 +53,8 @@ pub type CircuitRiscWrapperTreeHasher = CircuitGoldilocksPoseidon2Sponge;
5253
pub type RiscWrapperCircuitBuilder = CircuitBuilderProxy<GL, RiscWrapper>;
5354

5455
pub use rescue_poseidon::franklin_crypto::bellman::pairing::bn256::{Bn256, Fr};
55-
use rescue_poseidon::poseidon2::transcript::Poseidon2Transcript;
5656
use rescue_poseidon::poseidon2::Poseidon2Sponge;
57+
use rescue_poseidon::poseidon2::transcript::Poseidon2Transcript;
5758

5859
use snark_wrapper::implementations::poseidon2::tree_hasher::AbsorptionModeReplacement;
5960

@@ -73,8 +74,8 @@ use bellman::plonk::better_better_cs::cs::PlonkCsWidth4WithNextStepAndCustomGate
7374
use bellman::plonk::better_better_cs::cs::{ProvingAssembly, SetupAssembly};
7475
use bellman::plonk::better_better_cs::gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext;
7576
use bellman::plonk::better_better_cs::verifier::verify as verify_snark;
76-
use snark_wrapper::implementations::poseidon2::transcript::CircuitPoseidon2Transcript;
7777
use snark_wrapper::implementations::poseidon2::CircuitPoseidon2Sponge;
78+
use snark_wrapper::implementations::poseidon2::transcript::CircuitPoseidon2Transcript;
7879

7980
use bellman::worker::Worker as BellmanWorker;
8081

@@ -90,11 +91,14 @@ pub type SnarkWrapperSetup =
9091
pub type SnarkWrapperTranscript =
9192
bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript<Fr>;
9293

94+
pub use execution_utils::ProgramProof;
95+
9396
//CircuitAlgebraicSpongeBasedTranscript<GoldilocksField, 8, 12, 4, R>,
9497

9598
// RiscV -> Stark Wrapper
9699
pub fn get_risc_wrapper_setup(
97100
worker: &Worker,
101+
binary_commitment: BinaryCommitment,
98102
) -> (
99103
FinalizationHintsForProver,
100104
SetupBaseStorage<GL>,
@@ -105,7 +109,7 @@ pub fn get_risc_wrapper_setup(
105109
DenseWitnessCopyHint,
106110
) {
107111
let verify_inner_proof: bool = false;
108-
let circuit = RiscWrapper::new(None, verify_inner_proof);
112+
let circuit = RiscWrapper::new(None, verify_inner_proof, binary_commitment);
109113

110114
let geometry = RiscWrapper::geometry();
111115
let (max_trace_len, num_vars) = circuit.size_hint();
@@ -153,9 +157,14 @@ pub fn prove_risc_wrapper(
153157
vars_hint: &DenseVariablesCopyHint,
154158
witness_hints: &DenseWitnessCopyHint,
155159
worker: &Worker,
160+
binary_commitment: BinaryCommitment,
156161
) -> RiscWrapperProof {
157162
let verify_inner_proof = true;
158-
let circuit = RiscWrapper::new(Some(risc_wrapper_witness), verify_inner_proof);
163+
let circuit = RiscWrapper::new(
164+
Some(risc_wrapper_witness),
165+
verify_inner_proof,
166+
binary_commitment,
167+
);
159168

160169
let geometry = RiscWrapper::geometry();
161170
let (max_trace_len, num_vars) = circuit.size_hint();

src/main.rs

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![feature(allocator_api)]
2+
use std::alloc::Global;
13
/// Tool that takes the riscv proof from boojum 2.0, together with the final value of the
24
/// registers - and returns the SNARK proof.
35
// Inside, it runs 3 submodules:
@@ -11,6 +13,13 @@ use clap::Parser;
1113
use bellman::kate_commitment::{Crs, CrsForMonomialForm};
1214
use bellman::worker::Worker as BellmanWorker;
1315

16+
use execution_utils::{
17+
final_recursion_layer_verifier_vk, recursion_layer_no_delegation_verifier_vk,
18+
recursion_layer_verifier_vk, universal_circuit_no_delegation_verifier_vk,
19+
universal_circuit_verifier_vk,
20+
};
21+
use risc_verifier::prover::worker::Worker;
22+
use zkos_wrapper::circuits::BinaryCommitment;
1423
use zkos_wrapper::{Bn256, L1_VERIFIER_DOMAIN_SIZE_LOG};
1524
use zkos_wrapper::{
1625
circuits::RiscWrapperWitness, get_compression_setup, get_risc_wrapper_setup,
@@ -23,6 +32,12 @@ use zkos_wrapper::{
2332
struct Cli {
2433
#[arg(short, long)]
2534
input: String,
35+
36+
// Binary used to generate the proof.
37+
// If not specified, take the default binary (fibonacci hasher).
38+
#[arg(long)]
39+
input_binary: Option<String>,
40+
2641
#[arg(short, long)]
2742
output_dir: String,
2843
}
@@ -37,15 +52,68 @@ fn deserialize_from_file<T: serde::de::DeserializeOwned>(filename: &str) -> T {
3752
serde_json::from_reader(src).unwrap()
3853
}
3954

55+
pub fn create_binary_commitment(
56+
binary_path: String,
57+
expected_end_params: &[u32; 8],
58+
) -> BinaryCommitment {
59+
let bin = std::fs::read(binary_path).unwrap();
60+
61+
let worker = Worker::new_with_num_threads(8);
62+
63+
let expected_final_pc = execution_utils::find_binary_exit_point(&bin);
64+
let binary: Vec<u32> = execution_utils::get_padded_binary(&bin);
65+
66+
let base_params = execution_utils::compute_end_parameters(
67+
expected_final_pc,
68+
&setups::get_main_riscv_circuit_setup::<Global>(&binary, &worker),
69+
);
70+
71+
// Check which verifier was used.
72+
if universal_circuit_no_delegation_verifier_vk().params == *expected_end_params {
73+
let layers = vec![
74+
[0u32; 8],
75+
base_params,
76+
universal_circuit_verifier_vk().params,
77+
universal_circuit_no_delegation_verifier_vk().params,
78+
];
79+
BinaryCommitment {
80+
end_params: universal_circuit_no_delegation_verifier_vk().params,
81+
aux_params: execution_utils::compute_chain_encoding(layers),
82+
}
83+
} else if final_recursion_layer_verifier_vk().params == *expected_end_params {
84+
let layers = vec![
85+
[0u32; 8],
86+
base_params,
87+
recursion_layer_verifier_vk().params,
88+
recursion_layer_no_delegation_verifier_vk().params,
89+
final_recursion_layer_verifier_vk().params,
90+
];
91+
BinaryCommitment {
92+
end_params: final_recursion_layer_verifier_vk().params,
93+
aux_params: execution_utils::compute_chain_encoding(layers),
94+
}
95+
} else {
96+
panic!(
97+
"Cannot find a verifier for the proof end parameters: {:?}",
98+
expected_end_params
99+
);
100+
}
101+
}
102+
40103
fn main() -> Result<(), Box<dyn std::error::Error>> {
41104
let cli = Cli::parse();
42105

43106
println!("=== Phase 1: Creating the Risc wrapper proof");
44107

45108
let worker = boojum::worker::Worker::new_with_num_threads(4);
46109

47-
let program_proof = deserialize_from_file(&cli.input);
48-
let risc_wrapper_witness = RiscWrapperWitness::from_full_proof(program_proof);
110+
let program_proof: zkos_wrapper::ProgramProof = deserialize_from_file(&cli.input);
111+
let binary_commitment = match cli.input_binary {
112+
Some(binary_path) => create_binary_commitment(binary_path, &program_proof.end_params),
113+
None => BinaryCommitment::from_default_binary(),
114+
};
115+
let risc_wrapper_witness =
116+
RiscWrapperWitness::from_full_proof(program_proof, &binary_commitment);
49117

50118
let (
51119
finalization_hint,
@@ -55,7 +123,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
55123
setup_tree,
56124
vars_hint,
57125
witness_hints,
58-
) = get_risc_wrapper_setup(&worker);
126+
) = get_risc_wrapper_setup(&worker, binary_commitment.clone());
59127

60128
let risc_wrapper_proof = prove_risc_wrapper(
61129
risc_wrapper_witness,
@@ -67,6 +135,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
67135
&vars_hint,
68136
&witness_hints,
69137
&worker,
138+
binary_commitment,
70139
);
71140
let is_valid = verify_risc_wrapper_proof(&risc_wrapper_proof, &risc_wrapper_vk);
72141

0 commit comments

Comments
 (0)