An introduction to AZTEC

An Introduction to AZTEC

This article is in English, you can read a Mandarin(中文) translation here.

This is the first in a series of articles designed to help developers understand the core concepts of AZTEC and walk through the steps required to build a confidential loan dApp using AZTEC. It is assumed the reader has a good knowledge of web development and a working knowledge of solidity.

This series is split into 4 parts:

Part 1 — An introduction to AZTEC

Part 2 — Deploying AZTEC on Ganache

Part 3 — Constructing Proofs, Signing Flows and Key Management.

Part 4 — Creating, Settling, & Streaming Confidential Assets

Before explaining what AZTEC is and how it works, it is important to first understand why it exists.

One of the much heralded uses of a blockchain is encompassed by the phrase “programmable money” — a smart contract controlling the movement of capital inside a financial application. e.g. A bond transfer will only process if the buyers total position is less than a 4% regulatory limit. If this can be achieved, large swathes of the financial system can be rebuilt on top of public blockchains and in the process remove intermediaries, end reconciliation and delete counter-party risk. Using the Ethereum blockchain today, it is straightforward to create “programmable money”. However there is a problem — privacy.

The inputs and outputs of any blockchain transaction are publicly broadcast inside the transaction payload.

In the bond transfer example, the notional being traded and a traders current position would have to be broadcast, in order for a smart contract to validate the trade complies with the the 4% regulatory limit. This is a non-starter for real world financial applications in where transaction privacy is a pre-requisite.

The AZTEC protocol was created to enable privacy on public blockchains. It enables logical checks to be performed on encrypted values without the underlying values being revealed to the blockchain. The inputs and outputs of a transaction are encrypted using a series of zero-knowledge proofs and homomorphic encryption, yet the blockchain can still test the logical correctness of these encrypted statements.

Under the hood

The validation of traditional Zero-knowledge systems on Ethereum is unworkable. This is due to a combination of on-chain verification gas costs, slow proof construction, and a lack of interoperability between assets. The lack of interoperability and inability for proof construction to run on a clients browser make these systems unsuitable for use in real world financial applications. One of the largest costs inside a Zero-knowledge system is the range proof. A range proof allows the prover to prove to a verifier, that a number is within a specific range. This is critically important when dealing with addition of elliptic curve points. On an elliptic curve, a negative number is in fact a very large positive number and a range proof is used to ensure that any point is within a usable range and to prevent double spend attacks by wrapping around the modulo. AZTEC’s range proof utilises a trusted setup to drastically reduce the cost of this check.

Once an encrypted number is proven to be inside the usable range the additive properties of an elliptic curve allow logical checks to be performed on it. This concept known as homomorphic encryption allows logical checks to be carried out on encrypted numbers as if they had not been encrypted. i.e the same checks can be performed as in a public transaction but without ever revealing the underlying values of the encrypted numbers.

These two cryptographic methods are combined into a set of sigma protocols that allow specific logical statements to be validated on chain. If you would like to find out more about the cryptography underpinning the protocol, please read the white-paper.

AZTEC’s Mental Model

AZTEC follows a UTXO model similar to that of Bitcoin. The core of any AZTEC transaction is a Note. The state of notes are managed by a Note Registry for any given asset.

The user’s balance of any AZTEC asset is made up of the sum of all of the valid notes their address owns in a given Note Registry.

AZTEC’s UTXO model

Public blockchains offer two main benefits, an independent economic guarantee around the correctness of state and interoperability of capital. (The capital received as an interest payment for a loan can also be used to settle a trade for a different asset). Most Zero Knowledge systems lack this interoperability. They create siloed pools of private capital. AZTEC is designed to solve this. It allows interoperability between dApps interacting in zero knowledge.

To achieve this interoperability, all AZTEC assets share a common trusted setup and their state is managed by a single smart contract, the AZTEC Cryptography Engine or ACE. ACE has two primary functions; first to delegate the validation of proofs to specific validation contracts and secondly to process state update instructions inside note registries that result from the successful validated proofs.

1kBQuG0z7Bnd1oFK tCoTpA
AZTEC Architecture

A set of building blocks to enable privacy

The AZTEC protocol is designed to offer dApp builders a set of modular building blocks, each enabling a specific piece of functionality. A developer can compose together these building blocks to build a private dApp, without the need for a cryptographer. Under the hood these toolkits are Sigma protocols that prove a relationship between the supplied input and output notes. Currently AZTEC supports 7 of these toolkits:

Join Split (Transfer)

The Join Split proof allows a set of input notes to be joined or split into a set of output notes. Usually this is used to combine note values into a larger note, or split a note into multiple notes with different owners. This proof ensures that the sum of the input notes is equal to the sum of the output notes.

There are also two variants of the Join Split transactions that are used to deal with public ERC20 values. One in which a public ERC20 value is converted into an AZTEC note and it’s reciprocal, where an AZTEC note is converted into a public ERC20 value.

Bilateral Swap (Trade)

The bilateral swap proof allows an atomic swap of two notes to take place. This is useful for trading two assets e.g fiat and a loan/bond/security. A validated proof, proves that the makers bid note is equal to the takers ask note and the makers ask note is equal to the takers bid note.

Dividend Proof

This proof allows the prover to prove that the input note is equal to an output note multiplied by a ratio. This is useful for paying interest from an asset.


The mint proof allows the supply of AZTEC notes to be increased by a trusted party. e.g a stable coin mints an AZTEC note equal to the value of a bank transfer it receives.


The burn proof allows the supply of AZTEC notes to be decrease by a trusted party. e.g a stable coin burns an AZTEC note of equal value of the bank transfer it sends to the note owner.

Private Range

This is used to prove that an AZTEC note is greater than another AZTEC note or vice versa. This is useful for proving that ownership of an asset post trade is below a regulatory maximum. It can also be used to build identity and group membership schemes.

Public Range

Similar to the private range proof. This is used to prove that an AZTEC note is greater than a public integer or vice versa. This is useful for proving that ownership of an asset post trade is below a regulatory maximum.

Privacy, Anonymity and Confidentiality

These terms are often used when discussing zero-knowledge systems. It is important to define the meaning of each and address how AZTEC handles them.

Privacy: all aspects of a transaction remain hidden from the public or third parties.

Confidentiality: the inputs and outputs of a transaction are hidden from the public but the transaction parties remain public.

Anonymity: the inputs and outputs of a transaction are public but the transaction graph is obscured from one transaction to the next, preventing the identification of the transaction parties.

AZTEC enables confidential transactions out of the box. The inputs and outputs of any transactions are represented as encrypted numbers and the value hidden from public view.

Using normal Ethereum addresses the transaction graph of AZTEC is not anonymous. However anonymous transactions are possible. The protocol is forward compatible stealth addresses and as AZTEC does not mandate the transaction sender to be a party in the transaction, the transaction graph can be hidden. Combining stealth addresses and a trusted party to relay transactions achieves full anonymity. Using a trusted third party hides the payment of gas and provides full anonymity. Future updates to the protocol will allow the relay of transactions whilst obscuring the payment of gas in a decentralised manor. At that point fully private transactions will be possible.

Creating Confidential Assets

EIP1724 aims to standardise the interface for interacting with confidential assets that conform to a UTXO based models. AZTEC has reference implementations of EIP1724 for the supported asset types in the @aztec/protocol NPM package.

The EIP 1724 ZkAsset Standard

Let’s look at an example:

Imagine the dApp in question needs to perform a logical check to ensure that a traders post trade asset balance is less than a regulatory maximum.

In a normal dApp, this check is simple to perform. The transaction inputs would contain the public variables tradeNotional. The contract could then perform a simple check ensuring the new assetBalance[buyer] is below the regulatoryMax .

if(regulatoryMax > tradeNotional + assetBalance[buyer]) {
// the trade can proceed

In a private AZTEC dApp, the same logical check can be performed using one of the AZTEC proofs. The mental model is slightly different as all of the variables are stored as encrypted AZTEC notes, then a proof is constructed, which if validated by ACE, ensures the desired logical statement is correct.

In this example the Private Range Proof is used.

const {
} = await aztec.proof.privateRange.encodePrivateRangeTransaction({
originalNote: regulatoryMax,
comparisonNote: postTradeUserBalance,
senderAddress: accounts[0],

This proof proves that the comparisonNote is less than the originalNote . If the values are swapped it would prove the opposite. Once the proof is constructed it can be relayed to ACE for validation.

(bytes memory _proofOutputs) = ACE.validateProof(
// if the above statement succeeds we know that the users post trade balance is below the regulatory minimum.

AZTEC is designed to allow the combination of these logical checks to build the complex flows required by financial dApps. The later parts of this series will cover detailed examples of these complex flows.

That’s it for Part 1, you can read Part 2 — Deploying AZTEC to Ganache here.

Thanks for reading!