# The verifiability vision

- Speakers: [Jens Groth](https://streameth.org/speakers/jens-groth)
- Channel: [Devcon 7 SEA](https://streameth.org/devcon_7_sea)
- Date: 2024-11-14
- Duration: 27:51
- Watch: https://streameth.org/watch/6735d5949dbb7a90e184c02b

## Description

Imagine all data was guaranteed to be correct. We could build a trustworthy digital world based only on correct data. In this presentation, we will sketch layers and techniques that can realize this dream, in particular proof carrying data and succinct proofs.  We will also discuss the connection to the proof singularity vision for Ethereum as well as highlight caveats that apply; humanity is still in the early stages of the journey and there are obstacles and constraints to tackle

## About the speakers

### Jens Groth

Jens Groth is Chief Scientist at Nexus. His research on zero-knowledge proofs includes the invention of pairing-based SNARKs and co-inventions of pairing-friendly proof systems, logarithmic size proofs in cyclic groups, prover-efficient proofs with constant overhead, and usage of lookups in proving correct machine execution, recognized by IACR test-of-time awards in 2021 and 2023. He has been Professor at UCL and Director of Research at DFINITY.


## Transcript

Okay, and we're live. Welcome, everybody. My name's Andrew. I'm with Xerox PARC. And I'm here to talk to you a little bit about pods. How many here have been using pods this week? I think the answer should be everyone because you got into the building somehow and that actually required one. So what are pods? So your devs con ticket is a pod. The proof of attendance to this talk that you can claim from the Q&A app that's up on the screen there right now. If you're in the room, I don't think this works remotely. That's also a pod. Some of you have been playing Frog Crypto this week. I see some frog hats out there. All those frogs are pods. A pod really can be anything. It can be a secret message. It can be your identity credentials. It could be your driver's license if we get any governments involved to actually do this. If we get any governments involved to actually do this it can it's cryptographic data of any sort So what is the pod framework? So pod is is a technology a framework that makes it easy for apps to issue cryptographic data and to make zk proofs about that Data, it's a data format that's optimized for fish improving It's a standard of how that data format can be sent around and things can be proven about it And it's a framework of how that data format can be sent around and things can be proven about it. And it's a framework with some developer SDKs. Check out our documentation site. I'll have a link at the end if you want to try it out. It's mostly in TypeScript, but can be used on other platforms as well. We have ports in a few other languages. So I'm hoping some of you will get some use out of it. So one last WTF is zero-knowledge proofs. How many people here have used ZK proofs before? I feel like you understand them. Okay, a few. It's kind of obscure technology. That's kind of the point of pods is to make it easier to use so you don't have to understand how the underlying math works. But in brief, a ZK proof lets you prove the validity of any private data or any computation on your private data without revealing that private data itself. And that proof is trustworthy because there's some math that basically you can only calculate if you did it validly. At Xerox PARC, we think of ZKProofs as a universal cryptographic adapter. Basically, I've got lots of different kinds of private data. By doing computations on that data in a verifiable way, I can present to somebody whatever I want that is validly proven from that data. The example in this diagram, which you'll find in our blog post, is like, what if I could calculate my own credit score from signed data I got from my bank or from the IRS? I don't need to ask a credit reporting company to gather all this stuff together. I can gather it myself, and I can make a provable statement about what my credit course score is and apply for a loan. This is part of the vision of something we call the Parknet, programmable cryptography internet, which we think is going to be much better once programmable cryptography catches on in all of these ways. ZK proofs are a big part of this, but it's only the beginning. See the other talks being given by my colleagues this week. Also, we have a whole day CLS tomorrow about programmable cryptography. But today we're going to be focused on ZK proofs and what pods let you do with them. So this is the pod ecosystem that we envision. You need issuers who are issuing this cryptographic data. They're mostly using a private key to sign it. Those takes the form of attestations, which users themselves can hold on to. They hold on to their own private data. They don't need an intermediary. At some point, some consumer asks the user, please prove something about yourself, your identity, your age, the fact that you went to DevCon, things like that. And then the consumer can generate a ZK proof and send, sorry, the user can send the ZK proof to the consumer who can verify that proof. They do need that third arrow in the diagram, which is a little bit of knowledge about who the attester is. You need at the very least to know that that attester has a public key that you should trust. There might also be things like what is the event ID that represents DevCon on a ticket, things like that. But that kind of completes the diagram. Okay. So why are we doing this? So I work with the team that builds ZooPass. You've all been using that to check into DevCon. And we believe that the best learning on this kind of technology comes from contact with reality, meaning we want real users to try this. We want to do it at scale. There are 12,000 people at DevCon this week who are stress-testing ZooPass for us. Thank you. I'm sorry if the performance has not always been as great, but it seems to be standing up. And we want to use these opportunities to onboard new users by bridging data that is not ZK-friendly into our ZK-friendly world and take advantage of people who are willing to be early adopters like the crypto community. So by bridging, what I mean is we're bringing data in the red boxes on this diagram Into the green world red in my diagrams of this talk and the next one means like non zk friendly systems Whereas green means ek friendly systems we can bridge it in we can then issue it like your devcon ticket Which is loaded from a database that isn't cryptographically signed And then you can the verifiers can get you into another system like telegram in order to join the the DEVCON chat group. All that is working today. In order to bring this in front of the most users, we do have to accept some constraints. So we're not using the most cutting edge of ZK technologies. We want everyone to be able to use it, which means we've built a mobile friendly web app. Which means everything we do has to run in a browser on a phone. Even an older phone, even on a bad network when the Wi-Fi is overloaded at the conference. So that became a bit of a mantra when I was building some of these technologies. There's a lot of cool ZK technology out there that is great, but it needs to run on a big back-end server and I don't have one of those when I'm in a browser on a phone. So we've got to use tried and true technologies. For people who are in the know, we use SIRCOM and GROSS16. You may or may not have heard of those, but that's kind of the underlying technology. They've been around for quite a few years, so they're pretty well battle tested at this point. So I want to talk a little bit about the systems we built along the way. So this is what ZooPass ticketing looked like a year ago at DevConnect when we were in Istanbul. So it's the same triangle that you've seen here. We were pulling data out of Precix and issuing the tickets. We used a format called an EDDSA ticket. That's a signed piece of data, but it's not a pod, which I'll explain a little bit later. And then we had a proving circuit where you could prove your ticket, you could reveal some fields, you can prove that you owned it, etc. So what did it take us to build this? Don't pay attention to all the details here, but look at the line counts on these PRs when we wrote these things. It's pretty large. That's quite a few lines of code that it took. And in just the ZK proof, there's about 15,000 lines of code that are still there, not including tests and documentation. So it's kind of complicated. So that was the first thing we built. The second thing we built was Frog Crypto, the first version last year, which used a very similar data format. So frogs were issued by the server as what was called an EDDSA frog, very similar format to tickets, and then you could make a proof about it, you could present it to our Zucat telegram bot who would let you into the secret frog holders chat. This all happened last year in Istanbul. So what did it take to build that? It turns out it was very similar. There was a lot of duplication of effort. There was a lot of similar patterns, but you couldn't actually reuse the underlying data. So there clearly is a pattern here, right? We want to issue some signed data. We want someone to request a proof and then to be given a proof of that signed data, we want someone to request a proof and then to be given a proof of that signed data, but it turned out that each time we had to build it, we had to rewrite a whole bunch of code in order to customize it. So I'm an engineer, I don't like this kind of complexity, I'd rather do things once because I'm lazy. So why is this so hard? So the signed data part, the EDSA PCD that we were using as our underlying data format. Used as a fixed size hash, it hashes 16 numbers in an array. And therefore, every new data type that we wanted to put in there, we had to do some custom coding to decide how those numbers in that array go together to make this data type. I would analogize this to imagine you were processing all your data in a hex editor directly as bytes. It's kind of inconvenient. We have better tools than that now. And on the proof side, ZK circuits are a little bit awkward to program. Like they don't use a normal programming model. You don't write it in a language you're used to. Every variable is what's called a field element. This is a mathematical concept. It's a very big number, modulo some big prime number, and you've got to like write equations on those field elements. So it's kind of complicated. And also once you build a ZK circuit, it's very fixed. In order for the prover and verifier to agree on what's valid, the circuit can't change very much. You have to publish a whole new circuit. So that makes this a bit hard. I would analogize this, again, to in the hardware world, this is like an ASIC. It's a chip that does one thing. It In the hardware world, this is like an ASIC. It's a chip that does one thing. It might do it very well, but it still only does one thing, and every time you want to do another thing, you've got to build a whole new chip. It's kind of inconvenient. So what do we need here? Well, what we'd really like to have is what's called a ZKVM. Basically, if you have an ASIC and you want something more general, why don't you use a out there that lets you basically write code, run it inside of a ZK circuit and validate that this is the correct output. It's great. Some other people are giving talks about it this week. But unfortunately for our situation, it's a little bit too much. Like I said, my mantra has to work in a browser on a phone. ZK VMs are pretty big right now. You're not going to be able to do that on an older phone in a few seconds. So we have to do something a little bit more limited than that. But again, I'm an engineer, I like working within constraints and coming up with clever solutions. So here's what we came up with. So on the data side, I'm finally gonna explain to you what a pod is at some level. So a pod is just a collection of names and values. Think of it like a JSON object, except that it's flat. There's no hierarchy of nested objects, just names and values. It can have multiple data types in it for those values. The data is then cryptographically signed in a way that makes it easy to make proofs about it. And I'm going to get into more of that a little bit later. Also, I forgot to mention this at the beginning. We are having a deep dive session after this intro session. So stick around for that if you want lots more detail. But I'll give you what I can in the next 15 minutes. On the proof side, we also can generalize. So we have what we call a general purpose circuit, which means rather than having a fully CPU-like circuit in a ZKVM or having the ASIC fixed circuit, we can do something in between. I would analogize it more to an FPGA. We've got some logic blocks. We call them modules. You can feed in some inputs to your circuit in order to decide how those logic blocks are connected to each other and make a different proof every time using the same circuit. We call this framework GPC for general purpose circuit. And in addition to the circuits individually being configurable, we precompile a set of circuits in what we call a family at different sizes with different sets of modules. So when you want to make a proof, you can pick the circuit in the family that has enough modules for what you want and not any more because having a bigger circuit means more time to prove, more memory, etc. So you can make the right trade-offs there. So with that, we get the generalized version of the ZK ecosystem where every issuer is issuing pods. They might contain very different kinds of data. It might be a frog, it might be a driver's license, but it's still a pod. And then when you make proofs about it, you can freely decide what you want to prove and write a configuration to represent that proof. So with that in mind, at this point, what is a pod? So a pod is a data format that makes zkproofs easy. It's a key value store. It's going to be hashed and signed in a very specific way involving a Merkle tree, which I can explain more of later. And it's optimized for efficiency zkproving. Here's an example of a pod. So we've got some names and values. Most of these are very straightforward, so I'm not going to go through them all in detail. The one that's maybe a little bit interesting is the cardholder. So this is meant to look like a driver's license in some fictional country. The cardholder is my semaphore ID. This is what Zupass uses to identify you. It's really a public-private key pair. So the public key is what's going to go in the pod to say that this is my pod, or in this case, this is my driver's license. What you see on the right is the JSON format for this. It's optimized to be a little bit terse and also human readable. So things that don't need a type annotation, you'll notice don't have them because the JSON type itself is enough data for that. Once because the JSON type itself is enough data for that. Once you get down to actually building the Merkle tree, like everything does have a type, but in this table I call them type hints because the type is not part of the cryptographic data. Instead, it is guidance to how do I hash this data into a piece of cryptographically verifiable data. More on that later. So the first thing I do to make this into a pod is I build a Merkle tree tree i'm not going to go into detail on that but basically you arrange the elements into a tree you hash them all together until you get to a root and that root is what we call a content id the content id is derived from the data so if you have the same data you can derive the same content id regardless of how it was formatted in json one detail that you might notice on the right is that the names have been alphabetized. That's how we make sure that it is deterministic and you always get the same content ID. But everything else is just hashing. And then now once I've got the content ID, that's the thing that I sign. So if I'm an issuer and I want to issue a pod, first I get the data, I Merkle-ize it, I get a content ID, and then I just write a signature on that content ID, and that's enough to validate that the entire pod is valid. So we have a ZK-friendly data format. We'd probably like to do some ZK proving on it. So let's talk about the GPC side of this that is what lets you do that. As I mentioned earlier, GPCs are circuits made of reusable modules, as well as a family of multiple circuits so you can pick the size that you want. Let's look at what that looks like. So this is an example of a GPC configuration. This is how you say, what do I want to prove? And you're gonna present this as this JSON object that says what you wanna prove, and the system is gonna do the rest rest compiling this down to what to do with the circuit so here's a very minimal proof i'm going to try and prove that i have a driver's license that says i'm allowed to drive right so i my configuration says i have a pod i'm going to call it id card this is actually an arbitrary name that's just part of the configuration to refer to it later it has some entries and one of those entries is driver that is not not an arbitrary name. That's a name that was in the pod and is going to be hashed and checked. And what do I want to do with it? Well, I want to reveal it. So is reveal is true means this is a proof. It's going to prove that I have a pod, that it contains this entry, and it's going to reveal that its value is hopefully true because I'm going to try and drive a car. So that's simple enough. There's one detail that wasn't on the previous slide. That's because it's done by default, so I didn't need to include it in the config, but it's important to talk about. What I proved if I don't have, think about the signup key, is I just proved that I have a pod containing the word driver with the value true. That doesn't mean it's actually a driver's license. In order to do that, you've got to do something cryptographic. So the easiest way to do that is you check that the pod was signed by a public key that is well known. That might be the government of California, which is where I live. Hopefully we'll get them to issue pods eventually. But that is implicit. The signing key is also always revealed by default, but you can choose to not reveal it if you want to, in which case you can constrain it in other ways. You might constrain it to be equal to some other element without actually revealing it or constrain it to be a member of a list like maybe i have a list of all the signing keys of the 50 u.s states and i just want to prove i have a driver's license from one of them i don't want to tell you which one okay let's get straight and get a little bit more complicated um so i've proven that i have a driver's license that says driver equals true. I haven't actually proven that it's my driver's license yet. I could have stolen somebody else's. The thing is that pods, because they're just data, they are transferable. I can copy them. The way we make a pod bound to a single user is by putting that user's public key in it, which I showed earlier when we were looking at the entries. And the way you prove that you are that user is you make a proof that you hold the private key that corresponds to that public key. And the way you say that in the gpcconfig is this is owner ID field. You say is owner ID, and I give the type of public key I'm using, which is semaphore version 4 from our friends at PSE. And that basically means that this proof is going to be configured to check that I have the right private key in my private inputs. And in this case, it's not even going to reveal what my public key is, just that I own this pod and this pod says I can drive. Okay, let's get to a little bit more ZK and hiding some more data. Instead of proving that I'm a driver, what if I just want to prove I'm over 21? Maybe I want to go buy some alcohol. I don't know what the age is in Thailand, but back home it's 21. So I can just say I have a pod containing an entry called date of birth. That entry is not going to be revealed, but it's going to be in this range, and that's the numeric range for the date that is 21 years ago. We should make this more friendly and let you just pass in a date object, but for now it's a number. So this is a proof that I am over 21 and that I own this pod. I didn't take out that field, but everything else is not revealed and I'm being very anonymous. One last example, we can make proofs of multiple pods at once if we have a circuit with enough modules. So here's one that I'm proving I'm over 21 and also proving that I have a ticket to an event that maybe I'm going to go to an after party after DevCon. And in this case, the ticket, I'm proving that its attendee name is the same as the name in my driver's license. I'm proving that I own it and I'm also proving that the event ID of that ticket is in a valid list. I'm not revealing what I have a ticket to, but it's maybe a list of like DevCon related events that are happening in Thailand this week. So this is kind of a minimal anonymous way of checking into a party. Of course, if I'm there in person, I'm revealing some more about myself by being there, but you get the idea. Okay. So last piece of this, I've now configured my proof. I've decided what I want to prove How do I actually make a proof and all of this is an example of what you can do with the the GPC libraries So the three things I need in order to make a proof one of them is the proof config that I've already given you some examples of The second thing is the inputs. That's the actual pods Which I need to have in order to make proofs about them There are also other inputs like my private key or like that list of valid event IDs that I want to prove that my event ID is one of. Those are all inputs. The third thing I have to feed in is something called an artifact path. That is, where do we find the binaries that know how to generate this circuit? So when a ZK circuit is compiled, it generates a proving key, a verification key, and also a witness generator. Don't worry about what those are, but there's some like big binary things that the prover and verifier have to agree with. We distribute these via NPM. We also put them on various CDNs. You can download them. So you have to just decide for your app. Are you going to download them, put them on disk, give a path to them? Are you going to download them from a URL? There are options. give a path to them, are you going to download them from a URL, there are options. Once you've got these things together, the gpc proof function will generate the proof. It puts together that configuration, it picks a circuit that fits that configuration with enough modules, it downloads the corresponding artifacts for that circuit, and it generates the proof. And then the last thing it does, oh, I should have gone to the next slide, here we go. So it needs to compile down all those inputs into circuit signals that can feed into the actual ZK circuit, which are mathematical field elements, as I mentioned. And then after it's done and it gets a valid proof, it will decompile some of the outputs and turn them into what's called the revealed claims object. So it comes out of a proof. You've got the actual claims object. So it comes out of a proof. You've got the actual mathematical proof. That's just opaque numbers that are needed by the verifier. That's the actual ZK part. You've got a bound config, which is exactly like the configuration that you fed in, except that now it contains the identifier of the circuit that was selected so that the verifier knows how to verify it correctly. And then you've got the revealed claims. If I revealed that I am a licensed driver, driver equals true, that would be in this object. If I revealed my name, et cetera, that would be here. And that's what the decompiling is for. It's taking the circuit outputs and turning them back into a string or whatever the representative thing is. Okay, so those three things are exactly what I should send to a verifier, whoever I'm gonna prove this to. They need those three things. They also need an artifact path to download the corresponding verification key. And then they can verify the proof. They just do very much the same thing. They're going to compile some of those inputs back down into ZK land where there are circuit signals. They're going to verify the proof and they're going to say yes or no, whether it's valid. And, you know, gravy, we're at the end and hopefully everything went right and I've proven what I wanted to prove to you. So final takeaways, summary of what this was a bit of a speed run through. So pods are data that's designed to be proven about. Any pod is a signed attestation of something, whether it's I have a ticket, whether it's I have a driver's license, etc. GPCs allow you to flexibly make proofs about those pods by using modular circuits, which can be configured using a JSON-like configuration language. And the system will auto-select the circuit that you need depending on your configuration. So all your app needs to do is say, please make me a proof of this with these inputs and everything else is handled for you. Then the last step is the verifier verifies the proof, and then the apps do have to decide what things they trust. How do you trust that this is the correct proof? Like I alluded to before, you should check that this ID card was actually signed by the government. You should know the public key or you should check that this ID card was actually signed by the government. You should know the public key or you should know the event ID for DevCon. You should also check, and I'll say a little more about this in the deep dive, that the configuration that was sent to you was actually the configuration you asked for. So you don't want the prover to say, oh, I have a proof of something, but not necessarily the thing you asked for. That's something that you should check as well. But once you do all of that, this end-to-end should be very solid and you should be getting the information you need. Okay. That's it for the speedrun intro. Please check out our documentation. They're on pod.org that just went live yesterday. And also there's a link that just went by, t.me slash zoo pass to join the telegram group. And yeah, let's go do some Q&A. All right. Where do you store the sound for identity secret for users in Zupass? So that's all client side. Zupass stores all of your private data client side. The Zupass server is aware of your public key because that's how it can make sure that you get issued the right Devcon tickets and things like that But yeah, zoo pass is a client-side cryptographic data manager To what extent is pod an open data standard, so I consider it open we haven't like published a spec for it I should work on that but all of our code is open source, so people can do interoperability with it. The pod format itself is very generic and interoperable. It's the GPC compiler that turns a pod into the specifics of what you need to prove with a specific GPC. So the GPCs are kind of less standard and generic, though they also could be used on multiple platforms. We do have an example of GPC verification on chain that just started working a couple days ago, so all that is possible outside of a browser, but we don't have as many examples there as we do on the pod data. Can we scroll down? Is there anything more? Can you compare pod to verifiable credential? Yes. This is something I looked into. Pod is simpler. It doesn't really have a fixed schema or anything that ties it into a specific standard. You could put JSON-LD-based verifiable credential data in a pod if you wanted to. But a pod is much more flexible. At the cryptographic level, there is a difference in the kind of Merkle tree we use. The pod uses the lean IMT, which is something that Semaphore created, which is much shallower because pods tend to be relatively small, as opposed to the sparse Merkle tree that is used, at least for the implementation of verifiable credentials that I'm aware of, which is the one from IDEN3. That is a much deeper Merkle tree, but it can do things like prove absence of an entry, which pods can't do. Okay. What else do we have? How frequent is pod refresh? Very frequent so far, but we're hoping to keep it much more stable after DevCon. I don't have a strong answer to that. What else? How do you convert JSON to a Merkle tree? Please stick around for the deep dive session that's coming up. I'll tell you all about that. What else? Yeah. So, the—in the example of prover and verifier, the user's device can generate the proof and that's why everything has to work in a browser on a phone. Client side proving is definitely the default in ZooPass. Not every app has to do it. These are libraries. You can call them wherever you want. There's much more difference between verifiers, whether they're doing server side verification or client side verification. That depends what your use case is and what you're protecting against Are the issued credentials signed and the proof that the crunch loops we scrolled away We do not use BSS signatures to verify partial properties, that's what we use the Merkel tree for again more details on that coming up Is it possible to make information in ZooPass portable? I think that pods do make that possible, yes, as long as it's a pod and there are APIs for getting data out of ZooPass if you want to. That's called the ZAPI, at which point you can take this to whatever platform you want. We have implementations of pods in Python, C, and Rust for various projects, so it's not too hard to do. How do apps know whether a proof from a verifier is legit? Well, the framework tells you that it is a valid proof. And it will confirm for you that this configuration and these revealed claims and this proof match up and are valid. So the prover couldn't have cheated about that. What they could cheat about is app level semantics. So if you ask for a proof of a driver's license and I sent you a proof of a frog instead, that's something that the framework can't tell you because it just says that's a valid proof. So you do have to check, is that the configure I asked for? Is the signer of this driver's license the government, etc.? But yeah, that's the kind of level of verification we got. Okay. I think that's it. Can we go back to the slides briefly? Okay. Those of you who are collecting frogs, I've got something for you if we can switch back to my slides. Oh, yeah. We'll leave that up for a minute or two. I think we've got like three minutes before the next session starts anyway. So feel free to frog away. Okay. And as I said, we're going to go straight into a deep dive session, which is going to be 90 minutes. We probably won't use the whole thing, but that's what we're scheduled for. So stick around if you want more details to answer any of those questions.
