Skip to content
/ tlos Public

TLOS: Topology-Lattice Obfuscation for Smart Contracts

Notifications You must be signed in to change notification settings

igor53627/tlos

Repository files navigation

TLOS: Topology-Lattice Obfuscation for Smart Contracts

Ask DeepWiki

Five-layer obfuscation with a planted LWE puzzle (one-time floor) and a configurable hash-PoW layer.

TLOS is a practical circuit obfuscation framework for EVM. It uses standard LWE with Gaussian noise (σ=25, n=384) for control function hiding, full-rank linear hashing for wire binding, and a planted LWE puzzle that adds a one-time q^128 brute-force floor for recovering the planted solution (lattice estimator ~2^58 for current params). Security is based on standard LWE hardness (~2^112 PQ).

What is TLOS?

TLOS provides five-layer security for on-chain circuit obfuscation, with configurable PoW throttling:

  1. Topology layer: Structural mixing defeats structural/statistical attacks (heuristic)
  2. LWE layer: Standard LWE with Gaussian noise (σ=25, n=384) hides control functions (~2^112 PQ)
  3. Wire binding layer: Full-rank 64x64 public linear map binds wire values across gates (algebraic binding)
  4. Planted LWE puzzle: One-time q^128 brute-force floor for recovering the planted solution (8.62M gas, 14% of 60M block)
  5. Hash-PoW (Layer 5): Hashcash-style work bound to commit-time randomness; throttles on-chain guessing and binds each guess to its commit (set difficulty to 0 to disable)

The wire binding construction is inspired by Ma-Dai-Shi 2025 but is not subspace-evasive in the formal sense - it is a public bijective linear map providing algebraic binding, not cryptographic hiding.

Documentation

  • docs/ARCHITECTURE.md
  • docs/DEPLOYMENT.md
  • docs/FEATURE_FLAGS.md
  • docs/API_ENDPOINTS.md
  • docs/IMPLEMENTATION.md
  • docs/SECURITY.md

Components

Layer Purpose Security
Topology Anti-attack wire patterns (non-pow2 distances, uniform usage) Heuristic (empirical)
Lattice (LWE) Control function hiding via LWE with Gaussian noise (σ=25) ~2^112 PQ (n=384)
Obfuscation Circuit representation hiding Heuristic
Wire Binding Inter-gate wire consistency via full-rank linear hash Algebraic binding
Puzzle One-time floor for planted-solution recovery (not per-guess) Computational (q^128 brute-force)
PoW (configurable) On-chain throttling bound to commit-time randomness (per-commit guesses) Protocol-level

Architecture

+--------------------------------------------------------------+
| Input x + puzzle solution s                                  |
+--------------------------------------------------------------+
                              |
                              v
+--------------------------------------------------------------+
| Layer 4: Verify puzzle ||A s - b||^2 < threshold             |
+--------------------------------------------------------------+
                              |
                              v
+--------------------------------------------------------------+
| Wire binding init: acc0 = H(seed || x || H(s))               |
+--------------------------------------------------------------+
                              |
                              v
+--------------------------------------------------------------+
| Gates 0..N: LWE C&C + binding update                         |
+--------------------------------------------------------------+
                              |
                              v
+--------------------------------------------------------------+
| Verify: accN == expected AND output == expectedOutput        |
+--------------------------------------------------------------+

Gas Costs (Measured on Tenderly)

Total gas below is checkWithPuzzle() (includes the puzzle verification).

Config (n=384) Gates Total Gas % of 60M Block
Conservative 64 4,734,943 7%
Balanced 128 5,917,147 9%
Standard 256 8,981,516 14%
Full 640 18,184,574 30%

Optimizations applied:

  • Seed-derived a vectors: 99.6% storage reduction (11 bytes/gate vs 3083 bytes)
  • Wire binding PRG: 16 coefficients per keccak (320 calls vs 4096)
  • Single mod at end of inner product (vs per-term mod)
  • Batch size 128 (binding updates every 128 gates)
  • n=384 LWE dimension with Gaussian noise (σ=25) for ~2^112 PQ security
  • Layer 4 puzzle: n=128, m=192, q=2039 for a one-time q^128 brute-force floor

Storage

TLOS uses seed-derived a vectors - the public LWE vectors are regenerated on-chain from a circuit seed instead of being stored.

Config (n=384) Gates Storage Old Format Savings
Conservative 64 704 bytes 394 KB 99.6%
Balanced 128 1.4 KB 788 KB 99.6%
Full security 256 2.8 KB 1.58 MB 99.6%

Deployment scheme (Tenderly, receipts):

  1. Deploy circuit data via SSTORE2: 662,099 gas (256 gates) / 1,575,259 gas (640 gates)
  2. Deploy puzzle b via SSTORE2: fixed per-m (384 bytes for n=128, m=192)
  3. Deploy TLOS instance (no data duplication): 1,707,897 gas (256) / 1,707,885 gas (640)
  4. Total deploy: 2,454,436 gas (256) / 3,367,584 gas (640)

View vs Transaction costs:

  • check(input): Free (view function, local simulation)
  • reveal(input, puzzleSolution, nonce) / mint(): 4,734,943-18,184,574 gas (state-changing, executes _evaluate() + puzzle)
    • If PoW is disabled, nonce can be 0

Advantage Over Simple Hash Commitments

Why use TLOS instead of keccak256(secret)? For random 256-bit secrets, keccak is simpler and sufficient. However, TLOS provides significant advantage for low-entropy secrets and multi-bit payloads.

Secret Type Keccak Attack (est.) TLOS Attack (GPU)
Random 256-bit ~2^256 hashes min(2^256, ~2^112)
Human password (10^6) Milliseconds ~181 ms
Range 0-100K ~0.1 seconds ~17 ms
4-word phrase Seconds Seconds

Critical limitation: Layer 4 provides only ~0.17 µs per-guess overhead on GPU (5.8M guesses/sec on A100). For low-entropy secrets, dictionary attacks complete in milliseconds to seconds. The "q^128 floor" only applies to recovering the planted solution from (A,b) without guessing the secret.

Attack cost formula:

AttackCost = |Dictionary| × 0.17µs (GPU)
AttackCost = |Dictionary| × 75µs (CPU)

PoW throttles on-chain attempts only; it does not affect offline enumeration. High-entropy secrets are required for security against offline adversaries.

Concrete Use Cases

  • Password-gated vaults: Human phrase unlocks funds
  • On-chain treasure hunts: Riddle answer reveals GPS coordinates or URL
  • Number guessing games: Hide value in 0-100K range without enumeration
  • Multi-code access: OR of N event codes (any code unlocks)
  • Hidden game parameters: Tournament seeds revealed at game start

When to Use Keccak Instead

For random 256-bit secrets with no payload beyond TRUE/FALSE, simple keccak commitments are better (cheaper, simpler, no security loss).

Security Properties

Security is based on standard LWE hardness with Gaussian noise (σ=25). The lattice estimator confirms ~2^112 PQ security for n=384, q=65521, m=2560. See paper/tlos-paper.pdf for full analysis.

Layer 4 Puzzle Parameters

Parameter Value
Secret dimension n 128
Samples m 192
Modulus q 2039
Secret distribution Uniform mod q
Error distribution Uniform {-2,-1,0,1,2}
Threshold 800
Search space q^128 brute-force (lattice estimator ~2^58)
Verification gas 8.62M (Tenderly, 14% of 60M block)

Puzzle recovery cost (one-time): Brute-force search over q^128 is computationally infeasible. The lattice estimator suggests ~2^58 security for current parameters. This does not change low-entropy dictionary asymptotics.

What Wire Binding Provides

  • Mix-and-match prevention: Gates cannot be evaluated with inconsistent inputs
  • Execution trace binding: Full evaluation history is committed
  • Algebraic binding: Full-rank 64x64 matrix provides unique preimage (bijective map)

What Wire Binding Does NOT Provide

  • Cryptographic hiding: The linear map is public and invertible
  • Collision resistance: Trivial to find x given Ax = y
  • Key extraction resistance: Still relies on LWE layer for CF hiding

What TLOS Does NOT Provide

  • iO security: Obfuscations of equivalent circuits are not indistinguishable
  • VBB security: Virtual black-box is impossible in general
  • Long-term secret protection: Not recommended for secrets requiring decades of protection

Quick Start

# Clone
git clone https://github.com/igor53627/tlos.git
cd tlos

# Build contracts
forge build

# Generate circuit data
cargo run --bin generate_tlos -- --secret 0x... --seed 42

# Run benchmarks on Tenderly
source ~/.zsh_secrets
forge script scripts/BenchmarkTLOS.s.sol --rpc-url "$TENDERLY_RPC" --broadcast --unlocked -vvv

Repository Structure

tlos/
├── contracts/
│   ├── TLOSWithPuzzleV5.sol  # Production: 5-layer TLOS (PoW default; difficulty configurable)
│   ├── WeakLWEPuzzleV7.sol   # Production puzzle (n=128, m=192, q^128 brute-force floor)
│   └── interfaces/
│       └── IHoneypot.sol     # Commit-reveal interface
├── src/                       # Rust implementation
│   ├── circuit.rs            # Circuit/gate structures (Layer 1)
│   ├── lwe.rs                # LWE encoding (Layer 2, Gaussian noise, σ=25)
│   ├── wire_binding.rs       # Wire binding implementation (Layer 3)
│   ├── generator.rs          # Deployment generator
│   ├── security/             # Security estimation
│   │   └── lattice_estimator.rs  # lattice-estimator CLI wrapper
│   └── bin/
│       └── generate_tlos.rs  # CLI binary
├── test/                      # Foundry tests (168 tests)
│   ├── TLOSWithPuzzleV5.t.sol    # Production contract tests (61 tests)
│   ├── TLOSWithPuzzleV5Harness.sol  # Test harness for isolated testing
│   ├── PuzzleVariants.t.sol      # Puzzle V7 tests (7 tests)
│   └── *.t.sol               # Example contract tests
├── scripts/
│   ├── BenchmarkTLOS.s.sol   # Tenderly benchmark
│   └── attacks/              # Attack scripts organized by layer
│       ├── layer1-topology/  # SAT/oracle-guided attacks (Rust)
│       ├── layer2-lwe/       # Lattice attacks (Python)
│       ├── layer3-binding/   # Mix-and-match attacks (Python)
│       ├── layer4-puzzle/    # Brute-force attacks (Python/GPU)
│       └── estimators/       # Security estimation tools
├── docs/
│   ├── layers/               # Per-layer technical documentation
│   │   ├── layer1-topology/  # Circuit mixing (heuristic)
│   │   ├── layer2-lwe/       # LWE encryption (~2^112 PQ)
│   │   ├── layer3-binding/   # Wire binding (algebraic)
│   │   └── layer4-puzzle/    # Planted LWE puzzle (q^128 brute-force)
│   ├── SECURITY.md           # Security model
│   └── wire-binding.md       # Wire binding details
├── paper/
│   ├── tlos-paper.pdf        # Full paper (source of truth)
│   └── tlos.pdf              # Short paper
└── examples/
    ├── TLOSDeadManSwitch.sol # Inheritance: Heartbeat + hidden heir codes
    ├── TLOSRecovery.sol      # Wallet: Phrase-based recovery with puzzle
    ├── TLOSSealedAuction.sol # Gaming: Sealed-bid auction with puzzle
    ├── TLOSStopLoss.sol      # DeFi: Hidden stop-loss triggers
    └── TLOSTreasureHunt.sol  # Honeypot: Commit-reveal + puzzle (educational)

Example Contracts

The examples/ directory contains demonstration contracts showing TLOS integration patterns for various use cases. These are for education only - see warnings in each file.

Example Use Case Layers Used Puzzle Production Ready
TLOSWithPuzzleV5 Production 1-5 (all) Yes [OK]
TLOSDeadManSwitch Inheritance 4 (puzzle) Yes [X] Demo only
TLOSRecovery Wallet recovery 4 (puzzle) Yes [X] Needs phrase entropy
TLOSSealedAuction Sealed-bid auction 4 (puzzle) Yes [X] Demo only
TLOSStopLoss Stop-loss trigger 2 (circuit) No [X] Demo only
TLOSTreasureHunt Honeypot 4 (puzzle) Yes [X] Educational

Layer key:

  • Layer 1: Topology mixing (structural)
  • Layer 2: LWE control function hiding (n=384, σ=25 for production)
  • Layer 3: Wire binding (algebraic)
  • Layer 4: Planted LWE puzzle (one-time q^128 brute-force floor for planted-solution recovery)
  • Layer 5: Hash-based PoW (commit-time randomness binding; difficulty configurable)

Testing

TLOS has comprehensive test coverage with 168 tests across all layers:

# Run all tests
forge test

# Run with gas reporting
forge test --gas-report

# Run specific test file
forge test --match-path test/TLOSWithPuzzleV5.t.sol

Key test files:

  • test/TLOSWithPuzzleV5.t.sol - 61 tests for the production contract (deployment, puzzle, wire binding, cross-layer, commit-reveal, gas benchmarks)
  • test/PuzzleVariants.t.sol - 7 tests for the production puzzle V7 (n=128, q^128 brute-force)
  • test/TLOSWithPuzzleV5Harness.sol - Exposes internal functions for isolated layer testing

Security Disclaimer

TLOS security is based on the standard LWE problem with Gaussian noise and the planted LWE puzzle.

  • The ~2^112 PQ estimate (for n=384, σ=25) is confirmed by the lattice estimator
  • Layer 4 puzzle adds a one-time q^128 brute-force floor for recovering the planted solution; lattice estimator ~2^58 for current params
  • Brute-force search over q^128 is computationally infeasible
  • We encourage independent cryptanalysis
  • Attack scripts organized by layer in scripts/attacks/ - see scripts/attacks/README.md
  • Do not use for high-value, long-lived secrets until further analysis is available

Development Dependencies

For programmatic security estimation, set up the lattice-estimator:

# Clone the estimator (requires SageMath)
git clone https://github.com/malb/lattice-estimator estimator
export PYTHONPATH="$PYTHONPATH:$(pwd)/estimator"

# Add the CLI to PATH
export PATH="$PATH:$(pwd)/scripts"

# Verify installation
lattice-estimator-cli 384 65521 \
    --s-dist '{"distribution":"uniform_mod"}' \
    --e-dist '{"distribution":"discrete_gaussian","stddev":25.0}' \
    --m 2560

Then run the ignored tests to validate security parameters:

cargo test -- --ignored

References

License

MIT

About

TLOS: Topology-Lattice Obfuscation for Smart Contracts

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •