-
Notifications
You must be signed in to change notification settings - Fork 3
Add merkle verify gate #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
39905dc
Add merkle verify gate
4l0n50 ade39b4
Move merkle air
4l0n50 f16c2f6
Fix circuit building hash size mismatch
4l0n50 a859dee
Simplify type parameters
4l0n50 6f184d8
Minor
4l0n50 555b296
Merge with main
4l0n50 126c0d3
Make merkle configuration dynamic
4l0n50 1eb65af
Merge with main
4l0n50 c854951
Address reviews
4l0n50 780c10a
Minor
4l0n50 39d04c8
Missing file
4l0n50 2ec1c5e
Make merkle verify air no std
4l0n50 62c879d
Merge with main
4l0n50 537216a
Merge remote-tracking branch 'origin/main' into alonso/merkle_gate_si…
4l0n50 4dfbed9
Address Reviews and Add config to enabled ops
4l0n50 a642f51
Missing changes
4l0n50 cbb97e7
Update circuit-prover/src/air/merkle_verify_air.rs
4l0n50 deaef21
Clipy
4l0n50 5b0c2ab
Merge remote-tracking branch 'origin/main' into alonso/merkle_gate_si…
4l0n50 94fcc1f
Add packing option
4l0n50 6560907
Merge with main
4l0n50 b3a38f8
Update ci
4l0n50 fd559f7
Adress some reviews
4l0n50 a73e00c
Maldito clippy
4l0n50 3a52319
Minor
4l0n50 6a5769f
Remove compression function dependency for circuits
4l0n50 b819d47
Merge with main
4l0n50 8295a0c
Address reviews
4l0n50 2a615a4
Add test for private data generation
4l0n50 8249117
rename
sai-deng 7ed016e
Sai's fixes
sai-deng 98e3f78
fix ci
sai-deng 33c8543
Move TODO and add logger to mmcs_verify
4l0n50 2506178
Remove old TODOs
4l0n50 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| use std::env; | ||
|
|
||
| /// Fake Merkle verification circuit: Prove knowledge of a leaf in a Merkle tree | ||
4l0n50 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// Public inputs: leaf_hash, expected_root | ||
| /// Private inputs: merkle path (siblings + directions) | ||
| use p3_baby_bear::BabyBear; | ||
| use p3_circuit::NonPrimitiveOpPrivateData; | ||
| use p3_circuit::builder::CircuitBuilder; | ||
| use p3_circuit::config::CircuitRunnerConfig; | ||
| use p3_circuit::config::babybear_config::default_babybear_poseidon2_circuit_runner_config; | ||
| use p3_circuit::tables::MerklePrivateData; | ||
| use p3_circuit_prover::MultiTableProver; | ||
| use p3_circuit_prover::config::babybear_config::build_standard_config_babybear; | ||
| use p3_circuit_prover::prover::ProverError; | ||
| use p3_field::extension::BinomialExtensionField; | ||
| use p3_field::{BasedVectorSpace, PrimeCharacteristicRing}; | ||
| use p3_symmetric::PseudoCompressionFunction; | ||
|
|
||
| type F = BinomialExtensionField<BabyBear, 4>; | ||
|
|
||
| fn main() -> Result<(), ProverError> { | ||
| let depth = env::args().nth(1).and_then(|s| s.parse().ok()).unwrap_or(3); | ||
|
|
||
| let mut builder = CircuitBuilder::<F>::new(); | ||
|
|
||
| // Public inputs: leaf hash and expected root hash | ||
| let leaf_hash = builder.add_public_input(); | ||
| let index_expr = builder.add_public_input(); | ||
| let expected_root = builder.add_public_input(); | ||
|
|
||
| // Add fake Merkle verification operation | ||
| // This declares that leaf_hash and expected_root are connected to witness bus | ||
| // The AIR constraints will verify the Merkle path is valid | ||
| let merkle_op_id = builder.add_merkle_verify(leaf_hash, index_expr, expected_root); | ||
|
|
||
| let circuit = builder.build()?; | ||
| let config = default_babybear_poseidon2_circuit_runner_config(); | ||
| let compress = config.compress().clone(); | ||
| let mut runner = circuit.runner(config); | ||
|
|
||
| // Set public inputs | ||
| let leaf_value = F::from_u64(42); // Our leaf value | ||
| let siblings: Vec<(Vec<F>, Option<Vec<F>>)> = (0..depth) | ||
| .map(|i| { | ||
| ( | ||
| vec![F::from_u64((i + 1) * 10)], | ||
| if i % 2 == 0 { | ||
| None | ||
| } else { | ||
| Some(vec![F::from_u64(i + 1)]) | ||
| }, | ||
| ) | ||
| }) | ||
| .collect(); | ||
| let directions: Vec<bool> = (0..depth).map(|i| i % 2 == 0).collect(); | ||
| let index_value = F::from_u64( | ||
| (0..32) | ||
| .zip(directions.iter()) | ||
| .filter(|(_, dir)| **dir) | ||
| .map(|(i, _)| 1 << i) | ||
| .sum(), | ||
| ); | ||
| let expected_root_value = compute_merkle_root(&compress, &leaf_value, &siblings, &directions); | ||
| runner.set_public_inputs(&[leaf_value, index_value, expected_root_value])?; | ||
|
|
||
| // Set private Merkle path data | ||
| runner.set_non_primitive_op_private_data( | ||
| merkle_op_id, | ||
| NonPrimitiveOpPrivateData::MerkleVerify(MerklePrivateData { | ||
| path_siblings: siblings, | ||
| }), | ||
| )?; | ||
|
|
||
| let traces = runner.run()?; | ||
| let config = build_standard_config_babybear(); | ||
| let multi_prover = MultiTableProver::new(config); | ||
| let proof = multi_prover.prove_all_tables(&traces)?; | ||
| multi_prover.verify_all_tables(&proof)?; | ||
|
|
||
| println!( | ||
| "✅ Verified Merkle path for leaf {leaf_value} with depth {depth} → root {expected_root_value}", | ||
| ); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| pub type Hash = [BabyBear; 8]; | ||
4l0n50 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| /// Simulate classical Merkle root computation for testing | ||
| fn compute_merkle_root<C>( | ||
| compress: &C, | ||
| leaf: &F, | ||
| siblings: &[(Vec<F>, Option<Vec<F>>)], | ||
| directions: &[bool], | ||
| ) -> F | ||
| where | ||
| C: PseudoCompressionFunction<Hash, 2> + Sync, | ||
| { | ||
| directions.iter().zip(siblings.iter()).fold( | ||
| *leaf, | ||
| |state, (direction, (sibling, other_sibling))| { | ||
| let (left, right) = if *direction { | ||
| (state, sibling[0]) | ||
| } else { | ||
| (sibling[0], state) | ||
| }; | ||
| let mut new_state: Hash = compress.compress([ | ||
| left.as_basis_coefficients_slice() | ||
| .try_into() | ||
| .expect("Size is 4"), | ||
| right | ||
| .as_basis_coefficients_slice() | ||
| .try_into() | ||
| .expect("Size is 4"), | ||
| ]); | ||
| if let Some(other_sibling) = other_sibling { | ||
| new_state = compress.compress([ | ||
| state | ||
| .as_basis_coefficients_slice() | ||
| .try_into() | ||
| .expect("Size is 4"), | ||
| other_sibling[0] | ||
| .clone() | ||
| .as_basis_coefficients_slice() | ||
| .try_into() | ||
| .expect("Size is o4"), | ||
| ]); | ||
| } | ||
| F::from_basis_coefficients_slice(&new_state).expect("Size is 4") | ||
| }, | ||
| ) | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.