# Halo: A privacy layer for stablecoins 

By [Madhav Goyal](https://paragraph.com/@madhavg) · 2026-01-03

---

  

* * *

Abstract
--------

Halo is a privacy layer for stablecoins unlocking the next private neobanks and applications that were blocked by the lack of anonymity and confidentiality of networks. **Halo Network** introduces a new extension a a **privacy-preserving EVM chain purpose-built for stablecoin use cases**. Halo combines the **familiarity and composability of the EVM** with the **confidentiality of a UTXO-based privacy layer**, allowing users to transact and build privately without sacrificing interoperability or liquidity.

Introduction
------------

Privacy has been one of the afterthoughts but long standing problem in crypto, especially for an industry whose biggest pmf is payments and savings. While blockchains have revolutionized how value moves across borders, their transparency has come at a big cost: every transaction is publicly traceable, every balance is visible, and putting the targeted parties especially the core users of stablecoins → citizens in unstable economies in danger.

To fill this gap, users have relied on **centralized exchanges (CEXs)** as neobanks using them to hold and move stablecoins. These Exchanges are themselves prone the changing regulation landscape of different countries and the reliance on custodial intermediaries reintroduces the very risks blockchains were designed to eliminate: censorship, surveillance, opaque operations, and counterparty dependence

At the same time, **stablecoins** have emerged as crypto’s biggest product market fit → the digital equivalent of internet-native dollars. They have become the backbone of global crypto activity, powering remittances, commerce, and on-chain savings at a scale that now rivals traditional payment networks. Yet despite their adoption, stablecoins today operate on fully public rails, making privacy and confidentiality virtually impossible. Although a wide range of on-chain products attempt to provide varying degrees of privacy for users, **most suffer from fundamental trade-offs that compromise usability, composability, or economic feasibility**. Many of these systems achieve privacy only by isolating themselves from the broader EVM ecosystem → introducing new virtual machines, custom asset standards, or complex transaction formats that degrade user experience. Others rely on heavy cryptographic operations that make transactions slow, expensive, and impractical for everyday payments. While interacting with some thru public wallets can be of future concern and regulation.

Most of the tradefoffs

1.  Single state → Current prevelant method of introducing privacy is splitting the state in two and running one private state and second public evm state where most of the private ops occur as you guessed on the private state. This draws a big amount of flaws
    
    1.  Wallet → Its breaks wallet composability where either the user downloads a new wallet for the chain and manage a new private key
        
    2.  EIP delegation → or delegate their signing keys to a smart wallet which is the motherload of scurity issues.
        
2.  Client Side Compatbility → Users should be able to transact with just their metamask and not have either the need to donload a new walet or extension like metamask snap.
    
3.  Composability → being evm is just not about ethereum mainet but opening up privacy to the whole suite of applications built for ethereum with minimal changes.
    

These were some of the core design principles while Building Halo: A privacy layer focused on stablecoins supporting confidential balances transfers and multiple operations unlcoking a new suite of defi applications

In practice, this means that while privacy-preserving protocols exist, **none have managed to deliver a seamless, composable, and cost-efficient experience comparable to mainstream EVM networks**.

**Halo Network** was designed to address this structural gap.

Architecture and Design philosophy
----------------------------------

Halo design works backwards from focusing on

*   **Security →** Introducing newer ayers adds more security security and escape risk, Halo uses Polygon agglayer to allow exit hatches. This allows users to take their funds out even if the node is not responding by forcing txns on the l1.
    
*   **Composability** → Composability is the defining feature of the Ethereum ecosystem — the ability for applications to interoperate trustlessly, share liquidity, and build upon one another like money legos. Most existing privacy solutions sacrifice this by introducing custom virtual machines or new smart contract languages, making it impossible to leverage existing EVM codebases or DeFi primitives. Halo preserves **full EVM composability**, allowing any existing Ethereum-compatible contract, stablecoin, or application to be deployed without modification. Developers can integrate privacy into existing protocols with minute changes rather than rewriting them for a new stack.
    
    *   This also implies the need for a single shared state.
        
*   Wallets: The first point of interaction with any network onchain is a wallet, Most of the current privacy layers end p breaking the UX . Most privacy systems require specialized wallets, custom transaction formats, or new signing standards that alienate users and slow adoption. Halo eliminates this friction completely . Users interact with Halo through the same interfaces they already trust, such as **MetaMask, Rabby, or Frame**, using standard EIP-7702 authorization flows. This allows any user familiar with Ethereum to access private functionality on Halo instantly, without switching networks or learning new tools.
    

Halo Architecture
-----------------

The core idea is to keep as much as possible in house and relying on other networks ie TEEs,MPCs as low as possible.

*   **Public State (EVM account model)** — Standard Ethereum which is a Merkle Patricia Trie storing account balances, contract code, and storage. When you interact with public DeFi protocols, swap tokens on a DEX, or use any standard EVM operation, you're operating in this layer. It's fully composable, fully transparent, and fully compatible with every existing Ethereum tool.
    
*   **Encrypted balances** — We store encrypted balances directly into the ethereum state. These aren't stored in a separate UTXO tree or parallel VM they live in standard `SSTORE` slots, visible on-chain but cryptographically meaningless without decryption keys. User can hod both public and private balances and move them.
    

Twisted ElGamal over BN254
--------------------------

### Homomorphic Properties

ElGamal encryption is additively homomorphic, meaning you can perform arithmetic operations on encrypted values without decryption:

`Enc(a) + Enc(b) = Enc(a + b) Enc(a) - Enc(b) = Enc(a - b)`

This is critical for privacy-preserving transfers. When Alice sends 100 USDC to Bob:

1.  Alice's encrypted balance: `Enc(balance_alice)`
    
2.  Subtract encrypted amount: `Enc(balance_alice) - Enc(100)`
    
3.  Bob's encrypted balance: `Enc(balance_bob) + Enc(100)`
    

The sequencer performs these operations on encrypted elliptic curve points without ever learning the actual amounts. All it sees are point additions and multiplications on the BN254 curve.

### Why BN254?

BN254 (also known as alt\_bn128) is already supported by Ethereum through precompiles at addresses `0x06` (ecAdd), `0x07` (ecMul), and `0x08` (pairing check). This means:

*   **Hardware acceleration**: EVM clients already optimize these operations
    
*   **Low gas costs**: Precompiled operations are orders of magnitude cheaper than equivalent Solidity
    
*   **Proven security**: Widely audited and battle-tested in production systems
    

We've extended this with additional precompiles for ElGamal-specific operations at addresses `0x1A`, `0x18`, and `0x19`.

### Encrypted Balance Storage

Balances are stored as **elliptic curve points** in contract storage:

    mapping(address => EncryptedBalance) private balances;
    
    struct EncryptedBalance {
        uint256 c1_x;  // First curve point X coordinate
        uint256 c1_y;  // First curve point Y coordinate  
        uint256 c2_x;  // Second curve point X coordinate
        uint256 c2_y;  // Second curve point Y coordinate
    }
    

Each encrypted balance is actually a pair of BN254 curve points `(C1, C2)` representing the ElGamal ciphertext. These are stored in public storage slots—anyone can read them, but they reveal nothing about the actual balance without the private key.

The TEE Backend: Hardware-Backed Decryption
-------------------------------------------

While homomorphic encryption handles transfers, TEE is important for fair and isolated key generation that backs the encryption across the system and becoming the verifier for every single private txn.

### Intel TDX Secure Enclave

Halo runs a TEE backend using TDX enclave hosted on [phala](https://phala.com/). Think of these as hardware-isolated execution environments with several critical properties:

1.  **Memory Encryption**: All data inside the enclave is encrypted in hardware. Even if someone gains physical access to the server or dumps RAM, they see only encrypted data.
    
2.  **Attestation**: The TEE generates cryptographic proofs (attestations) that specific code ran inside a genuine secure enclave, producing specific outputs. This is verifiable on-chain.
    
3.  **Isolated State**: The TEE maintains internal state tracking to prevent double-spending. It knows which encrypted balances it's previously decrypted and attested.
    

### Precompiles

We've implemented two key precompiles for TEE integration:

**0x15 - VerifyTEEAttestation(message, signature, timestamp)**

*   **Input**: Message data + TEE's ECDSA signature + timestamp
    
*   **Purpose**: Verifies that a signature actually came from the authorized TEE's private key
    
*   **Output**: Boolean indicating valid/invalid signature
    
*   **Usage**: Called by SetPrivateBalance (0x10) to ensure encrypted balance updates are TEE-authorized
    

**0x17 - RegisterTEEPublicKey(publicKey)**

*   **Input**: 64-byte uncompressed ECDSA public key
    
*   **Purpose**: Registers which TEE is authorized to sign balance updates
    
*   **Access**: Admin-only, typically called once during system setup
    
*   **Output**: Success/failure status
    

* * *

Transaction Flow: From Wallet to Settlement
-------------------------------------------

Let's walk through a complete private transfer from start to finish.

Setup: TEE Key Generation
-------------------------

A **trusted execution environment (TEE)** is used for secure key generation, providing cryptographic assurance that the process is isolated and free from interference. The private key is generated and remains entirely within the enclave, never leaving the trusted boundary.

*   TEE (Intel SGX/AMD SEV secure enclave) generates a public/private keypair on initialization
    
*   Public key is shared on-chain, available to all users as `TEEpubkey`
    
*   Private key never leaves the TEE hardware
    

* * *

Step 1: User Transaction (Standard EIP-1559)
--------------------------------------------

Alice wants to send 100 USDC privately to Bob. She opens MetaMask and signs a standard transaction:

    // MetaMask handles this natively
    {
      from: "0xAlice",
      to: "0xPrivateUSDC",  // Privacy-enabled USDC contract
      data: transferPrivate(
        "0xBob",
        amount  // 100 USDC (plaintext at this stage)
      ),
      gas: 150000,
      maxFeePerGas: 50,
      maxPriorityFeePerGas: 2
    }
    

**No custom transaction format. No special wallet. Just a standard Ethereum transaction calling a contract function.**

* * *

Step 2: Sequencer Routing (cdk-erigon)
--------------------------------------

The Halo L2 sequencer (running cdk-erigon, the same client Polygon zkEVM uses) receives the transaction and routes it based on the called function:

**For** `transferPrivate()`**:**

1.  **Check if transaction is private**: `isPrivate == true`
    
2.  **Encrypt the transaction data** using `TEEpubkey`:
    
    *   Encrypt amount: `Enc(100)`
        
    *   Encrypt recipient address: `Enc(0xBob)`
        
3.  **Send encrypted transaction to TEE** for attestation and validation
    
4.  **TEE validates** the transaction:
    
    *   Decrypts transaction inside secure enclave
        
    *   Verifies Alice has sufficient encrypted balance
        
    *   Checks for double-spending using internal state
        
    *   Returns `isValid == true` with attestation signature
        
5.  **If** `isValid == true`, sequencer proceeds with homomorphic operations:
    
    *   Read Alice's encrypted balance from storage: `balances[0xAlice]`
        
    *   Call precompile `0x18` for homomorphic subtraction: `Enc(balance_alice) - Enc(100)`
        
    *   Store updated encrypted balance: `SSTORE(balances[0xAlice], newEncryptedBalance)`
        
    *   Read Bob's encrypted balance: `balances[0xBob]`
        
    *   Call precompile `0x19` for homomorphic addition: `Enc(balance_bob) + Enc(100)`
        
    *   Store updated encrypted balance: `SSTORE(balances[0xBob], newEncryptedBalance)`
        

**Critical point**: The sequencer never decrypts these values. It's performing elliptic curve arithmetic on encrypted points. The actual amounts remain confidential throughout execution.

* * *

Step 3: TEE Attestation for Withdrawals (When Required)
-------------------------------------------------------

Now suppose Bob wants to withdraw his private balance to public state or a DEX. The contract needs to verify he actually has 100 USDC before allowing the withdrawal:

    function withdrawToPublic(uint256 requestedAmount) external {
        // Get encrypted balance from storage
        EncryptedBalance memory encBal = balances[msg.sender];
        
        // Call TEE to decrypt and attest
        (uint256 actualBalance, bytes memory attestation) = 
            decryptTEE(encBal, userPublicKeys[msg.sender]);
        
        // Verify the attestation came from genuine TEE
        require(
            verifyTEEAttestation(actualBalance, attestation, block.timestamp),
            "Invalid TEE attestation"
        );
        
        // Check sufficient balance
        require(actualBalance >= requestedAmount, "Insufficient balance");
        
        // Update encrypted private balance (homomorphic subtraction)
        balances[msg.sender] = encBal.subtract(requestedAmount);
        
        // Credit public ERC-20 balance
        publicBalances[msg.sender] += requestedAmount;
    }
    

The TEE attestation proves Bob has sufficient balance without revealing his total holdings to the public chain state.

* * *

Balance Queries: Private vs Public
----------------------------------

Users can query balances through two paths depending on their privacy needs:

### Private Balance Query

    function getPrivateBalance() external view returns (uint256) {
        EncryptedBalance memory encBal = balances[msg.sender];
        
        // TEE decrypts and attests
        (uint256 balance, bytes memory attestation) = 
            decryptTEE(encBal, userPublicKeys[msg.sender]);
        
        // Verify attestation
        require(verifyTEEAttestation(balance, attestation, block.timestamp));
        
        return balance;
    }
    

This reveals the balance only to the querying user, with cryptographic proof of correctness via TEE attestation.

### Public Balance Query

    function balanceOf(address account) external view returns (uint256) {
        return publicBalances[account];  // Standard ERC-20
    }
    

Standard transparent balance—fully composable with existing DeFi protocols.

* * *

Compliance and Regulatory Features
----------------------------------

Privacy doesn't mean lawlessness. Halo includes built-in compliance mechanisms:

### TEE Selective Disclosure

The TEE can decrypt specific encrypted balances under authorized conditions (e.g., court order, regulatory audit). When this occurs:

1.  Authority provides signed authorization to TEE
    
2.  TEE validates authorization signature against pre-configured compliance keys
    
3.  TEE decrypts requested balance and generates audit log
    
4.  Audit log is cryptographically attested and timestamped
    

This creates an **auditable trail** of all compliance disclosures—who requested what, when, and under what authority.

### 0xPredicate Protocol-Level Rules

Smart contracts can enforce compliance rules directly:

    // Example: Maximum daily transfer limit
    mapping(address => uint256) public dailyTransferVolume;
    uint256 constant MAX_DAILY_VOLUME = 10000e6;  // 10k USDC
    
    function transferPrivate(address to, EncryptedAmount memory amount) external {
        // Decrypt amount using TEE for compliance check
        (uint256 decryptedAmount, ) = decryptTEE(amount, msg.sender);
        
        // Enforce daily limit
        dailyTransferVolume[msg.sender] += decryptedAmount;
        require(
            dailyTransferVolume[msg.sender] <= MAX_DAILY_VOLUME,
            "Daily limit exceeded"
        );
        
        // Proceed with private transfer...
    }
    

These predicates run at the protocol level & no way to bypass them without forking the chain.

* * *

Why This Architecture Works
---------------------------

Let me tie together why each design decision matters:

**1\. No UTXO Complexity** By storing encrypted balances in standard EVM storage, we avoid the massive complexity of UTXO state management—no Merkle trees to sync, no nullifier sets to maintain, no spent output tracking. It's just storage slots.

**2\. Instant Homomorphic Transfers** Private transfers execute in milliseconds using precompiled elliptic curve operations. No MPC coordination, no complex circuit proving, no expensive zk-SNARK generation on the critical path.

**3\. Full EVM Composability** Since encrypted balances are accessible via precompiles, any smart contract can read and manipulate them. A DEX can check private balances, a lending protocol can verify collateral, a payment processor can confirm funds—all while maintaining privacy.

**4\. Standard Wallet Compatibility** Users sign standard EIP-1559 transactions. MetaMask, Rabby, Frame—they all work out of the box. No browser extensions, no custom signing flows, no new key management.

**5\. Regulatory Viability** Built-in compliance through TEE selective disclosure and protocol-level predicates means Halo can serve regulated institutions (neobanks, payment processors) without sacrificing privacy for everyday users.

---

*Originally published on [Madhav Goyal](https://paragraph.com/@madhavg/halo-a-privacy-layer-for-stablecoins)*
