-
Notifications
You must be signed in to change notification settings - Fork 22
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
Working code, small tests #228
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The algorithm looks correct to me. I left a couple of nits inline.
Do you want to merge this into twenty-first
? The repository doesn't have any other functions that take nondeterminism. You can make it fit though by planting the relevant function on a data structure, similarly to what was done with MmrSuccessorProof
. In this case the right struct might be AuthStructIntegrityProof
or something like that, and the function verify(&self, leafs : &[Digest], leaf_indices: &[u64], auth_struct: &[Digest], root: Digest) -> bool
.
I intentionally left the indices of the auth path elements from this function signature because they can be inferred from the leaf indices. They are not part of the current authentication structure. Come to think of it, rather than computing the auth struct indices, it probably makes more sense to divine them in and then verify them.
Since the indices are u64
s, this method and/or struct probably belongs in mmr/
rather than merkle_tree.rs
.
sponge.pad_and_absorb_all(&leafs.encode()); | ||
sponge.pad_and_absorb_all(&auth_struct.encode()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a non-standard mode of use of the sponge construction. While I cannot find an attack, I am concerned that a vulnerability might hide here. If we definitely want this construction (for instance, because it is more efficient to compute in Triton VM) then we need an iron-clad security argument.
The alternative would be something like sponge.pad_and_absorb_all(&(leafs, auth_struct).encode())
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your suggestion probably requires allocation in Triton VM. It's preferable if we can avoid that as much as possible.
p *= fact1.inverse() * fact2.inverse() * fact_parent; | ||
} | ||
|
||
let x_as_xfe = XFieldElement::new([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better name might be index_1_as_xfe
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or root_index_as_xfe
.
Moved code to |
So we have a nice solution that works for Merkle trees. How do we translate this to something that works for Merkle mountain ranges? Do we just include an authentication structure for each peak that the list of leafs are contained in? |
I don't see how things could be done more efficiently, seen as how the various trees in an MMR are completely uncorrelated. |
Now this data structure and associated data can be derived from two sources: Either from an (MMR, membership-proof list) pair, or from a Merkle tree and a list of indices into this tree. In the general case for MMRs, we would need to build a list of these authenticity witnesses, as a collection of leafs will not in the general case be contained to one Merkle tree. |
3bfa553
to
7fdfd33
Compare
Add a function to calculate a Merkle root from an authentication struct in a way that conductive to ZK calculations. And add a function to generate the relevant witness data for this calculation. The authentication structure is a list of digests that is identical to what can be found in `authentication_structure` field in the `MerkleTreeInclusionProof`. With appropriate witness structure, this authentication structure can be verified faster than verifying each individual leaf in an MMR, we hope. This `root_from_authentication_struct` function now needs to be implemented in `tasm-lib` to see if this actually gives shorter programs in Triton-VM. The purpose of this cryptography is to speed up the program that verifies that no double-spends are occurring. See #228.
fa70267
to
2c46e5e
Compare
Add a function to calculate a Merkle root from an authentication struct in a way that conductive to ZK calculations. And add a function to generate the relevant witness data for this calculation. The authentication structure is a list of digests that is identical to what can be found in `authentication_structure` field in the `MerkleTreeInclusionProof`. With appropriate witness structure, this authentication structure can be verified faster than verifying each individual leaf in an MMR, we hope. This `root_from_authentication_struct` function now needs to be implemented in `tasm-lib` to see if this actually gives shorter programs in Triton-VM. The purpose of this cryptography is to speed up the program that verifies that no double-spends are occurring. See #228.
2c46e5e
to
cb9cd37
Compare
Add a function to calculate a Merkle root from an authentication struct in a way that conductive to ZK calculations. And add a function to generate the relevant witness data for this calculation. The authentication structure is a list of digests that is identical to what can be found in `authentication_structure` field in the `MerkleTreeInclusionProof`. With appropriate witness structure, this authentication structure can be verified faster than verifying each individual leaf in an MMR, we hope. This `root_from_authentication_struct` function now needs to be implemented in `tasm-lib` to see if this actually gives shorter programs in Triton-VM. The purpose of this cryptography is to speed up the program that verifies that no double-spends are occurring. See #228.
… nd-sibling indices
Add a function to derive an MMR authentication structure from an MMR accumulator and a list of indexed MMR membership proofs.
The work to find these indices was already done in a helper function. No need to derive them again inside of the constructor-functions.
Add a struct for encapulating the Merkle authentication struct authenticity witness and one for encapsulating the auth struct, its withness, and the data, which are the indexed leaves.
cb9cd37
to
2744ab5
Compare
I'm happy with the state of this code now. Now the only question is just whether a) we actually want to use this data structure, and b) if we do want to use it, whether it belongs in this repo. Oh, and c) whether the interface of |
…-first to this repo The witness generation is somewhat program-specific, so it seems to me to be a better fit for this repo than for twenty-first. Cf. Neptune-Crypto/twenty-first#228
…-first to this repo The witness generation is somewhat program-specific, so it seems to me to be a better fit for this repo than for twenty-first. Cf. Neptune-Crypto/twenty-first#228
Add stub for calculating a Merkle root from an authentication struct. Also adds code to generate the witness. Cf. Neptune-Crypto/twenty-first#228
This is how the
RootFromAuthStruct
implementation could look in Rust. Code works for these two very small test cases.