How does FHE address the compliance and programmable privacy issues raised by a16z?
Title: Programmable Privacy and Onchain Compliance using Homomorphic Encryption
Author: Rand Hindi
Compiled by: Luccy, BlockBeats
Editor’s Note:
On September 19, a16z's crypto team posed seven questions in the Nakamoto Challenge, namely: limitations of atomic composability and shared sequencing, DePIN verification, JOLT + Lasso problem, compliant programmable privacy, optimal LVR mitigation, designing MEV transaction supply chains, and utilizing blockchain for Deepfake protection.
For the compliant programmable privacy issue, the open-source cryptographic tool Zama proposed a solution: Fully Homomorphic Encryption (FHE) or the fhEVM confidential smart contract protocol. fhEVM provides developers with a new way to build compliant programmable privacy applications on-chain by enabling computation on encrypted states.
Decentralized Identifiers (DIDs), as issuers of digital identities, are stored in encrypted states, achieving a win-win for user identity privacy and programmable compliance. By defining token transfer rules between individuals through regulatory contracts, dynamic oversight of transfer conditions is realized. This design enforces regulatory provisions at the smart contract level without hardcoding, allowing users to ensure application compliance with just a few lines of Solidity code.
Zama's CEO Rand Hindi demonstrated in the article how to build a compliant ERC20 token using fhEVM, abstracting identity through on-chain DIDs. He pointed out that, compared to other privacy solutions, all data and computation in fhEVM occur on-chain, ensuring composability and data availability.
A few months ago, a16z's crypto team released the Nakamoto Challenge, a list of the most important problems to solve in blockchain. Among them, the fourth question particularly caught our attention: "compliant programmable privacy," as we have been actively thinking about this issue. Today, we present the first solution using homomorphic encryption and the fhEVM confidential smart contract protocol.
fhEVM is a regular EVM that includes some precompiles, allowing computation on encrypted states using our TFHE-rs homomorphic encryption library. From a developer's perspective, there is no involvement of cryptography; they only need to write Solidity code using the encrypted data types we provide (euint32, ebool, etc.). A significant advantage of fhEVM over other privacy solutions is that all data and computation occur on-chain. This means you can achieve the same composability and data availability as conventional plaintext contracts.
This feature is crucial for building programmable privacy, as all access control logic can be defined within the contract itself. There is nothing that needs to be hardcoded in the protocol, and users do not need to perform any off-chain operations to ensure compliance. Applications can enforce compliance directly with just a few lines of Solidity code.
In this article, we will demonstrate how to build a compliant ERC20 token using on-chain DIDs. The source code for this tutorial can be found in the examples folder of the fhEVM repository.
Identity Abstraction through On-chain Confidential DIDs
Decentralized Identifiers (DIDs) are unique digital identities issued by entities such as governments, registries, companies, or the users themselves. This DID can be bound to a cryptographic key that proves the user owns the DID, such as an EVM wallet. However, it can also store a range of attributes, such as the user's age, nationality, social security number, etc. These attributes can, in turn, be used to prove that you meet certain conditions (referred to as "proofs"), such as being over 18 or not being a citizen of Narnia. Issued by entities like governments, registries, companies, or the users themselves.
Most DIDs are actually implemented on the user side, utilizing zero-knowledge proofs to generate proofs. While this is feasible in many cases, it becomes complicated when multiple users are involved in transactions, requiring complex rules to be applied to DIDs, or when everyone needs to adhere to a common set of rules. This is essentially similar to the trade-off between edge applications and cloud applications.
However, having a centralized DID registry can solve these issues, as you can simply ask the registry to check whether everyone complies with the regulations. This would also simplify regulatory tracking, as you only need to implement it in one place. The blockchain would be the ideal infrastructure for this, as it would allow for composability between DIDs and applications that need to comply with regulations, as well as composability between regulations. This is essentially similar to the trade-off between edge applications and cloud applications.
The problem: Everyone will see everyone else's identity!
Fortunately, we have a solution: homomorphic encryption, more specifically, fhEVM! With the ability to have composability on encrypted states, we can host users' DIDs directly on-chain in encrypted form and allow compliant applications to verify attributes through simple contract calls. The ability to manage identity through smart contracts is what we call "identity abstraction," similar to how funds are managed through smart contracts with account abstraction.
This tutorial is divided into three parts:
Identity Abstraction is implemented through a registration contract that manages identities and proofs. Here, we assume that DIDs are official government IDs. The registry itself is managed by a central authority (e.g., AFNIC), which can create registrars (e.g., KYC companies like Onfido, Jumio, etc.), and then registrars can create user DIDs. Users then manage and update their DIDs through their registrars.
Regulation is defined in a contract that encodes the rules for token transfers between individuals based on the information contained in the user DIDs. It essentially enforces regulation at the contract level rather than at the user level.
Compliant Confidential Transfers are implemented in a compliant ERC20 contract that uses regulatory contracts to enforce the compliance of token transfers without making any changes to the ERC20 API itself. In this example, we use a confidential ERC20 contract where balances and amounts are hidden, but it is equally valid for a conventional plaintext ERC20 token.
Identity Registration Contract
The identity registration contract is a registry that issues user DIDs by registrars and contains a set of encrypted identifiers such as nationality, age, social security number, etc. These identifiers are stored as encrypted 32-bit values (euint32).
The contract also handles permissions, including:
- Allowing the contract owner (e.g., AFNIC) to add, remove, or update registrars.
- Allowing registrars to add, remove, or update the user DIDs they create.
- Allowing users to grant smart contracts access to specific attributes of their DIDs. It is important to note that users are responsible for not granting access to malicious contracts, just as they are responsible for not allowing malicious contracts to spend their tokens.
The first step is to implement the logic for creating and managing DIDs:
Note: The image is a partial screenshot; the complete code can be viewed in the original text.
The next step is to implement the logic for identifiers and access control.
An identifier is simply a string (e.g., "date of birth") and an encrypted 32-bit value. It can only be created or updated by the registrar. Users cannot create their own identifiers because we want them to be certified by the registrar.
However, since the identifiers are encrypted, users need to grant the contract access to specific values, which we will handle through a simple access control mechanism, similar to how you can allow a contract to spend your ERC20 tokens.
Note: The image is a partial screenshot; the complete code can be viewed in the original text.
Now we can complete our identity registration contract by adding the necessary getters, some conditions, and error handling.
Note: The image is a partial screenshot; the complete code can be viewed in the original text.
Regulatory Contract
The next step is to create the regulatory contract.
When implementing transfer rules between two individuals, it is important to recognize that these rules may evolve over time. Having a single smart contract to define all regulatory provisions for a given context (such as fund transfers) means that the ERC20 contract does not need to track regulatory provisions itself. The government only needs to update this contract, and it will automatically propagate to all tokens that implement it.
At its core, the regulatory contract is just a set of conditions that match encrypted identity attributes. To prevent abuse, users do not grant access directly to the regulatory contract; instead, they grant access to the ERC20 token contract, which then performs delegated calls to the regulatory contract. This approach ensures that only ERC20 contracts trusted by the user can access their information. Remember, before a transfer occurs between the sender and receiver, both must have granted permission to the ERC20 contract.
In this example, we will implement some basic rules:
- Domestic transfers are unrestricted, but the limit for transfers to foreign entities is 10,000 tokens.
- Blacklisted users cannot transfer or receive tokens.
- Users cannot transfer tokens to blacklisted countries.
Instead of failing the transaction, which may leak sensitive information if one of the conditions is not met, we will simply set the transfer amount to 0. This uses a homomorphic ternary operator called cmux: value = TFHE.cmux(encryptedCondition, valueIfTrue, valueIfFalse);
Note: The image is a partial screenshot; the complete code can be viewed in the original text.
Compliant Privacy ERC20 Contract
Now that we have the identity registration and regulatory contracts, we can finally create the compliant, privacy-protecting token contract. This contract will be called CompliantERC20 and will have the following key features:
- User balances and transfer amounts are encrypted.
- Compliance is enforced by calling the regulatory contract during transfers.
- Visibility of certain balances can be granted to whitelisted addresses (e.g., regulatory bodies).
Note: The image is a partial screenshot; the complete code can be viewed in the original text.
The regulatory contract can be called simply. This means that users must provide access to the ERC20 contract before initiating any transfers; otherwise, the transfer will be rolled back.
Finally, we can now create our ERC20 contract:
Similar to how users grant DeFi protocols permission to spend their tokens, they need to grant the contract access to the identifiers required by the regulatory contract. This is achieved by calling Identity.grantAccess(contractAddress, identifiers), which can be retrieved by calling the ERC20.identifiers() view method. This list comes directly from the ERC20Rules contract to allow for attribute updates.
Compliance and Privacy Can Coexist
Establishing compliance is not difficult if the right tools are available. While we initially built fhEVM to achieve privacy on the blockchain, we quickly realized that this technology could be used for identity management, thus enabling programmable compliance.
This design is still far from perfect, but we believe it can continue to improve and be launched as a real use case, making compliance no longer synonymous with regulation.