# Mirage
import { Callout } from 'vocs/components'
## A Simple Example
Let's say Alice wants to send 100 USDC to Bob privately.
### The Flow

**Alice's experience is very simple:**
1. Open the Mirage app
2. Enter Bob's address and the amount (100 USDC)
3. Add a small tip (2 USDC) to incentivize a node to execute the transfer
4. Hit send
That's it. From Alice's perspective, it feels like any other crypto transfer. But behind the scenes, something clever is happening.
Instead of Alice sending directly to Bob (which would be visible onchain and link them together), the Mirage app sets up a mechanism where someone else sends the money to Bob on Alice’s behalf. To anyone watching the blockchain, it just looks like a random address sent Bob 100 USDC. Nothing unusual or suspicious.
#### Step 1: Setting Up the Escrow
When Alice hits send, she deploys a small, temporary escrow contract through the Mirage app. This contract handles the transaction safely and privately.
* The contract looks completely ordinary. Just another contract among thousands deployed daily on Ethereum
* It's unique to Alice's transaction (not a shared pool everyone uses)
* Each deployment has small random variations in code, making it costly and unreliable to detect which contracts belong to Mirage.
Alice’s wallet deposits into this escrow:
* **100 USDC** (the amount she wants Bob to receive)
* **2 USDC** (a small tip to reward whoever completes the transfer)
At the same time, the Mirage app encrypts Alice’s instructions: *“Send 100 USDC to Bob’s address. You’ll earn 2 USDC for doing this.”* This encrypted message is then broadcast to the Mirage node network, where nodes compete to decrypt and execute it.
#### Step 2: A Node Picks Up the Job
The encrypted message is now floating out there, and nodes in the Mirage network are competing to decrypt it. Decryption isn't free. It requires compute resources and time. This is intentional, making it expensive for anyone to try to decrypt and analyze every message on the network.
Once a node successfully decrypts Alice's message, they see the details: *"Send 100 USDC to Bob, earn 2 USDC."*
If they want to take the job, here's what happens:
1. **The node posts a security deposit** into Alice's escrow contract (ensuring they only profit by completing the job honestly)
2. **The node sends 100 USDC from their own wallet directly to Bob via another address**
This is the key moment. Onchain, it looks like this node (some random address) is sending Bob 100 USDC. There's no visible connection to Alice. No privacy contract. No obvious privacy behavior. Just a regular stablecoin transfer.
Actually all Mirage nodes are run inside Trusted Execution Environments (TEEs). This means no one can extract the decrypted request, and even if such an attack ever successfuly takes place, the risk is contained since each node will only get a partial view of the full network as it needs to spend compute to decrypt each request.
#### Step 3: The Node Gets Reimbursed
The node just sent 100 USDC to Bob out of their own pocket. Now they need to get paid back from Alice's escrow contract:
1. **The node submits proof** that they sent 100 USDC to Bob (a cryptographic proof the blockchain transaction exists)
2. **The escrow contract verifies** the proof and confirms Bob received exactly 100 USDC
3. **The contract releases payment:**
* 100 USDC (reimbursement for what they sent Bob)
* Their security deposit (returned in full)
* 2 USDC (their tip for executing the transaction)
The node walks away with a 2 USDC profit. Bob has his 100 USDC. Alice has successfully sent a private payment. And to anyone analyzing the blockchain, there's no visible link between Alice and Bob, and there is no sign Alice used a privacy solution to begin with. Everything looks normal.
### Why This Provides Privacy
Let's step back and look at what an observer sees when analyzing the blockchain:
**Transaction 1:** Alice deployed a contract and deposited some USDC into it
*Interpretation: Could be anything. A multisig, an MEV contract, an automated trading bot, whatever*
**Transaction 2:** Some random address sent Bob 100 USDC
*Interpretation: Just a normal transfer. Happens thousands of times per day*
**Transaction 3:** Another random address later withdrew funds from Alice's contract
*Interpretation: who knows?*
There's no visible connection between Alice and Bob. The node's transfer to Bob looks completely independent from Alice's activity.
import { Callout } from 'vocs/components'
## How Mirage Compares
Mirage differs from other privacy tools in fundamental ways. While other solutions, mostly mixers and privacy coins, rely on consolidating various users' funds in a shielded pool or smart contract and rely on the size of deposits and number of users to enhance their privacy guarantees, Mirage makes all stabelcoin activity be the anonymity set for each private transaction while providing usage privacy that protects the users against stigma.
#### On Privacy Coins
Privacy coins such as ZCash ($ZEC) and Monero ($XMR) offer transactional privacy through their own volatile assets. While crypto circles generally accept their privacy guarantees, they have failed to capture the larger crypto market for several reasons:
* Different networks and trust assumptions make interoperability harder and add another loop users must navigate. This challenges the UX and turns off users who don't trust the isolated blockchains behind these coins. Users typically purchase these coins from sketchy websites with opaque processes, or from centralized exchanges.
* Volatile prices bring instability for real world payments and are less reliable than stablecoins.
* No built-in forced exclusion and compliance is a good trait for a blockchain network, but combined with a privacy protocol, these networks become ideal spaces for money laundering by criminals and sanctioned entities. This taints everyone who interacts with the network. Even CEXs that don't require KYC specifically restrict purchases of these tokens to KYCed users.
* The UX is difficult to navigate for non-technical and non-crypto-native users.
These concerns make privacy coins unattractive to users who simply want easier payments and financial sovereignty. It's unrealistic to expect a remote business owner to buy these coins and take on these challenges for payroll or daily transactions, even if they're already familiar with blockchains and comfortable on Ethereum. Privacy coins don't serve normal people who prefer regulated exchanges or banks over jumping through hoops.
#### On Mixers
Mixers such as Tornado Cash offer unlinkability, which is an upgrade over the transparent nature of public blockchains. However, the user experience and risks far outweigh the benefits for most users, who can simply use CEXs to achieve better privacy guarantees.
* The sanctioning of Tornado Cash set a bad precedent for mixers and introduced legitimate compliance concerns for innocent users worried about having their funds tainted because they benefit from and help maintain an anonymity set that includes bad actors.
* Funds typically wait for days in smart contracts, and there must be enough users who have deposited the same asset in amounts equal to or higher than what the user deposited, depending on the implementation. This makes scaling difficult and introduces serious UX issues.
* Interacting with mixers typically means high gas costs as there are large data structures being manipulated and altered (depending on implementation).
* As soon as you interact with a mixer, your funds are tagged and scrutinized by CEXs, on/off-ramp solutions, and other protocols.
For these reasons, although mixers remain the best current privacy solution on Ethereum, they haven't generated enough trust or proper UX to achieve adoption by everyday users and businesses.
import { Callout } from 'vocs/components'
## The Problem And The Solution
Privacy is a notoriously hard problem to solve on public blockchains. Over the years there have been many attempts at solving this significant issue, largely through privacy coins and mixers. Mirage takes a fundamentally different approach to address this issue on Ethereum, though Mirage can adapt the design for other networks such as L2s like Arbitrum and Base, or L1s like Solana.
### The Privacy Problem
Free market economies rely on privacy rights to function. Internet capital markets are powerful today, but their current significance is nothing compared to what they could be with privacy enabled. Many businesses and individuals still rely on centralized, permissioned, and outdated setups that are inefficient and expensive, but offer basic privacy guarantees that public blockchains can't. Banks and centralized exchanges are where even crypto companies process private transactions like payroll and treasury management, despite higher costs and worse user experience.
### The Solution
We're building Mirage on the belief that privacy should be easy to use, fast, cheap, and headache-free. Your money shouldn't mix with others. You shouldn't have to wait more than a minute or two. And no one should know you used a privacy solution to begin with. The next generation being onboarded to stablecoins will turn their backs when they discover the lack of privacy, or won't onboard at all, or will just use a centralized solution with worse UX. Here are features Mirage brings that no other privacy solution does:
#### Speed, Affordability, and Flexibility
Mirage is cheap and fast. On Ethereum mainnet, transactions are processed in less than 90 seconds. On L2s such as Base and Arbitrum, this drops to under 6 seconds. Compare that to parking your funds in a mixer contract for days while spending both time and gas.
Moreover, Mirage is not a blockchain, making upgrades easier. New features are simpler to add, and the network can be adjusted to suit different needs as they appear. We don't believe in one size fits all. Privacy can be tailored for each user.
#### Self-Sovereignty and Compliance
Instead of using obvious mixer contracts, Mirage creates different unique smart contracts for each transaction. To outside observers, these look like normal, unverified contracts that appear on Ethereum every day. There's no obvious "privacy contract" to monitor, like Tornado Cash's pools. And if you're concerned about interacting with unverified contracts, both Mirage's [escrow contract](https://github.com/MiragePrivacy/escrow) and the tool used to make these different versions ([Azoth](https://github.com/MiragePrivacy/Azoth)) are completely open source and auditable. Since Azoth's outputs are deterministic, you can perform an integrity check to ensure the contract you're interacting with hasn't been tampered with. This is exactly what the executors do to verify the contract is healthy before committing the bond.
Once you connect your address to the Mirage web app, the service screens the origin of your funds to ensure they're not related to sanctioned entities, criminal activity, or a suspicious DeFi hack happening in real time.
Our users don't need to worry about being linked with any illegitimate fund or activity. The contracts are only used by them, so these funds never touch one another. In a theoretical sense, though we prevent this proactively, even if illegitimate funds entered the system somehow, all users remain safe since these funds don't make contact with others. Additionally, Mirage can pause its service at any time or roll out an update that proactively deals with any contaminated section of the network swiftly. Users enjoy the benefits of self-sovereignty without worrying about strangers. **Your money, your business.**
#### The Undetectability Challenge
Traditional privacy tools fail because you interact directly with obvious privacy contracts on the blockchain, essentially announcing to everyone that you want privacy. Mirage solves this by moving all **coordination** off-chain. When you want to make a private transaction, your wallet broadcasts an encrypted message (called a 'signal') to a network of independent executors. Each signal is locked behind a cryptographic puzzle that must be solved before its contents can be read. Your actual intentions are only revealed to the node that picks up your transaction. Importantly, while we coordinate off-chain, **everything** is validated and verified immediately and trustlessly onchain, without a trusted party.
This means your funds are never revealed to be handled by a privacy protocol, which itself would bring unwanted attention. Since Mirage transactions are designed to be indistinguishable from normal Ethereum activity, no external observer can definitively prove someone used a privacy protocol. When you use Mirage, your on-chain footprint consists entirely of routine-looking interactions: depositing tokens into what appears to be an ordinary contract, and someone else later making a standard transfer to your intended recipient. These actions could have countless legitimate explanations: business escrow agreements, freelance payments, automated trading strategies, or any number of everyday DeFi activities.
To increase your privacy levels, you have the option to multi-route through the protocol so that multiple nodes execute pieces of your transaction and bring it to temporary stops until the next node takes over. This means no single node knows your intentions. Furthermore, all nodes run inside Trusted Execution Environments, meaning the decrypted data is only visible to the isolated part of the CPU chip.
#### Integrations & UX
To use Mirage, you only need to submit at most two transactions, a user experience unparalleled in the privacy market. Similarly, integrating Mirage into your protocol and wallets is an easy, high-reward task for development teams. It's essentially a simple API call that leaks no information. All data is encrypted locally on users' devices.
### Who Uses Mirage
Mirage serves users and institutions that need financial privacy without the stigma or regulatory exposure of traditional privacy tools. Businesses can use it to protect sensitive financial information from competitors who monitor blockchain activity for strategic intelligence, including payroll. Individual users can rely on Mirage to keep their personal finances private from data brokers, surveillance companies, and malicious actors who build profiles from public transaction data. DAOs can use the protocol to make confidential payments without telegraphing their strategies to the market, while developers integrate Mirage into applications that require built-in privacy without asking users to take on regulatory risk.
The protocol serves anyone who believes financial privacy shouldn't come with a target on your back. Mirage recognizes that true privacy means no one should even know you're trying to be private. This makes it practical for legitimate users who simply want the same level of financial confidentiality they expect from traditional banking, without the legal and social risks of using obviously detectable privacy protocols.
import { Callout } from 'vocs/components'
## The Undetectability Challenge
One of the core ideas behind Mirage is that **no one should know you used a privacy protocol to begin with**.

Mirage is the first privacy solution that makes an attempt at protecting its users against the high-risk stigma of using privacy protocols. All existing privacy solutions today are solely focused on breaking the recipient-sender link and hiding the transaction amount, while it's trivial to identify all of their users and flag them while interacting with CEXs, on/off-ramp solutions, etc...
This is essentially how all Tornado Cash users were blacklisted when the contracts were under sanctions. Even today, after the sanctions have been cleared, many services refuse to work with addresses and funds that have interacted with Tornado Cash.
import { Button } from 'vocs/components'
## Nomad Overview
The Nomad network is a network of TEE-backed nodes that decrypt, validate, and execute client signals without exposing transaction details or node activity to any specific party.
#### How is nomad used in the network?

1. Clients encrypt their signal (containing recipient, amount, ...) using the enclave's global secp256k1 public key, and send it to the network.
2. The signal propagates through a libp2p gossip layer, where nodes receive incoming signals and randomly sample them for execution.
3. Inside each node's SGX enclave, the signal is decrypted and processed:
1. The enclave validates the escrow contract bytecode
2. Bonds tokens using one of its internal EOAs
3. Executes the transfer from another EOA
4. Builds a Merkle proof for the transfer and collects the reward by submitting the proof to the escrow contract using the bonded EOA
#### Basic requirements
To run a node, you must be able to provide the following requirements:
* At least $10k in USDC liquidity
* Dedicated SGX machine (cloud-hosted)
#### Node Revenue
Nodes generate revenue from tips paid alongside the signals.
Operators can expect each signal's tip to be for a few dollars each, and the node will hold the profits until withdrawn
by the node operator at a later time.
Maintaining good node uptime will allow the node to accept as many unsolved signals as it can from the network gossip.
#### Mitigating Vulnerabilities
Nodes run a lightweight enclave that manages the funds and handles executing signals.
In the event of a vulnerability or hack, the platform will issue a signature revoking the enclave, blocking any clients from producing any more signals for nodes.
Once a sufficient mitigation is released by the platform, a new enclave is signed and distributed to nodes to resume work.
## Running a Nomad Node
**Difficulty**: Medium (linux server management, cli usage)
**Setup Time**: \~1 hr
### Technical Requirements
* Dedicated server or virtual machine supporting Intel SGX2, for example:
* OVH Cloud [Rise 1](https://us.ovhcloud.com/bare-metal/rise/rise-1) or [Rise 2](https://us.ovhcloud.com/bare-metal/rise/rise-2) ($70-80/mo)
* Azure Cloud [DC2s-v3 Instances](https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dcsv3-series) ($140/mo)
* Linux Kernel >=5.11
* Docker (with compose)
* Intel Aesmd
### SGX Setup (Ubuntu 24.04 LTS)
1. Ensure SGX is enabled in BIOS
> Note: On OVH, make sure to enable Remote KVM or IPMI when provisioning the machine to be able to access the BIOS
2. SSH into your server
```
ssh ubuntu@my.server.ip
```
> Note: It is highly recommended to do some basic hardening on the instance.
>
> * Create a new user and delete the ubuntu user
> * Setup `~/.ssh/authorized_keys` and disable password login for ssh
> * Routinely update the system packages
3. Setup Intel's package signing key and install `aesmd`
```
curl -fsSL https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo apt-key add -
sudo add-apt-repository "deb https://download.01.org/intel-sgx/sgx_repo/ubuntu noble main"
sudo apt-get update
sudo apt-get install -y sgx-aesm-service libsgx-dcap-default-qpl
sudo ln -s /usr/lib/x86_64-linux-gnu/libdcap_quoteprov.so.1 /usr/lib/x86_64-linux-gnu/libdcap_quoteprov.so
```
4. Configure the quote provider to use Intel PCS for attestations
```diff
sudo cp /etc/sgx_default_qcnl.conf /etc/sgx_default_qcnl.conf.bkp
sudo sed -s -i 's/localhost:8081/api.trustedservices.intel.com/' /etc/sgx_default_qcnl.conf
```
5. Install the Rust programming language
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup toolchain default stable
```
6. Install sgxs tools from fortanix
```
cargo install sgxs-tools
```
7. Add the current user to the sgx group
```
sudo groupadd sgx_prv
sudo groupadd sgx
sudo usermod -aG sgx_prv $USER
sudo usermod -aG sgx $USER
```
Logout and re-login to ensure the group is fully added to your user.
8. Verify sgx installation
From the sgxs-tools crate we installed, we can verify if the machine has been provisioned correctly by running:
```
sgx-detect
```
You should see an output similar to the one below:
```
Detecting SGX, this may take a minute...
✔ SGX instruction set
✔ CPU support
✔ CPU configuration
✔ Enclave attributes
✔ Enclave Page Cache
SGX features
✔ SGX2 ✔ EXINFO ✔ ENCLV ✔ OVERSUB ✔ KSS
Total EPC size: 378.0MiB
✔ Flexible launch control
✔ CPU support
? CPU configuration
✔ Able to launch production mode enclave
✔ SGX system software
✔ SGX kernel device (/dev/sgx_enclave)
✔ libsgx_enclave_common
✔ AESM service
✔ Able to launch enclaves
✔ Debug mode
✔ Production mode
✔ Production mode (Intel whitelisted)
You're all set to start running SGX programs!
```
### Docker compose
Create a directory for your node with the following structure:
```
nomad/
├─ data/
│ └─ config.toml
└─ docker-compose.yml
```
```bash
mkdir nomad && cd nomad
mkdir data
touch docker-compose.yml
```
#### Example docker-compose.yml
The following docker compose file runs the nomad node with the required sgx devices connected, configuration and state mounted, node auto-restart, and a healthcheck script:
```yml
services:
nomad:
container_name: nomad
hostname: nomad
image: "..." # Unreleased for now
command: ["run", "-v"]
devices:
# Allow access to sgx devices
- /dev/sgx_enclave:/dev/sgx_enclave
- /dev/sgx_provision:/dev/sgx_provision
volumes:
# Mount aesmd dir for socket access
- /var/run/aesmd:/var/run/aesmd
# Mount quote provider configuration
- ./sgx_default_qcnl.conf:/etc/sgx_default_qcnl.conf
# Mount configuration and state directory
- ./data:/root/.config/nomad
environment:
# Enable sgx logs
- SGX_DEBUG=1
# Enable rust backtraces
- RUST_BACKTRACE=0
ports:
# Forward networking ports from configuration
- "8000:8000"
- "9000:9000"
healthcheck:
# Healthcheck endpoint integration
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
restart: unless-stopped
```
##### Telemetry
Telemetry can be exported by adding standard `OTEL_EXPORTER` environment variables to the compose file:
For example, using Signoz Cloud:
```yml
services:
nomad:
...
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.us.signoz.cloud
- OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=
```
You may also create a `.env` file next to the docker-compose.yml containing the variables, and expose it to the node:
```yml
services:
nomad:
...
env: .env
```
#### Generating config.toml
Next to your docker compose file, the `data/` directory is exposed to the container for configuration and enclave state.
Generate the configuration using the `nomad config` command:
```bash
nomad config --network ethereum -w
```
If successful, a config file should be created at `data/config.toml`.
#### Example config.toml
The generated configuration should look like this:
```toml
[p2p]
# List of peer multiaddrs to bootstrap from
bootstrap = ["/ip4/15.235.50.174/tcp/9000"]
# Interval for searching for more network peers
bootstrap_interval = "5m"
# Port to listen on for the node's libp2p tcp server
# Must match the port forwarded in docker-compose.yml
tcp = 9000
[api]
# Port to listen on for the node's REST API server
# Must match the port forwarded in docker-compose.yml
port = 8000
[eth]
network = "ethereum"
# Ethereum RPC endpoint
geth_rpc = "https://ethereum-rpc.publicnode.com/"
builder_rpc = "https://ethereum-rpc.publicnode.com/"
# Number of active EOA accounts to manage
num_accounts = 8
# Minimum ETH balance to maintain per account
min_eth = 0.001
# Mirage platform compliance signers
whitelist_signers = ["9070a3c16a130e1db8f27414f3c6081c99798c7c856670ae49ac2f10b3faa4a4"]
polling_interval = "4s"
polling_max_attempts = 30
use_faucet = false
[eth.uniswap]
# Uniswap V2 router for automatic ETH replenishment
router = "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
max_slippage_percent = 5
swap_deadline = "20m"
# Amount of ETH to swap for when balance is low
target_eth_amount = 0.005
[eth.token.USDC]
# Token address to swap from for ETH
address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
# Minimum balance to reserve (in human-readable units)
min_balance = 10000.0
# Enable swapping from this token
swap = true
[otlp]
# OpenTelemetry export settings
# Configure exporter via OTEL_EXPORTER environment variables
logs = false
traces = false
metrics = false
[enclave]
# SGX enclave binary paths
enclave_path = "enclave.sgxs"
signature_path = "mirage.sig"
seal_path = "."
# Bootstrap nodes to fetch enclave key from
nodes = ["15.235.50.174:8000"]
debug_keys = []
```
### Funding the node
Node runners can onboard new clean funds by sending them to the address printed by the deposit subcommand:
```
docker compose run nomad deposit
```
The node will move the funds into encumbered accounts and uses them to execute user signals.
Direct CEX transfers are best to ensure the smoothest onboarding process.
### Starting and updating the node
Once the configuration has been created and funds have been deposited, the node can be started and managed using normal docker compose commands:
```
docker compose up -d --pull always
```
It is required to re-run this command with `--pull always` periodically, to ensure the node software is up-to-date. Failure to do so may lead to missing out on signals and rewards.
### Stopping and withdrawing from the node
At any point the node operator can request funds to be withdrawn from the node's accounts. Simply halt the node process, and run one of the the following commands:
```
# Stop the node first
docker compose down
# For all funds
docker compose run nomad withdraw --all
# For a specific amount of funds.
# Amount MUST include token decimals, for example 5000 USDC with 6 decimals:
docker compose run nomad withdraw --contract --amount 5000000000
```
The node will begin the withdraw process inside the enclave, sending the platform any outstanding fees, producing Mirage signals, and broadcasting them to other nodes for final transfers.
import { Callout } from 'vocs/components'
## An Introduction to Azoth
Azoth is the most advanced open-source deterministic EVM bytecode obfuscator. It's the engine that makes Mirage's undetectability possible.
### Why Bytecode Obfuscation?
Remember the undetectability challenge? Traditional privacy tools fail because their contracts are obvious. Everyone knows what Tornado Cash's contracts look like. Blockchain analysis firms maintain databases of known privacy contract signatures and patterns. The moment you interact with one, you're flagged.
Mirage solves this by deploying fresh, unique escrow contracts for every transaction. But here's the problem: if every contract was compiled from the same source code, they'd all look identical. Blockchain analysts could still identify them by their bytecode pattern.
This is where Azoth comes in. It takes the escrow contract and transforms it into countless different versions that all behave identically but look completely different at the bytecode level. Each deployment appears to be a unique, unrelated contract.
### How Azoth Works
When you compile a Solidity contract, the compiler produces EVM bytecode: a sequence of low-level instructions the Ethereum Virtual Machine executes. Think of it like assembly code for Ethereum. Azoth operates at this level, restructuring the bytecode while preserving its exact behavior.
The process works in three stages:
#### Stage 1: Analysis
Azoth first decodes the raw bytecode into individual instructions, then builds a **Control Flow Graph** (CFG). This graph maps out every possible execution path through the contract: which instructions can jump to which, where functions begin and end, and how the contract's logic flows.
This is like creating a detailed map of a building before renovating it. You need to understand every room, hallway, and staircase before you start moving walls around.
#### Stage 2: Transformation
With the CFG in hand, Azoth applies a series of **transforms**—modifications that change how the code looks without changing what it does. Each transform targets a different aspect of the bytecode, for example:
* **Function Dispatcher Obfuscation**: Solidity contracts use a standard pattern to route function calls. This pattern is a dead giveaway for identifying contracts. Azoth replaces the obvious selector-based routing with an obscured token-based system that behaves identically but looks completely different.
* **Control Flow Shuffling**: The order of code blocks in bytecode typically reflects the order in the source code. Azoth randomizes this layout, scattering the logic across the contract while maintaining correct jump targets.
The transforms are designed to defeat both manual reverse engineering and automated pattern matching. An analyst looking at the bytecode sees what appears to be a completely different contract each time. Automated tools searching for known signatures find nothing recognizable.
#### Stage 3: Reassembly and Validation
After transformation, Azoth reassembles the modified CFG back into executable bytecode. But here's the critical part: it validates that the new bytecode is **semantically equivalent** to the original. The obfuscated contract must behave exactly the same as the original in every possible scenario.
This validation happens at multiple levels, from basic structural checks to formal verification using SMT solvers. If anything doesn't match, Azoth rejects the output. This guarantee is what makes it safe to use in production.
### Why Determinism Matters
Azoth is **deterministic**: given the same input bytecode and the same seed value, it always produces exactly the same output. This might seem like a minor technical detail, but it's actually fundamental to Mirage's security model.
Here's why: when you use Mirage, you're depositing funds into what appears to be a random contract. How do you know that contract is safe? How do you know it's actually a Mirage escrow and not something malicious?
Because Azoth is deterministic, anyone can verify a deployed contract:
1. Take the original escrow contract source code (which is public)
2. Compile it to bytecode
3. Run it through Azoth with the same seed
4. Compare the result to what's deployed on-chain
If they match, the contract is legitimate. This is exactly what Mirage executors do before committing their bond. They independently verify that the contract they're about to interact with is a valid, unmodified Mirage escrow.
The seed can be derived deterministically from public information (like the transaction parameters), so verification doesn't require any secrets. Anyone can check any Mirage contract at any time.
### What Makes Azoth Different
There are other bytecode manipulation tools out there, but Azoth is built specifically for this use case:
**Open Source and Auditable**: The entire codebase is public. You don't have to trust claims about what it does—you can read the code yourself or have it audited.
**Semantic Preservation**: Azoth doesn't just scramble bytes and hope for the best. It maintains a formal understanding of the code's behavior and validates equivalence after every transformation.
**Production-Grade Reliability**: Azoth is designed for real contracts handling real money. The validation pipeline catches any transformation that could alter behavior, no matter how subtle.
**Extensible Architecture**: New transforms can be added as needed. As blockchain analysis techniques evolve, Azoth can evolve with them.
### The Result
After Azoth processes the escrow contract, the output is bytecode that:
* Executes identically to the original
* Looks completely different at the byte level
* Doesn't match any known contract signatures
* Can be independently verified by anyone
* Provides no useful patterns for blockchain analysts to identify
To an observer examining the blockchain, a Mirage escrow contract looks like just another of the thousands of unverified contracts deployed every day. There's no signature, no pattern, nothing to flag. The contract does its job and disappears into the noise.
This is how Mirage achieves what no other privacy solution has: **actual undetectability**. Not just breaking the sender-recipient link, but making it impossible to prove a privacy protocol was ever used.