{"tags":["zokrates","ethereum","blockchain","zksnarks","zero-knowledge-proofs"],"id":"37a2319942ce4916a60a6f84a193edb4_2","article_id":"37a2319942ce4916a60a6f84a193edb4","article_version":2,"title":"Building Identity-linked zkSNARKs with ZoKrates","content":"{\"markdown\":\" \\n[ZoKrates](https://github.com/Zokrates/ZoKrates)\\n is a toolbox for zkSNARKs on Ethereum. It includes an easy-to-use domain specific language for developers to leverage the power of zero-knowledge proofs in their decentralized applications.\\nWith the latest release, we’re excited to announce that the \\n[BabyJubJub](https://github.com/barryWhiteHat/baby_jubjub_ecc)\\n elliptic curve was added to the \\n[ZoKrates standard library](https://zokrates.github.io/concepts/stdlib.html)\\n , as well as various cryptographic primitives such as signature schemes! This is a major milestone as it finally enables running cryptography inside of ZoKrates programs.\\n\\n## Cryptography in a zkSNARK?\\nzkSNARKs are often described as enabling someone to prove that they know some secret without revealing it. However, zkSNARKs do not in themselves carry any notion of identity, so it would be more accurate to say that they only prove that *someone* knows some secret. For many applications, this is an issue: you would not want a minor to be allowed to buy alcohol just by presenting a proof of age generated by an adult!\\nIn this blogpost, we describe how this missing link between proofs and identities can be established using ZoKrates, as an example of why and how to run elliptic curve cryptography (ECC) inside a SNARK. First, we show how to use ECC from the standard library by proving knowledge of a private key. We then analyze two use cases that require linking identities with proofs.\\n\\n## Setting the Scene: Pre-Image Proofs with ZoKrates\\nArithmetic Circuits, Rank-1 Constraints Systems (R1CS), and Quadratic Arithmetic Programs (QAPs): it can be confusing to get started with zkSNARKs.\\nZoKrates greatly simplifies this by providing an imperative programming language that is easy to use and reason about. Instead of designing circuits, you write programs with well-known concepts such as variables, functions or loops.\\nHere is how you would prove that you know of the pre-image of a given public hash:\\n\\n```\\nimport \\\"hashes/sha256/512bitPacked.code\\\" as sha256\\n```\\n\\n\\n\\n```\\ndef main(private field[4] i) -> (field[2]):\\n return sha256(i)\\n```\\n\\n\\n\\n\\n\\n * The **main** function is the entry point of the program. One can create a valid proof if and only if **main** ran without error.\\n\\n * The visibility tags of the parameters ( _private_ and _public)_ define which information will be revealed to the verifier and which remains hidden. The default visibility tag is _public_ ; outputs are always public. In the example above, the verifier will only learn the main function’s return value.\\n\\n * The hash function used in this example is SHA256 applied to an array of four 128-bit words. It is available as part of the standard library.\\n\\n * The execution can efficiently be verified — for example on the Ethereum Blockchain — given only the _public_ inputs and the outputs.\\nTo write your first zero-knowledge program and verify proofs on Ethereum, check out our \\n[tutorial](https://zokrates.github.io/sha256example.html)\\n !\\n\\n## Identity-linked Proofs of Knowledge\\nOne of the most common uses of zero-knowledge proofs is proving knowledge of a secret to someone without revealing it. This could be proving that you submitted a bid to an auction without revealing its price, or that you voted in an election without anyone knowing who you voted for. Let’s call that a Proof of Knowledge.\\nAs an example, we will use the simple hash pre-image proof we just presented as a Proof of Knowledge. But don’t worry: everything we will discuss also applies to more advanced Proofs of Knowledge.\\nThe following figure shows how Alice uses ZoKrates to create a pre-image proof. When she inputs her secret pre-image labeled \\n_private_\\n , she can execute the program fully, which returns the hash and a proof.\\n\\n![](https://api.kauri.io:443/ipfs/QmV7kxJW1GZoGiopPBsHq4vHUYRe1jRhGgtkqACpNjha5i)\\n\\nAlice wants to prove knowledge of the pre-image to Bob. Hence, she sends both the hash and the proof she generated on her machine to him. Bob can easily verify the correctness of the proof and thus be convinced that Alice knows the secret. Right?\\nWell, no.\\nConsider the following case where Charlie knows the secret and Alice does not.\\n\\n![](https://api.kauri.io:443/ipfs/QmQYPuUGUHaURHnJzdFb7cTz8JCYcT5qEgNPYawmgGpzUw)\\n\\nCharlie uses the secret to create a Proof of Knowledge. She then sends it to Alice, who forwards it to Bob. Note that Alice does not learn the pre-image and could hence not create the proof herself.\\nObviously, something is missing here: there is no link between the Proof of Knowledge and the identity who claims it.\\nHow about signing the proof? Alice could just as well sign the proof she got from Charlie, so that does not work. It’s now clear: proving knowledge and proving the creator’s identity must happen at the same time. Since the proof of pre-image happens in the zkSNARK, this means that we need the identity to also be proven in the zkSNARK!\\n\\n### Proof of Private Key Ownership\\nIn the context of public key cryptography, the simplest way to prove one’s identity is using key derivation: this one-way process takes a private key as input and returns the associated public key.\\nUsing ECC functions from the ZoKrates standard library, we can run key derivation inside a zkSNARK, so that the prover can expose their public key and prove that they know the associated private key. This constitutes a Proof of Private Key Ownership.\\n\\n\\n\\n\\n```\\nimport \\\"ecc/edwardsAdd.code\\\" as add\\nimport \\\"ecc/edwardsScalarMult.code\\\" as multiply\\nimport \\\"utils/pack/unpack256.code\\\" as unpack256\\n\\n/// Verifies match of a given public/private keypair.\\n///\\n/// Checks if the following equation holds for the provided keypair:\\n/// pk = sk*G\\n/// where G is the chosen base point of the subgroup\\n/// and * denotes scalar multiplication in the subgroup\\n///\\n/// Arguments:\\n/// pk: Curve point. Public key.\\n/// sk: Field element. Private key.\\n/// context: Curve parameters (including generator G) used to create keypair.\\n///\\n/// Returns:\\n/// Return 1 for pk/sk being a valid keypair, 0 otherwise.\\ndef main(field[2] pk, private field sk, field[10] context) -> (field):\\n\\n field[2] G = [context[4], context[5]]\\n\\n field[256] skBits = unpack256(sk)\\n field[2] ptExp = multiply(skBits, G, context)\\n\\n field out =\\tif ptExp[0] == pk[0] && ptExp[1] == pk[1] then 1 else 0 fi\\n\\n return out\\n\\n```\\n\\n\\n\\n### Putting the Pieces Together\\nLet’s recap:\\n\\n\\n\\n * we have one function which proves knowledge of a secret\\n\\n * we have another function which checks that a given public key was derived from a given private key\\nWe simply combine the two to complete our protocol:\\n\\n![](https://api.kauri.io:443/ipfs/QmTh8hdp5zaYGESNJAYQJxPrPYKccX7QbqmgYtGiL1gxar)\\n\\n\\n\\n\\n\\n```\\nimport \\\"ecc/babyjubjubParams.code\\\" as context\\nimport \\\"ecc/proofOfOwnership.code\\\" as proofOfOwnership\\nimport \\\"hashes/sha256/512bitPacked.code\\\" as sha256packed\\ndef hash(private field[4] secret) -> (field[2]):\\n return sha256packed(secret)\\n\\ndef main(field[2] pkA, private field[4] secret, private field skA) -> (field[2]):\\n // load BabyJubJub context\\n context = context()\\n // prove ownership of skA\\n proofOfOwnership(pkA, skA, context) == 1\\n // return hash\\n return hash(secret)\\n\\n```\\n\\n\\nAlice can now convince Bob that *she* knows the pre-image: Bob checks that the program returns the expected hash as well as Alice’s public key. If the proof is verified, then whoever created it:\\n\\n\\n\\n * knew Alice’s private key: it must be Alice!\\n\\n * knew the pre-image: she must know the secret!\\n\\n## Repudiable Identity-linked Proofs of Knowledge\\nNow that we’re able to link Alice’s identity to the Proof of Knowledge, Bob can be sure that Alice knows the secret pre-image.\\nInterestingly, this is not only true for Bob, though. Consider the following case, where Bob forwards the message received from Alice to Dave.\\n\\n![](https://api.kauri.io:443/ipfs/QmYcGbhXHjLvSiiqfnUCpueWM2hAMMkvbD2FVQpPuGyZbm)\\n\\nFrom the forwarded message, Dave also learns that Alice knows the secret.\\nEven though the secret itself is always only known to Alice, the proof can still be very sensitive: if Alice is proving to Bob that she holds more than 1000 bitcoins, that’s already a lot of information she would not want Dave to get, even if the exact amount is hidden.\\n\\n### Repudiation\\nWhile our solution elegantly links identity and proofs, there is an obvious shortcoming: Alice cannot plausibly deny creation of the proof. In cryptography, this is referred to as non-repudiation.\\nHow can Alice be protected from Bob leaking her proof to third parties like Dave?\\nThis is where the power of zero-knowledge proofs strikes again. We create a new program that guarantees \\n**either**\\n of the following things about the prover:\\n\\n\\n\\n * The prover knows the secret and the sender’s private key\\n\\n * The prover knows the receiver’s private key.\\nLet’s see how this solves the issue.\\n\\n\\n\\n * Alice is able to create the proof because she knows her own private key as well as the secret (1.)\\n\\n * Bob is able to create valid proofs with only his private key (2.)\\nWe just added repudiation: No one (except Bob) can be convinced that Alice created a given proof, since it could trivially have been created by Bob. Technically, this can simply be done using a logical OR linking the original statement and a Proof of Private Key that succeeds for the receiver’s private key.\\n\\n![](https://api.kauri.io:443/ipfs/QmSig3gWmPTvi9aoJDt6ei12D8UDC3e427zAGjtzBwJcmZ)\\n\\nLet’s see how this idea can actually be implemented using ZoKrates.\\n\\n\\n\\n\\n```\\nimport \\\"ecc/babyjubjubParams.code\\\" as context\\nimport \\\"ecc/proofOfOwnership.code\\\" as proofOfOwnership\\nimport \\\"hashes/sha256/512bitPacked.code\\\" as sha256packed\\n\\ndef proofOfKnowledge(private field[4] secret, field[2] hash) -> (field):\\n // check that the computed hash matches the input\\n hash == sha256packed(secret)\\n return 1\\n\\ndef main(field[2] pkA, field[2] pkB, field[2] hash, private field skA, private field[4] secret, private field skB) -> (field):\\n\\n context = context()\\n field AhasKnowledge = proofOfKnowledge(secret, hash)\\n field AhasOwnership = proofOfOwnership(pkA, skA, context)\\n field BhasOwnership = proofOfOwnership(pkB, skB, context)\\n\\n field isAwithKnowledge = if AhasKnowledge == 1 && AhasOwnership == 1 then 1 else 0 fi\\n field out = if isAwithKnowledge == 1 || BhasOwnership == 1 then 1 else 0 fi\\n\\n return out\\n\\n```\\n\\n\\n\\n## Conclusion\\nIn this post, we showed how to prove identity in a zkSNARK with ZoKrates based on the cryptographic primitives available in the Standard Library. Then we derived Repudiable Identity-Linked Proofs of Knowledge as a mean to link proofs with identities. Looking at the ZoKrates implementation of these ideas showed how easy it is to leverage these primitives to guarantee correctness and privacy in decentralized applications.\\nIn academia, this basic principle has been described as \\n[Designated Verifier Proofs](http://markus-jakobsson.com/papers/jakobsson-eurocrypt96.pdf)\\n . We’d like to thank Jordi Baylina for sharing it with the community.\\nStay tuned for more guides on how to use ZoKrates to enhance your DApp’s privacy and scalability!\\n\\n![](https://api.kauri.io:443/ipfs/QmQR2JveG3xcQPEZ9tgs5s1Tc6j1EQxeh2tnmC3o7fq4uT)\\n\\n_Special thanks go to Stefan Deml and Thibaut Schaeffer for their contributions to this article._\\n \\n_Diagrams by_\\n \\n[Chloé Heinis](http://chloeheinis.fr)\\n \\n\"}","author":"5a05daf6c250aa41869922fbae8d282c60ffa4b7","timestamp":1557392994736,"attributes":{"origin_name":"medium","origin_url":"https://medium.com/zokrates"}}