ZK14 - A Security Guide to ZK Engineering - Michael Belegris (Nethermind)
18 May 2026 · 10:51
Michael Belegris of Nethermind presents a security-focused walkthrough of zero-knowledge circuit engineering, recorded at Zero Knowledge Summit 14 in Rome. He surveys the most common pitfalls when implementing ZK circuits and translates them into concrete steps engineers can take to secure their protocols. The talk moves from vulnerabilities inside the circuits themselves to how those circuits behave once deployed in production, aimed at teams building zero-knowledge proof systems.
Speakers
Topics
Transcript
Hi everybody. Hi everybody. I'm Michael Belegris. I'm in the Nethermind security team. Where I should have specialized in ZK and cryptography audits. And sort of as part of that we've had to audit various protocols that should have integrate ZK and use ZK as part of their protocol. And doing so we should have noticed some issues, bugs that sort of kept popping up. And a while back we we wrote this article that sort of outlined the various um the various bugs and the mentality that engineers should have when implementing ZK and integrating it within their own protocol.
And in doing so we sort of outlined some actionable steps, some some checklist that sort of helped engineers sort of prepare for security audit of their code. And that's sort of what this talk is about. It's sort of quick intro into ZK engineering from a security perspective. Okay. So what are we going to talk about? First I'm going to outline the various different security notions that we sort of think of when when doing a security audit of ZK and a ZK integrated protocol.
And that specifically will be a circuit issue, a production issue, a protocol issue. And then at the end I'll I'll sort of give a ZK security guide as to the sort of mentality that engineers should have and the questions that they should be asking when it comes to integrating ZK into their protocol and also writing their own circuit. And then obviously I'll conclude. Okay. So let's jump to it. The first thing that I want to talk about are the three different security notions when it comes to ZK.
So over the course of many uh different audits uh and reviews of of different protocols, we sort of noticed that there's three main classifications of issues we have. We've got circuit issues, which is probably what everybody thinks of when they think of uh a bug in their ZK, uh and that's under and over constraint. Uh protocol issues, um and that sort of comes down to the misunderstanding of the guarantees of the circuit itself and the ZK. And then also production issues, which is something a little newer. Um, and that comes from uh problematic deployment.
Okay, so let's go through each one. Uh a circuit issue. So, as I said, sort of relates to under and over constraint issues, um and the most common type of issues that that exist uh and are the most widely talked about. Um an example of this I've just put arithmetic underflows, overflows, uh whatever you want to call it. Um and this sort of relates to uh in let's say Circom whereby uh doing any operation is wrapped within a finite field, so it's always uh modded. Um and this can sort of lead to various different interesting bugs. Um an interesting case study is that of the range check. A range check um is simple to do in traditional engineering. You
just check that X is less than Y. But in Circom in a language uh in a ZK DSL, it's not as simple because uh there needs to be some additional constraints that that sort of take into account this uh finite field math. Um and this sort of means that engineers need to be deeply aware of the various different bugs and issues that comes from actually using uh circuits and implementing uh their own uh their own circuits. Um And final thing on on circuit issues is the sort of idea that there there is this there are tools that exist, so um you can think of Circumspect when it comes to Circum, which is a static
analyzer that can help engineers sort of detect bugs in the circuits that they've written to sort of try and catch these pretty early on. Then there is I think Noir has fuzzers. I think Circum also has fuzzers, but Noir also has fuzzers, and those can of course be used to sort of detect various different bugs when it comes to uh when it comes to implementing their own circuits. Okay. The next one, and probably the newest of these issues, is that of production issues. And this comes from incorrectly deploying the code. So in the previous case we were thinking that
okay, the bug is in the circuit, whereas this is of how you use the circuit and how you actually deploy the circuit. So the the best example and probably the that comes to mind is that of the incomplete Snark JS ceremony. So I think a month or two ago uh the two protocols got hacked because they didn't complete the Snark JS ceremony from phase one to phase two if I if I'm correct. And this led to a bad Groth16 trusted setup. Um trusted ceremony setup, which led their code to be hacked and and funds lost. So this you can see is not actually an issue with a bug with the uh circuit itself, but actually with how
you then go ahead and use the how you deploy the uh uh the circuit. Cool. Uh this sort of means that engineers need to be aware of the proof system that they're using quite deeply and not side step these these sort of crucial um these sort of crucial uh points like the completing the phase two ceremony. Cool. The final set of issues to discuss is that of protocol issues. Personally, my favorite because it's they've always sort of been there, but I feel like they're a bit undiscussed. And this comes from incorrectly using, uh, the ZK circuit within the wider protocol.
So, uh, an example I put up here is the unverified public key attack. Um, what that is, very simply, you've got a circuit, the goal of circuit is very simple is that it, uh, verifies the digital signature of a message, uh, for a given public key, and that public key is then made public. Uh, as a public, uh, value of the circuit. Um, great, the circuit works, uh, very well, and it proves this, uh, perfectly. But what it doesn't do is it doesn't have any attribution of the public key. So, there is this missing guarantee of authenticity of the, uh, public key that it could just come from anybody. And what does that mean? That
means that anybody could sort of arbitrarily sign the, uh, a message by generating their own key pair uh prove it, and then, um, send that up to the verifier. And that's a valid proof. Uh, and the proof is correct, great. But how does the wider protocol take this into account? Does it make any guarantees as to what this public key is from? Is it from, you know, a a set of uh, valid public keys? Is it, uh, proven knowledge of X, Y, and Z? Uh, checks need to be done that sort of make this proof usable within the wider protocol.
Um, and that's sort of where where this all comes from. Uh, because what you're doing is you've got a circuit that works, but you're not using it in any meaningful way. Um, so we should have uh, uh of this in a way of like um you can you need to balance the public keys such that they are public and not the public keys, the public inputs such that they're public enough that they sort of bind the circuit, but not public enough that they reveal anything meaningful uh about, you know, cuz then you still lose uh confidentiality and a lot of the actual ZK guarantees, right?
Um maybe a different way of thinking about this is let's say you prove that you nullify a nullifier correctly, but you don't actually nullify the nullifier in the remainder of your uh protocol. So, yeah, very well, you've proved that this works, but how are you taking it into account within your wider protocol? And that sort of leads to replay attacks and that sort of thing when it comes to the wider protocol. So, you got to kind of think about what um what value enforcements need to be taken into account outside the circuit such that they are um such that the proof itself is is valid and and actually usable within your wider protocol.
Okay. The sort of final thing to talk about is the ZK security notions. Um there's three here, the three main questions to sort of ask as a ZK engineer. Um but then there's probably multiple. But anyway, getting to them. So, what needs to be proved? Uh we need to know exactly what uh proving statement uh we're actually proving for and also um the actual guarantees of the circuit. So, what aren't we taking them into account in the circuit such that we need to take it into account within the wider protocol?
Then, how should the proof be verified? Sort of is about understanding the proof system, uh what exactly we're proving and and how uh the verifier is deployed. And then finally, uh, where should the proof be generated? So, this is talking about client versus server-side proving. So, client versus server-side proving is the idea that do you want the client to hold all the information, prove generate the proof themselves, but this is, you know, computationally expensive and and quite slow. And then there is server-side proving, but whereby you're giving away all the private information, even if you're blinding it, that still leads to, uh, you trusting the server to generate the
proof on your behalf. Um, and these sort of three security, uh, these three questions need to be asked when, uh, trying to integrate with ZK and, uh, use a ZK circuit. Okay. Uh, just before I say thank you, uh, the final thing is just to sort of conclude what I said. So, I introduced the three security notions that exist, um, circuit issues, production issues, and protocol issues, and then also, uh, introduced, uh, the sort of mindset that engineers should have when, uh, integrating with ZK and and using ZK.
Thank you. >> [applause]