Replies: 4 comments 1 reply
-
I have a few questions:
|
Beta Was this translation helpful? Give feedback.
-
I do see the benefits behind this proposal and I think it makes sense. We are optimizing the zkProof creation specially on the big census (i.e Nation size), so I'd go for it. However as @brickpop stated, we need to be aware of some details in order to allow a user fetch its MerkleProof (the user does not know about the index). We need to abstract the behavior and write a special implementation of the census tree which will be composed of two data structures: A. The merkle tree itself (using an incremental index as key) Lets take into account that we have two use cases for this zkSnark census:
So for the scenario 1 the census-service (HTTP based) will keep this index internally when the keys are being added. This census needs to be published on IPFS so other Gateways can import it and use for generating merkle-proofs for the users. The export dataset must contain an ordered data structure which allow other Gateways to reconstruct both the merkle tree and the index-map. So when a user asks for a merkle-proof she only needs to provide its key (not the index). For the second scenario the census is build inchain thus the Gateways do not need to import the census from IPFS and it does not need to be exported either. |
Beta Was this translation helpful? Give feedback.
-
I think this is a major improvement because it allows decreasing the merkle tree size in the circuit reducing the number of constraints considerable, which means less computation time on the phone of the user. Without incremental indexes, collisions can happen in the hash used as key, and the two solutions are not nice: either increase the merkle tree size so that the collision probability is negligible (more constraints), or find a way to calculate alternative keys until there's no collision (which is cumbersome). |
Beta Was this translation helpful? Give feedback.
-
Added the spec in the docs.vocdoni.io: vocdoni/docs#60 |
Beta Was this translation helpful? Give feedback.
-
These last days we've updated the design & impl of the circuit for the anonymous-voting with zk-census-proofs. But currently the usage of the merkletree leafs, is that the key that determines the path of the leaf in the tree is determined by the hash of the
secretKey
of the user. This brings into a tree that might not be fully used, having empty leafs that might not be used before finding a collision in the paths. Meaning that if the tree has for example 10 levels, it has available 1024 leafs, but not all the spots will be used as there will be collisions much before of reaching the 1024 available leafs, thus having an inefficient use of the tree space.As an example, I did some tests with random key values in leafs (the old approach), and with 10 levels, when adding the leaf 27 it found a collision of already used leaf. Even using 16 levels (
2**16=65536
total leafs) there were collisions when adding the leaf number 526. With 21 levels (2**21=2097152
leafs) is the smaller nLevels that allowed me to insert 1000 leafs (with random keys) without finding collisions (and even some of the iterations there were collisions).So, the proposal would be that for the leaf, instead of using
key: hash(secretKey), value: 0
, to use a incremental index in thekey
, so the tree can eventually be filled at its maximum potential. It would look likekey: incremental-index, value: hash(secretKey)
. Theindex
would start at0
and be incremented by1
for each new leaf addition.Meaning that if the tree has for example 10 levels, it has available 1024 leafs, and all the spots will be able to be used always.
This translates into more efficient usage of the Merkle Trees, thus using smaller circuits for the same census size, which means faster zkSNARK proof generation time in the user side.
For the previous example numbers, for a census of 1000 leafs, we could use a tree of 10 levels instead of a tree of at least 21 levels).
The current circuit for
10 levels
it has4214 constraints
, while for21 levels
it has6931 constraints
(and take in mind that with 21 levels for 1000 leafs in the old approach there are still high probabilities of collision, so more levels would be needed to be safe).This design is possible in the zk-census-proof scheme because is the Vochain who is updating the merkletree, so can maintain in the state the current index to be used in the next leaf addition.
This change would require:
leafIndex
to the circuit, and update the way how the leaf is done to use theleafIndex
as key and thehash(secretKey)
as the value of the leafleafIndex
needed logic into the Vochain. And make the gateway return theleafIndex
of the user leaf when sends thesiblings
to the userleafIndex
value when generating the zkInputs data structureBeta Was this translation helpful? Give feedback.
All reactions