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

Adds sparse merkle tree in noname stdlib #249

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

0xnullifier
Copy link
Contributor

This pr adds the sparse merkle tree to stdlib and closes #223

The testing was done against the output of circomlibjs you can find the script here.

The approach taken is almost identical to the circom's implementation mentioned in the issue.

@0xnullifier
Copy link
Contributor Author

Hey @katat can you take a look?

@katat
Copy link
Collaborator

katat commented Jan 3, 2025

Thanks! Will take a look soon.

@0xnullifier
Copy link
Contributor Author

hey it seems the checks failed due to enforce formating
So I will go ahead and fix them

Copy link
Collaborator

@katat katat left a comment

Choose a reason for hiding this comment

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

Nice work!
I just had a round of review, and will need another rounds. I left some comments.

I think some of the arithmetic logic can be simplified using ifelse block.
More documentation on the arithmetic logic in the compute_roots and next_state, if they can't be simplified ifelse, would be useful.

src/tests/stdlib/smt/smt_verify.no Outdated Show resolved Hide resolved
src/stdlib/native/smt/lib.no Outdated Show resolved Hide resolved
/// Field: mimc7 hash for key = 1 and values = [key,value]
fn compute_leaf_hash(key: Field, value: Field) -> Field {
let hash_values = [key, value];
return mimc::mimc7_hash(hash_values, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

is it correct to provide 1 as the secret key?

Copy link
Contributor Author

@0xnullifier 0xnullifier Jan 6, 2025

Choose a reason for hiding this comment

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

Yeah this was in the iden3 specification I think this is mainly for domain seperation of the internal and leaf hash functions other than that I cannot find a reason why

src/stdlib/native/smt/lib.no Outdated Show resolved Hide resolved
src/stdlib/native/smt/lib.no Outdated Show resolved Hide resolved
/// `is_update`: whether the operation is an update operation
/// # Returns
/// `[Bool;6]`: the next state
fn next_state(
Copy link
Collaborator

Choose a reason for hiding this comment

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

it'd better to have more documentation on the logic for each transition.

Copy link
Contributor Author

@0xnullifier 0xnullifier Jan 6, 2025

Choose a reason for hiding this comment

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

Got it. It was written at the top but I will repeat it below

src/stdlib/native/smt/lib.no Show resolved Hide resolved
src/stdlib/native/smt/lib.no Outdated Show resolved Hide resolved
let new_key_bits = bits::to_bits(LEN , new_key);

let mut level_inserted = old_level_inserted(enabled,siblings);
let mut states = [[false;6]; LEN];
Copy link
Collaborator

Choose a reason for hiding this comment

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

would it be easier if it is a field value to represent the different states intead of using an array of booleans?

Copy link
Contributor Author

@0xnullifier 0xnullifier Jan 6, 2025

Choose a reason for hiding this comment

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

yeah but that makes the states computation a bit more difficult as in this case I can directly do boolean operations as my state transitions are dictated by booleans.
Also the assertion that there is only one state at a time

I tried the single state variable earlier but it got too difficult but when we do #248 it will be way easier maybe we can refactor then?

One more point is that circomlib also uses 6 variables for some reason maybe it has less constraints this way?

src/stdlib/native/smt/lib.no Outdated Show resolved Hide resolved
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.

[stdlib] add sparse merkle tree in
2 participants