{"id":18906271,"url":"https://github.com/enricobottazzi/designated-verifier-proof","last_synced_at":"2025-06-27T19:35:45.427Z","repository":{"id":60353372,"uuid":"529588341","full_name":"enricobottazzi/designated-verifier-proof","owner":"enricobottazzi","description":"Reusable component to add a designated verifier to your zk circom circuit. It means that the zk proof generated from your circuit cannot be verified by someonewho is not the designated verifier (identified by its ethereum public address)","archived":false,"fork":false,"pushed_at":"2023-03-08T10:14:08.000Z","size":93765,"stargazers_count":40,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-15T04:43:11.606Z","etag":null,"topics":["circom","cryptography","ecdsa-cryptography","signature-verification","snarkjs","zk-snarks"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/enricobottazzi.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,"zenodo":null}},"created_at":"2022-08-27T13:07:30.000Z","updated_at":"2025-03-21T04:07:11.000Z","dependencies_parsed_at":"2025-04-15T04:32:46.971Z","dependency_job_id":"3e1b7c3d-1d8a-46c0-8a8b-ed463eed86f6","html_url":"https://github.com/enricobottazzi/designated-verifier-proof","commit_stats":null,"previous_names":["enricobottazzi/designated-verifier-proof"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/enricobottazzi/designated-verifier-proof","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enricobottazzi%2Fdesignated-verifier-proof","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enricobottazzi%2Fdesignated-verifier-proof/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enricobottazzi%2Fdesignated-verifier-proof/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enricobottazzi%2Fdesignated-verifier-proof/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/enricobottazzi","download_url":"https://codeload.github.com/enricobottazzi/designated-verifier-proof/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enricobottazzi%2Fdesignated-verifier-proof/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262319567,"owners_count":23293047,"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":["circom","cryptography","ecdsa-cryptography","signature-verification","snarkjs","zk-snarks"],"created_at":"2024-11-08T09:15:38.212Z","updated_at":"2025-06-27T19:35:45.402Z","avatar_url":"https://github.com/enricobottazzi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Protecting Private Communication Channels with Designated Verifier Proofs \n\n\u003e The code in this repo is unaudited and not recommended for production use\n\n**Core Team**: Enrico Bottazzi (Developer) and Shrey Jain (Researcher and PM). Enrico Bottazzi is an Applied ZK Developer and Shrey Jain is a Web3 Researcher at Microsoft.\n\nDespite the progress being made in cryptography, we still lack the technological countermeasures to prevent the public revelation of private communication. Examples of this abuse is seen with China’s digital Yuan, Snowden's Turnkey Tyranny, media giants profiting off of users private information, large technology companies merging with surveillance states, and the rise of foreign and domestic conflicts that spur the erosion of civil liberties [1-3]. \n\nRegardless of the methods being used to improve both the security and privacy on a communication channel, so long as an agent is able to interpret and understand information, there is no technological tool that can prevent this information from being shared. \n\nThe gap that exists today is that we associate privacy with being a mathematical problem that can be solved by cryptography. Privacy is not mathematical, it is fundamentally social. Given that it is a social problem, it requires social data structures to solve it, yet there are few solutions today that look at privacy from this angle. \n\nTo protect our privacy, not only do we need to ensure that our cryptographic tools withstand the test of quantum computers, but we also need to design social data structures that can prevent information from being persuasive in its shared form (having a 3rd party believe private information) [4]. Designated verifier proofs (DVPs) were introduced in 1996 as a social data structure in the form of a cryptographic scheme to ensure that only a designated verifier is persuaded of information being communicated to them and any 3rd party is unsure whether the designated verifier is telling the truth or not [5]. \n\nThis repository aims at providing the tools for builders to use DVPs for communication more broadly to mitgiate the persuasiveness of private information in its shared form. \n_________________________________________________________________________________________________\n\nDVP is a reusable component to add a designated verifier to your zk circom circuit. It means that the zk proof generated from your circuit cannot be verified by someonewho is not the designated verifier (identified by its ethereum public address). For this example we used the component to generate a designated verifier proof of valid ECDSA signature. \n\nDVP uses Zero Knowledge Proof to achieve that:\n\n- The prover chooses the designated verifier\n- The prover signs the message to be shared with the designated verifier \n- The prover generates a proof that the signature is valid (1st condition) **OR** he/she knows the private key of the designated verifier (2nd condition)\n- The verifier receives the proof\n\nAfter the verifier receives the proof, he/she can potentially share it with third parties. But here's the cool thing:\nNo one, except for the designated verifier, can tell if the proof verifies because of the 1st condition or the 2nd condition, i.e. because it has been forged by the designated verifier.\n\nIdea inspired by: \n\n- [Jordi Baylina - ZKP and SSI - Iden3](https://www.youtube.com/watch?v=Rd6SMShk7-c\u0026t=998s)\n- [Markus Jakobsson - Designated Verifier Proofs and Their Applications paper](http://markus-jakobsson.com/papers/jakobsson-eurocrypt96.pdf)\n\n## Circuit Design \n\nThe design of the circuit relies on two main components: \n\n- [0xPARC `ECDSAVerifyNoPubkeyCheck`](https://github.com/0xPARC/circom-ecdsa/blob/master/circuits/ecdsa.circom#L129): Given a signature (r, s), a message hash, and a secp256k1 public key, it follows ecdsa verification algorithm to extract r' from s, message hash and public key, and then compares r' with r to see if the signaure is correct. The output result is 1 if r' and r are equal, 0 otherwise.\n- [0xPARC `ECDSAPrivToPub`](https://github.com/0xPARC/circom-ecdsa/blob/master/circuits/ecdsa.circom#L14): Given a secp256k1 private key, outputs the corresponding public key by computing (private_key) * G where G is the base point of secp256k1.\n\nThe circuit [`DesignatedVerifierProof`](./circuits/lib/designated-verifier-proof.circom) meshes these two circuits together to verify 2 conditions: \n\n- Is the signature actually been performed by that `pubkey`?\n- Does the private key match the `Designated Verifier Address`? \n\nEach of these conditions generates an intermediate signal =\u003e 1 if verifier and 0 if not verified. These two signals are eventually passed into a `OR` verification that generates the single public output of the circuit: 1 if at least one of the condition verifies or 0 if none of the condition verifies.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src= \"./imgs/dvs.png\" align=\"center\"/\u003e\n\u003c/div\u003e\n\n## Designated Verifier Proof in Practice\n\nThe essence of the DVP is based on a simple yet very powerful concept. Let's consider an example: Alice signs a message X and passes it to Bob (not using a DVP). In this scenario Bob is able to check that the signature is valid and it actually comes from Alice. Bob can now share this proof with third parties and *anyone will be persuaded* by the fact \"Alice signed message X\".\n\nUsing DVP, Alice generates a proof that the signature of message X is valid *OR* that she knows the private key of the designated verifier. This proof is passed to Bob. Bob is aware that his private key hasn't been compromised by Alice, therefore he knows that the proof must be valid because the signature is valid. \n\nWhat if Bob wants to persuade other people that \"Alice signed message X\"? He can still share the proof received by Alice with third parties but they wouldn't know whether: \n\n- The proof verifies because the signature is valid\n- The proof verifies because the verifier knows his own private key (which is true by definition)\n\nWith DVP *only the Designated Verifier will be persuaded* by the signature provided by the Prover.\n\n## Setup \n\n- Install package dependencies `npm i`\n- Clone submodule from root directory `git submodule update --init`\n- Install sub module dependencies `cd circom-ecdsa / npm i`\n- Download ptau inside circuits folder `cd circuits / wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_21.ptau`\n\n## Test \n\n- `export NODE_OPTIONS=--max-old-space-size=120480000` to specifies the amount of virtual memory allocated to Node.js in order to avoid Javascript running out of memory\n- `mocha`\n\nNote; in order to successfully test it a patch to circom_tester must be applied:\n\nComment out line 90 and 91 inside `node_modules/circom_tester/wasm/tester.js`. These avoids breaking the circom_tester compiler due to warnings included in the circuit compilation.\n\n```js\n// assert(b.stderr == \"\",\n//   \"circom compiler error \\n\" + b.stderr);\n```\n\n## Machine setup to build\n\nTo interact with such large circuits, it is needed to operate with very large machines and set a few tweaks to make it possible:\n\n- [Set up your instance](https://hackmd.io/V-7Aal05Tiy-ozmzTGBYPA?view#Setup-from-scratch)\n- [Remove system memory limit](https://hackmd.io/V-7Aal05Tiy-ozmzTGBYPA?view#Remove-system-memory-limit)\n- [Install Snarkjs](https://docs.circom.io/getting-started/installation/#installing-snarkjs)\n- Clone the repo and follow the setup previously described\n- `export NODE_OPTIONS=--max-old-space-size=120480000` \n- To build `bash scripts/setup_dvp.sh`\n\nI used a AWS c3.8xlarge instance to build this. This instance has 32vCPU, 60GB of RAM and 30 GB of SSD Memory. The instance will use Ubuntu 20.04. It costs $1.6/hour to run.\n\nThe circuit specified in this repo has 1756287 constraints.\n\n## Benchmarks\n\nAll benchmarks were run on the AWS c3.8xlarge machine previously described.\n\n|   |dvp|\n|---|---|\n|Constraints                          |1756287 |\n|Circuit compilation                  |153s    |\n|Witness generation                   |232s     |\n|Trusted setup phase 2 key generation |722s     |\n|Trusted setup phase 2 contribution   |104s      |\n|Proving key size                     |1.2G     |\n|Proving key verification             |787s     |\n|Proving time                         |66s      |\n|Proof verification time              |1s      |\n\nThe most intense step is the proving key generation. Luckily, this process need to be executed only once and can be reused for every application that wants to use this circuit architecture. \n\nThe artifacts generated during the Trusted Setup are publicly available :\n\n- proving key **zkey** `wget https://dvs-eb-bucket.s3.eu-west-2.amazonaws.com/dvs.zkey` \n- circuit **wasm** `wget  https://dvs-eb-bucket.s3.eu-west-2.amazonaws.com/dvs.wasm`\n- verification key **vkey** `wget https://dvs-eb-bucket.s3.eu-west-2.amazonaws.com/vkey.json`\n\nUsers will only need these artifact in order to generate/verify proofs. These processes are much less light weight and can be executed locally inside any browser.\n\n**References**\n\n- [1] The, “The digital yuan offers China a way to dodge the dollar,” Economist (London, England: 1843), The Economist, Sep. 05, 2022. Accessed: Oct. 16, 2022. [Online]. Available: https://www.economist.com/finance-and-economics/2022/09/05/the-digital-yuan-offers-china-a-way-to-dodge-the-dollar\n- [2]\tE. Snowden, “Edward Snowden on Protecting Activists Against Surveillance,” WIRED, Sep. 18, 2018. https://www.wired.com/story/wired25-edward-snowden-malkia-cyril-activist-surveillance/ (accessed Oct. 16, 2022).\n- [3]\tB. X. Chen, “The Battle for Digital Privacy Is Reshaping the Internet,” The New York Times, The New York Times, Sep. 16, 2021. Accessed: Oct. 16, 2022. [Online]. Available: https://www.nytimes.com/2021/09/16/technology/digital-privacy.html.\n- [4]\tE. Kamenica and M. Gentzkow, “Bayesian Persuasion,” Am. Econ. Rev., vol. 101, no. 6, pp. 2590–2615, Oct. 2011.\n- [5]\tM. Jakobsson, K. Sako, and R. Impagliazzo, “Designated Verifier Proofs and Their Applications,” Advances in Cryptology — EUROCRYPT ’96, pp. 143–154, 1996.\n\n## Using the CLI \n\n0. Create a `.env` file in the project directory and add there an Etherscan API KEY following this format: \n\n```\nAPI_KEY_ETHERSCAN=\"XXXXX\"\n```\n\nWe are gonna use this API in step 2 to retrieve the public key of the alleged signer starting from its address\n\n1. Download the artifacts generated during the trusted setup\n\n```bash\n    mkdir artifacts-folder\n    cd artifacts-folder\n    wget https://dvs-eb-bucket.s3.eu-west-2.amazonaws.com/dvs.zkey\n    wget  https://dvs-eb-bucket.s3.eu-west-2.amazonaws.com/dvs.wasm\n    wget https://dvs-eb-bucket.s3.eu-west-2.amazonaws.com/vkey.json\n```\n\n2. Generate the proof\n\n```\nnode cli/dvp.js gen-proof 0xaf365471712541c890ccfefbb999ead07c1a9de89dd31ee78b3414b7afe0bcd0616171dd276e19e3a2b259be28693ea434bc16d6dbd317a1411f45a61a5f16b41b msg.txt 0x9992847Cb19492673457f7f088Eb2d102F98aeCC 0xe4D9621321e77B499392801d08Ed68Ec5175f204 artifacts-folder\n```\n\nWhere: \n\n-`0xaf365471712541c890ccfefbb999ead07c1a9de89dd31ee78b3414b7afe0bcd0616171dd276e19e3a2b259be28693ea434bc16d6dbd317a1411f45a61a5f16b41b` is a standard [EIP-191 signature](https://docs.ethers.io/v5/api/signer/#Signer-signMessage). You can generate one using [this Sandbox](https://codesandbox.io/s/react-eth-metamask-signatures-ibuxj?file=/src/SignMessage.js)\n- `msg.txt` is the path to the file that contains the message that was been signed \n- `0x9992847Cb19492673457f7f088Eb2d102F98aeCC` is the address of the alleged signer. This is a public signal inside the zk program. Note that this doesn't have to match the address of the **actual** signer of the message. A malicious prover can arbitrarly choose the address to put here.\n- `0xe4D9621321e77B499392801d08Ed68Ec5175f204` is the address of the designated verifier has been saved\n- `artifacts-folder` is the folder where the artifacts have been downloaded from step 1\n\n\u003e Alert: the ECDSA verify circuit takes the public key of the alleged singer as input. Not the address! In order to fetch the public key we need the address to have executed at least one tx on ethereum. Here's the [why](https://ethereum.stackexchange.com/questions/13778/get-public-key-of-any-ethereum-account) and the[how](https://gist.github.com/chrsengel/2b29809b8f7281b8f10bbe041c1b5e00). This means that if the address of the alleged signer you entered has never interacted on Ethereum mainnet, the program won't work\n\nBy default, we consider that the PrivateKey of the Designated Verifier is not known by the prover. In that case a random private key is generated. In the case the (malicious) prover knows the private key of the designated verifier, this can be passed as optional input \n\n```\nnode cli/dvp.js gen-proof 0xaf365471712541c890ccfefbb999ead07c1a9de89dd31ee78b3414b7afe0bcd0616171dd276e19e3a2b259be28693ea434bc16d6dbd317a1411f45a61a5f16b41b msg.txt 0x9992847Cb19492673457f7f088Eb2d102F98aeCC 0xe4D9621321e77B499392801d08Ed68Ec5175f204 artifacts-folder -pkey 7e4a26d6d34648fdc64848f87fcf798107e6c08b3b4628498b5fdf73304eded1\n```\n\nwhere `7e4a26d6d34648fdc64848f87fcf798107e6c08b3b4628498b5fdf73304eded1` is the private key of the designated verifier.\n\nAdditionally, it can be specified where to save the outputs of this command, which are the proof and the public signals. \n\n```\nnode cli/dvp.js gen-proof 0x439c9002d40Fb1AfEBc3969B06e9b9F66fd8B3ee artifacts test-folder/sig.json  -oProof test-folder/proof.json -oPublic test-folder/public.json\n```\n\nIf not specified, the will be saved by default to a file named `proof.json` and `public.json` inside your current directory.\n\n3. Verify the Proof\n\n```\nnode cli/dvp.js verify-proof proof.json public.json artifacts-folder                                                                               \n```\n\nWhere: \n\n- `proof.json` and `public.json` are the paths where the proof and the public Signals have been saved\n- `artifacts-folder` is the folder where the artifacts have been downloaded from step 1\n\n## Updates\n\n- [ ] Create an independent circuit component that can be plugged into every circuit\n- [ ] Make it work like \"I know the signature of the designated verifier\" rather than \"I know the private key of the designated verifier\". This is mainly for UX and security reason and it is always advisable not to deal with plain private keys\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenricobottazzi%2Fdesignated-verifier-proof","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fenricobottazzi%2Fdesignated-verifier-proof","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenricobottazzi%2Fdesignated-verifier-proof/lists"}