- 
                Notifications
    
You must be signed in to change notification settings  - Fork 34
 
foundry voting example<updated> #37
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
          
     Open
      
      
            satyambnsal
  wants to merge
  13
  commits into
  noir-lang:master
  
    
      
        
          
  
    
      Choose a base branch
      
     
    
      
        
      
      
        
          
          
        
        
          
            
              
              
              
  
           
        
        
          
            
              
              
           
        
       
     
  
        
          
            
          
            
          
        
       
    
      
from
satyambnsal:master
  
      
      
   
  
    
  
  
  
 
  
      
    base: master
Could not load branches
            
              
  
    Branch not found: {{ refName }}
  
            
                
      Loading
              
            Could not load tags
            
            
              Nothing to show
            
              
  
            
                
      Loading
              
            Are you sure you want to change the base?
            Some commits from the old base branch may be removed from the timeline,
            and old review comments may become outdated.
          
          
  
     Open
                    Changes from 1 commit
      Commits
    
    
            Show all changes
          
          
            13 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      2ee49e2
              
                Update foundry voting example
              
              
                satyambnsal d6b1544
              
                code cleanup and Readme changes
              
              
                satyambnsal f32a29a
              
                feat: Use zk-kit package for merkle tree
              
              
                satyambnsal b76328a
              
                chore: fix foundry ci pipeline
              
              
                satyambnsal f8c9751
              
                Add option for triggering workflow manually
              
              
                satyambnsal 8bbaa86
              
                chore: CI workflow changes
              
              
                satyambnsal e49a395
              
                Merge branch 'master' into master
              
              
                critesjosh 979cb5f
              
                Update foundry-voting.yml
              
              
                critesjosh 9134313
              
                Update foundry-voting.yml
              
              
                critesjosh d37c8e5
              
                Remove merkle tree usage from zk-kit
              
              
                satyambnsal 8cf77b8
              
                Merge branch 'master' of github.com:satyambnsal/noir-examples
              
              
                satyambnsal 9367f56
              
                Add circuit target files
              
              
                satyambnsal 2c1f91f
              
                Fix circuit generate script
              
              
                satyambnsal File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,20 +1,177 @@ | ||
| # Compiler files | ||
| cache/ | ||
| out/ | ||
| # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore | ||
| 
     | 
||
| # Ignores development broadcast logs | ||
| !/broadcast | ||
| /broadcast/*/31337/ | ||
| /broadcast/**/dry-run/ | ||
| # Logs | ||
| 
     | 
||
| # Docs | ||
| docs/ | ||
| logs | ||
| _.log | ||
| npm-debug.log_ | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| lerna-debug.log* | ||
| .pnpm-debug.log* | ||
| 
     | 
||
| circuits/target | ||
| # Caches | ||
| 
     | 
||
| cache | ||
| .cache | ||
| 
     | 
||
| # Diagnostic reports (https://nodejs.org/api/report.html) | ||
| 
     | 
||
| report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json | ||
| 
     | 
||
| # Runtime data | ||
| 
     | 
||
| pids | ||
| _.pid | ||
| _.seed | ||
| *.pid.lock | ||
| 
     | 
||
| # Directory for instrumented libs generated by jscoverage/JSCover | ||
| 
     | 
||
| lib-cov | ||
| 
     | 
||
| # Coverage directory used by tools like istanbul | ||
| 
     | 
||
| coverage | ||
| *.lcov | ||
| 
     | 
||
| # nyc test coverage | ||
| 
     | 
||
| .nyc_output | ||
| 
     | 
||
| # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
| 
     | 
||
| .grunt | ||
| 
     | 
||
| # Bower dependency directory (https://bower.io/) | ||
| 
     | 
||
| bower_components | ||
| 
     | 
||
| # node-waf configuration | ||
| 
     | 
||
| .lock-wscript | ||
| 
     | 
||
| # Compiled binary addons (https://nodejs.org/api/addons.html) | ||
| 
     | 
||
| build/Release | ||
| 
     | 
||
| # Dependency directories | ||
| 
     | 
||
| node_modules/ | ||
| jspm_packages/ | ||
| 
     | 
||
| # Snowpack dependency directory (https://snowpack.dev/) | ||
| 
     | 
||
| web_modules/ | ||
| 
     | 
||
| # TypeScript cache | ||
| 
     | 
||
| *.tsbuildinfo | ||
| 
     | 
||
| # Optional npm cache directory | ||
| 
     | 
||
| .npm | ||
| 
     | 
||
| # Optional eslint cache | ||
| 
     | 
||
| .eslintcache | ||
| 
     | 
||
| # Optional stylelint cache | ||
| 
     | 
||
| .stylelintcache | ||
| 
     | 
||
| # Microbundle cache | ||
| 
     | 
||
| .rpt2_cache/ | ||
| .rts2_cache_cjs/ | ||
| .rts2_cache_es/ | ||
| .rts2_cache_umd/ | ||
| 
     | 
||
| # Optional REPL history | ||
| 
     | 
||
| .node_repl_history | ||
| 
     | 
||
| # Output of 'npm pack' | ||
| 
     | 
||
| *.tgz | ||
| 
     | 
||
| # Yarn Integrity file | ||
| 
     | 
||
| .yarn-integrity | ||
| 
     | 
||
| # dotenv environment variable files | ||
| 
     | 
||
| # Dotenv file | ||
| .env | ||
| .env.development.local | ||
| .env.test.local | ||
| .env.production.local | ||
| .env.local | ||
| 
     | 
||
| # parcel-bundler cache (https://parceljs.org/) | ||
| 
     | 
||
| .parcel-cache | ||
| 
     | 
||
| # Next.js build output | ||
| 
     | 
||
| .next | ||
| out | ||
| 
     | 
||
| # Nuxt.js build / generate output | ||
| 
     | 
||
| .nuxt | ||
| dist | ||
| 
     | 
||
| # Gatsby files | ||
| 
     | 
||
| # Comment in the public line in if your project uses Gatsby and not Next.js | ||
| 
     | 
||
| # https://nextjs.org/blog/next-9-1#public-directory-support | ||
| 
     | 
||
| # public | ||
| 
     | 
||
| # vuepress build output | ||
| 
     | 
||
| .vuepress/dist | ||
| 
     | 
||
| # vuepress v2.x temp and cache directory | ||
| 
     | 
||
| .temp | ||
| 
     | 
||
| # Docusaurus cache and generated files | ||
| 
     | 
||
| .docusaurus | ||
| 
     | 
||
| # Serverless directories | ||
| 
     | 
||
| .serverless/ | ||
| 
     | 
||
| # FuseBox cache | ||
| 
     | 
||
| .fusebox/ | ||
| 
     | 
||
| # DynamoDB Local files | ||
| 
     | 
||
| .dynamodb/ | ||
| 
     | 
||
| # TernJS port file | ||
| 
     | 
||
| .tern-port | ||
| 
     | 
||
| # Stores VSCode versions used for testing VSCode extensions | ||
| 
     | 
||
| .vscode-test | ||
| 
     | 
||
| # yarn v2 | ||
| 
     | 
||
| .yarn/cache | ||
| .yarn/unplugged | ||
| .yarn/build-state.yml | ||
| .yarn/install-state.gz | ||
| .pnp.* | ||
| 
     | 
||
| node_modules | ||
| crs | ||
| # IntelliJ based IDEs | ||
| .idea | ||
| 
     | 
||
| circuits/contract | ||
| circuits/proofs | ||
| # Finder (MacOS) folder config | ||
| .DS_Store | 
This file was deleted.
      
      Oops, something went wrong.
      
    
  
                              
      
                  satyambnsal marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
            
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,54 +1,113 @@ | ||
| # zk Voting with Foundry | ||
| # Foundry Voting Example | ||
| 
     | 
||
| [](https://github.com/noir-lang/noir-starter/actions/workflows/foundry-voting.yml) | ||
| This project demonstrates a voting system implementation using Noir circuits and Foundry. | ||
| 
     | 
||
| This example project shows how to create a simple zk voting circuit in Noir with a corresponding Solidity contract to track eligible voters, proposals and votes. | ||
| ## Quick Start | ||
| 
     | 
||
| This example was last tested with Noir version 0.28.0. You can install it with [noirup](https://noir-lang.org/docs/getting_started/installation/#installing-noirup) using | ||
| Install dependencies: | ||
| ```bash | ||
| bun install | ||
| ``` | ||
| 
     | 
||
| ## Development Guide | ||
| 
     | 
||
| ### Interactive Build Process | ||
| 
     | 
||
| Run all steps interactively with status updates: | ||
| ```bash | ||
| noirup -v 0.28.0 | ||
| bun run build:ultraplonk | ||
| ``` | ||
| 
     | 
||
| ## Overview | ||
| This will guide you through all the steps with prompts and status updates. | ||
| 
     | 
||
| ### Manual Steps | ||
| 
     | 
||
| This is the model used for creating the [circuit](circuits/src/main.nr) and the [zkVote contract](src/zkVote.sol) to manage private voting. | ||
| #### 1. Circuit Testing | ||
| 
     | 
||
| 1. Create a set of voters. A merkle root is stored in the zkVote Solidity contract that voters will use to verify membership against. In this example, there are 4 accounts in the set of voters. The private keys are 0, 1, 2, 3 and the secret value to create the commitment is 9. | ||
                
      
                  satyambnsal marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| Run the test suite: | ||
| ```bash | ||
| bun run circuits:test | ||
| ``` | ||
| 
     | 
||
| #### 2. Circuit Execution Flow | ||
| 
     | 
||
| | Private Key | Commitment = pedersen(private key, secret) | | ||
| | ----------- | ------------------------------------------------------------------ | | ||
| | 1 | 0x03542cb720369f19a74fd05b4edfbedb27a78514ad3283f1b3270a1656cced8e | | ||
| | 2 | 0x1efa9d6bb4dfdf86063cc77efdec90eb9262079230f1898049efad264835b6c8 | | ||
| | 3 | 0x24013340c052ebf847e0d7081f84e6a8e92f54e2e1726a1e559ac46a8f242007 | | ||
| | 4 | 0x04fd3da9756f25c72ca8990437b7f7b58e7ca48bfc21e65e7978320db8b1e5c5 | | ||
| Execute the circuit (generates witness and circuit JSON file): | ||
| ```bash | ||
| bun run circuits:execute | ||
| ``` | ||
| 
     | 
||
| This gives intermediate hashes of `0x046394ae1ebbf494f2cd2c2d37171099510d099489c9accef59f90512d5f0477` (`pedersen(commitment0, commitment1)`) and `0x2a653551d87767c545a2a11b29f0581a392b4e177a87c8e3eb425c51a26a8c77` (`pedersen(commitment2, commitment3)`) and a root hash of `0x215597bacd9c7e977dfc170f320074155de974be494579d2586e5b268fa3b629`. | ||
| #### 3. Proof Generation | ||
| 
     | 
||
| 2. Users will input their information into the circuit and generate a proof (see example inputs in [Prover.toml](./circuits/Prover.toml) and run `nargo prove` to generate the proof.) | ||
| 1. Public inputs and outputs are printed in [Verifier.toml](./circuits/Verifier.toml). | ||
| 2. The proof is saved to `./proofs/foundry_voting.proof`. | ||
| 3. The generated proof + the contents of Verifier.toml are sent in a transaction to the `castVote` function in the [zkVote](./src/zkVote.sol) contract. The function verifies that the sender is authorized to vote on the proposal, that they haven't already voted and tallies their vote. | ||
| Generate UltraPlonk proof: | ||
| ```bash | ||
| bun run circuits:ultraplonk:generate-proof | ||
| ``` | ||
| 
     | 
||
| ## Testing | ||
| Generate verification key: | ||
| ```bash | ||
| bun run circuits:ultraplonk:generate-vk | ||
| ``` | ||
| 
     | 
||
| You can run the Noir tests (also defined in main.nr) with `nargo test`. To print test output, use `nargo test --show-output`. | ||
| #### 4. Contract Generation | ||
| 
     | 
||
| See the test file [here](./test/zkVote.t.sol). Run tests with `forge test`. | ||
| Generate the Solidity verifier contract: | ||
| ```bash | ||
| bun run circuits:contract | ||
| ``` | ||
| 
     | 
||
| 1. Run `nargo compile` to compile the circuit. | ||
| 2. Run `nargo prove` to generate the proof (with the inputs in Prover.toml). | ||
| 3. Run `nargo codegen-verifier` to generate the solidity verifier contract. | ||
| 4. Run `yarn test` to run the Foundry test the Solidity verifier contract at `./test/zkVote.t.sol`. | ||
| #### 5. Proof Processing | ||
| 
     | 
||
| ## Development | ||
| Clean and format the proof for contract verification: | ||
| ```bash | ||
| bun run ultraplonk:clean-proof | ||
| ``` | ||
| 
     | 
||
| If you change the circuit at `./circuits/src/main.nr` you will need to recompile (`nargo compile`) the circuit and regenerate the Solidity verifier (saved to `./circuits/contract/plonk_vk.sol`). | ||
| #### 6. Contract Testing | ||
| 
     | 
||
| The merkle tree will need to be recalculated whenever there are users added to the set or if there are any changes to the voters secrets (secrets are the input to the merkle membership commitment, so changing a key changes the corresponding leaf in the merkle tree, which changes the root). See `test_valid_build_merkle_tree` for an example calculation. | ||
| Run Forge tests: | ||
| ```bash | ||
| forge test | ||
| ``` | ||
| 
     | 
||
| Run `nargo test --show-output` in `./circuits` to print the example merkle tree. | ||
| ### Advanced Usage | ||
| 
     | 
||
| ## Contributions | ||
| #### Manual Circuit Commands | ||
| 
     | 
||
| Thanks to the folks at zkCamp modifying the original example and adding tests. You can see their repo [here](https://github.com/ZKCamp/noir-voting/tree/6-security). | ||
| If you need to run circuit commands directly: | ||
| 
     | 
||
| 1. Navigate to circuits directory: | ||
| ```bash | ||
| cd circuits | ||
| ``` | ||
| 
     | 
||
| 2. Run Noir tests with output: | ||
| ```bash | ||
| nargo test --show-output | ||
| ``` | ||
| 
     | 
||
| 3. Generate Prover.toml file: | ||
| ```bash | ||
| nargo check | ||
| ``` | ||
| 
     | 
||
| 4. Execute circuit (after updating Prover.toml with inputs): | ||
| ```bash | ||
| nargo execute | ||
| ``` | ||
| This generates: | ||
| - Circuit JSON in `target/circuits.json` | ||
| - Witness file in `target/circuits.gz` | ||
| 
     | 
||
| #### Manual Proof Generation | ||
| 
     | 
||
| Generate proof using UltraPlonk: | ||
| ```bash | ||
| bb prove -b ./target/circuits.json -w ./target/circuits.gz -o ./target/proof | ||
| ``` | ||
| 
     | 
||
| Generate proof string manually: | ||
| **Number of character to tail is counted with formula, 32 * NUMBER_OF_PUBLIC_INPUTS + 1** | ||
| **Number of public inputs also includes return values, that's why we have 4 public input for our circuit.** | ||
| ```bash | ||
| tail -c +129 ./target/proof | od -An -v -t x1 | tr -d $' \n' | ||
| ``` | ||
            Binary file not shown.
          
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,7 +1,6 @@ | ||
| [package] | ||
| authors = [""] | ||
| compiler_version = ">=0.22.0" | ||
| name="foundry_voting" | ||
| type="bin" | ||
| name = "circuits" | ||
| type = "bin" | ||
| authors = ["Satyam Bansal"] | ||
| 
     | 
||
| [dependencies] | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,9 +1,9 @@ | ||
| hash_path = [ | ||
| "0x1efa9d6bb4dfdf86063cc77efdec90eb9262079230f1898049efad264835b6c8", | ||
| "0x2a653551d87767c545a2a11b29f0581a392b4e177a87c8e3eb425c51a26a8c77" | ||
| "0x2a653551d87767c545a2a11b29f0581a392b4e177a87c8e3eb425c51a26a8c77", | ||
| ] | ||
| index = "0" | ||
| proposalId = "0" | ||
| root = "0x215597bacd9c7e977dfc170f320074155de974be494579d2586e5b268fa3b629" | ||
| secret = "1" | ||
| vote = "1" | ||
| vote = "1" | 
This file was deleted.
      
      Oops, something went wrong.
      
    
  
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.