This is the story of how Payy transformed their ZK ecosystem from one bottlenecked by a single developer to a system their entire team can modify and maintain.
Payy, a privacy-focused payment network, just rewrote its entire ZK architecture from Halo2 to Noir while keeping its network live, funds safe, and users happy.
Code that took months to write now takes weeks (with MVPs built in as little as 30 minutes). Payy’s codebase shrank from thousands of lines to 250, and now their entire engineering team can actually work on its privacy infra.
This is the story of how they transformed their ZK ecosystem from one bottlenecked by a single developer to a system their entire team can modify and maintain.
Eighteen months ago, Payy faced a deceptively simple requirement: build a privacy-preserving payment network that actually works on phones. That requires client-side proving.
"Anyone who tells you they can give you privacy without the proof being on the phone is lying to you," Calum Moore - Payy's Technical Lead - states bluntly.
To make a private, mobile network work, they needed:
To start, the team evaluated available ZK stacks through their zkbench framework:
STARKs (e.g., RISC Zero): Memory requirements made them a non-starter on mobile. Large proof sizes are unsuitable for mobile data transmission.
Circom with Groth16: Required trusted setup ceremonies for each circuit update. It had “abstracted a bit too early” and, as a result, is not high-level enough to develop comfortably, but not low-level enough for controls and optimizations, said Calum.
Halo2: Selected based on existing production deployments (ZCash, Scroll), small proof sizes, and an existing Ethereum verifier. As Calum admitted with the wisdom of hindsight: “Back a year and a half ago, there weren’t any other real options.”
Halo2 delivered on its promises: Payy successfully launched its network. But cracks started showing almost immediately.
First, they had to write their own chips from scratch. Then came the real fun: if statements.
"With Halo2, I'm building a chip, I'm passing this chip in... It's basically a container chip, so you'd set the value to zero or one depending on which way you want it to go. And, you'd zero out the previous value if you didn't want it to make a difference to the calculation," Calum explained, “when I’m writing in Noir, I just write ‘if’. "
With Halo2, writing an if statement (programming 101) required building custom chip infra.
Binary decomposition, another fundamental operation for rollups, meant more custom chips. The Halo2 implementation quickly grew to thousands of lines of incomprehensible code.
And only Calum could touch any of it.
The Bottleneck
"It became this black box that no one could touch, no one could reason about, no one could verify," he recalls. "Obviously, we had it audited, and we were confident in that. But any changes could only be done by me, could only be verified by me or an auditor."
In engineering terms, this is called a bus factor of one: if Calum got hit by a bus (or took a vacation to Argentina), Payy's entire proving system would be frozen. "Those circuits are open source," Calum notes wryly, "but who's gonna be able to read the Halo2 circuits? Nobody."
During a launch event in Argentina, "I was like, oh, I'll check out Noir again. See how it's going," Calum remembers. He'd been tracking Noir's progress for months, occasionally testing it out, waiting for it to be reliable.
"I wrote basically our entire client-side proof in about half an hour in Noir. And it probably took me - I don't know, three weeks to write that proof originally in Halo2."
Calum recreated Payy's client-side proof in Noir in 30 minutes. And when he tested the proving speed, without any optimization, they were seeing 2x speed improvements.
"I kind of internally… didn't want to tell my cofounder Sid that I'd already made my decision to move to Noir," Calum admits. "I hadn't broken it to him yet because it's hard to justify rewriting your proof system when you have a deployed network with a bunch of money already on the network and a bunch of users."
Convincing a team to rewrite the core of a live financial network takes some evidence. The technical evaluation of Noir revealed improvements across every metric:
Proof Generation Time: Sub-0.5 second proof generation on iPhones. "We're obsessive about performance," Calum notes (they’re confident they can push it even further).
Code Complexity: Their entire ZK implementation compressed from thousands of lines of Halo2 to just 250 lines of Noir code. "With rollups, the logic isn't complex—it's more about the preciseness of the logic," Calum explains.
Composability: In Halo2, proof aggregation required hardwiring specific verifiers for each proof type. Noir offers a general-purpose verifier that accepts any proof of consistent size.
"We can have 100 different proving systems, which are hyper-efficient for the kind of application that we're doing," Calum explains. "Have them all aggregated by the same aggregation proof, and reason about whatever needs to be."
Initially, the goal was to "completely mirror our Halo2 proofs": no new features. This conservative approach meant they could verify correctness while maintaining a live network.
The migration preserved Payy's production architecture:
"If you have your proofs in Noir, any person who understands even a little bit about logic or computers can go in and say, 'okay, I can kinda see what's happening here'," Calum notes.
The audit process completely transformed. With Halo2: "The auditors that are available to audit Halo2 are few and far between."
With Noir: "You could have an auditor that had no Noir experience do at least a 95% job."
Why? Most audit issues are logic errors, not ZK-specific bugs. When auditors can read your code, they find real problems instead of getting lost in implementation details.
Halo2: Binary decomposition
Payy’s previous 383 line implementation of binary decomposition can be viewed here (pkg/zk-circuits/src/chips/binary_decomposition.rs).
Payy’s previous binary decomposition implementation
Meanwhile, binary decomposition is handled in Noir with the following single line.
pub fn to_le_bits<let N: u32>(self: Self) -> [u1; N]
(Source)
With Noir's composable proof system, Payy can now build specialized provers for different operations, each optimized for its specific task.
"If statements are horrendous in SNARKs because you pay the cost of the if statement regardless of its run," Calum explains. But with Noir's approach, "you can split your application logic into separate proofs, and run whichever proof is for the specific application you're looking for."
Instead of one monolithic proof trying to handle every case, you can have specialized proofs, each perfect for its purpose.
"I fell a little bit in love with Halo2," Calum admits, "maybe it's Stockholm syndrome where you're like, you know, it's a love-hate relationship, and it's really hard. But at the same time, when you get a breakthrough with it, you're like, yes, I feel really good because I'm basically writing assembly-level ZK proofs."
“But now? I just write ‘if’.”
Technical Note: While "migrating from Halo2 to Noir" is shorthand that works for this article, technically Halo2 is an integrated proving system where circuits must be written directly in Rust using its constraint APIs, while Noir is a high-level language that compiles to an intermediate representation and can use various proving backends. Payy specifically moved from writing circuits in Halo2's low-level constraint system to writing them in Noir's high-level language, with Barretenberg (UltraHonk) as their proving backend.
Both tools ultimately enable developers to write circuits and generate proofs, but Noir's modular architecture separates circuit logic from the proving system - which is what made Payy's circuits so much more accessible to their entire team, and now allows them to swap out their proving system with minimal effort as proving systems improve.
Payy's code is open source and available for developers looking to learn from their implementation.
Preventing sybil attacks and malicious actors is one of the fundamental challenges of Web3 – it’s why we have proof-of-work and proof-of-stake networks. But Sybil attacks go a step further for many projects, with bots and advanced AI agents flooding Discord servers, sending thousands of transactions that clog networks, and botting your Typeforms. Determining who is a real human online and on-chain is becoming increasingly difficult, and the consequences of this are making it difficult for projects to interact with real users.
When the Aztec Testnet launched last month, we wrote about the challenges of running a proof-of-stake testnet in an environment where bots are everywhere. The Aztec Testnet is a decentralized network, and in order to give good actors a chance, a daily quota was implemented to limit the number of new sequencers that could join the validator set per day to start proposing blocks. Using this system, good actors who were already in the set could vote to kick out bad actors, with a daily limit of 5 new sequencers able to join the set each day. However, the daily quota quickly got bottlenecked, and it became nearly impossible for real humans who are operating nodes in good faith to join the Aztec Testnet.
In this case study, we break down Sybil attacks, explore different ways the ecosystem currently uses to prevent them, and dive into how we’re leveraging ZKPassport to prevent Sybil attacks on the Aztec Testnet.
With the massive repercussions that stem from privacy leaks (see the recent Coinbase incident), any solution to prevent Sybil attacks and prove humanity must not compromise on user privacy and should be grounded in the principles of privacy by design and data minimization. Additionally, given that decentralization underpins the entire purpose of Web3 (and the Aztec Network), joining the network should remain permissionless.
Our goal was to find a solution that allows users to permissionlessly prove their humanity without compromising their privacy. If such a technology exists (spoiler alert: it does), we believe that this has the potential to solve one of the biggest problems faced by our industry: Sybil attacks. Some of the ways that projects currently try to prevent Sybil attacks or prove [humanity] include:
Both zkEmail and ZKPassport are powered by Noir, the universal language of zk, and are great solutions for preventing Sybil attacks.
With zkEmail, users can do things like prove that they received a confirmation email from a centralized exchange showing that they successfully passed KYC, all without showing any of the email contents or personal information. While this offers a good solution for this use case, we also wanted the functionality of enabling the network to block certain jurisdictions (if needed), without the network knowing where the user is from. This also enables users to directly interface with the network rather than through a third-party email confirmation.
Given this context, ZKPassport was, and is, the perfect fit.
For the Aztec Testnet, we’ve integrated ZKPassport to enable node operators to prove they are human and participate in the network. This integration allows the network to dramatically increase the number of sequencers that can be added each day, which is a huge step forward in decentralizing the network with real operators.
ZKPassport allows users to share only the details about themselves that they choose by scanning a passport or government ID. This is achieved using zero-knowledge proofs (ZKPs) that are generated locally on the user’s phone. Implementing client-side zk-proofs in this way enables novel use-cases like age verification, where someone can prove their age without actually sharing how old they are (see the recent report on How to Enable Age Verification on the Internet Today Using Zero-Knowledge Proofs).
As of this week, the ZKPassport app is live and available to download on Google Play and the Apple App Store.
Most countries today issue biometric passports or national IDs containing NFC chips (over 120 countries are currently supported by ZKPassport). These chips contain information on the full name, date of birth, nationality, and even digital photographs of the passport or ID holder. They can also contain biometric data such as fingerprints and iris scans.
By scanning the NFC chip located in their ID document with a smartphone, users generate proof based on a specific request from an app. For example, some apps might require only the user’s age or nationality. In the case of Aztec, no information is needed about the user other than that they do indeed hold a valid passport or ID.
Once the user installs the ZKPassport app and scans their passport, the proof of identity is generated on the user's smartphone (client-side).
All the private data read from the NFC chip in the passport or ID is processed client-side and never leaves the smartphone (aka: only the user is aware of their data). Only this proof is sent to an app that has requested some information. The app can then verify the validity of the user’s age or nationality, all without actually seeing anything about the user other than what the user has authorized the app to see. In the case of age verification, the user may want to prove that they are over 18, so they’ll create a proof of this on their phone, and the requesting app is able to verify this information without knowing anything else about them.
For the Aztec Testnet, the network only needs to know that the user holds a valid passport, so no information is shared by the user other than “yes, I hold a valid passport or ID.”
This is a nascent and evolving technology, and various phone models, operating systems, and countries are still being optimized for. To ensure this works seamlessly, we’ll be selecting the first cohort of people who have already been running active validators on a rolling basis to help test ZKPassport and provide early feedback.
If someone successfully verifies that they are a valid passport holder, they will be added to a queue to enter the validator set. Once they are in line, they are guaranteed entry. The queue will enable an estimated additional 10% of the current set to be allowed in each day. For example, if 800 sequencers are currently in the set, 80 new sequencers will be allowed to join that day.
This allows existing operators to maintain control of the network in the event that bad actors enter, while dramatically increasing the number of new validators added compared to the current number.
With ZKPassport now live, the Aztec Testnet is better equipped to distinguish real users from bots, without compromising on privacy or decentralization.
This integration is already enabling more verified human node operators to join the validator set, and the network is ready to welcome more. By leveraging ZKPs and client-side proving, ZKPassport ensures that humanity checks are both secure and permissionless, bringing us closer to a decentralized future that doesn’t rely on trust in centralized authorities.
This is exciting not just for Aztec but for the broader ecosystem. As the network continues to grow and develop, participation must remain open to anyone acting in good faith, regardless of geography or background, while keeping out bots and other malicious actors. ZKPassport makes this possible.
We’re excited to see the community expand, powered by real people helping to build a more private, inclusive, and human Web3.
Stay up-to-date on Noir and Aztec by following Noir and Aztec on X.
Imagine an app that allows users to post private messages while proving they belong to an organization, without revealing their identity. Thanks to zero-knowledge proofs (ZKPs), it's now possible to protect the user’s identity through secure messaging, confidential voting, secured polling, and more. This development in privacy-preserving authentication creates powerful new ways for teams and individuals to communicate on the Internet while keeping aspects of their identity private.
Compared to Glassdoor, StealthNote is an app that allows users to post messages privately while proving they belong to a specific organization. Built with Noir, an open-source programming language for writing ZK programs, StealthNote utilizes ZKPs to prove ownership of a company email address, without revealing the particular email or other personal information.
To prove the particular domain email ownership, the app asks users to sign in using Google. This utilizes Google’s ‘Sign in with Google’ OAuth authorization. OAuth is usually used by external applications for user authorization and returns verified users’ data, such as name, email, and the organization’s domain.
However, using ‘Sign in with Google’ in a traditional way reveals all of the information about the person’s identity to the app. Furthermore, for an app where you want to allow the public to verify the information about a user, all of this information would be made public to the world. That’s where StealthNote steps in, enabling part of the returned user data to stay private (e.g. name and email) and part of it to be publicly verifiable (e.g. company domain).
When you "Sign in with Google" in a third-party app, Google returns some information about the user as a JSON Web Token (JWT) – a standard for sending information around the web.
JWTs are just formatted strings that contain a header (some info about the token), a payload (data about the user), and a signature to ensure the integrity and authenticity of the token:
Anyone can verify the authenticity of the above data by verifying that the JWT was signed by Google using their public key.
In the case of StealthNote, we want to authorize the user and prove that they sent a particular message. To make this possible, custom information is added to the JWT token payload – a hashed message. With this additional field, the JWT becomes a digitally signed proof that a particular user sent that exact message.
You can share the message and the JWT with someone and convince them that the message was sent by someone in the company. However, this would require sharing the whole JWT, which includes your name and email, exposing who the sender is. So, how does StealthNote protect this information?
They used a ZK-programming language, Noir, with the following goals in mind:
The payload and the signature are kept private, meaning they stay on the user’s device and never need to be revealed, while the hashed message, the domain, and the JWT public key are public. The ZKP is generated in the browser, and no private data ever leaves the user's device.
By executing the program with Noir and generating a proof, the prover (the user who is posting a message) proves that they can generate a JWT signed by some particular public key, and it contains an email field in the payload with the given domain.
When the message is sent to the StealthNote server, the server verifies that the proof is valid as per the StealthNote circuit and validates that the public key in the proof is the same as Google's public key.
Once both checks pass, the server inserts the proof into the database, which then appears in the feed visible for other users. Other users can also verify the proof in the browser. The role of the server is to act as a data storage layer.
Stay up-to-date on Noir and Aztec by following Noir and Aztec on X.
It’s no secret that we’re at a pivotal moment for Ethereum.
Ethereum has come a long way since the publication of its white paper in 2014 and has matured in ways that allow us to move closer toward mainstream adoption. Now, with ZK technology and programmable privacy, we’re in a stronger position and better equipped to scale Ethereum and create the next generation of applications. ETHDenver is where this begins.
We’re showing up to Denver in a big way to celebrate the epic builders of Ethereum and a new dawn of applications with the second NoirCon and an immersive night at Meow Wolf.
Following the success of NoirCon 0 in Bangkok, which featured talks from Vitalik and leading privacy researchers, we're bringing the community together again in Denver on Monday, February 24th, 2025 to focus on practical application building.
Since the start of this year, we've seen massive adoption for applications built with Noir, such as Anoncast. The World Team shared their experience, calling Noir "a best-in-class robust and ergonomic tool for ZK developers," and, a number of new Noir Research Grants (NRGs) have been issued to enable privacy to come to AI and identity.
At NoirCon 1, you can expect hands-on workshops from teams actively building with Noir, technical deep dives on AI and privacy applications, real-world case studies of privacy-first development, and interactive sessions with the broader ZK community. In addition, we’ll have a few fiery panels, including zkVMs versus zkDSLs, hosted by Alice Lui, host of House of ZK, and featuring panelists from RISC Zero, Succinct, and Aztec.
With partners such as EigenLayer, BuidlGuidl, Starknet, and House of ZK, we’re excited to create an event focused on helping developers build actual applications.
See event details and sign up for NoirCon 1 here.
To celebrate the new dawn of Ethereum, we’re rolling out the red carpet at Meow Wolf, an interactive venue with artwork from over 350 local and international artists.
We’re encouraging maximum creativity and celebrating you – the builders of the next wave of innovative applications on Ethereum. Dress up fancy, funky, or wild. This is your opportunity to let your creativity shine and revel in the Ethereum culture we all know and love.
Explore Meow Wolf’s immersive space while enjoying cocktails, hors d'oeuvres, and music from an incredible local house DJ. We will have a silent screening of 1995’s Hackers starring Angelina Jolie, along with custom swag from Chipped that you won’t want to miss.
Spots for this event are limited and will be first come, first served. We encourage you to get there early and lean into the theme. A good outfit or costume may even get you to the front of the line.
Sign up for the Ethereum Ball here, and NoirCon 1 here, and let’s build the next generation of applications on Ethereum together.
Stay up-to-date on Noir and Aztec by following Noir and Aztec on X.
It’s been a big year for Noir, the universal language for zero-knowledge.
We made things official with GitHub and became an official coding language, cozied up with Vitalik at the inaugural NoirCon0 in Thailand, and now we’re making zero-knowledge proofs more accessible and powerful for developers worldwide with the Noir 1.0 pre-release.
Noir is an open-source, proving-system-agnostic language designed specifically for zk applications, which marks a significant advancement in zk app development.
Noir has quickly emerged as a developer favorite in the zk space, boasting over 600 GitHub projects, 900 stars, and 2,000+ VS Code extension installations. Its growing popularity stems from an emphasis on developer experience, featuring an intuitive Rust-inspired syntax that makes zk programming more accessible than ever. Leading projects like zkEmail, zkPassport, zkLogin, and Aztec Network are already leveraging Noir's capabilities to create innovative zk applications.
Noir was built with a clear vision: to be the most developer-friendly and versatile language for zero-knowledge applications. As a public good, it empowers developers to build on-chain and off-chain applications with confidence. Its proving system agnostic design means you have complete flexibility to use Noir with supported proving systems like Barretenberg, Halo2, Plonky2, or Groth16.
With privacy baked into Noir as a default, developers have full control over which aspects they want to expose with a simple pub keyword. No underlying knowledge of cryptography or complicated mathematics is required, and we’re starting to see more and more developers turn to Noir to build their privacy-focused applications such as AnonCast.
The 1.0 pre-release brings a comprehensive set of language features that make writing ZK circuits feel natural and intuitive:
We’ve already seen many incredible libraries developed by the community, but Noir also ships with its extensive library that includes:
The feedback is in – developers love Noir!
We’ve been relentlessly focused on delivering a world-class developer experience with an emphasis on providing tooling to speed up and simplify the development process.
Noir supports integration with different proving systems to cater for varying development needs in e.g. proving times, memory footprint, proof sizes for different applications:
This pre-release marks the beginning of Noir's journey to 1.0 and we're committed to ensuring stability and security through comprehensive audits before the full release.
Noir is more than just a language—it's a community-driven effort to make zero-knowledge proofs accessible to every developer. We invite you to:
The future of ZK development is here, and it speaks Noir.
In the ever-evolving landscape of digital privacy, the power of Zero-Knowledge Proofs (ZKPs) is revolutionizing how we protect and prove information. Noir, a leading language for privacy-first programmable privacy, is at the forefront of this innovation and is calling on you to help us enhance provable emails using Noir. This research campaign (NCR#1), running from August 8th - 25th, 2024 presents a unique opportunity to push the boundaries of privacy while creating novel solutions for secure email verification.
The rise of Programmable Cryptography and Zero-Knowledge Proofs offers unprecedented potential for trustless and private verification of information, cryptographically bridging data across silos. Imagine a world where you can prove ownership of an email address or an email received without revealing its content or personal details. This capability is not just a theoretical possibility, but a practical reality waiting to be unlocked through advanced research and development.
Aztec Labs has been a strong supporter of this vision, particularly with the ZK Email team's pioneering work. As a part of these continued efforts, we invite researchers, developers, tech enthusiasts, and anyone with creative ideas to propose a two-month research plan that explores ways to leverage Noir (and Aztec) to augment this work and its broader vision.
We’re looking for proposals focused on building end-user-oriented projects, including MVPs. Proposals focused on building developer tooling and technical/cryptography research are also welcome as long as their relevance to zkEmail is clear.
Multiple submissions are welcomed, however, to be considered, your proposal must meet the following criteria:
To participate, please head to our GitHub and submit your proposal using the following format:
Proposal submissions are open now and will close on August 25th, 2024. Our selection committee will pick two proposals that will receive up to US$40,000 in grants. Winners will be announced before September 5th, 2024, via GitHub Discussions and X.
Click here to get started on your proposal today.
We believe in the value of the real-world impact of top-tier research.
To ensure the security and quality of applying research outcomes, we’re onboarding audit partners to sponsor and provide auditing for the final implementations of selected proposals. Potential audit partners will be evaluated up to August 20th, 2024, and announced on GitHub by August 31st, 2024.
To learn more about how to get involved, please contact Savio or Lisa.
Join us in pioneering the future of privacy-first communication. Submit your proposal and be part of this transformative journey with Noir!
Aztec Labs is committed to enabling developers to build with ZK and unlock the full potential of this transformative technology. To that end, we built Noir, an open source Domain Specific Language for safe and seamless construction of privacy-preserving ZK proofs. We fund tooling, libraries, and applications that make Noir more accessible and enjoyable for developers.
Earlier this year, the Ethereum Foundation announced the first ZK Grants Round, a cofunded proactive grants round to encourage research and development for Zero-Knowledge proofs and standards for ZK L2s. Aztec Labs contributed US$150,000 to the US$900,000 prize pool alongside other projects such as Polygon, Scroll, Taiko, and zkSync. We sponsored this initiativeas a part of our commitment to support builders who are advancing ZK across dimensions including research, performance, tooling, and applications.
We were thrilled to see submissions to the ZK Grants Round from both new and existing Noir contributors. In this post, we want to highlight the ZK Grants Wave awardees for the Noir ecosystem to showcase what the community is working on and provide inspiration for how you could contribute.
Team: @eryxcoop, @manastech
Noir is back-end agnostic and its Arithmetic Circuit Intermediate Representation (ACIR) can be integrated with different proving backends. This project will enable Noir users to prove and verify their programs with Plonky2 technology, unlocking more possibilities to develop blockchain and ZK infrastructure with Noir. Meanwhile, it will also allow Plonky2 users to benefit from Noir’s developer-friendly abstractions, tooling, and growing sets of libraries, lowering the barrier of entry to the proving technology.
Team: @schaliasosvons, @theosotir
Noir abstracts away underlying cryptography so it’s accessible to a broader developer base. However, one risk of these abstractions is unintentionally leaking private variable information. This tool will apply static analysis, taint tracking, input generation, and SMT solving to detect privacy leaks in Noir program designs. Noir users can leverage this easy to use framework and debugging tool to identify, analyze and amend such leakages in their projects.
Team: @wz__ht
Performance benchmarking varies across different languages and proving systems. This project aims to produce benchmarking suites, articles, and a website that compares and informs developers about characteristics, performance, and tradeoffs between Noir-compatible and other proving backends in the ZK ecosystem.
Team: @wz__ht
Noir reduces barriers for developers to use ZK with its simple and familiar Rust-like syntax. But a solid developer experience is more than just language design. It also depends on a strong ecosystem of developer tooling. This project will offer treesitter grammars that unlock features like syntax highlighting and code formatting for the language in more development environments like Helix and Neovim – providing Noir developers with more flexibility and choice.
Team: Neoxham, Lakonema2000, @0x18a6
Noir tooling and libraries are created to support and enable application developers who solve problems using ZK. This team will leverage Noir to create an educational end-to-end example of verifiable Know Your Customer (KYC) with compliance checks, and provide onboarding guides to increase adoption of the application.
We are grateful to the Ethereum Foundation for coordinating the ZK Grants Round and to the teams who submitted proposals. We look forward to seeing how the Noir community leverages these tools and resources to build the next wave of ZK powered applications.
If you’d like to learn more about Noir, read our docs and follow @NoirLang for more contribution opportunities coming soon.
Kev Wedderburn is the father, architect, and team lead of Noir, a universal zero knowledge circuit writing language funded by Aztec Labs.
We're excited to bring you this interview and profile of the man and mystery behind the DSL creating a step-function change in the accessibility of ZK programs.
Alyssa: Hey Kev! Thanks so much for your time, I’d love to give readers a snapshot of your journey into web3 and Aztec Labs, as well as your focus on the Noir team.
Kev: Sure! Let’s jump in.
Alyssa: Can you start by sharing your web2 background?
Kev: Yes. I started out as a front-end developer, then moved into app development.
I built a social media site for books. Then, a janky music-sharing app that would check your playlist, then check my playlist, then if our playlists overlapped enough, it would recommend each of us songs on each other's playlist (this was before Spotify became Spotify I think).
Alyssa: How’d app development lead you to going full-time web3?
Kev: While transitioning to crypto, I made a tax app that scanned your bitcoin QR code and told you how much tax you owed.
From there, I started doing tutorial videos focused on smart contracts. I wanted to do one for a particular blockchain, and it turned out that they didn’t have a well-functioning wallet. So that’s actually what led to my entry into the web3 space. I didn’t end up finishing that tutorial, I just went on to build the wallet myself.
Alyssa: And this work led to your first formal web3 role?
Kev: Eventually, yes. While I was working on an improved wallet, I noticed the node that the original wallet was interacting with wasn’t that great either. So once the new wallet was finished, I moved on to creating a node in Golang (the wallet was also originally built in Golang).
After I finished the node, I got recruited by a privacy-focused project. And they asked me to build a node for their privacy network.
Once I dug deeper, it turned out they didn’t have a proving system. So then I started learning cryptography to implement a type of ZK proof called bulletproofs — state of the art at the time.
Alyssa: And you’ve primarily worked on privacy within web3 ever since, is that right?
Kev: Yes, I worked for several other privacy blockchains prior to Aztec, such as Monero. At Monero, I pivoted from implementing Bulletproofs to Plonk for increased proving speed, but noticed it was very challenging to program on top of Plonk.
The Plonk constraint system and proving system both have nice properties, but the UX was really bad. So Kobi Gurkan from Geometry Research, and Barry Whitehat from the Ethereum Foundation asked if I wanted to make a compiler — I guess they saw that I was pretty active within Plonk and cryptography in general.
Alyssa: Had you built one before?
Kev: At the time, I didn’t know much about compilers at all, so it was exciting to figure out what the compiler I’d build would look like, what other compilers were doing, and how to make a compiler with the safety guarantees needed for zero knowledge proofs.
That was the beginning of what we now call Noir, and I’ve been at Aztec since.
Alyssa: Wow, okay, so you’ve been with the Noir project since the beginning of Noir’s existence?
Kev: Yeah, exactly.
Alyssa: Amazing, congrats on all the progress you and the team have made. And what about getting into web3 in the first place? Was it through engineering, or your own interest in cryptocurrency? How did that look?
Kev: I first looked at Bitcoin in university, but was deterred by the codebase being challenging to read. But I wanted to learn Bitcoin and teach people about it. Back then, everything was a bit scammy. I even created a Bitcoin book…
Alyssa: Going back to Noir, how do you feel about the experience of learning the language you helped build? Is it intuitive for developers?
Kev: I can tend to over-criticize the things I do. But Noir’s in a solid place. There’s not much to really compare it to….there are other zkDSLs, but they give different guarantees for the most part. For example, Noir provides devs with a high-level language that aims not to sacrifice performance and safety, while Circom gives devs very little safety but allows them to do anything. There are pros and cons to both of these approaches.
The more control you give to a developer, the more powerful things they can do, but they can also easily make mistakes because the compiler is no longer holding your hand or stopping you from doing something potentially dangerous.
But yes, Noir is in a good place for developers to use. There’s still a lot we want to put into the language to make it comparable to common programming languages in terms of UX. But we’re well on our way.
Alyssa: And what about just being on the Aztec Labs team in general, and maybe even the Noir team within Aztec Labs? What’s that like? What do you enjoy about it?
Kev: The Aztec team is cross-functional and fluid, meaning that even though you’re on the Noir team, or the tooling team, or the engineering team, you can touch other parts of the stack. So that’s great about being at Aztec.
The fun thing about the Noir team in particular is that there are so many challenges we have yet to solve. We’ve solved quite a lot of them, but there’s still a lot we’re excited to work on like continuing to improve the UX, as I mentioned.
Alyssa: Love that answer as I know there’s a job opening on the Noir team, so someone joining can have exposure beyond understanding their specific role.
Kev: In fact, we encourage that, if you’re on tooling and you want to create something and the compiler just doesn’t seem to be fit to do what you want, feel free to start some print or tasks to modify the compiler. We’re always open to new ideas.
Alyssa: Really cool, that’s great. And what about beyond web3, any general interests or hobbies?
Kev: Generally speaking, I really like maths. I also used to sing and play guitar for quite a while, and I exercise a lot these days.
Alyssa: Thanks again for the chat, great learning a bit more about your work, Kev!
Kev: Thank you!
We think Noir has the best syntax, most modularity, and best ecosystem of any ZK language. But don't take our word for it.
Get started with Noir at noir-lang.org.
Today Aztec Labs is proud to announce that Aztec’s core circuits have been rewritten in Noir.
Aztec’s core circuits were previously written in C++. The circuits spanning private execution, public execution, and proof recursion are now in Noir. We didn’t undertake this decision lightly, but we made the call based on a single fact:
It was always our goal to achieve Aztec-Noir alignment, unifying our cryptography stack and making our code safer, simpler, and easier to audit.
We’re there now, in the era of unabashed Noir maximalism.
💻 You can find the open Noir circuit repos here.
The Noir circuits are merged and passing Aztec’s stringent protocol test suite–huge achievement for Noir as a language.
Writing your code in a domain-specific language (DSL) does not make it safer than writing it in a library.This may not be apparent – a DSL is just a language made for a specific problem. One could create a DSL that makes writing circuits easier, but does not improve on performance. One could even create one that makes writing circuits harder, but it’s very performant. Noir makes writing circuits easier and safer than our cpp library with little sacrifice to performance.
As a startup you want to be able to write code fast, but also safely. If you take too long to ship, you may just die. If you write code that is unsafe or brittle, you may lose the trust of your target audience.
We could say that all developers need to do better. Skill issue. However, this approach doesn’t scale beyond. Developers love to write smart, elegant, clever code, i.e. code that’s subject to bugs. In Noir, you need to opt into writing unsafe code.
So what’s wrong with using Barretenberg as a C++ library?
Nothing.
In fact, a library inherits a lot of adoption from its host language; a Solidity library can be picked up quickly by Solidity developers, for example.
Aztec’s constraint system library is written in C++, and while this allows developers to do anything they want, it also allows developers to do anything they want.
Developers need to be aware of quirks with C++ whenever they use Barretenberg. This can lead to subtle bugs due to the inherent compounding of quirks specific to C++ and quirks specific to the library. In other words, more gotchas or footguns.
Library writers also need to be careful because in some places they are reasoning about constraints. In other places, they are reasoning about unconstrained code or non-constraint system code.
The overarching problem here is that in order to write safe circuits, you need to be able to write C++ code and also be a good circuit writer. These are two different skill sets that Noir reduces to one because Noir is specifically designed as a circuit writing language.
In March, a team of cryptography engineers developed Aztec’s core cryptography circuits under the guidance of Aztec Labs CEO Zac Williamson. Developing in C++ required significant onboarding and technical overhead, including:
In the meantime, the Noir team has built a comprehensive toolchain that makes ZK development significantly smoother:
In addition to developer tooling like performance profiling, syntax highlighting, and auto-formatting.
With Noir, we built the fast and safe DevEx we wanted for ourselves, resulting in a full rewrite of all Aztec core circuits from C++ to Noir in less than a month of three engineers’ time.
Here’s a side-by-side code snippet comparison of our private kernelbase rollup circuit in C++ and Noir, highlighting the legibility and simplicity of Noir.
C++:
Noir:
Finally, Aztec Labs gets to more fully participate in Noir’s vibrant ecosystem.
The community continues to develop new tooling that improves code analysis. Developers building in the Noir ecosystem and discovering bugs continuously battle-test the compiler. And Aztec is now fully aligned with the many developers building applications and protocols on Noir.
We too would like to share in the fruits of the Noir community.
Noir maximalism is open-source maximalism.
While Noir is still Beta software and isn’t fully production-ready until it is audited, the language is progressing towards an implementation freeze by the first half of 2024, and a completed audit by the back half of the year.
🏗️ Start building with Noir at noir-lang.org.
In addition to basic optimizations required for the kernel circuit to run on low-powered mobile devices, we intend on integrating Noir with the arsenal of novel cryptography in our development pipeline:
Building Aztec in Noir has been a long time coming.
As a result of adapting our core circuits to Noir, testing a wide array of features, and having Noir code pass extensive test suites, we have dramatically more confidence in its stability.
The collaborative approach between our internal Aztec and Noir teams demonstrates a commitment to advancing the capabilities of zero-knowledge proof technologies in an integrated fashion.
Improving Noir now improves Aztec.
The truth of the matter is: you cannot escape potentially dangerous code.
You can still write unsafe code in Noir.
You can only move the responsibility of writing dangerous code to folks who are least likely to make a mistake. And with Noir, you make it Aztec Labs engineers’ responsibility to write compiler code and optimizations. And with our stack, we make it the cryptographers’ responsibility to write absolutely unhinged cryptographic proving systems.
You are free to rebuild all of this yourself in C++. But Noir makes it so you don’t need to.
Where we cannot help you is unsafe business logic. If your application was meant to choose a random number between 1 and 10 and it instead chooses a random number between 0 and 1, then that’s on you.
But that’s as it should be! That’s the sort of code that you should be responsible for, and Noir aims to make it such that that’s the only thing you are responsible for.
If that sounds good to you, you might consider making the switch, as we have.
⭐ Get started with Noir today at noir-lang.org.
Today we’re releasing NoirJS– a Javascript package for Noir developers who want to build real applications that generate zero knowledge proofs in the browser.
Web development within the Noir ecosystem has historically been, uhm, complex. Practically, that meant Noir developers couldn’t really build applications that ran in the browser. And we want people to build applications with our software!
A browser is an application used to access the World Wide Web and interact with Internet applications. It turns out most people like using browsers.
Before today, Noir didn’t really let you build applications that could run in-browser. Instead, developers were forced to run applications locally in a CLI.
In simple terms, that meant Noir couldn’t actually support real applications.
But now Noir does support applications with NoirJS.
The goals of NoirJS are simple:
Noir is a zero knowledge circuit-writing language that works with multiple crypto proving back-ends. That means the front-end (the language) remains the same but Noir can be modularized to support the latest and greatest in zero knowledge proving research.
We do this through the ACIR (abstract circuit intermediate representation). Learn more about the ACIR here.
NoirJS lets developers build around the core concept of client-side compute: the ability to harness user hardware–phones, laptops, tablets–through the browser in order to compute proofs of execution.
And client-side compute in turn allows for fully private and trustless blockchain systems.
…sound familiar??
That’s the core philosophy of Aztec–giving developers the tools to develop programs with private data and compute while remaining fully trustless.
In English: do blockchain things without anyone knowing! Cool, right?
And for developers’ convenience, NoirJS is packaged with Barretenberg–the same Plonkish backend used by Aztec Labs in the Aztec rollup. No need to go shopping for a proving system unless you like, really want to.
NoirJS does a lot of other things, too! Developers were previously burdened by the need to manage multiple components like `bb.js`, `acvm`, `noirc_abi`, and future components like `noir_wasm`.
But managing component libraries and balancing version compatibility is not our idea of fun.
To install NoirJS you simply run `npm i @noir-lang/noir_js` in your Javascript directory
Install your proving backend of choice (ahem, probably Barretenberg), and you’re good to go.
NoirJS handles all Noir dependencies, exposing them through one clean interface, allowing you to focus on building rather than fiddling with packages.
Here are some other advantages:
Immediate Access: Browser-based applications don’t require additional software, making it easier for developers to reach a wider audience.
Improved User Experience: By enabling Noir functionality in the browser, users can interact with applications in real-time. That means fast apps.
Enhanced Security: Operating in the browser allows for client-side cryptography, offering an additional layer of security for applications that require cryptographic proofs.
Developer Flexibility: NoirJS enables developers to build rich, client-side applications with cryptographic functions, providing a broader toolkit for web development.
Community Building: Browser-based Noir enables rapid prototyping and sharing among the developer community. This is especially useful for teams who focus on in-browser applications and use-cases.
In-Browser Tooling: NoirJS fits seamlessly with in-browser IDEs like VSCode for web, allowing for a streamlined development process in which Noir programs can be compiled and proven directly in the browser.
So to summarize, by bringing Noir to the browser, we’re:
Siiick.
Less development pain means more time for building new applications. Here are some use-cases we’re excited to see:
NoirJS lets you build real Noir applications that run in the browser. It also makes your life easy breezy beautiful CoverGirl.
If you don’t know what Noir is, read this announcement, scan these docs, and watch this video.
If you do know what Noir is, install NoirJS right now. Right now. Right now.
And if you end up building something cool, come ask us for money.
When we compute a ZK circuit we are not just executing some code, but proving that we have executed the code correctly.
Take a program that computes x + y = z. It’s not enough for a ZK program to simply output z, the program also needs to prove that x + y was executed correctly to arrive at the value z.
Producing the proof requires establishing constraints.
In other words, circuits are comprised of constrained functions–meaning ZK programs that generate proofs based on a set of constraints.
So why then, would you need a function with no constraints–an unconstrained function? You might think unconstrained functions would be unsafe, given their name–like taking the guardrails off of a ZK circuit. And you’d be right!
Circuit code without constraints can be “proven” to create any outcome! Rather than creating a proof that deterministically proves the validity of a piece of code, unconstrained functions allow you to execute code that would otherwise be very expensive or difficult to compute inside the circuit.
But being able to execute logic outside of a circuit is critical for both circuit performance and constructing proofs on information that is external to a circuit.
Generally, we want to use unconstrained functions whenever there's something that's easy to verify but hard to compute within the circuit.
An unconstrained function simply executes code as you would expect in a normal programming execution environment.
In this post we want to make sure that developers who are tapping into the performance benefits of unconstrained functions aren’t incorrectly implementing unconstrained functions in a way that leads to worse security for their programs. Incorrect usage of unconstrained functions could lead to bugs, and zk development overall is a newer, scarier paradigm. We want to make it easy for developers to use Noir to write performant and secure ZK programs, and unconstrained functions can help them optimize their circuits when implemented correctly.
Assuming proving divisions in ZK is costly while proving multiplications is easy, and we want to prove the computation of 100 / 5.
Proving 100 / 5 = x directly in ZK would be inefficient:
Instead, we might use unconstrained functions to optimize our circuits. A more optimized approach would involve:
1. Computing 100 / 5 = x in an unconstrained manner
2. Proving x * 5 = 100 in ZK
Here’s a way to optimize the same division operation:
Cautious readers however might notice both the code excerpts above yield approximately the same number of constraints in Noir’s abstract circuit intermediate representation (ACIR) given the optimization is simple enough to implement in Noir’s compiler.
The key intuition here is that in a ZK execution environment, proving multiplications is cheaper than proving divisions.
Given all Noir programs compile to an intermediate representation called the Abstract Circuit Intermediate Representation (ACIR), we can judge circuit optimization on both ACIR opcodes and the ultimate number of backend circuit gates.
This simple division case has 2 ACIR opcodes and 7 final backend circuit gates. The unoptimized version where we check assert(x == 20) has 3 ACIR opcodes and 8 final backend circuit sizes. Our optimization reduced the final backend size by one gate. Given this is a super simple example, let’s dive into a more complex case where the optimizations are more meaningful.
Colin Nielsen, developer in the Noir community wrote the following code for converting unsigned integers (uints) to u8 arrays, without the use of unconstrained functions.
👀 See Colin's Twitter + Github
Here's the unoptimized code:
This code has 91 total ACIR opcodes and a circuit size of 3,619. A lot of the operations in this function are already optimized away by the compiler (e.g., all the bitshifts turn into divisions by constants).
However, we can save a bunch of gates by casting to u8 a bit earlier. This automatically truncates the bitshifted value to fit in a u8, which allows us to remove the XOR against 0xff.
This is what the slightly-optimized code looks like:
ACIR opcodes generated: 75
Backend circuit size: 3,143
Already, this saves us ~480 gates in total, but we can do better.
This code is all constrained, so we're proving every step of the calculation using num. But in fact, we don't actually care about how we make the calculation, just that the computation is correct.
This is where unconstrained functions come in.
It turns out that truncating a u72 into a u8 is hard to do inside of a SNARK. Each time we do this operation to truncate down into u8, we lay down 4 ACIR opcodes, which get converted into multiple gates.
It's actually much easier to calculate num from out, rather than the other way around. All we need to do is multiply each element of out by a constant and add them all together, both of which are relatively easy operations to do inside of a SNARK.
So, instead of truncating u72 into u8, we can run u72_to_u8 as unconstrained function code in order to calculate out. Then, we can use that result in our constrained function and assert that if we were to do the reverse calculation, we'd get back num.
An example of what this looks like is below:
Total ACIR opcodes generated: 78
Backend circuit size: 2,902
This usage of unconstrained functions ends up optimizing our circuit even further and taking off another ~250 gates from our circuit!
We've ended up with more ACIR opcodes than before, but these are easier for the backend to prove (resulting in fewer gates overall). This is the beauty of using unconstrained functions – optimizing code that’s easy to verify but hard to compute within the circuit.
Put differently, unconstrained functions allow you to reformulate certain pieces of code that are easier to check than to execute directly in a ZK circuit.
Resources
For more on unconstrained functions, see this post by Tom French in the official Noir docs: https://noir-lang.org/docs/noir/concepts/unconstrained
Are you a developer interested in getting started with Noir?
Jump into the noir-starter Github repo and when you’re ready apply for a Grant–we’re currently supporting Noir use-cases through the end of 2023.
Today we’re announcing Aztec.nr, a powerful new smart contract framework for Aztec applications. Aztec.nr enables smart contract developers to intuitively manage private state.
In other words, Aztec now has a smart contract language.
👀 Explore the Aztec.nr Github repo here
Aztec.nr is a framework built on top of Noir, an open-source, universal zk programming language to which Aztec Labs is a core contributor.
Aztec.nr allows developers to write private smart contracts in Noir and extend their functionality with templated functions that simplify state management.
Last week we teased how simple and intuitive private state management would be on Aztec.
📕 Read the first post in this series: Privacy Abstraction with Aztec
Today we’re explaining how Aztec.nr works and showing how you can get started building smart contracts and full-fledged privacy-preserving applications on Aztec.
The Aztec.nr framework helps you deal with complex note management that is critical to privacy preservation within smart contract development.
But it does so in a way that makes it so that developers don’t have to rebuild smart contract functionality from scratch every time they write a Noir program.
Without Aztec.nr, you wouldn’t be able to emit events, make calls to other contracts, or even have the notion of a contract or an address. You’d have no msg.sender or access to historic blockchain.
Aztec.nr takes Noir — a general zero knowledge programming language — and gives it the smart contract functionality and syntax developers might expect coming from Solidity.
Developers can now access a complete set of smart contract features:
For examples of Aztec.nr at work, check out examples of:
At Aztec Labs we harbor two very strong beliefs:
The Aztec.nr framework is a major step in improving the developer experience for managing private state — functionality that “vanilla” Noir doesn’t have.
For example for a simple private token contract, Aztec.nr includes helper functions like:
In other words, the kinds of functions you might expect to call in a standard token contract!
Let’s walk through this private token contract to show you how Aztec.nr helps with abstracting private note management:
Follow along in the Github repo of our private token contract example here
Say Alice wants to send funds to Bob. Practically, she would have to aggregate all of the existing non-nullified notes they have of the asset she were sending, add up the values, and once she had enough notes to send the amount, create a change note to reconcile her balance.
For example, say Alice had two UTXO’s of 0.25 ETH each, and wanted to send 0.4 ETH to Bob. In order to spend the note Alice would have to sum the two 0.25 ETH notes together, nullify them both, and create a change note for herself of 0.1 ETH.
Thankfully, Aztec.nr makes it easy to manage notes. Take for example the decrement and decrement_by_at_most functions written by the Aztec Labs team for the private token example above.
Here’s how decrement_by_at_most works:
Follow along with the decrement_by_at_most example here.
1. Find notes to decrement. The function begins by getting some notes that add up to max_amount or less from the set of notes owned by owner.
2. Destroy selected notes. It then iterates over these selected notes and destroys them, adding their values to a variable decremented.
3. Handle Change: If the total value of the destroyed notes (decremented) is greater than max_amount, it creates a new note with the excess value (change_value) and assigns it back to the owner.
4. Return the Decrement: Finally, the function returns the total value that was decremented, which is stored in decremented.
The decrement example is a perfect showcase for how Aztec.nr makes it easy to manage notes and nullifiers with built-in get, insert, replace, and remove functions.
If a dev wanted to write this without Aztec.nr (as in, write it with “vanilla” aka non-smart-contract Noir), they would have to write their own Merkle trees to insert and prove membership of notes and support non-membership checks for nullifiers.
But as a developer, you don’t have to worry about rebuilding core privacy primitives — the Aztec Labs team has already done all of that work on your behalf.
You just focus on smart contract logic.
Soon, anon, soon.
We’ll soon release a local developer environment for developers to write and test Aztec smart contracts against a local instance of an Aztec node.
Developers will soon get a full-fledged development kit for building smart contracts and applications on Aztec, supported by Aztec.nr’s functionality.
But for now, you can preview what comes in the box.
➡️ Explore the Aztec.nr Github repo here
Start familiarizing yourself with Noir syntax, since Aztec.nr is simply a smart contract framework written in vanilla Noir.
To get started learning Noir, check out:
Finally, sign up for Aztec Labs’ developer e-mail list to stay apprised of all technical developments across Noir and Aztec:
To learn more about Aztec generally, keep up to date on our Discourse, where we discuss major protocol decisions like upgrade mechanisms and decentralizing sequencers.
Aztec Labs is on the lookout for talented engineers, cryptographers, and business people to accelerate our vision of encrypted Ethereum.
If joining our mission to bring scalable privacy to Ethereum excites you, check out our open roles.
And continue the conversation with us on Twitter.
Private voting is the “real-world” default, and for good reason! Public voting has been problematic for DAOs, creating things like 11th hour problems, vote coercion, and bandwagon effects.
When NounsDAO recognized the need for confidential governance within their own community, Aztec Labs and Aragon ZK Research (AZKR) joined forces to answer the call.
We have now published two final reports on our research results and what’s next for NounsDAO private governance.
🤖 Read the technical report here.
👪 Read the general report here.
In short, our proposal was to provide privacy-first governance, including:
Now, at the conclusion of this research sprint, we are presenting our findings in the form of both technical and general reports.
The Aztec team focused on implementing storage proofs in Noir, while AZKR explored the design and implementation of the voting solution powered by these proofs.
In practice, prove that you’re a Noun without saying which Noun you are, then use that proof to vote in the DAO.
The general report also details the primary research questions addressed. TL;DR:
You can review the code and general report for AZKR’s early roadmap for what is currently called zk-POPVOTE (zk Proof-based On-chain Private Voting), which is a continuation of the project we’ve started together.
🐦 Join the Twitter Spaces we’ll host on September 5th at 12:00 UTC here
At Aztec Labs, we will continue contributing to the development of the Noir programming language, and we look forward to building privacy-preserving infrastructure to empower private governance.
Aztec is a first-of-its-kind public-private hybrid zkRollup bringing together the best of Ethereum smart contracts and encrypted execution.
It is a culmination of Aztec Labs’ long-term vision: a collectively-owned, fully decentralized L2 on Ethereum with encryption as a first class citizen.
We at Aztec Labs are thrilled to be able to build this together with you, and we can’t wait to see you in the forum.
Aztec Labs is on the lookout for talented engineers, cryptographers, and business people to accelerate our vision of encrypted Ethereum.
If joining our mission to bring scalable privacy to Ethereum excites you, check out our open roles.
Brand new to Noir? Start building your application with the universal language of zero-knowledge, supported by best-in-class developer advocates and developer relations engineers at Aztec. Get started here.
Noir was designed to be developer-first. This means simple and familiar Rust syntax, and now the support of the world’s most popular code editor. In just a matter of weeks, the extension has gone from ~70 to nearly 400 downloads.
Even if you’re new to the language — you won’t feel like you’re learning to program again, you’ll just start programming in zero-knowledge.
The following features should sound very familiar:
Differentiate key words from each other with color.
There are safety checks built into the language that will prevent certain mistakes (and subsequently, unexpected behaviors) before you make them. Noir x VS Code will let you know what they are instantly on file save, before you switch to terminal and compile.
Save time and key-strokes by utilizing quick code templates. Insert code snippets instead of writing function definitions repeatedly.
As of the latest version of the extension (version 0.0.4), you can run Noir tests, compile and execute Noir programs — all just one click away.
v0.0.4 is best paired with Nargo v0.10.3. Install Nargo with `noirup -v 0.10.3` and try it out.
More features could be tackled like hover tooltip, auto formatting, and proving on click.
Want to contribute? Leave a message on the GitHub quest board.
Brand new to Noir? Start building your app with the universal language of zero-knowledge, supported by best-in-class developer advocates and developer relations engineers at Aztec.
Noir, the universal language for zero-knowledge applications, is now in beta.
Noir was originally created to solve the two-brain problem for ZK circuits: with previous zero knowledge DSL's, developers were required to understand basic cryptography in addition to reasoning about business logic. The way we described it was needing two brains:
After over a year of development since Noir’s alpha release, we’re ready to present a powerful version of Noir that is:
If you’ve thought about Noir but wasn’t sure about it’s stability, now’s the time to dive in. While Noir remains unaudited and we warn against production use-cases involving financial assets, we believe the DevEx and feature-suite are mature.
> Discover Noir with Noir Guardians
> Get started with Noir documentation at noir-lang.org
Noir has never been more fun or usable for writing games, identity solutions, and much more that allow for privacy on-chain:
Noir is designed to be familiar to a wide swath of developers, which is why it’s based on Rust. You won’t feel like you’re learning to program again, you’ll just start programming in ZK.
Abstract Circuit Intermediate Representation (ACIR) allows for multiple crypto-providing backends. Noir is Aztec network friendly, not Aztec network only. Plug into any crypto backend you’d like.
awesome-noir boasts a collection of core cryptographic primitives written by best-in-class cryptographers. Take advantage of what your fellow devs have already built, then pay it forward with your own contributions.
Versioned releases: Noir comes released with numbered versions, providing its users the flexibility to choose and settle on a certain snapshot of the language and freeing developers’ minds from the need to constantly keep track of breaking changes. Refer to GitHub to learn more.
Continuous integration testing: Noir is developed with a comprehensive set of integration tests that minimizes the probability of unintentionally breaking existing features with new features. Refer to GitHub to learn more.
Over the development cycles since Alpha, numerous features were introduced to the Noir language and Noir's tooling, including but not limited to:
UltraPlonk Integration: The UltraPlonk proving backend by Aztec enables fast proving speeds and gives Noir developers access to natively optimized gadgets like Keccak256 and ECDSA signature verifications. This unlocks a variety of use-cases such as ECrecover, Ethereum Storage Proofs, and zkWebAuthn. Read the announcement to learn more. While UltraPlonk is the default, Noir supports integration with any backends where the community has been developing integrations with the likes of Halo2, Gnark, etc.
NoirJS: A Javascript package for building privacy-preserving applications that work in web browsers. This major milestone essentially means you can build user-ready web apps with Noir. Read the announcement to learn more.
Unconstrained Functions: Noir supports the development of unconstrained functions using the same language syntax. This means developers can define and write computations that execute outside of circuits, enabling more highly optimized circuits and programs. Read the announcement to learn more.
VS Code Extension: This extension helps developers write, understand, and improve Noir code with features such as:
Read the announcement and download the extension to start using it.
Extended Grammar: From basic control flow like if-else and for-loops to composite data types like structs and traits, Noir supports a wide set of syntaxes that you may expect coming from other programming languages to ease developers building their zero-knowledge applications. Read the Noir docs to learn more.
Standard Library: Re-use trusted and efficient implementations of common primitives without re-implementing cryptography from scratch. Noir comes with a comprehensive standard library covering primitives for hashing, signature verification, merkle proofs, elliptic curve arithmetics, etc. Developed by world class engineers from Aztec Labs and the Noir community, importable right off the shelf. Read the documentation to learn more.
A Noir workflow consists of three stages: Compilation, Execution and Proving.
Compilation is where the user’s program is converted into a sequence of Abstract Circuit Intermediate Representation (ACIR) opcodes for execution and proving that follows. This is done by the Noir compiler, designed with effective circuit optimizing logic and fast compilation.
Execution is where each opcode is executed and the values that each opcode produces is saved, generating proof inputs for proving that follows. This is done by Noir’s Abstract Circuit Virtual Machine (ACVM), a component within the Noir stack.
Proving is where the saved values along with the sequence of opcodes is sent to a proving backend, which generates a proof of the program being executed with said input values. This is done by the proving backend of choice.
Noir enables developers to write, test and compile optimized circuits easily, where they are then handed over to a proving backend of developers’ choice for blazinging fast proving. The default proving backend is the UltraPlonk-based Barretenberg developed and maintained by Aztec Labs.
A quick reference of proving times of common Noir primitives are detailed as below:
A Noir user flow typically starts from developers compiling and distributing the compiled artifacts as a part of their applications to users, where users then execute the application and prove their execution. Execute and Prove times combined hence represent what application users are expected to experience when interacting with applications built with Noir.
Note that execution times depend largely on the Noir stack, while circuit sizes and prove times depend largely on the proving backend of choice. The results were gathered using Noir v0.21.0 paired with the default UltraPlonk-based Barretenberg proving backend on M3 Macbook Pro.
UltraPlonk-based Barretenberg contains small fixed costs for circuits that are amortized in complex circuits. For example, a Noir program doing 1 Keccak256 hash has a circuit size of 55k constraints, while a program that does 100 Keccak256 hashes has a circuit size of 1.8m constraints, rather than 5.5m constraints. This also applies when primitives are mix-and-matched, not just when the same primitive is used at scale.
Expect different results if a different proving backend is used, or when Barretenberg undergoes a significant change (e.g. upgrading from UltraPlonk to UltraHonk).
As a general reference for cross checking performance of Noir programs not listed above, the compilation, execution and proving times for Noir programs spanning different circuit sizes are detailed below:
The Noir technology stack is the main contributor to compilation and execution times, while the proving backend of choice is the main contributor to proving times.
The benchmarking results were gathered using Noir v0.21.0 paired with the default UltraPlonk-based Barretenberg proving backend on M3 Macbook Pro. Refer to Github for more benchmarking details.
Noir is now entering its Beta phase of maturity for developers to start building applications and projects using the language, but that is far from being the destination.
On the road towards production, a vast amount of effort around language features, tooling additions, performance improvements, security audits are continuously being sketched out for the exciting year to come.
If you have been considering developing a Noir project, now is the prime time to start building with the Noir community towards production and launch alongside Noir 1.0.
We’re proud and excited for you to build with Noir Beta as we have ourselves.
We at Aztec Labs have recently completed rebuilding the entirety of Aztec network’s protocol circuits in Noir (read the announcement to learn more). This is the time for your users to experience on-chain privacy via gaming, voting, identities, and so much more.
Learn Noir on Node Guardians today and check resources and projects on Awesome Noir to get started.