{"id":27021209,"url":"https://github.com/jonas089/cypher-poll","last_synced_at":"2025-04-04T19:43:07.645Z","repository":{"id":248178932,"uuid":"817954780","full_name":"jonas089/cypher-poll","owner":"jonas089","description":"Anonymous Github Voting Protocol","archived":false,"fork":false,"pushed_at":"2024-10-17T21:58:34.000Z","size":972,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-20T08:50:18.689Z","etag":null,"topics":["anonymous-voting","dao","distributed-systems","github-voting","governance","portfolio","rust","zero-knowledge-proofs"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonas089.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-20T19:49:40.000Z","updated_at":"2024-10-17T21:58:38.000Z","dependencies_parsed_at":"2024-10-21T17:09:44.054Z","dependency_job_id":null,"html_url":"https://github.com/jonas089/cypher-poll","commit_stats":null,"previous_names":["jonas089/cypher-poll"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fcypher-poll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fcypher-poll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fcypher-poll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fcypher-poll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonas089","download_url":"https://codeload.github.com/jonas089/cypher-poll/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247239056,"owners_count":20906557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anonymous-voting","dao","distributed-systems","github-voting","governance","portfolio","rust","zero-knowledge-proofs"],"created_at":"2025-04-04T19:43:07.008Z","updated_at":"2025-04-04T19:43:07.637Z","avatar_url":"https://github.com/jonas089.png","language":"Rust","readme":"\u003e [!NOTE]\n\u003e This project has a few limitations. The more people participate in a poll the more anonymous it becomes. A poll with just one participant is not anonymous. When there are two participants then the anonymity is limited since you know that either of the two voted for X. For many participants this should be secure (no audit, no guarantees).\n\n\n# Anonymous GitHub GPG Voting Protocol built with Risc0\nCypher-poll is an anonymous voting protocol which anyone with a GitHub identity and at least one associated GPG key can use.\nThe service can be modified to enforce further restrictions on who is eligible to vote, by default any GitHub account with a GPG key can vote once (not once per GPG key!).\n\n![reg](https://github.com/jonas089/cypher-poll/blob/master/assets/demo.png)\n\n## Registration process\nThe registration process consists of the user submitting their `Identity`, which is a `Hash` of their unique `Nullifier` concatenated by their `Public Key`.\nIf the user successfully generates a `Signature` for a `Public Key` that is associated with their GitHub account, the Hash of the `Nullifier` and `Public Key` is inserted in a fixed size `Merkle Tree`. A Snapshot of the `Merkle Tree` at that point in time is returned to the user.\n\n## Voting process\nTo issue a vote, the user must submit a zero knowledge proof that the `Nullifier` that is being redeemed was included in the `Merkle Tree` for a given Snapshot. The Snapshot that was returned by the server at the end of the registration process is sufficent as long as the corresponding `Merkle Root` is included in the set of valid `Merkle Roots` in service (or Blockchain) state.\n\nIf the proof is accepted, the vote is counted and the `Nullifier` is added to a list to ensure that it cannot be used again.\n\n## Generate and Export a GPG key\n```\ngpg --full-generate-key\ngpg --armor --export-secret-keys keyID_or_email \u003e private_key.sec.asc\ngpg --armor --export keyID_or_email \u003e public_key.asc\n```\n\n## Specify Github API Token\nExample `.bashrc`:\n```bash\nexport GITHUB_TOKEN=\"YOUR_API_TOKEN_WITH_PGP_READ_PERMISSION\"\n```\nClick [here](https://github.com/settings/tokens) to generate an access token.\n\n## Run the Server\n```bash\ncargo run -p service\n```\n\n## Client Documentation\n```bash\ncargo run -p client\n```\nThis will print all the available commands (`register`, `vote`)\n\nExample commands can be found in `scripts`, review them to make sure to change the user-specific inputs (`username`, `public-key-path`, `private-key-path`, `random-seed`, `data`). \n\nThe Client will write the `Nullifier` and `Snapshot` for the vote are to files, therefore environment variables must be present:\n```bash\nexport NULLIFIER_PATH=\"/Users/chef/Desktop/cypher-poll/artifacts/nullifier\"\nexport SNAPSHOT_PATH=\"/Users/chef/Desktop/cypher-poll/artifacts/snapshot\"\n```\n\nComplete `.bashrc`:\n```bash\nexport GITHUB_TOKEN=\"YOUR_API_TOKEN_WITH_PGP_READ_PERMISSION\"\nexport NULLIFIER_PATH=\"/Users/chef/Desktop/cypher-poll/artifacts/nullifier\"\nexport SNAPSHOT_PATH=\"/Users/chef/Desktop/cypher-poll/artifacts/snapshot\"\n```\n\n## Client Arguments Meaning\n\n| `data` | `*-key-path` | `random-seed` | `username` |\n| --- | --- | --- | --- |\n| challenge to be signed with the gpg key | path to a gpg key encoded in .asc (ASCII) | seed used to generate a unique nullifier, must be random and kept secret | github username |\n\n## The `vote` Argument\nThe vote must be the same for both `register` and `vote`. With `vote` a leaf in the Tree is redeemed that was inserted during `register`. Trying to redeem an invalid vote will result in an error =\u003e an incorrect leaf.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonas089%2Fcypher-poll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonas089%2Fcypher-poll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonas089%2Fcypher-poll/lists"}