Skip to content

orthonode/Stylus-Hardware-Anchor

Repository files navigation

Stylus Hardware Anchor (SHA)

CI License Arbitrum Rust ESP32 Sepolia

Hardware truth as a primitive. Silicon identity on-chain. No TEE. No secure element. Just a $5 chip.


The Problem Nobody Has Fixed

DePIN networks assume their nodes are real hardware. But nobody proves it.

Right now, anyone can spin up a hundred virtual machines, register a hundred identities, and farm rewards β€” and the chain has no idea. Software identities are trivially faked. Serial numbers can be cloned. Private keys can be copied. ZKPs prove computation correctness, not that the source data is real.

The gap is at the silicon level.


What SHA Does

Stylus Hardware Anchor (SHA) is a reusable hardware identity verification primitive for Arbitrum Stylus smart contracts. It cryptographically binds the immutable eFuse identifiers inside an ESP32-S3 microcontroller to on-chain execution logic.

eFuses are burned into the chip during fabrication. They are permanent. They cannot be changed. They cannot be emulated. A virtual machine has no eFuse.

SHA turns that physical fact into an on-chain guarantee.


Why This Is Only Possible on Stylus

Running receipt verification in Solidity is prohibitively expensive. The Keccak reconstruction, counter enforcement, and batch validation logic requires computation that would make per-receipt gas costs unviable at scale.

Stylus changes the economics:

Batch Size Total Gas Gas Per Receipt
N=5 148,741 29,748
N=10 202,090 20,209
N=20 308,387 15,419
N=50 628,201 12,564

Gas per receipt drops sharply as batch size grows β€” native-compiled WASM amortization at work. This is impossible to replicate in Solidity at these costs.


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              LAYER 1 β€” SILICON (ESP32-S3)               β”‚
β”‚                                                         β”‚
β”‚  Manufacturer-burned eFuse identifiers                  β”‚
β”‚  Base MAC (6 bytes) + Chip Model (1 byte)               β”‚
β”‚  β†’ Keccak-256 (Ethereum-compatible, 0x01 padding)       β”‚
β”‚  β†’ 32-byte Hardware Identity (HW_ID)                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚ HW_ID + Firmware Hash + Counter
                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            LAYER 2 β€” MIDDLEWARE (Python SDK)            β”‚
β”‚                                                         β”‚
β”‚  Receipt generation and signing                         β”‚
β”‚  Device authorization flows                             β”‚
β”‚  On-chain submission helpers                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚ Packed receipt blob (bytes)
                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         LAYER 3 β€” VERIFICATION (Stylus / Rust / WASM)  β”‚
β”‚                                                         β”‚
β”‚  1. Identity Check:    authorized_nodes[hw_id] == true  β”‚
β”‚  2. Firmware Gate:     approved_firmware[fw_hash] == trueβ”‚
β”‚  3. Replay Protection: counter > counters[hw_id]        β”‚
β”‚  4. Digest Verify:     Keccak-256 reconstruction        β”‚
β”‚                                                         β”‚
β”‚  β†’ ReplayDetected()   if counter already used           β”‚
β”‚  β†’ DigestMismatch()   if receipt tampered               β”‚
β”‚  β†’ Status 1           if all four checks pass           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Receipt Format (117 bytes)

Field Size Value
Protocol ID 13 bytes "anchor_RCT_V1"
Hardware ID 32 bytes Keccak-256(eFuse data)
Firmware Hash 32 bytes Keccak-256(firmware binary)
Execution Hash 32 bytes Keccak-256(computation result)
Counter 8 bytes Monotonic uint64 (Big-Endian)
Total 117 bytes β†’ Keccak-256 β†’ 32-byte digest

Four On-Chain Guarantees

Device-Bound Identity β€” 1 physical chip = 1 on-chain identity, derived from manufacturer-burned eFuse registers that cannot be changed or cloned.

Replay Protection β€” Monotonic counter enforcement via ReplayDetected() custom error. Each receipt can be processed exactly once. The counter state is stored per hardware ID on-chain.

Firmware Governance β€” Execution is restricted to firmware hashes explicitly approved by the contract owner. Unauthorized firmware versions are rejected at the contract level.

Deterministic Verification β€” Ethereum-compatible Keccak-256 (0x01 padding) across all three layers β€” ESP32 firmware, Python middleware, and Stylus contract β€” with 10,000+ cross-validated test vectors confirming cryptographic parity.


Live Evidence

Artifact Link
Stylus Contract 0xD661a1aB8CEFaaCd78F4B968670C3bC438415615
On-chain Activity 89+ verified transactions on Arbiscan
Deploy TX 0x1a9eaa02f816d86a71f9bf234425e83b5c090d1f3e4f3691851964b71747a489
Activate TX 0x353d26f4dea36a4410454b7b081cc41610f691dfea7ce29d5c9b1e9aa968f955
WASM sha256 4c00997c2bb00e8b786f2ea9d4e3eb87600bf6995bf4e3dd4debf6c473a5bd26
Gas Benchmarks See BENCHMARKS.md
v1.0.0 Release View Release

Quick Start

Prerequisites

  • Rust + cargo-stylus (v0.6.3)
  • Python 3.10+
  • Foundry (cast)
  • An Arbitrum Sepolia RPC URL

Setup

git clone https://github.com/arhantbarmate/stylus-hardware-anchor
cd stylus-hardware-anchor
cp .env.example .env
# Edit .env with your RPC_URL, CONTRACT_ADDRESS, PRIVATE_KEY, HW_ID, FW_HASH

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Run Gas Benchmarks

# First run β€” setup + benchmark
python scripts/run_gas_benchmarks.py --setup --batch-fn bitset --sizes "1,5,10,20"

# Subsequent runs β€” benchmark only (state already initialized)
python scripts/run_gas_benchmarks.py --batch-fn bitset --sizes "1,5,10,20,50"

Note: Always use --setup on the first run or after contract redeployment. The setup phase runs initialize(), authorizeNode(), and approveFirmware() to prepare contract state. Without it, all verification calls will revert.

Key Cast Commands

# Read contract state
cast call $CONTRACT "isNodeAuthorized(bytes32)(bool)" $HW_ID --rpc-url $RPC_URL
cast call $CONTRACT "isFirmwareApproved(bytes32)(bool)" $FW_HASH --rpc-url $RPC_URL
cast call $CONTRACT "getCounter(bytes32)(uint64)" $HW_ID --rpc-url $RPC_URL

# Admin setup (owner only)
cast send $CONTRACT "authorizeNode(bytes32)" $HW_ID --rpc-url $RPC_URL --private-key $PK
cast send $CONTRACT "approveFirmware(bytes32)" $FW_HASH --rpc-url $RPC_URL --private-key $PK

Important: Stylus SDK 0.6.x exports camelCase ABI names. Always use authorizeNode not authorize_node, verifyReceipt not verify_receipt. Snake_case will produce a different selector and revert with 0x.


Known Limitations

Single-call verifyReceipt counter synchronization β€” The single-call verification path has a counter synchronization issue with the batch path. Batch verification is the primary and recommended interface. This is under investigation and will be addressed in v0.2.

ReplayDetected() after batch runs β€” This is correct behavior, not a bug. The monotonic counter advances with each batch, so single-call verification using an already-consumed counter value correctly reverts. This demonstrates SHA's core replay protection working as designed.

Research prototype β€” The current deployed contract at 0xD661a1aB8CEFaaCd78F4B968670C3bC438415615 has not undergone a professional third-party audit. Treat it as a testnet research prototype. Mainnet deployment is deferred to Phase 2.


Technical Challenges Overcome

Building cross-layer cryptographic parity between C firmware, Python middleware, and Rust/WASM contracts required solving several non-obvious problems:

Keccak-256 vs NIST SHA-3 β€” Standard ESP32 libraries provide SHA-3 (0x06 padding). Ethereum uses Keccak-256 (0x01 padding). The digests are different. SHA implements a custom Keccak-256 on the ESP32 with Ethereum-compatible padding, validated against 10,000+ cross-layer test vectors.

Stylus SDK 0.6.x camelCase ABI export β€” The SDK exports external method names in camelCase, not snake_case. Calling authorize_node computes a different 4-byte selector than authorizeNode. Documented in CAST_CHEATSHEET.md and fixed in all scripts.

ruint dependency conflict β€” Stylus SDK pulled ruint v1.17.2 requiring unstable edition2024. Fixed via Cargo.toml git patch forcing v1.12.3.

Unaligned memory access on ESP32 β€” Direct uint64_t* casting in the Keccak implementation caused undefined behavior on strict architectures. Replaced with byte-wise XOR throughout.

See DEBUGGING_POSTMORTEM.md and TECHNICAL_CHALLENGES.md for full details.


Roadmap

Phase 1 β€” Current Grant Scope ($25,000 β€” Under Review)

Arbitrum Sepolia testnet only β€” 6 months β€” Single milestone

Milestone 1 β€” Security Hardening & Developer Release ($25,000)

  • Hardened Stylus verification contract with full input validation and edge-case handling
  • Coverage-guided fuzz validation (β‰₯1,000,000 execution cycles via cargo-fuzz)
  • Cryptographic parity validation suite (β‰₯10,000 device ↔ contract Keccak-256 test vectors)
  • Reproducible gas benchmark scripts with public performance documentation
  • Threat model and attack surface documentation
  • Tagged developer-ready GitHub release with deterministic build instructions

Phase 2 β€” Future Scope (Separate Grant)

  • Python SDK (anchor-verifier) published to PyPI
  • Rust crate (stylus-hardware-primitives) published to crates.io
  • Reference integration templates deployable on Sepolia
  • Professional third-party security audit
  • Mainnet deployment
  • Hardware expansion to ARM Cortex-M and RISC-V targets
  • Ecosystem integrations with Orbit-based DePIN networks

Documentation Index

Document Contents
SETUP_GUIDE.md Environment setup and dependencies
BENCHMARKS.md Gas benchmarks with reproducible scripts
docs/ARCHITECTURE.md Detailed system design
docs/DEPLOYMENT_GUIDE.md Contract deployment walkthrough
docs/CAST_CHEATSHEET.md All cast commands with correct ABI names
docs/DEBUGGING_POSTMORTEM.md ABI export and revert resolution
docs/TECHNICAL_CHALLENGES.md Engineering challenges and solutions
docs/MILESTONE_1.md Prototype validation evidence

Grant Status

  • Arbitrum Foundation Ecosystem Support Program grant: $25,000 β€” under review
  • No funding received to date. Pre-revenue infrastructure project.

License

MIT β€” See LICENSE


Built by Orthonode Infrastructure Labs β€” hardware-rooted verification for Arbitrum.

About

The first protocol-level bridge anchoring physical ESP32-S3 silicon identity into Arbitrum Stylus. Enabling Sybil-resistant DePIN and verifiable hardware-bound execution via Rust/WASM.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors