NoirHack: Library Workshop - ZK Email
NoirHack 2025 · April 2025 · 58:54
Jack and Ian walk NoirHack participants through how ZK Email works with Noir. The workshop shows how to deploy the proof infrastructure at scale using the ZK Email registry, so developers can build applications that prove facts about emails with zero-knowledge proofs.
Speakers
Topics
From NoirHack 2025, hosted by Aztec Network.
Transcript
Hey everyone. GM GM. How's everyone doing? We'll let everyone get a second to get settled in and then I'll kick things off. Let a couple people trickle in. Cool. Cool. All right. Uh, hey everyone. Super excited to kick this off uh with uh you guys today. Today we'll have a ZK email workshop. Uh let me quickly introduce our speakers and panelists. We got uh Aush from ZK email who co-founded this. Um and uh we've got Root who's uh Devril for ZK email uh at PSSE to help folks like us uh implement this tech uh into our projects. And then
we've got the Mach 34 folks, Jack and Ian. Uh these guys have been building uh ZK email uh into Noir and have a bunch of practical advice on how to actually make it work for us. Uh quick update on Noir hack. Uh we got the week 2 action items on the uh notion page right now. And this week we've got a ton of cool workshops. We got this workshop with the ZKML folks. Um and we've got uh workshops like uh the one with Michael from our noir team. We'll talk about unconstrained functions for all you advanced folks out there. Uh but today is all about ZK email. Um, we'll learn how to do some cool privacy preserving stuff with uh with emails, which will hopefully open up a ton of cool possibilities for what you guys are building. So, I will uh hand it off uh
to Root uh to go into the workshop. Yes. So, let's go dive into ZK email. Let me just share my screen. I also dropped some useful links already in the chat. [Music] Okay. Okay. So, uh as Rafi said, I'm good. I'm a dev engineer at ZKML and we are here to show you uh how ZKML works
and how ZKML Noir works and how can you integrate it uh into your Noir hack uh project. So the plan for today is going through some basics of uh what ZK email is. Then we will talk a bit more about how to integrate it uh into your app using the registry and SDK. We will cover a bit briefly the some dev tooling and then we will go deep dive into ZK mail with Jack and Ian. So what exactly is ZK email? So turns out that some time ago uh due to
anti-pam and anti- spoofing reasons emails started to be signed according to protocol which means that every time uh someone sends uh an email there is a RSA signature from the sender domain with a shot 256 of some of the contents of that email. And what ZK email does under the hood is that it wraps this full signature into a ZK proof, which allows you to parse and do selective disclosure. So you can verify all of those emails and still maintain some uh
parts uh private. And this is pretty cool because you can uh move a lot of web two data into web 3. You can uh verify a lot of interesting data you might have on your inbox but still maintaining some control of your own data and also some privacy around it. And you can uh programmatically extract arbitrary information using uh the reax and you can move this data uh around to any service or any chain chain making it portable.
So, one of the like most intuitive use cases I see for ZK email is like this whistleblowing example where you might have some uh really important email with really important and impactful information and you want to reveal this information uh to the world. uh but you still want to maintain your identity private due to security reasons. And you can do this with DKmail by simply parsing the all email contents and hide and still being able to hide all of the parts that might reveal your identity.
like for example the two fields uh on the on that email and we have a lot of uh infrastructure for people to build apps uh with ZK email and but the the easiest way to start to play around it and build some cool stuff like in a really simple and fast way is by using our registry. tree and our SDK uh which I'm going to present right now.
Let's like the registry you can see it like a place where you can create uh a blueprint and the blueprint is something that defines what is the information that you want to parse and to reveal or hide from some uh email example you might have. After defining this blueprint, uh you we deploy all of the info for you without you having the need to understand what exactly Z which ZK framework is being used. Uh how should we you build uh the circuits and etc.
And also this is pretty cool because you can also share any blueprint that you created with others and you can also reuse uh blueprints that other people just created. Then we also have the our SDK which you can integrate any blueprints that you created previously uh into your codebase with just a few lines of code. So as you can see from this example, you just you can just initialize the SDK. You can uh get one blueprint from the registry by just
simply get the slug or even the ID from the blueprint. Then you can uh generate a proof and you can specify if you want it to be locally or remote uh for privacy reasons. And you can also just verify with just a simple line of code. So yeah, as you can see, it's pretty straightforward. Uh you you will also have uh our docs uh in this QR code if you want to check it out. And uh we also provide some uh boiler plates and and templates for how to start with a really simple example uh to use the
SDK. And now uh we also want you to get inspired for some stuff that you might want to build. So I will just show you some uh interesting examples that you that people are building with ZK email. So you have like this uh example of a decentralized domain marketplace where uh you can prove that you own a namechip transfer email and you can build a marketplace on top of it. And also as you all might be familiar uh with stealth note built by celil you
can it's a web app where you can prove that you belong to an organization and post about it but still remain your identity private. Yeah. As a side note, uh I also wanted to just briefly cover uh our archive uh because this solves a really um important uh problem that we started to have when trying to verify old emails.
And the issue is that uh the public keys for each sender domain uh are public but and you can uh simply query them. But the issue is that once they are expired uh which is happening more or less like 6 months to one year uh they are deleted and they are completely gone. So then you lose the ability to verify these old emails. So what we did is we have this DKIM key archive where you where we store uh each um public key for each sender
domain that we might know. And yeah, and we also reverse engineered uh some of the public keys of some older emails by just having like two examples of uh selector and domains and then we can uh reverse engineer their public key. So also there is a way to contribute to this archive by just uploading uh some domains and some selectors that you might have uh on your inbox. So you can check it out on our website and do it if you
want. Yeah. So right now I also wanted to cover a bit like what what is the process of creating a blueprint on the registry and right now we still are working to um deploy the noir uh version into our registry but should be uh completed uh until the the the end of the week and it should be reassembled something like this on this screenshot. But yeah, for now, let's just try to do a really cool. Okay. So, okay. So, I go to
registry.k. As you can see, you can check a lot of blueprints here. So I will create a blueprint for proving that I got into noir hack. Uh so for this you can do like download this uh message and you just download a EML file that you can upload it here afterwards. So like I have it here and I also can show you it looks like this. So let's do proof of our
heck. So just upload that in EML file and also for your information that can be relevant in the future if you want to prove something that we don't have in our archive. Uh this email was sent by this domain Aztec labs which we didn't have in our archive. So what I did is that I just queried the this domain to look for their public key. You get the public
key. So you check that it exists indeed and then you just uh call our API to um to add this domain name in selector to the archive. Okay. So then you have like this sender domain which should match this domain here on the DKIM signature of the EML. And for now I will skip the body
hash check because I I just want to verify some stuff on the headers. So I will just create a really simple pattern with the subject. I will just increase the max length here. And uh yeah, so we have this default one default reax which will show all of the subjects as a public uh output. But yeah, for now I can also just do I want to just show this part.
So I can put this here and then put this as private. And yeah, so you just uh show welcome to Noir hack from the old email that you that you have. So then I will just submit it and it's compiling and then later on uh you can prove that you have an email for Noir hack. Okay, so that's it on my side. I will pass it over to Jack.
Um do you want to actually I can pull it up on my screen. Um, how do I pop this? No, sorry. Give me a second here. Um, just make it bigger. Okay. So, now we'll go through uh actually dkml.nr on the lower level.
Um, so right here is uh QR to the GitHub. Uh, it's also linked in there uh in the chat if you want that. Um, so let's start with that. Um, and I'm going to go through uh the repository, but you don't actually need to clone the repository as you're working with uh the circuits at the lower level. Um, you can just like import nargo tomlal um for input generation. You know, you can use the mpm package. Um, ton of really good examples in here.
Again, I'm I'm working with it because uh can show everything off. Um, you don't need to clone anything to use ekml.r. You can just pull stuff in. So, let's start out with um the most basic example. Um, we're going to take, um, basically, uh, R said, um, an email by verifying an RSA signature over a header. And then if you want the body as well, there's a body hash included in that signed header. Uh, so if you validate that signed body hash, then you've got authenticity over the entire email. Um, okay. So, really quickly, uh, the
inputs, like some of these might make sense, right? like header, body, pub keys, signature. You can figure out how those work. And then you've got auxiliary inputs, uh, body, hash, index, dkim, header, sequence. You'll see other stuff in here as well, uh, that might seem more confusing, but the procurement of all these inputs, you really don't need to worry much about. Um, you need to wire them up, right? But, um, like how you actually get these bytes or these in indices, um, you really don't need to worry about. So don't don't fret too much about that but um okay so let's start out uh with the most basic part uh the first part uh maybe not the most basic part but um
which is actually verifying um the header itself um and in ciron this is uh a lot of work uh there's definitely abstraction of templates and stuff but uh it's not pretty um noir uh it's one line right uh you have to instantiate the public key strct correctly as you pass it in and stuff like that. But all you have to do is call pubkey.verify dkim signature. Um you pass it in the header, pass in the signature. And I mean if you go in again there's abstraction, there's all this stuff going on. There's further layers and layers as you get down. But uh for your purposes, um this will hash the header. uh it'll check the signature by the pub key um
over that header and um it'll it'll only continue if it passes. Right? So that's the first step. Cool. Uh we also might want to operate over the body, right? Maybe there's some interesting information in there. Maybe there's not. Maybe you're doing a use case where you don't need this um and you don't need to be verifying the body. But in this case, let's say we are. Um, you're first going to have to get the body hash out of the header. And this version does not use regex. Uh, this is, um, we actually have a version with like reg xv1 that has reg x for all the string searches, but uh, we're actually in reg xv2 now for noir.
Um, and across zkl. Uh, that's not quite production grade. Um, so we're still going to use this and should be pretty secure according to the audit. So, um, and again, uh, body hash index, DK matter sequence. You just toss them in there and you're good to go. And this will pop out, uh, the body hash. And the body hash is B 64 encoded. So, it'll also decode that into um, the SHA 256 bytes that you're expecting. Um, and because we verified the signature over the header here, this is the signed body hash. This is the authentic body hash that uh the mail transfer agent asserts is correct, right? Uh meanwhile, we have
our body that we want to operate on. Um this is the actual plain text that we might want to do like select and reveal over just like check some information, right? Um we need to constrain that to be uh correct. So we basically just shot 256 hash the entire thing. This is pretty expensive, right? um like something like um uh 100 bytes or 100 constraints per bite, 100 gates per bite. Um we'll get into some tricks for that um in a second. But um you got to you got to hash the body in order to operate on the body. And then once you've done that, you just check that the sign body hash matches what you computed. There you go. You've you've
validated the authenticity of the entire email. except what what is what does that really mean? Uh signed by who? Um without actually having like the public key infrastructure um it's kind of meaningless, right? So one of the things we need to do is export out the public key. Um and uh the cheapest way to do this is to hash it into a single field element. Uh especially if you're going on chain, right? Uh you want to minimize the work that the verifier is going to have to do. So, we'll hash this into a single field element. Um, and then, you know, if you're on uh just like a a backend web service or something, maybe it looks it up uh against like
Cloudflare, Google's DNS. Maybe there's an onchain registry of all the uh authenticated um uh public keys, which um if you're if you're interested in that kind of supply chain, uh I'd probably uh investigate more in the Telegram uh exactly how to do that best. But in general you you'll probably have you can registry on chain. Um, by the way, one nice thing about um like Aztec specifically, not just Noir, is like you can you can check this privately. Like you could instantiate this as um a public immutable um in Aztec uh which is actually private uh privately accessible and you could uh validate um the DKIM
key, the public key without revealing which domain. Um you could do this in a contract too. you'd have to add like uh a Merkel route, a Merkel proof uh and and the infrastructure to kind of manage that, but uh pretty simple to do in Aztec. Um and then also um like let's say we're doing ZKP uh I send Rafie some money, right? And um uh I don't want to be able to well maybe I want to, but the the app doesn't want to allow me to keep using this email over and over and keep withdrawing money out. So I need a way to nullify this email. This is the simplest way to do it. You just hash the signature. Um there are issues with this. Uh the first off uh first being um
you know you might be able to predict the pre-image of the signature um which like if it's if it's not particularly um like like the body and the header are fairly uniform, you might be able to actually reverse engineer uh the pre-image. Um, so you could leak that. Um, there's V I think it's OPRF. I don't think that exists in Noir yet. I'm sure someone will get it with Kon Noir pretty soon, but um, uh, there are ways to get around that. Uh, just not trivially today. Um, and then also like some services you might be able to like resend an email. Uh, like you could go
on the website and say, "Send me uh another copy of this email." And that's going to give you a different signature as well. So you need to be resistant against that as well. But for the most basic level of of uh kind of double spend resistance on emails, um this is a good way to do it. So that's the most basic example. Um and we'll go through some of the other things uh most of the other functionality that comes with ekmail.nr. Um the first would be uh this is a 2048 bit signature. Um, vast majority of signatures you will see are 2048 bit. The only one I've ever seen that's 1024. I'm sure there's others out
there, but the only one I've seen is uh and worked with is GitHub. Um, one sorry, one quick question in the Q&A. Yeah. Um, this this is the circuit we write on top of. Yes. So, okay. Um, exactly. So you can see this is the library and it's got all the stuff here and then this is an example circuit. So we import CK email couple other things. You don't even need to import that.
Um and that actually is a new package which that needs to be updated. But so yeah, we import all these things and then string them together. Um, we also don't need that actually. Um, so it's pretty pretty simple. I mean, for the most part, uh, a lot of a lot of cases you can pretty much copy paste a lot of the example stuff and get 99% of the way there. Obviously, string searching, regex, stuff like that is going to be slightly more manual. We'll get into reg x actually uh in a in a little bit. But
um yeah uh you're importing a library and then writing a circuit. Hopefully that answers the question. Um okay. Yeah. So, uh GitHub's 1024bit and that's implemented as well. If for some reason you had like 4096 bit or some something else, um just copy paste the implementation into like chat GBT or run cursor over it or something. Tell it you want um whatever key length.
Uh and it should be able to do it instantly or even do it manually yourself. It should take like two minutes. Uh but you would have to implement it for other key lengths. The input generation should be able to handle it though. uh it's just like arithmetic circuits constant size stuff. So um you would have to do that uh partial hashing. Okay, so I mentioned that hashing the body is super expensive. Uh a really neat trick is that you can actually partially hash uh the body out. And this work works when you have like maybe the last 200 bytes of the body of your email is like super
interesting and has all this information you want. The first 800 is just filler. It doesn't matter. Um outside of the circuit you can partially construct the hash using like the first 800 something bytes. Um and then uh inside of the circuit you'll give it that partial hash state. you'll give it the rest of the bytes to finish the hash and then the circuit will complete the rest of the hash process. And and this is like free optimization. It's very easy to use. Uh if your use case supports it, there's literally no reason not to do it. Um it's going to save you a ton of constraints. Um so, uh again, it might look a little confusing with you've got
like now a different body length, you've got these extra parameters. Don't worry about it. um you really just need to pass in like you need to wire them up inside of the circuit but uh obtaining those inputs is is really not uh a concern. Um the one thing the one caveat on that is that it works when the bytes are at the end. It doesn't work when the bites are at the beginning. Um, so what you can do, um, this is a lot more involved, but maybe like like a lot of emails you'll see have like the really interesting information at the beginning and then you'll see all this CSS and and stuff at the end that you just don't care about. Maybe you've got like a use case like I want to prove I took a
flight somewhere. Um, and I don't care that I'm revealing I used like American Airlines, but I don't want to reveal my the last for my credit card number. I don't want to reveal my name, um, the date I flew on, stuff like that. Maybe that's in the first like 10 20% of the email. I could use partial Shaw 256 var start. Beautiful naming. Um, hash it and export that partial hash out of the out of the proof. Now, it's not constrained yet. But you could potentially like you could either string together a bunch of proofs that you prove locally if you really needed client side uh privacy and then recurse over them. You could send
it off to a server and again maybe you don't care about uh them knowing that you took American Airlines. Maybe you're going to recurse this in Noir or maybe you're even going to compose with like um some ZKVM. You're going to use client side privacy for the important stuff. If you're going to use Noir, then you're going to use um a ZKVM that'll be easier to deal with the hashing or even like circum with icicle or something with the hashing um on the back end and uh stick the two proofs together kind of. Um maybe not even recursing, maybe you just like verify two proofs, right? Um a lot more involved for sure. Uh definitely doable though. Um, so I if you have like really big emails, um, you're probably going to have to do something like that.
If you have like some critical privacy element, you can select out the exact bytes that you need, hash that part, and then put the the uh kind of stuff that's not confidential on a server. Um, compose those together. Um, extracting addresses. Okay, so again, you're probably going to want to use regex in the future. Um but if you have like a simple use case uh where it's just like a single recipient or like sender or something like that um it does ship with a pretty easy to use API where you can just get email address.
you have to you have to instantiate like to or from. Um but header uh again to and from or to header sequence to address sequence um those will all be supplied for you by input generation. Uh and then that'll pop out the email address. Um so for a lot of use cases this is sufficient. Um, there's definitely some complex ones where this isn't good enough, but I would I would expect the majority of things that you're thinking of would probably be served by this. Um, and then the last one I'll talk about really quickly is removing soft line bras. Um, not going to get in to all of it, but um, essentially like emails are uh, sent in like seven bit
encoding um, which is not UTF8. Um, and one artifact of that is like when when email services need to deal with that, they'll use something called quoted printable encoding. And that gives you basically these soft line breaks uh at every 80 bytes in your email body. And it's super annoying to deal with, especially if you're trying to string search or reg x match. Um, so what you can do is you can just constrain the removal of the softline breaks. Um, we'll give you body decoded body. So instead of operating on body, you're still going to verify the body, you're going to hash body, but then once you've verified the body, you can decode the body and then
operate on top of that to make string searching or reg xing a lot more straightforward. Cool. So how do we use this? Um I'm going to I'm just going to do witness generation uh just for the sake of time. Um, couple of other notes. I'm using this ZKML prover class, but this really just wraps like noir and ultra honk back end or whatever you're using. I guess no one's going to be using plunk pretty soon. Um, in fact, in the regx, I don't even touch this. Uh, so don't don't think too much about that in the demo, but um, yeah.
So that first example I showed you, that's it. Um, basically you're going to give it the email. Um, where's email? Give it your email. Um, there's examples. Uh, I think I I sent a link with one that's hooked up to uh a VIP front end. Um, but in this case, we're just importing it um from the file system. And then we're telling it uh the max header length is 512 bytes, max body length 1024 because again it's a it's a circuit. It needs to have these max lengths. And um sorry, what am I looking for? Um
that's it, right? Uh you'll call generate email verifier inputs from zkmail.nr uh the JS package. It'll give you your inputs, simulate it, good to go. Um maybe like you might have other inputs that you're using in your your circuit. You might add those in or you might rename these inputs. But uh that's pretty much it. Partial hashing also looked kind of confusing, right? Not really. Um all you do shop premputee selector tells it like this is the text I want to partial hash up to and it'll find that spot partial hash up to. It'll give you the partial state. And then as well um in this case because we're
hashing a lot less um we're just setting a very small body length right. Um good to go. Um not going to deal with masked header. Um okay so extracting the sender and recipient. Um this all is input validation or output validation. Um so don't worry too much about that. We want the from address extract from. Want the two address extract to. There we go. Um and I'll show a little more about bounded ve parsing in the reg x but it's it's very simple. This is just actually validating the exact stuff. Um so again email address is also very simple to get. Removing softline breaks you just
set it to true again. So so the point of all this is um you know there's a little bit to wire up in the examples. Uh the input generation is very very straightforward as well. um you really don't need to worry too much about how to get anything then yeah if we just want to don't worry about that. Okay. Yeah, my computer is not very quick. So, um, yeah, like M1's or especially M3s, this is, uh, pretty
lightning fast with proving. Um, so this is this is pretty abysmal. Again, I need a new computer. Um, cool. So, that's, um, ZK email. Uh, again, um, I would just start by kind of taking any of these templates and wiring it up from there. Um, if you have questions integrating it, um, definitely hop in the Telegram. Uh, I can go on ZKrex in a second. Um, if there aren't any questions, which I don't see, I'm just going to go for it.
Okay, so ZKrex is uh in a little bit less of a production state. Um if you really need uh reg X matching and you're feeling a little intrepid, you can try to do it right now. I'd expect in the next few days to see something a lot uh more put together. Um but yeah, you Um, this is going to take a little bit more to get working. Um, it still works though. Um, just keep in mind, uh, it's
it's going to be a little more manual, uh, until like packages are released and things are finalized. Um there's a version one um which was pretty much production grade uh but uh ZKML has uh iterated and and made a new version of the compiler that can support more reg x's. Um so this is kind of built from scratch and also mirrors that uh the circom implementation. Um so yeah, you might have to bear with a little pain if you want to use it. Um so I'm going to use the CLI a little bit. Uh, but you probably I haven't tested this, but you could probably just get it working in JS. Uh, eventually you won't need to do any of the CLI stuff.
You can just generate everything from JS. Um, only thing you need to set up is the template. Um, so also keep that in mind. Um, but let's let's jump into actually regexing. Um, okay. So, the first thing we want to do, I'm going to I'm going to do the time stamp regex. um which is this expression right here. Okay. Um in order to actually generate it with the CLI, we need to create a template that defines it like decomposes it. Um this is very simple as well. Like if if you're struggling again, just give it the context of like one of these examples. Uh throw it in the AI and it
should figure it out very quickly. Um so basically we're splitting it up into parts. pattern pattern. Uh the the thing to note here is this public pattern. Um this doesn't mean it's actually public. This is just defining that we want to capture this substring. Uh in this case we want like the time stamp the exact value there. Um and also in this case we know that the time stamp is always going to be 10, right? Um and maybe we're working with an email and that email could be like 80 characters. It could be up to 320 characters. So if this was an email, we would probably set 320 here.
And that defines like the max length of the substring to extract. And uh this is more or less uh kind of an efficiency feature um that allows us to minimize the amount of work that we have to do when capturing. Otherwise, we would have to operate over the entire um hay stack, the entire like body or or header. Um so fairly simple though. Again, you just specify what parts you want to actually extract out. And then this is your entire match, right? So once we have that, we have everything we need to generate uh the regx uh circuit as as well as the inputs that we're going to give to it. So again, I'm going to use the scripts, the CLI. Uh and this is set up to generate for all of the templates.
Um so there's a little extra stuff in here, but this is really what we care about. Uh we're running the CLI uh binary which is here. Um we're going to tell it we want to run it decomposed which is that template where we had like uh pattern pattern public pattern. That's the decomposition. Um actually pass it the path to that. Tell it where we want it to output. Give it a name. I don't you don't even really need the name for uh noir. Um, and then tell it you want noir, uh, cuz it'll default to circum. Um, and if you run all that, uh, that's all you need to get two artifacts. The first
is this timestamp graph, which, uh, you don't really need to worry about, but you need for input generation. So, just keep in mind that it exists. Um, as well as the actual regx itself, which is this. So this is all autogenerated. Um we don't really need to go into exactly how it works but essentially you've got all these inputs um which the input generation will handle creation for you. Uh as well as in this case we've got one capture group so it's going to return the single one.
If you have 10 capture groups it's going to return 10 you know um each with those those max lengths as you as you set them. Um really don't need to worry about any of this. Um, if you were like just developing locally, you really didn't want to deal with JS. Um, there's also uh this this has some hard-coded inputs. Um, but uh and a bunch of other stuff to kind of manually handle it. So, you'd have to pick through it. Uh, but you could generate like a prover.tomal tomal or even like the formatted inputs uh when you run this and you supply it the right uh inputs and that'll give you uh something like this and then you can
turn around and dump those into a test and and run it this way if you really wanted to. Um, but we're going to show an end to end example of CK email that we hooked up into JS. So, first off, um, let's look at the circuit. Um, so if you all remember, uh, just pure ZKL, the the first example, it's going to look very similar, uh, in a lot of ways. So, uh, again like that one question, uh, asked like we're importing the ZKML library. Uh these are all the inputs we expect. So you can kind of see how we're composing like a new one. Now um we import that library.
We have to wire in all the inputs again and do the same thing uh here. Uh again this is pretty much copy pasted from um the the the 2048 bit verification, right? Um and then we've got all these inputs. Kind of confusing, right? M not really. Um all we have to do is we import our reg x um you know we have the number of capture groups we have the length of in this case it's one capture group maybe we've got many but um those const as well as just reg x match right and then all we do is reg x match and wire all those inputs in. One thing
to note is like the reg x match has this in haystack and the input generation will give you a hstack. What we want to do with ck email is we want to reg x over like content that we've already authenticated. Um so in this case it's the header. Maybe in your case you're regexing over the body. But um we want to specifically make sure that whatever the h stack is we're actually using something that's been validated. it's signed header or signed body. So, we want to make sure we pass that in. But, um, we just call reg x match, toss in all those inputs, and it's going to pop out a substring for you or multiple substrings. Um, and maybe like, okay, so maybe we're doing something where um
you're getting like a a ticket to some conference by proving that um you received uh a DevCon 2024 acceptance email. Maybe you're like in this case you wanted to prove that you received it at some date. Uh you know maybe you could like hardcode uh some time stamp in this circuit and then do a range proof. You'd have to convert this to a number from bytes which is pretty trivial to do but um you know you just do a range proof on that and you don't actually have to export it even though it says public pattern. Again, the point there is it just captures the substring for you and then you can do whatever you want inside of the circuit. In this case, we are going to um actually export
it. But so yeah, that's that's the process of like composing reg x together right now. Um and then what am I looking for? Okay, so we've got our time stamp graph. I messed I mentioned we've got the email. Um, again, this is not totally production grade. So, we had to go here and wasn't packet. If you wanted to uh build it for the web, you'd have to target web. Um, but we did that already.
Um, import cKL import noir. We don't even actually use db because this is just simulating the circuit. But if you were to prove it's one extra function call and then we import the um input generation proving system stuff from that was impact um codegen utility that we have right we can see when we go to generate like an email uh the email inputs it's it's the same thing right generate email inputs and then we've got a little extra work here um to actually get the the regax Um, again, this is not polished. There's actually some bugs here. Um, which are easy to
work around, but things that you wouldn't see uh hopefully in a couple of days. Um, first thing we want to do is our hstack for the regx is the header. So, we're just going to grab the header back out. Uh, we're going to pass it into the circuit inputs uh generation function. Uh, also going to give it the the uh reg x graph like the um the fa I think. Um, and we're going to tell it we're generating it for noir. Those are like the main parts of this as well. Uh, this is like the max length. I don't know why this is off by four. It is. It should be 512 because we're
working with 512. Um, and then our maximum match length. This is a little bit manual. Um, you would say like in this case I expect the maximum number of bytes I have to go through to get to the end of the reg x is like 100 bytes or 200 bytes or however many bytes. But uh you would set this uh the same way that you set it uh here max match length. Um and that'll just make sure everything's padded to the right length and make sure the inputs generate correctly.
Um, so all you have to do to get all these inputs is run that. Same as kind of generate email verifier inputs. Um, cool. Now we've got our inputs. We're going to it's going to generate the haystack again for you. Um, we're going to toss that out because we're going to use the header as the haystack. Uh, also this is another very small bug that really is pretty immaterial but you just don't want to have to handle um is the capture group start indices. They're like offset because of this match length. Uh, for some reason they're not in the codegen. So for this I just offset it here. Ideally you won't even have to think about this, but if you
were to start writing this in the next hour you would have to uh do this offset as well to deal with it. Um, but that'll just normalize it to the kind of the start of the match. Uh, like the reg x match. Um, and in this case, we've only got one capture group, so we technically could just get the first index and or zeroth index and just change that, but it'll handle however many you have. Cool. And then, so this is like another example of like how I mentioned maybe your circuit has like a bunch of different inputs.
um you uh you can just put them together like this. Um so whatever email inputs plus whatever else you're operating on, put them together, toss them into war, execute them. And then this is uh how I mentioned with to and from emails. Um this is just the process of like turning a bounded ve into whatever you want to read at least in JS. You might have to deal with it differently in Solidity or um if you were using Aztec or something. um Aztec contracts. Uh parsing it would be different obviously, but if you just want to read it, there you go. Uh all that all that other stuff was just again validation.
Um so we do uh test again, this is going to run slower because my computer's overheating. There you go. We got our email nullifier, pub key hash, and we've also extracted out a time stamp. Now if we go look that looks right to me. Um yeah so that's the process of like a we've taken a ZK email circuit uh and integrated it with just arbitrary other functionality if you wanted to compose it. But specifically in this case we also used regx um for pattern matching. The one caveat, one other caveat on regexing I will say is um if
your use case can support it, if you can just do string searching for one reason or another, it's going to be a lot cheaper. Um regxing is a lot more secure. Uh it's a lot more dynamic. Um you can prove exclusion with regex. Uh you can only prove inclusion with noir string search. Um, so you need to be like cognizant of where you're using what, but that's definitely worth considering is reg x is not always the optimal tool. Um, but it is very powerful one. Um, okay, I see two questions.
Which library are you using for ZK email? Uh, I am using this library right here. So this is the code. This is github.com/dkmail/dkmail.nr. Um this is actual library right here. Right? So when I was showing the example, I was just importing by path. But for regax, it's the same code. Um what I actually do is I import it in naro.l Um, it's the most recent version. Uh, go
get it from ckmail.nr. Um, and then it's exactly the same from here. It's just how you access it. Uh is this the upbase? It is the upto-date codebase. Uh but it is also dynamic. Um I so this more hack demo branch adds JS on the fly. Uh I don't know if that branch will get like orphaned or what. Um but um cuz there are like a couple of small changes to
some other bugs I found from just like the main branch that we're working off of. So I might just merge that back into the main branch. Um pretty soon um it should get merged at least into the main like v2 branch. I don't know exactly what the timeline looks like for like overwriting all of ZKrex with that. Um, this is that branch is the most upto-date noir code though. Um, I guess I I will drop though the main um the main repository. Uh, how do I do that?
Um, how do you use Zoom? Um, chat. Okay, there we go. Um, no, it's not showing me chat. Uh, I'll I'll post that in a second. Actually, I'll let other people finish up. Are there any restrictions on decomposed reg x parts? That might be a better question for Aush.
Yeah, I think um in terms of decompos there's kind of uh so in the old compiler which is kind of what is live I think right now um there was like some restrictions on basically not being able to use like you know uh non-deterministic things like looks um in a new version of reject we still have you can't use nondeterministic things like looks but um various bugs around uh certain things not working like character classes are now fixed. So um basically yeah with a new compiler you can use anything that you expect to um to not have to like loop around the redex multiple times. So as long as it's
processing the redex in order it should compile totally fine on the new new redex compiler. Um yeah, Zoom is not cooperating with me now. Okay. Um yeah, I think uh I think that's everything. Uh again, the regex will be like there there aren't really docs on it. uh the integration of it. This is by far like the recording of this is going to be
your best friend. Uh also the telegram um can support through that um which I can throw up the links in a sec. Um zkmail.nr a lot more documented. U still though if you're having issues go through the telegram uh it's probably the easiest way to get help. Uh you can open an issue as well I suppose on GitHub. Um, so yeah. Um, definitely if you're if you're trying to track the progress of the regx though, uh, I would I would 100% be hopping in the the Telegram, uh, cuz there should be some updates there. So, I guess I'll pull
up. Um, oh, and there's also N JWT, which I'm not super prepared to speak about right now. Um, but uh it's very similar to uh how Zika email works. Obviously, you're validating JSON web tokens, but a lot of them are signed with RS 256, which is RSA. Um, so um definitely check that out as well because there's a bunch of other really interesting things that you can do that are very similar to ZK email um except using uh JSON web tokens. So, leave that up for a sec.
Yeah, I guess. Are you sure if you guys have anything else you want to say? No, all good. So I think yeah if you have any more questions also you can reach out to the telegram which is the main place where we support everyone and yeah to follow along with the work. You can also follow Twitter and uh our website. Yeah and we will support anyone that uh will hack uh during hack with ZK. So yeah, don't know if I I want to add
something else. No, it's great. Yeah, excited to for people to ask questions and and use the tech. Awesome. Thank you guys so much. Also, we have a Discord, like a whole set of channels in our Noir Discord for Noir Hack. If we could have one of y'all in there, I I'll also share the Telegram, too. Um, but yeah, if anyone's asking questions in there that are more Noir specific, but they're also working on ZK email, be sure to tag uh ZK email in some way, just mention that you're using ZK email. Um, and then hopefully we can have uh you maybe you can crossost it also in in the telegram. Uh, but cool.
Thanks everyone. Um, this will be recorded um and we'll share it to the the notion soon and I'll also add all the resources that uh the ZK email team has shared here um in the notion too. Uh, but thank you guys for for joining. This was great. Um, and yeah, I'm sure we'll get more questions from the recording. Um, and I'll I'll I'll send send them to you and we'll I'll also share the Telegram with everyone. Cool. Bye everyone. Have a good one. Happy Monday. Thank you.