A modular, multi-node ESP32 anti-tracking decoy swarm. summon the crowd, bury the signal.
142
stars
602
commits
C
primary language
Sep 11, 2026
updated
root@simulacra:~# ./summon --crowd --bury-signal
██████ ██▓ ███▄ ▄███▓ █ ██ ██▓ ▄▄▄ ▄████▄ ██▀███ ▄▄▄
▒██ ▒ ▓██▒▓██▒▀█▀ ██▒ ██ ▓██▒▓██▒ ▒████▄ ▒██▀ ▀█ ▓██ ▒ ██▒▒████▄
░ ▓██▄ ▒██▒▓██ ▓██░▓██ ▒██░▒██░ ▒██ ▀█▄ ▒▓█ ▄ ▓██ ░▄█ ▒▒██ ▀█▄
▒ ██▒░██░▒██ ▒██ ▓▓█ ░██░▒██░ ░██▄▄▄▄██ ▒▓▓▄ ▄██▒▒██▀▀█▄ ░██▄▄▄▄██
▒██████▒▒░██░▒██▒ ░██▒▒▒█████▓ ░██████▒▓█ ▓██▒▒ ▓███▀ ░░██▓ ▒██▒ ▓█ ▓██▒
▒ ▒▓▒ ▒ ░░▓ ░ ▒░ ░ ░░▒▓▒ ▒ ▒ ░ ▒░▓ ░▒▒ ▓▒█░░ ░▒ ▒ ░░ ▒▓ ░▒▓░ ▒▒ ▓▒█░
░ ░▒ ░ ░ ▒ ░░ ░ ░░░▒░ ░ ░ ░ ░ ▒ ░ ▒ ▒▒ ░ ░ ▒ ░▒ ░ ▒░ ▒ ▒▒ ░
░ ░ ░ ▒ ░░ ░ ░░░ ░ ░ ░ ░ ░ ▒ ░ ░░ ░ ░ ▒
░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░
summon the crowd · bury the signal [ ble · wifi · esp-now ]
A modular, multi-node ESP32 anti-tracking system. Simulacra continuously fabricates a churning crowd of plausible-but-fake wireless devices around you - drowning your real devices in noise so that passive trackers, ALPR add-ons, and co-travel correlators can't reliably pick your signal out of the crowd - while passively watching for the trackers that follow you.
It is built from cooperating nodes, each playing to a different board's strengths, coordinated over an encrypted ESP-NOW link.
Try it in your browser - no toolchain. Plug in a board and flash a starter fleet at em3ritus.github.io/simulacra (desktop Chrome/Edge).
Jump to: Legal · How it works · Architecture · Features · Security model · Hardware · Build & flash · Repo layout · Offline tools · Recent updates · Contributing · Credits · License · Wiki
Simulacra is a research and personal-privacy tool. It transmits synthetic BLE/Wi-Fi advertising traffic and observes the RF around you. You are responsible for complying with the radio regulations and laws in your jurisdiction. Do not use it to harass, impersonate a specific person or device, interfere with networks or emergency services, or evade lawful process. Use it on hardware you own, in ways that are legal where you are. No warranty; see the license.
TURBO is not a DoS mode. It's still in-spec, non-connectable BLE advertising and standard 802.11 probe requests at legal power - no deauth, no jamming, no malformed frames. A handful of ESP32 boards cannot meaningfully deny service to nearby real networks or clients; what it does is raise the volume of traffic someone has to process. The same rules above apply to it.
These follow directly from the design rather than being gaps waiting to be filled, so they're worth stating plainly.
presence_duration is the weakest axis on the audit scorecard, deliberately. It's the measured
cost of the 15-minute ceiling. Closing it by re-adding long-lived identities is the one fix that
must not be applied, and tools/decoy_audit/tests/test_addr_onair_cap.py exists to fail if someone
tries.| Node | Board | Role |
|---|---|---|
| Ward | ESP32-C5 (dual-band Wi-Fi 6) | Fixed / vehicle decoy - dense, dual-band crowd generation |
| Shade | ESP32-C6 | Mobile / everyday-carry decoy - lean, 2.4 GHz, low-profile |
| Vigil | ESP32 + "Cheap Yellow Display" | Controller & librarian - radar/status screen, touch control, encrypted SD library, fleet key custody |
Roles are selected at build time so one firmware tree serves every board. ESP32-C5 (Ward) is the suggested board to start with - dual-band, and it takes and charges its own battery - so a minimal build is one C5 + one Vigil. ESP32-C6 (Shade) remains fully supported for anyone who wants the lower-power/everyday-carry variant.
ADDR_MAX_ONAIR_MS),
matching real-phone RPA rotation: RPAs/NRPAs rotate on realistic schedules, and static addresses
honour the same ceiling by dying and being reborn as wholly new devices rather than rotating - an
address whose top two bits declare "I am static" must not rotate, or it contradicts itself on air.-DSIMULACRA_FLEET_PROVISION=1 - rotates
automatically with tools/gen_ctrl_key.py). The baked-key demo regime still keys it from a
published, non-secret placeholder constant - an accepted tradeoff for that regime, matching its
documented "shared key, not private" posture elsewhere.CLOAKED / EXPOSED when there's no crowd to hide in / HUNTED when a follower is confirmed /
DARK) - plus a live radar/threat display, grouped status pages, a per-node fleet roster, and
enroll/revoke control for fleet members. Tap in for depth: a per-node telemetry console, a
per-threat detail card (device class, confidence, vendor, persistence), a two-page system
console + colour legend, and signed fleet control - all from the touch panel, no laptop.DEGRADED or LOW BATT node on its roster before it goes quiet in the field.esptool read_flash. Revoke a lost or captured board immediately
(fleet roster → REVOKE) - this rotates the whole fleet onto a new key and re-enrolls the survivors,
cutting the compromised board out. Until you do, treat a missing decoy as a live risk to the mesh's
confidentiality, not just a lost board.Specific boards and part numbers: see web/README.md's board table. For what
every screen and setting on the Vigil console does once it's flashed, see the
project wiki.
The fastest way to try Simulacra:
Open it in desktop Chrome or Edge, plug in a board, click Connect & Flash - the
browser web-flasher (ESP Web Tools / Web Serial) auto-detects the chip and installs the right
role (C5 → Ward, C6 → Shade, ESP32 → CYD), no ESP-IDF and no command line. It installs the
baked starter regime (shared public key), so it's for trying Simulacra out, not a private
deployment. Source and self-host notes: web/.
Requires ESP-IDF - v5.5 for the C5 decoy, v5.4 for the C6 decoy and the Vigil (classic ESP32). With the IDF environment active:
# Decoy (Ward / Shade) - from the repo root
idf.py set-target esp32c5 # or esp32c6 for Shade
idf.py -DSIMULACRA_ESPNOW=1 -DSIMULACRA_CONFIG_CTRL=1 -DSIMULACRA_FLEET_PROVISION=1 build
idf.py -p <PORT> flash monitor
# Vigil controller - from ./cyd
cd cyd
idf.py set-target esp32
idf.py -DSIMULACRA_CONFIG_CTRL=1 -DSIMULACRA_FLEET_PROVISION=1 build
idf.py -p <PORT> flash monitor
Build-time gates (-D…=1) select each node's role and optional subsystems (fleet control,
enrollment, self-test). See docs/ for design specs and per-feature notes.
Fleet-key regime must match across the whole fleet. With -DSIMULACRA_FLEET_PROVISION=1
(shown above) the Vigil mints a random fleet key at first boot and grants it to decoys through
enrollment - so decoys need the flag too, or they fall back to the baked compile-time key, never
receive the grant, and stay invisible to the controller even while healthy. To run the simpler
baked-key regime instead, omit -DSIMULACRA_FLEET_PROVISION=1 from every node (all then share
the key in components/simulacra_radar/radar_key.h). Changing any -D… flag needs a clean build
(rm -rf build sdkconfig) so the old define doesn't linger.
Rotate the CONTROL signing key before real use. -DSIMULACRA_CONFIG_CTRL=1 (shown above) is a
separate keypair from the fleet-transport key: whoever holds it can sign presets and CLEAR THREATS
commands for every node trusting the matching public key. The committed placeholder bytes
(cyd/main/sim_ctrl_sk.h.example) are public knowledge - they're in this repo's git history -
so a fleet left on them has no real control-plane authentication. Regenerate before deploying
anything you care about:
python tools/gen_ctrl_key.py # rewrites the secret + public key headers
then rebuild and reflash every board together (decoys bake the new public key, the Vigil the new secret) - a half-rotated fleet stops verifying.
main/ decoy firmware (churn, lifecycle, probes, self-learning, detection, ESP-NOW)
cyd/ Vigil controller firmware (display, touch, SD librarian, fleet authority)
components/simulacra_radar/ shared code (wire formats, learning, signatures, rendering)
components/tweetnacl/ vendored TweetNaCl (Ed25519 / X25519)
tools/pcap_learn/ replay a BLE capture through the real learn/detect pipeline
tools/decoy_audit/ score how separable the BLE decoys are from a real crowd
tools/probe_audit/ verify Wi-Fi probe frames are archetype-faithful and Law-3 safe
tools/radar_audit/ verify the Vigil console's render/control/fleet-status logic on the host
tools/seq_gate/ post-flash check that each fake phone's 802.11 sequence stays independent
web/ browser web-flasher (ESP Web Tools) - flash a starter fleet with no toolchain
docs/ design specs, implementation plans, and the roadmap
Simulacra's host tools compile the real firmware code (not reimplementations), so behaviour is verified against the same source that runs on-device:
tools/pcap_learn/ - replay a BLE capture (.pcap or .pcapng) through the actual
self-learning pipeline (validate structure-only learning, emit a seed library) and the tracker
matcher with dwell/co-travel analysis.tools/decoy_audit/ - compile the real BLE generator on the host and score how separable the
synthetic crowd is from a real capture, as a ranked scorecard plus a single regression-gate number.tools/probe_audit/ - byte-exact verification that the Wi-Fi probe frames match the
capture-derived IE structures, and that directed-SSID probes only ever name generic public
networks from a fixed compiled-in pool - never one sourced from observed or local traffic.tools/radar_audit/ - compiles the Vigil console's own render/control/fleet-status code on the
host, so every screen (radar, node/threat detail, INFO console, CONTROL presets) and the fleet
aggregation logic (stale-node pruning, threat dedup, live-vs-pending preset) are verified against
the exact source that runs on the CYD.tools/seq_gate/ - a two-board post-flash gate confirming each fake phone keeps its own
802.11 sequence counter after an IDF/toolchain bump.Each tool has its own README with build and run steps.
Newest first - full history in CHANGELOG.md. Forward-looking milestones live in
docs/ROADMAP.md.
MIXED fleet), and a
signed, two-tap CLEAR THREATS control.Issues welcome - bug reports, questions, hardware requests. PRs aren't being merged yet - see
CONTRIBUTING.md for why and what to expect.
Originally forked from and built on 0xXyc/splinter - the project that started the idea. Simulacra extends it into a multi-node, self-learning, fleet-managed system.
GNU GPL v3.0. Simulacra is derived from 0xXyc/splinter, which carries no license file of its own - its author has confirmed directly that splinter was written for others to build on. The current codebase is almost entirely original work; the small remainder still tracing back to those early files is covered by that same permission.
C
72.7%
Python
24.6%
PowerShell
1.4%
A modular, multi-node ESP32 anti-tracking decoy swarm. summon the crowd, bury the signal.
142
stars
602
commits
C
primary language
Sep 11, 2026
updated
root@simulacra:~# ./summon --crowd --bury-signal
██████ ██▓ ███▄ ▄███▓ █ ██ ██▓ ▄▄▄ ▄████▄ ██▀███ ▄▄▄
▒██ ▒ ▓██▒▓██▒▀█▀ ██▒ ██ ▓██▒▓██▒ ▒████▄ ▒██▀ ▀█ ▓██ ▒ ██▒▒████▄
░ ▓██▄ ▒██▒▓██ ▓██░▓██ ▒██░▒██░ ▒██ ▀█▄ ▒▓█ ▄ ▓██ ░▄█ ▒▒██ ▀█▄
▒ ██▒░██░▒██ ▒██ ▓▓█ ░██░▒██░ ░██▄▄▄▄██ ▒▓▓▄ ▄██▒▒██▀▀█▄ ░██▄▄▄▄██
▒██████▒▒░██░▒██▒ ░██▒▒▒█████▓ ░██████▒▓█ ▓██▒▒ ▓███▀ ░░██▓ ▒██▒ ▓█ ▓██▒
▒ ▒▓▒ ▒ ░░▓ ░ ▒░ ░ ░░▒▓▒ ▒ ▒ ░ ▒░▓ ░▒▒ ▓▒█░░ ░▒ ▒ ░░ ▒▓ ░▒▓░ ▒▒ ▓▒█░
░ ░▒ ░ ░ ▒ ░░ ░ ░░░▒░ ░ ░ ░ ░ ▒ ░ ▒ ▒▒ ░ ░ ▒ ░▒ ░ ▒░ ▒ ▒▒ ░
░ ░ ░ ▒ ░░ ░ ░░░ ░ ░ ░ ░ ░ ▒ ░ ░░ ░ ░ ▒
░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░
summon the crowd · bury the signal [ ble · wifi · esp-now ]
A modular, multi-node ESP32 anti-tracking system. Simulacra continuously fabricates a churning crowd of plausible-but-fake wireless devices around you - drowning your real devices in noise so that passive trackers, ALPR add-ons, and co-travel correlators can't reliably pick your signal out of the crowd - while passively watching for the trackers that follow you.
It is built from cooperating nodes, each playing to a different board's strengths, coordinated over an encrypted ESP-NOW link.
Try it in your browser - no toolchain. Plug in a board and flash a starter fleet at em3ritus.github.io/simulacra (desktop Chrome/Edge).
Jump to: Legal · How it works · Architecture · Features · Security model · Hardware · Build & flash · Repo layout · Offline tools · Recent updates · Contributing · Credits · License · Wiki
Simulacra is a research and personal-privacy tool. It transmits synthetic BLE/Wi-Fi advertising traffic and observes the RF around you. You are responsible for complying with the radio regulations and laws in your jurisdiction. Do not use it to harass, impersonate a specific person or device, interfere with networks or emergency services, or evade lawful process. Use it on hardware you own, in ways that are legal where you are. No warranty; see the license.
TURBO is not a DoS mode. It's still in-spec, non-connectable BLE advertising and standard 802.11 probe requests at legal power - no deauth, no jamming, no malformed frames. A handful of ESP32 boards cannot meaningfully deny service to nearby real networks or clients; what it does is raise the volume of traffic someone has to process. The same rules above apply to it.
These follow directly from the design rather than being gaps waiting to be filled, so they're worth stating plainly.
presence_duration is the weakest axis on the audit scorecard, deliberately. It's the measured
cost of the 15-minute ceiling. Closing it by re-adding long-lived identities is the one fix that
must not be applied, and tools/decoy_audit/tests/test_addr_onair_cap.py exists to fail if someone
tries.| Node | Board | Role |
|---|---|---|
| Ward | ESP32-C5 (dual-band Wi-Fi 6) | Fixed / vehicle decoy - dense, dual-band crowd generation |
| Shade | ESP32-C6 | Mobile / everyday-carry decoy - lean, 2.4 GHz, low-profile |
| Vigil | ESP32 + "Cheap Yellow Display" | Controller & librarian - radar/status screen, touch control, encrypted SD library, fleet key custody |
Roles are selected at build time so one firmware tree serves every board. ESP32-C5 (Ward) is the suggested board to start with - dual-band, and it takes and charges its own battery - so a minimal build is one C5 + one Vigil. ESP32-C6 (Shade) remains fully supported for anyone who wants the lower-power/everyday-carry variant.
ADDR_MAX_ONAIR_MS),
matching real-phone RPA rotation: RPAs/NRPAs rotate on realistic schedules, and static addresses
honour the same ceiling by dying and being reborn as wholly new devices rather than rotating - an
address whose top two bits declare "I am static" must not rotate, or it contradicts itself on air.-DSIMULACRA_FLEET_PROVISION=1 - rotates
automatically with tools/gen_ctrl_key.py). The baked-key demo regime still keys it from a
published, non-secret placeholder constant - an accepted tradeoff for that regime, matching its
documented "shared key, not private" posture elsewhere.CLOAKED / EXPOSED when there's no crowd to hide in / HUNTED when a follower is confirmed /
DARK) - plus a live radar/threat display, grouped status pages, a per-node fleet roster, and
enroll/revoke control for fleet members. Tap in for depth: a per-node telemetry console, a
per-threat detail card (device class, confidence, vendor, persistence), a two-page system
console + colour legend, and signed fleet control - all from the touch panel, no laptop.DEGRADED or LOW BATT node on its roster before it goes quiet in the field.esptool read_flash. Revoke a lost or captured board immediately
(fleet roster → REVOKE) - this rotates the whole fleet onto a new key and re-enrolls the survivors,
cutting the compromised board out. Until you do, treat a missing decoy as a live risk to the mesh's
confidentiality, not just a lost board.Specific boards and part numbers: see web/README.md's board table. For what
every screen and setting on the Vigil console does once it's flashed, see the
project wiki.
The fastest way to try Simulacra:
Open it in desktop Chrome or Edge, plug in a board, click Connect & Flash - the
browser web-flasher (ESP Web Tools / Web Serial) auto-detects the chip and installs the right
role (C5 → Ward, C6 → Shade, ESP32 → CYD), no ESP-IDF and no command line. It installs the
baked starter regime (shared public key), so it's for trying Simulacra out, not a private
deployment. Source and self-host notes: web/.
Requires ESP-IDF - v5.5 for the C5 decoy, v5.4 for the C6 decoy and the Vigil (classic ESP32). With the IDF environment active:
# Decoy (Ward / Shade) - from the repo root
idf.py set-target esp32c5 # or esp32c6 for Shade
idf.py -DSIMULACRA_ESPNOW=1 -DSIMULACRA_CONFIG_CTRL=1 -DSIMULACRA_FLEET_PROVISION=1 build
idf.py -p <PORT> flash monitor
# Vigil controller - from ./cyd
cd cyd
idf.py set-target esp32
idf.py -DSIMULACRA_CONFIG_CTRL=1 -DSIMULACRA_FLEET_PROVISION=1 build
idf.py -p <PORT> flash monitor
Build-time gates (-D…=1) select each node's role and optional subsystems (fleet control,
enrollment, self-test). See docs/ for design specs and per-feature notes.
Fleet-key regime must match across the whole fleet. With -DSIMULACRA_FLEET_PROVISION=1
(shown above) the Vigil mints a random fleet key at first boot and grants it to decoys through
enrollment - so decoys need the flag too, or they fall back to the baked compile-time key, never
receive the grant, and stay invisible to the controller even while healthy. To run the simpler
baked-key regime instead, omit -DSIMULACRA_FLEET_PROVISION=1 from every node (all then share
the key in components/simulacra_radar/radar_key.h). Changing any -D… flag needs a clean build
(rm -rf build sdkconfig) so the old define doesn't linger.
Rotate the CONTROL signing key before real use. -DSIMULACRA_CONFIG_CTRL=1 (shown above) is a
separate keypair from the fleet-transport key: whoever holds it can sign presets and CLEAR THREATS
commands for every node trusting the matching public key. The committed placeholder bytes
(cyd/main/sim_ctrl_sk.h.example) are public knowledge - they're in this repo's git history -
so a fleet left on them has no real control-plane authentication. Regenerate before deploying
anything you care about:
python tools/gen_ctrl_key.py # rewrites the secret + public key headers
then rebuild and reflash every board together (decoys bake the new public key, the Vigil the new secret) - a half-rotated fleet stops verifying.
main/ decoy firmware (churn, lifecycle, probes, self-learning, detection, ESP-NOW)
cyd/ Vigil controller firmware (display, touch, SD librarian, fleet authority)
components/simulacra_radar/ shared code (wire formats, learning, signatures, rendering)
components/tweetnacl/ vendored TweetNaCl (Ed25519 / X25519)
tools/pcap_learn/ replay a BLE capture through the real learn/detect pipeline
tools/decoy_audit/ score how separable the BLE decoys are from a real crowd
tools/probe_audit/ verify Wi-Fi probe frames are archetype-faithful and Law-3 safe
tools/radar_audit/ verify the Vigil console's render/control/fleet-status logic on the host
tools/seq_gate/ post-flash check that each fake phone's 802.11 sequence stays independent
web/ browser web-flasher (ESP Web Tools) - flash a starter fleet with no toolchain
docs/ design specs, implementation plans, and the roadmap
Simulacra's host tools compile the real firmware code (not reimplementations), so behaviour is verified against the same source that runs on-device:
tools/pcap_learn/ - replay a BLE capture (.pcap or .pcapng) through the actual
self-learning pipeline (validate structure-only learning, emit a seed library) and the tracker
matcher with dwell/co-travel analysis.tools/decoy_audit/ - compile the real BLE generator on the host and score how separable the
synthetic crowd is from a real capture, as a ranked scorecard plus a single regression-gate number.tools/probe_audit/ - byte-exact verification that the Wi-Fi probe frames match the
capture-derived IE structures, and that directed-SSID probes only ever name generic public
networks from a fixed compiled-in pool - never one sourced from observed or local traffic.tools/radar_audit/ - compiles the Vigil console's own render/control/fleet-status code on the
host, so every screen (radar, node/threat detail, INFO console, CONTROL presets) and the fleet
aggregation logic (stale-node pruning, threat dedup, live-vs-pending preset) are verified against
the exact source that runs on the CYD.tools/seq_gate/ - a two-board post-flash gate confirming each fake phone keeps its own
802.11 sequence counter after an IDF/toolchain bump.Each tool has its own README with build and run steps.
Newest first - full history in CHANGELOG.md. Forward-looking milestones live in
docs/ROADMAP.md.
MIXED fleet), and a
signed, two-tap CLEAR THREATS control.Issues welcome - bug reports, questions, hardware requests. PRs aren't being merged yet - see
CONTRIBUTING.md for why and what to expect.
Originally forked from and built on 0xXyc/splinter - the project that started the idea. Simulacra extends it into a multi-node, self-learning, fleet-managed system.
GNU GPL v3.0. Simulacra is derived from 0xXyc/splinter, which carries no license file of its own - its author has confirmed directly that splinter was written for others to build on. The current codebase is almost entirely original work; the small remainder still tracing back to those early files is covered by that same permission.
C
72.7%
Python
24.6%
PowerShell
1.4%