Skip to content
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

feature:add-merkle-proof-circuit-and-tests #14

Merged
merged 20 commits into from
Aug 5, 2024

Conversation

EkamSinghPandher
Copy link
Collaborator

Added the merkle tree proof of inclusion circuit and prover along with tests.

@EkamSinghPandher EkamSinghPandher changed the base branch from main to dev August 1, 2024 06:57
let mut sum_equity = F::ZERO;
let mut sum_debt = F::ZERO;

self.equity.iter().for_each(|x| {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can use fold for consistency

@cliff0412
Copy link
Collaborator

STANDARD_CONFIG can set zk to false; only last layer can use true


/// Assert 0 <= x <= MAX_POSITIVE_AMOUNT
/// MAX_POSITIVE_AMOUNT = (1 << MAX_POSITIVE_AMOUNT_LOG) - 1
pub fn assert_non_negative_unsigned<F: RichField + Extendable<D>, const D: usize>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion]: can make F to the GoldilocksField, rather than generic; MAX_POSITIVE_AMOUNT_LOG is tied to 64 GL, rather than any generic field

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we can remove generics as much as possible

}

/// Computes `if b { h0 } else { h1 }`.
pub fn select_hash(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also not needed right now

}

/// Hash 2 hashout targets by splitting it into its individual component elements
pub fn hash_2_subhashes_circuit(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might not be necessary


let sum_debt = self.debt.iter().fold(F::ZERO, |acc, x| acc + *x);

let hash = PoseidonHash::hash_no_pad(vec![sum_equity, sum_debt].as_slice());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the account hash should includes user_id

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would we represent the user id in a field?

});
let num_assets = 50;
let accounts = gen_accounts_with_random_data(batch_size, num_assets);
let prover = MerkleSumTreeProver { accounts };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the idea of prove_with_circuit is to avoid build multiple times. copy is lighter compared to build circuit again. can have a comparison between copy and build

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah will add a version for this

}

pub fn set_account_targets(&self, account_info: &Account, pw: &mut PartialWitness<F>) {
assert_eq!(self.equity.len(), account_info.equity.len());
assert_eq!(self.debt.len(), account_info.debt.len());

println!("{:?}", account_info.get_user_id_in_field());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this, or use trace::debug

/// Given children nodes, generate the MerkleSumNodeTarget
pub fn get_parent_from_children<const N: usize>(
builder: &mut CircuitBuilder<F, D>,
children: [&MerkleSumNodeTarget; N],
children: &Vec<MerkleSumNodeTarget>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the same? what is the reason changing to a vector

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because in the old code we go from arr -> vec but if we just use a vec we avoid the conversion

for i in 0..self.accounts.len() {
account_targets[i].set_account_targets(self.accounts.get(i).unwrap(), &mut pw);
}
let mut timing = TimingTree::new("prove", Level::Debug);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need use Level::Info for release mode

}
}

pub fn prove_n_subproofs<
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is unused; the recursive circuit building takes a lot of time; we'd better copy

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed


builder.print_gate_counts(0);

let mut timing = TimingTree::new("prove", Level::Debug);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need use Level::Info for release mode

let mut timing = TimingTree::new("prove_merkle_sum_tree", Level::Debug);
let proof =
prove(&prover_only, &common, pw, &mut timing).map_err(|_| ProofError::InvalidProof)?;
println!("Started Proving");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm this

Ok(proof)
match proof_res {
Ok(proof) => {
println!("Finished Proving");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use tracing


match proof_res {
Ok(proof) => {
println!("Finished Proving");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use tracing


circuit_data.verify(proof.clone()).unwrap();
let proof_res = prove(&prover_only, &common, pw.clone(), &mut timing);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pw.clone() is not necessary

Cargo.toml Outdated
@@ -34,8 +34,8 @@ once_cell = "1.14"
static_assertions = { version = "1.1.0", default-features = false }
unroll = { version = "0.1.5", default-features = false }
# zkp
plonky2 = { git = "https://github.com/okx/plonky2"}
plonky2_field = { git = "https://github.com/okx/plonky2"}
plonky2 = { git = "https://github.com/okx/plonky2", branch="clone-circuit"}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it has already been merged to main; i moved

@cliff0412 cliff0412 merged commit 059f8b9 into dev Aug 5, 2024
1 check passed
@cliff0412 cliff0412 mentioned this pull request Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants