Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ Azoth is a research-grade toolchain for Ethereum smart-contract obfuscation. The

1. **Pre-processing/Analysis**: Isolate runtime bytecode and measure structure
2. **Obfuscation Passes**: Apply reversible transforms to raise analyst effort
3. **Re-assembly & Validation**: Splice segments back and validate equivalence
3. **Re-assembly & Validation**: Splice segments back, run structural checks, and use contract-specific differential EVM tests where available

## Architecture

This is a Rust workspace with six main crates:

- **`crates/core/`**: Core functionality including bytecode decoder, encoder, section detector, bytecode stripper, and CFG-IR generation. The detection module includes section isolation (`detection/sections.rs`) and dispatcher pattern detection (`detection/dispatcher.rs`)
- **`crates/analysis/`**: Analysis utilities for measuring bytecode complexity and obfuscation quality through comprehensive metrics
- **`crates/transforms/`**: Obfuscation passes including opaque predicates, control flow shuffling, function dispatcher obfuscation, and jump address transformation. The `obfuscator.rs` module orchestrates all transforms
- **`crates/verification/`**: Formal verification engine providing mathematical proofs of semantic equivalence using Z3 SMT solver, plus practical testing with REVM. Supports multiple verification levels and generates cryptographic certificates
- **`crates/transforms/`**: Obfuscation passes and the unified pipeline in `obfuscator.rs`. The production default applies selector-only dispatcher rewriting when detected, then jump-trampoline topology diversification and cluster shuffling; literal synthesis and the other passes are opt-in experiments and string obfuscation is disabled
- **`crates/verification/`**: Experimental verification scaffolding. Contract-equivalence entry points fail closed as unsupported; the optional Z3 feature and proof data structures do not provide a mathematical equivalence guarantee
- **`crates/utils/`**: Shared utilities including deterministic seed generation and error types
- **`crates/cli/`**: Command-line interface (`azoth` binary) with subcommands for decode, strip, cfg, and obfuscate

Expand Down Expand Up @@ -115,8 +115,8 @@ Write documentation in clear, professional prose rather than fragmented bullet p
///
/// This function performs the core transformation from linear bytecode instructions
/// into a structured graph representation that enables sophisticated analysis and
/// obfuscation transforms. The resulting CFG maintains semantic equivalence while
/// providing the structural information necessary for advanced code analysis.
/// obfuscation transforms. The resulting CFG represents the decoded control flow
/// and provides the structural information necessary for advanced code analysis.
///
/// The construction process involves several phases: basic block identification
/// through control flow analysis, edge creation based on jump target resolution,
Expand Down Expand Up @@ -236,7 +236,7 @@ When creating GitHub issues, always assign appropriate labels to ensure proper c
- `component:core` - Issues related to core bytecode processing
- `component:transforms` - Obfuscation transform implementations
- `component:analysis` - Metrics and analytical functionality
- `component:verification` - Formal verification and testing
- `component:verification` - Experimental verification scaffolding and testing
- `component:utils` - Shared utilities and helpers
- `component:cli` - Command-line interface and user experience
- `component:tests` - Testing infrastructure and test cases
Expand Down
61 changes: 23 additions & 38 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@

## What is Azoth?

Azoth is a deterministic EVM bytecode obfuscator designed to make Mirage's execution contracts indistinguishable from ordinary, unverified deployments on Ethereum. The name "[Azoth](https://www.wikiwand.com/en/articles/Azoth)" derives from medieval alchemy, where it referred to the universal solvent: a hypothetical substance capable of dissolving any material and serving as the essential agent of transformation.
Azoth is a deterministic EVM bytecode obfuscator that varies deployment and runtime bytecode while preserving the behavior of supported contracts. Its research goal is to reduce static linkability and make transformed contracts resemble the broad population of unverified Ethereum deployments. Indistinguishability is an evaluation target, not a guarantee. The name "[Azoth](https://www.wikiwand.com/en/articles/Azoth)" derives from medieval alchemy, where it referred to the universal solvent: a hypothetical substance capable of dissolving any material and serving as the essential agent of transformation.

## How does it work?

1. Dissection: decode the contract’s init/runtime layout, resolve sections, and build a control-flow graph of block bodies and jump targets.

2. Transformation: apply deterministic transformations (e.g dispatcher transforms, block shuffling etc.) that changes the structure of the bytecode without blowing gas or size limits.
2. Transformation: apply seed-derived passes transactionally. The production default is selector-only `FunctionDispatcher` when a supported dispatcher is detected, followed by low-density `JumpTrampoline` topology diversification and LCS-bounded `ClusterShuffle` layout diversification.

3. Recovery: lower the rewritten runtime, patch init-code offsets, and mask any exact constructor-argument suffix so the final bytecode stays deployable without retaining an ABI-aligned plaintext tail.

Azoth also incorporates a formal verification system that provides mathematical guarantees of functional equivalence between original and obfuscated contracts.
The verification crate is experimental scaffolding. Contract-equivalence entry points currently return `Unsupported`; Azoth does not provide a formal proof or mathematical guarantee of semantic equivalence. Safety must instead be established with compiler-specific differential deployment and behavioral tests for the exact contract and pass set.

Constructor-argument masking is an obfuscation boundary, not encryption: it defeats verbatim static suffix recovery, but public creation code can still be analyzed or executed to recover values. See the [constructor-argument security and benchmark report](docs/constructor-argument-obfuscation.md).

## Status

Azoth is under active development: the parsing pipeline, CFG builder, and several core transforms are in daily use, while additional passes, verification tooling, and resilience metrics are landing incrementally as we harden the stack for production-facing deployments.
Azoth is under active development. The current pipeline fails closed for unsupported self-code-layout and gas-observation patterns, including all `EXTCODE*` introspection because its target may alias the current contract, as well as ambiguous dispatcher selector uses, unsupported constructor layouts, and EVM size-limit violations. Those guards reduce known risks but do not establish equivalence for arbitrary bytecode. Treat generated deployments as experimental until they pass contract-specific differential tests.

The optional JSON report records byte sizes and exact EVM code-deposit gas for the deployed runtime (`200 gas/byte`). It deliberately does not estimate creation calldata cost, EIP-3860 word cost, constructor execution, or runtime execution gas; measure those with an EVM harness.

The current hardening results, benchmark methodology, red-team findings, and remaining limitations are documented in the [technical report](docs/AZOTH_TECHNICAL_REPORT.md) and [executive report](docs/AZOTH_EXECUTIVE_REPORT.md).

## Getting Started

Expand Down
14 changes: 9 additions & 5 deletions crates/analysis/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Azoth Analysis

The `azoth-analysis` crate provides analytical metrics for evaluating EVM bytecode obfuscation transforms. This crate implements a minimal set of metrics to assess transform potency and gas efficiency.
The `azoth-analysis` crate provides analytical metrics for evaluating EVM bytecode obfuscation transforms. It measures structure, size, original-byte retention, and seed-to-seed diversity; it does not measure execution gas or prove semantic equivalence.

## Architecture

Expand All @@ -10,15 +10,15 @@ The analysis crate focuses on quantifying bytecode complexity through:
2. **Stack Usage** - Maximum stack height measurements
3. **Dominator Analysis** - Control flow critical points using dominator/post-dominator overlap
4. **Size Metrics** - Bytecode length tracking
5. **Obfuscation Persistence** - Longest preserved byte sequences and n-gram diversity across randomized obfuscations
5. **Obfuscation Persistence** - Conservative ordered-byte retention, longest contiguous runs, aligned differences, and pairwise n-gram similarity across randomized obfuscations

## Key Components

### Metrics System (`metrics.rs`)

Implements core metrics for evaluating bytecode complexity and transformation effectiveness:

- **Bytecode Size** (`byte_len`) - Size of cleaned runtime bytecode in bytes
- **Bytecode Size** (`byte_len`) - Encoded size of the current runtime CFG plus appended transform data
- **Block Count** (`block_cnt`) - Number of basic blocks in the CFG (excluding Entry/Exit)
- **Edge Count** (`edge_cnt`) - Number of edges in the CFG
- **Maximum Stack Peak** (`max_stack_peak`) - Maximum stack height across all body blocks
Expand All @@ -29,7 +29,8 @@ Implements core metrics for evaluating bytecode complexity and transformation ef

The crate provides these primary functions:

- `collect_metrics(ir: &CfgIrBundle, report: &CleanReport) -> Result<Metrics, MetricsError>` - Collects all metrics from CFG and clean report
- `collect_metrics(ir: &CfgIrBundle) -> Result<Metrics, Error>` - Collects metrics from the current CFG, including its current transformed byte length
- `current_byte_len(ir: &CfgIrBundle) -> usize` - Measures the instruction stream and appended transform data directly
- `dominator_pairs(g: &DiGraph<Block, EdgeType, Ix>) -> (DominatorMap<Ix>, DominatorMap<Ix>)` - Computes dominator and post-dominator pairs
- `dom_overlap(doms: &DominatorMap<Ix>, pdoms: &DominatorMap<Ix>) -> f64` - Calculates dominator overlap fraction
- `compare(before: &Metrics, after: &Metrics) -> f64` - Compares metrics between transformations
Expand Down Expand Up @@ -62,6 +63,9 @@ Runs multiple obfuscation attempts with randomized seeds and aggregates:
- Summary statistics (average, median, percentiles, range, standard deviation)
- Histogram distribution of preserved lengths
- Top ten most frequent preserved sequences
- N-gram diversity (n = 2, 4, 8) across obfuscated outputs
- Conservative longest-common-subsequence retention and aligned original-to-output difference
- Pairwise aligned seed difference and pairwise n-gram set Jaccard similarity (n = 2, 4, 8)

Pairwise n-gram Jaccard replaces the former pooled unique-window percentage, whose value decreased mechanically as more iterations were added. The report stores ratios in `0.0..=1.0` and renders them as percentages.

Use `AnalysisConfig` to configure iterations, transform passes, and output path, then call `analyze_obfuscation(config)` to produce a markdown report. The CLI subcommand `azoth analyze` builds on this module.
10 changes: 5 additions & 5 deletions crates/analysis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//! Analytical utilities for assessing Azoth obfuscation results. The crate exposes:
//! - Core metrics for bytecode size, control-flow structure, stack usage, and dominator overlap to
//! estimate transform potency and gas impact.
//! - Comparison helpers that derive before/after deltas directly from a `CfgIrBundle` and
//! `CleanReport`.
//! - Comparison helpers that derive before/after deltas directly from the current `CfgIrBundle`.
//! - An obfuscation study that repeatedly obfuscates bytecode with randomized seeds,
//! aggregates longest preserved byte sequences, emits percentile summaries, tracks top repeated
//! motifs, and measures n-gram diversity for multiple n values before producing a Markdown
//! report.
//! motifs, and measures pairwise byte and n-gram similarity before producing a Markdown report.

pub mod decompile_diff;
pub mod metrics;
pub use metrics::{Metrics, collect_metrics, compare};
pub use metrics::{Metrics, collect_metrics, compare, current_byte_len};

pub mod similarity;

pub mod obfuscation;

Expand Down
Loading
Loading