Announcing Noir Beta: Stabler, Faster ZK Applications in the Browser

A Follow Up to Noir’s Hit Debut Alpha from 2022

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:

  • A cryptography brain to understand proving systems, trusted setups, and some low-level cryptography
  • An app development brain to reason intuitively about public and private state to create novel blockchain applications

After over a year of development since Noir’s alpha release, we’re ready to present a powerful version of Noir that is:

  • Significantly more stable
  • Offers hand-in-glove compatibility with Aztec’s UltraPlonk proving back-end
  • Is browser compatible via NoirJS, a Javascript framework for web applications

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

Why Noir?

Noir has never been more fun or usable for writing games, identity solutions, and much more that allow for privacy on-chain:

Noir is Simple.

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.

Noir is Flexible. 

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.

Noir is Open. 

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. 

Stability 

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.

The Future Features

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:

  • Code snippets
  • Auto-formatting
  • Error diagnostics
  • Performance profiling

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.

Performance for developers and users

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.

Benchmarking Primitives

A quick reference of proving times of common Noir primitives are detailed as below:

PrimitiveCircuit Size
(UltraPlonk Barretenberg)
Execute + Prove Time (s)
keccak25655,0001.957
keccak256
(100 times)
1,800,00057.538
ecdsa_secp256k135,0002.168
compute_merkle_root
(depth 4)
29,0001.177
compute_merkle_root
(depth 32)
30,0001.231
verify_proof250,0008.448
storage_proof_depth_81,700,00051.757
rsa3,000,000189.772

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).

Benchmarking General Programs

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:

bjwkB6uPboLg2sVPDPBCt7Io3IIWQxxXOMBx bKH87abeGEciAXIGBWotEzedfiDCmRSgfitNWfwSZV3ntPRWdAtTW2d08tC5kT0SC7nOSFVnE4B0fe X2fsfoAoi0IIPXdMIjtXBy02dUSsD7of72c
Backend Circuit Size
(UltraPlonk Barretenberg)
Compile Time (s)Execute Time (s)Prove Time (s)
2^14, i.e. 16,3840.3750.4501.069
2^15, i.e. 32,7680.6690.5991.791
2^16, i.e. 65,5361.4400.8903.379
2^17, i.e. 131,0722.1221.5056.581
2^18, i.e. 262,1445.2862.71413.029
2^19, i.e. 524,28811.0405.24526.011

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.

What’s next

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.

xj84hBZ8OfObv 4W SXyxsgaZZdQl x4Q3eZNCt1h1ao4e2tPY1A6pc8Cfuatv6N3osmHuhijcyDX3jBSSUXSX7jWXcF3FXoqMQ6LQL tlANLL8kyP5UhsCF JID6FF6Gzxj63FLfxCUPimSd 1ldd0

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.

In Conclusion

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.