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

Use a tree to compute the result commitment #89

Conversation

weijiekoh
Copy link
Contributor

@weijiekoh weijiekoh commented May 1, 2020

Currently, during the tally process, we use MiMCSponge to hash all the results and a salt to create a result commitment:

commitment = hash([...results, salt])

When we switch to Poseidon hashes, however, we will need a different way. This is because the Poseidon EVM code supports up to 5 elements, while we need to support many more than 5 vote options. correction, 3 May 2020: this is incorrect; we can still safely use Poseidon for more than 5 elements

The solution presented in this PR is to generate the commitment by using a Merkle tree:

commitment = hashLeftRight(computeRoot(results), salt)

This means that we can simply use PoseidonT3 (to hash 2 elements) for the Merkle tree and for hashLeftRight, so we won't need to write new EVM code or a PoseidonSponge.

edit, 3 May 2020: This also means that a client application can verifiably prove that they know the value of any leaf by providing a Merkle path from the leaf to the root.

Original QVT circuit: 121466 constraints
New QVT circuit: 141266 constraints

Original proveVoteTallyBatch(): 740772 gas
New proveVoteTallyBatch(): 740860 gas

Using zkutil, the difference in proof generation time is negligible.

There is also a bugfix in cli/ts/utils.ts which makes genMaciStateFromContract correctly read the tree depths from the contract.

Related to #88

@weijiekoh weijiekoh added the enhancement New feature or request label May 1, 2020
@weijiekoh weijiekoh self-assigned this May 1, 2020
@weijiekoh weijiekoh force-pushed the feat/result-commitment-as-tree branch from ff2b106 to 193c0fc Compare May 1, 2020 06:58
@weijiekoh weijiekoh force-pushed the feat/result-commitment-as-tree branch from 193c0fc to aeb9e69 Compare May 1, 2020 07:26
@weijiekoh weijiekoh force-pushed the feat/result-commitment-as-tree branch from ac2bd6b to 10fca58 Compare May 1, 2020 08:22
@weijiekoh weijiekoh marked this pull request as ready for review May 1, 2020 09:02
@weijiekoh
Copy link
Contributor Author

This PR should be OK to merge even though the latest test failed (as of 5pm today -https://circleci.com/workflow-run/c9a47f2f-c1a4-43be-9119-33fb3b25ce14). This is due to the low performance of the CircleCI VM, not a problem with the code.

@weijiekoh
Copy link
Contributor Author

There is one issue which this PR does not address: the final invocation of proveVoteTallyBatch() requires that the sender pass in a uint256[] memory _finalResults value. There may be an upper limit on the size of the array (e.g. perhaps if we pass in 1024 values), and make it impossible to tally the final batch. Let's address this in #90.

@weijiekoh
Copy link
Contributor Author

weijiekoh commented May 3, 2020

In lieu of #91, this PR will also remove the requirement that the coordinator must publish the final tally on-chain.

Copy link
Collaborator

@ChihChengLiang ChihChengLiang left a comment

Choose a reason for hiding this comment

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

Only a nitpick. Other parts look good.

Note that changes in this PR are not reflected in the specs.
It might be tedious to do that in every PR, so I created a tracking issue #93. When we feel something that requires a spec update we just refer to #93.

// Calculate and store a commitment to 2 ** voteOptionTreeDepth zeros,
// and the salt of 0.
currentResultsCommitment = hashLeftRight(
computeEmptyRoot(_treeDepths.voteOptionTreeDepth, 0),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be emptyVoteOptionTreeRoot?

Suggested change
computeEmptyRoot(_treeDepths.voteOptionTreeDepth, 0),
emptyVoteOptionTreeRoot,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops! Computing the root twice wastes gas. Thank you for spotting this. I'll push a commit to fix it.

@weijiekoh
Copy link
Contributor Author

Updated the spec :D

@weijiekoh weijiekoh merged commit 77ef551 into privacy-scaling-explorations:master May 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants