Secure Execution Layer (Layer 4) of the TUR55 protocol. Sandboxed MicroPython program execution for ESP32 with encryption, strict resource limits, and isolated runtime.
TUR55 (Trust Unified Regulation) is an open standard for executing blockchain commands on IoT devices. It is blockchain-agnostic, transport-independent, and designed around sandboxed execution.
Author: NOMOS-H Fixed: 2026-04-10 Repository: https://github.com/Tabintaban/Protocol_TUR55
| Layer | Purpose |
|---|---|
| Event Layer | Trigger from a smart contract |
| Executor Layer | Forms the encrypted package |
| Delivery Layer | Transport (MQTT, HTTP, BLE, LoRaWAN, QR) |
| Execution Layer | Sandboxed execution on the device |
ESP32_Python_FUEL implements Layer 4 — Execution Layer.
~95% TUR55/Bronze — Bronze closed.
| Section | Status |
|---|---|
| 3.2 — TUR55 envelope | ✅ |
| 3.4 — Packet format | ✅ works end-to-end |
| 4 — AES-256-GCM | ✅ NIST 3/3 on ESP32 |
| 4 — ECDSA secp256k1 | ✅ |
| 4 — RSA-OAEP | ✅ |
| 4 — BLAKE2s | ✅ |
| 4 — eFuse | ⏳ Gold (not Bronze) |
5 — command_id (replay) |
✅ NVS |
5 — expires |
✅ NTP |
| 6 — whitelist / timeout / memory | ✅ |
| Delivery — MQTT + physical | ✅ |
| 9 — UART log | ✅ |
TUR55/Bronze — closed fully. Pipeline works end-to-end on CPython and ESP32.
See TUR55_COMPLIANCE.md for the full compliance table.
TUR55 packet (bytes)
│
▼
parse_packet() ── ECDSA verify + RSA-OAEP decrypt + AES-GCM decrypt
│
▼
validate envelope 3.2 ── program_loader
│
▼
validate permissions ── execution.permissions
validate runtime limits ── runtime_limit_ms, memory_limit_kb
validate expires ── optional (if time_synced)
validate command_id ── replay protection (FIFO 100)
│
▼
execute_program() ── execution_engine
│
├─ setup (functions + setup lines)
└─ loop (loop_logic lines)
│
▼
sandbox ── execution_sandbox (whitelist + cooperative timeout)
| Module | Purpose |
|---|---|
main.py |
Entry point — standard pipeline |
program_loader.py |
Parse + validate TUR55 envelope |
execution_engine.py |
Setup + loop execution |
execution_sandbox.py |
Sandbox (whitelist, timeout, memory) |
tur55_packet.py |
TUR55 packet format (build + parse) |
gcm_adapter.py |
Unified GCM interface |
gcm.py |
GCM on pure Python (CPython fallback) |
memory_optimizer.py |
Memory management |
| Algorithm | Purpose | Implementation |
|---|---|---|
| AES-256-GCM | Symmetric encryption | C-module on mbedTLS |
| ECDSA secp256k1 | Signature | usecp256k1 (Bitcoin Core) |
| RSA-OAEP | Session key encryption | ucryptography |
| BLAKE2s | Hashing | ucryptography |
Compliance: AES-256-GCM passed NIST SP 800-38D tests (3/3) on ESP32.
CPython compatibility: embit (libsecp256k1-compatible) for signatures.
| Component | Version | Why |
|---|---|---|
| MicroPython | v1.24.1 | Stable release |
| ESP-IDF | v5.2.2 | Compatible with v1.24.1 |
| ESP32 | ESP32-D0WDQ6-V3 (WROOM) | Without PSRAM |
| Python (WSL) | 3.10.12 | ESP-IDF requirement |
ESP-IDF v5.1.2 and v5.3.2 — NOT suitable.
See BUILD_GCM_FIRMWARE.md for full instructions.
Short version:
# Activate ESP-IDF
. ~/esp/esp-idf-v5.2.2/export.sh
# Build MicroPython with C-modules
cd ~/micropython/ports/esp32
rm -rf build-ESP32_GENERIC
make BOARD=ESP32_GENERIC USER_C_MODULES=/home/tavintavan/cmodules/micropython.cmakeThree files, three addresses:
| File | Address |
|---|---|
bootloader.bin |
0x1000 |
partition-table.bin |
0x8000 |
micropython.bin |
0x10000 |
py -m esptool --chip esp32 --port COM3 --baud 460800 write-flash --flash-mode dio --flash-size 4MB --flash-freq 40m -z 0x1000 "bootloader.bin" 0x8000 "partition-table.bin" 0x10000 "micropython.bin"WARNING: Do NOT flash micropython.bin at 0x1000 — this causes boot loop.
Python modules are frozen into firmware (see FIRMWARE_WITH_MANIFEST.md). No need to upload them.
Upload via mpremote (or MicroPico):
secrets.py
esp32_private_key.json
executor_pubkey.bin
programs/program.enc (for FILE-transport)
import main
main.main()Expected output:
[INFO] === TUR55 Pipeline ===
[INFO] Init ProgramLoader...
[INFO] Init ExecutionEngine...
[INFO] Loading packet: test_packet_engine.bin
[INFO] command_id: 0xtest_engine_001
[INFO] permissions: ['time', 'math']
[INFO] runtime_limit_ms: 5000
[INFO] memory_limit_kb: 25
[INFO] Executing program (max_iterations=5)...
setup done, x = 42
loop iter 0 x = 42
...
[INFO] setup success: True
[INFO] loop iterations: 5
[INFO] === Done ===
Create secrets.py in the project root (it is gitignored).
Template:
# secrets.py — NOT in git
WIFI_SSID = "YOUR_SSID"
WIFI_PASSWORD = "YOUR_PASSWORD"
MQTT_BROKER = "broker.emqx.io"
MQTT_TOPIC = "tur55/device/esp32_001"
Without secrets.py:
NTP skipped (expires not checked)
MQTT skipped (only file / programs/program.enc works)
Pipeline works — just no time sync and no network
With secrets.py:
NTP sync on ESP32
MQTT receive (if mqtt_client.py used){
"tur55_version": "1.0",
"command_id": "0x7e5f8a3c",
"device_id": "esp32_001",
"source": {
"smart_contract": "0x1234",
"transaction_hash": "0xabcd",
"block_number": 12345678
},
"execution": {
"user_wallet": "0xUserWallet",
"amount": 50.5,
"expires": 1741500000,
"runtime_limit_ms": 5000,
"memory_limit_kb": 25,
"permissions": ["gpio", "time"],
"functions": [],
"setup": ["led = machine.Pin(2, machine.Pin.OUT)"],
"loop_logic": ["led.value(1)", "time.sleep(0.5)"]
},
"custom_data": {
"action": "unlock",
"duration": 30
}
}Binary, JWE-inspired:
HEADER 8 bytes (magic "TUR5", version, flags)
PUBKEY 1 + 33 (compressed secp256k1)
SESSION_KEY 2 + ~256 (RSA-OAEP encrypted)
SCRIPT 12 + 4 + N + 16 (iv + length + ct + tag)
SIGNATURE 2 + M (DER-encoded ECDSA secp256k1)
Signature covers: HEADER + PUBKEY + SESSION_KEY + SCRIPT
AAD for GCM: HEADER + PUBKEY + SESSION_KEY
import build_packet_cpython
packet = build_packet_cpython.build_packet(
json_data=my_envelope,
esp32_public_key=rsa_pubkey,
executor_sk=ecdsa_secret,
executor_pubkey=ecdsa_pubkey_bytes
)| Measure | Implementation |
|---|---|
| Encryption | AES-256-GCM (NIST 3/3) |
| Signature | ECDSA secp256k1 |
| Key exchange | RSA-OAEP |
| Replay protection | command_id FIFO (100) |
| Sandbox | SafeImporter with whitelist |
| Blocked builtins | eval, exec, compile, open, getattr |
| Timeout | Cooperative (machine.Timer) |
| Memory limit | _check_memory_usage |
| Limits from packet | limit_resources |
machine, time, math, struct, json, gc
sys, _thread, select, socket, ssl, network, uos
| File | Purpose |
|---|---|
| PROJECT_HISTORY.md | Full history (12 sessions) |
| DECISIONS_LOG.md | 31 key decisions |
| ERRORS_AND_SOLUTIONS.md | 28 errors and fixes |
| TODO.md | Current plan |
| TUR55_COMPLIANCE.md | Compliance table |
| CHANGELOG.md | Version history |
| BUILD_GCM_FIRMWARE.md | Firmware build instructions |
| FIRMWARE_WITH_UCRYPTOGRAPHY.md | ucryptography details |
| FIRMWARE_WITH_MANIFEST.md | Firmware build with freeze + gc.threshold |
- eFuse not implemented — Gold level (not Bronze). Keys in
esp32_private_key.json. - Secure boot — Gold level.
- Cooperative timeout — does not interrupt hung C code. No hard guarantee.
used_command_idsin NVS — survives reboot. ✅expireschecked — via NTP. ✅- MQTT / network stack — implemented. ✅
- Physical delivery (
programs/program.enc) — implemented. ✅ - UART log — implemented (Logger → stdout → UART0). ✅
| Test | Platform | Purpose |
|---|---|---|
test_program_loader.py |
CPython | ProgramLoader |
test_loader_replay.py |
CPython | Replay + expires (4/4) |
test_engine_cpython.py |
CPython | Engine |
test_gcm.py |
CPython | GCM (NIST 3/3) |
tests/ (pytest) |
CPython | Sandbox, Engine, Memory (5/5) |
test_engine_esp32.py |
ESP32 | Engine (hardware) |
test_esp32.py |
ESP32 | ProgramLoader (hardware) |
test_tur55_packet_esp32.py |
ESP32 | Packet format (hardware) |
test_gcm_esp32.py |
ESP32 | GCM (C-module) |
test_rsa_esp32.py |
ESP32 | RSA-OAEP (hardware) |
ESP32_Python_FUEL/
│
├── main.py # Entry point — standard pipeline
├── program_loader.py # Parse + validate TUR55 envelope
├── execution_engine.py # Setup + loop execution
├── execution_sandbox.py # Sandbox (whitelist, timeout, memory)
├── tur55_packet.py # TUR55 packet format (build + parse)
├── gcm_adapter.py # Unified GCM interface
├── gcm.py # Pure Python GCM (CPython fallback)
├── memory_optimizer.py # Memory management
├── mqtt_client.py # MQTT receiver (ESP32)
├── time_sync.py # NTP time sync (ESP32)
│
├── build_packet_cpython.py # Packet builder (executor side)
├── build_test_packet_cpython.py # Test packet builder
├── mqtt_publisher.py # MQTT publisher (CPython)
│
├── test_program_loader.py # ProgramLoader (CPython)
├── test_loader_replay.py # Replay + expires (CPython)
├── test_engine_cpython.py # Engine (CPython)
├── test_engine_esp32.py # Engine (ESP32)
├── test_esp32.py # ProgramLoader (ESP32)
├── test_tur55_packet_esp32.py # Packet (ESP32)
├── test_gcm.py # GCM (CPython)
├── test_gcm_esp32.py # GCM (ESP32)
├── test_rsa_esp32.py # RSA-OAEP (ESP32)
│
├── tests/ # Unit tests (pytest-style)
│ ├── __init__.py
│ ├── test_execution_engine.py
│ ├── test_execution_sandbox.py
│ └── test_memory_optimizer.py
│
├── patches/ucryptography/ # ucryptography patches
│ ├── des3_stubs.c # 3DES stubs (DES was removed in ESP-IDF v5.0)
│ ├── micropython.cmake # Integration of ucryptography into the MicroPython build
│ └── modcryptography.c # Patch for mp_obj_int_to_bytes (wrapper for v1.24.1)
│
├── programs/ # Offline packets (TUR55 physical delivery)
│ └── readme.md
├── data/ # Decrypted HTML/CSS/JS (future)
│ └── readme.md
├── utils/ # Utilities
│ └── readme.md
├── .vscode/ # VS Code settings
│ └── settings.json
│
├── PROJECT_HISTORY.md # 12 sessions
├── DECISIONS_LOG.md # 31 decisions
├── ERRORS_AND_SOLUTIONS.md # 28 errors
├── TODO.md # Current plan (Bronze closed)
├── TUR55_COMPLIANCE.md # Compliance table (~95% Bronze)
├── CHANGELOG.md # v3.4.1
├── BUILD_GCM_FIRMWARE.md # Firmware build
├── FIRMWARE_WITH_UCRYPTOGRAPHY.md # ucryptography details
├── README.md # This file
├── README_RU.md # Russian version
├── LICENSE.md # MIT
└── .gitignore
Runtime artifacts (gitignored):
esp32_private_key.json— RSA private key of ESP32executor_pubkey.bin— secp256k1 pubkey of executortest_packet_engine.bin— test packetsecrets.py— Wi-Fi credentials (SSID, password)programs/*.enc— offline packets (physical delivery)
Released under the MIT License.
Based on the TUR55 Standard (Trust Unified Regulation), author: NOMOS-H. Original specification: https://github.com/Tabintaban/Protocol_TUR55
- TUR55 Standard: https://github.com/Tabintaban/Protocol_TUR55
- MicroPython v1.24.1: https://github.com/micropython/micropython/releases/tag/v1.24.1
- ESP-IDF v5.2.2: https://github.com/espressif/esp-idf/tree/v5.2.2
- NIST SP 800-38D: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
- mbedTLS GCM: https://mbed-tls.readthedocs.io/en/latest/kb/how-to/encrypt-with-aes-gcm/
- ucryptography: https://github.com/dmazzella/ucryptography
- secp256k1-embedded-ecdh: https://github.com/MicroPythonOS/secp256k1-embedded-ecdh
- embit: https://github.com/diybitcoinhardware/embit