Scaling Semaphore: Noir in Action
NoirCon 2 Berlin 2025 · June 2025 · 22:45
Vivian Plasencia, a software engineer on the Ethereum Foundation's PSE team, explains what Semaphore is, how it works and why it matters. Semaphore lets users prove group membership with zero-knowledge proofs without revealing who they are, and the talk shows how Noir is used to scale it. It was given at NoirCon 2.
Speakers
Topics
From NoirCon 2 Berlin 2025, hosted by Aztec Network.
Transcript
[Music] Hello everyone. My name is Vivian Placencia and I'm a software engineer in PSC at the the foundation and today I'm going to talk about scaling sema for no in action. So let's start with what is semaphore. Semaphor is a serish protocol that allows users to prove their membership in a group and send messages such as votes or feedback without revealing their identity. This means that identities are not linked to the messages and it also provides a mechanism to prevent double signaling which means that you cannot verify the same proof twice and it works offchain
and on EVM compatible chains. It's a public good project so everyone can use it and contribute to it. There are some use cases for SEMA for I'm going to mention a few. There is the supas project. It it was used last year at defcon like for ticketing and the work project the it's focus on to prove that you are a real human and also paywise which is focused on anonymous voting. So in this URL you can find the list of projects some other projects that are using semaphore.
So the first comet for semaphore was in 2019 and after that we have been releasing a new version almost every year and the last one was in July in 2024 and it's the one that I will be talking a bit about and it's semaphore version 4. So here you're talking about semaphore on >> yes I'm going to talk about semaphore and then semaphore nor >> okay >> yeah so you need to understand a bit about semaphore to then understand the other part so semaphore version 4 introduces two significant pro protocol updates so one is the identity schema
and the other is the lin incremental tree which is an optimized incremental tree here you can find the In this URL you can find the the audit for this new version. And for the identities they are EDSA public private key pairs and also a commitment and with semaphore version 4 you can create and verify signatures. So are the bus before people used to use CKS for that. So now you can do it with the identities directly.
The lin incremental milk tree is the tree used in sema for version four for the group operations. In version three it was use the incremental tree. And the improvements for this new tree are that first you don't need zero hashes anymore. This means that before you had a node and then to there were some leaves and then for specific nodes you needed to to hash it with to create the parent hash you needed another node. So now if there is just one node to to create the hash you don't need to create a zero hash node for that. So that's that's good. and also dynamic depth
which means that if you have three members then it's fine if you add another one that your your tree depth is going to grow over time. So you don't need to in version three you needed to create the tree like initialize it with specific tree depth. So you don't need that anymore. So here are two examples like the incremental tree and now the lin incremental tree. As you can see for the incremental macro tree you needed a power of two elements and then for the incremental macro tree it will grow over time. So you you don't need that.
So here you can find the research for semiporation 4 like you can find the explanation about every decision and all the things we consider like data structures and benchmarks. So there is a page in the SEMA 4 documentation for benchmarks. So you can find benchmarks for version three and version four. And version four performs better than version three. So yeah, I'm going to talk a bit about the scaling process we have been working on lately and one of these is yeah I I will focus more on semifor which is what was created to improve performance
for generating and verifying proofs but I'm going to start with this which is the sema for specification document it was used for the creation of sema for no implementation it's a document for developers to it will help developers to build sema for version 4 because it has everything like all the explanation about the circuits and everything and it helps developer to implement it on different texts. So also semma for rust which is which was created to support native mobile and now the sema for proofs are compatible across different ecosystem like raw
solidity and native mobile and javascript and this is a collaboration with PSD research and the moro team. You can find the repo here in this link. Also another thing we we did for scaling like for the previous one was for to support semifor on different ecosystems. So this is SEMA for private information retrieval which was focused to have faster client side micro proof generation and this is a collaboration with the PSC research team and the idea is to to have faster micro proof generation because right now you need to do everything in the browser and when
you have million of members for example like one yeah million of members you will need to fetch all this data and recreate the tree in the browser and it's not a good de user experience. You will need to use something like web workers or something and it's still not a good user experience. So the idea with P was to to do it in a server faster and the results you can find the blog here the the report in the PSC blog and the results are that is is not fast enough for a production application. So for some specific cases, it can be interesting, but but it's not that fast.
So we won't use it in production. It's not ready yet. But you can find all the benchmarks there and there are interesting outcomes. So yeah, let's talk about semaphorn for the rest of the presentation. and semifor is a research and development process we did for to optimize semaphore proving and verification performance using noir. So this is a collaboration with the Aztec team and it was implemented by the hashlo team. They did a great work and you can find the final report here.
They did really good work and I'm going to talk about the benchmarks and some interesting results. So sema for version 4 is using circomus graph 16 and snarjs. And the idea of this semaphorn implementation was to do the same but with n and ultra honk. And for that we needed to modify some components in semur. The main semaphore components are identity group, the circuit, the proof package and the smart contracts. So for semma for noir you could use the identity package and the
group package because they are both in JavaScript and you don't need to modify anything from the those packages because this these packages don't have CK there and we needed to modify the circuit to support NAR instead of circum everything write the circuit from scratch and then we needed to to modify the proof package and the the smart contracts. For those we only needed to modify the proving system which is ultra honk we yeah because these two packages were using grow 16.
So you we didn't need to write both packages from scratch just to modify to use the new proving system. The only thing we needed to write from scratch was the circuit. So let's talk a bit about the circuit because that's the main part for nor. So this is the diagram for of the sema for circuit the circum and also the noir one because they are very similar. So I'm going to explain a bit.
So for the circuit we need the proof of membership and to calculate the the fruit and then also the secret and the scope. With the secret we will calculate the public key using baby YouTube and also with Poseidon we will get the identity commitment and with the secret and the scope we can get the nullifier. So with a message in circum we used to create a we we have a dummy square to prevent the circum compiler to optimizing it and so that it creates a constraint but with the new implementation we don't need that. So
there is no need to create the dummy square because when you have an input it will create the constraint directly. So no need to to have any dummy square. So I'm going to show how it is the circuit is in circum and also noir so that you see the difference for both and for circum as you can see there is like the first part is the the you can find the variables and then the first part is the check for the L value. This is for the baby YouTube part. And then we can get the here we we are getting the baby YouTube public key and then we are
generating here the identity commitment with Poseidon and then the calculating the mer using the proof of membership and then calculating the nullifier and the do square because that's this is circum then for noir you you have the the inputs and the check for the L value, the public key generation, the identity commitment, then calculating the root using the proof of membership, then generating the nullifier, and that's it. No need to create the dummy constraint. So, as you can see, they are both similar. So, it's almost
the same thing, but different languages. So that's that was the circuit. So for the proof package and the smart contracts we only needed to update the proving system because now with no is ultra honk and before we were using gross team so so it's just that part we don't need to write everything from scratch just for the proof package how to generate and verify the proof and for smart contract how to verify it. So it was the verifier.
One feasure the hash glow team worked on and created was the batching part. The idea of this was to lower the onchain costs. The idea is to have several semiformal proofs and just verify this proof once in a way that you don't have to send all the proofs and verify many times and there are great benchmarks and is faster and this is using recursive proofs in no. So this is a great feature and very interesting for the noir ecosystem.
I'm going to talk a bit about some benchmarks and I'm going to start with NodeJS. So these benchmarks are for circum graph 16 implementation and also no ultra honk. So for both proof generation and verification they are around 1.4 to 1.7 times slower from for semifor and assuming that the back end was in pre-initialized. So this means that it's slower with NAR and ultra honk and the proof generation with NAR will take from two 29 to 538
milliseconds and sircom implementation will be 175 from from that to 387 milliseconds. So for different three depths. So yeah there is a difference here and proof verification takes from 14 to 15 milliseconds and compared to 8 milliseconds with circum. So for browser the proof generation with noir will be about from one to two seconds while in sema 4 in circum will take you 200 to 300 milliseconds. So that's there is a difference here too
for smart contracts the validation of the CK proof will be seven times more expensive in so yeah it's more expensive so the good part here will be the batching functionality some benchmarks for the CK artifact size so for proof generation in circum we need the wasam file and also the CK file And for no we only need the JSON file. And for the NOR activifats they are five times and 11 times smaller than circums combining the wasam and CK files. So in this case noir is yeah it's better
because you don't need to download all these yeah all these files and for circum it take is more they are bigger. So the smaller the tree the bigger the difference will be in our artifact size. This was for this was for proof generation and for proof verification for no the the verification key are around 1.78 kilobytes and for circum it will be 3.66 so kilobytes. So yeah there is a different here too and good for noir and for the verification key it will be about half the size across all three depths. So for
this the s artifact size nor is is much better in the batching part which is the new feature in semma for no the the perproof gas cost is reduced. So for example for 100 proofs can that can be verified on chain only 4.4 times the gas cost is that's the difference from a single proof. So that's really good and the bad part is that the generating this will take you around 20 minutes and this which means that there is a trade-off here. So if
you need that part to save gas then you will need 20 minutes to generate that. But this can be useful for some use cases. So yeah it's something good but there are trade-offs like all the time with everything. So as a summary from this free search implementation we can say that NAR with ultra honk does not require trusted setup per circuit per circuit and circum and grain will require that. This is great that you don't need that with noir and ultra hung because yeah that's that's a pain because every time you change something
in the circuit you will need to run another trust setup and it's true that circuits won't change that much probably but they can still change so so that's good for the nor ecosystem and proof generation and verification are faster with cirra 16 compared to nor and ultra honk So it's still faster to use circumst but in the future I think nor ultra home will be faster. So let's see in the future but the idea is that in the future nor ultraong should be faster so that we can use that and circumsting is more cost efficient that
nor and ultra hung when using smart contracts. So grocerying is still cheaper in contracts. So So yeah, let's see in the future too. But for now, yes, with the batching part is it's better. But but yeah, with the other part in general, I per proof is still faster to use circumst artifacts for proof generation and verification. The nor with ultra are smaller than circum with gross. So yeah, as I mentioned before, this is this is great for the new ecosystem because you don't need to download a lot of gigabyte or megabytes in browser to
generate a proof. So you can use semaphore implementation. It's very similar to the current semaphore implementation. The architecture and everything is very similar. So the first part you will create the identity the group add members and the me message and scope those will be the same for both the difference here will be that you need to initialize the back end so that you can you will need to do that per circuit. So you can do this once and you don't need to do it all the time. Every time you generate a proof, you can create something a way that you don't need to do that all the time. Then you will generate the proof is very similar the
way to generate the proof, the same parameters and almost the same and then verify the proof. So the architecture of an application will be very similar. So you can in this link you can follow an entire tutorial so that you can use it also for contracts and yeah to learn more about semaphore you can go to the GitHub documentation and telegram there is a telegram chat too like a group for semaphur and you can also visit the website it has all the information yeah thank you very much so here is my contact.
[Applause] >> Yeah. >> What are some use cases for the batch proof verification? I'm assuming. >> Yeah. >> Yeah, that's a good question and also we have been talking about it and we would like to find more use cases. But the idea is that if you need in some application you need to verify many proofs and you will do this onchain. The idea is that you have a back end to get all these proofs. You will need in the back end to verify each proof separately so that you can create a proof in a way that you know that they will they should be verified successfully and then you will generate this in the back end and
then send it to the contract and it will be cheaper. So, >> so you kind of ceue them up in your back end and then when >> Yes. And then and then it will be shipper in contracts and then you will know that this will be verified successfully because you will send back the ones that were not verified successfully since the back end. So yeah, that's the idea to lower gas cost on chain. >> Yeah. So you have these two versions like ceram and no but if I have a new project which one should I use will you support both or is one superior or do I just get the true?
>> Yes. So right now there are two and the hash code team is maintaining the n implementation. It depends on your application. If you need yeah just like the sema for the normal like to for feedback or voting or normal applications circum is faster as I was mentioning here circumst is faster but if you want something like batch chin or and you it's for you the 20 minutes to create this the offchain part you can go with that one and it depends also on the ecosystem if your application is using no everywhere Maybe you would like to use this one and also semaphore is using CKit and there is a CKit N repository.
So, so yeah, you can combine all these things for your N application. It depends but in general if it's a real world application sema for version 4 circumjs was audited and it's faster. Yeah. And also cheaper in contracts.