docs(privshield): rebrand project to "WiFi Veil"

Adopt "WiFi Veil" as the product name across all user-facing surfaces, keeping
VEIL (Verifiable Emission-shaping for Identity-Leakage prevention) as the
technical codename it's built on. Only prose, titles, descriptions, and the
console UI change — no code identifiers, file names, crate/npm `name` fields,
or the deterministic proof witness are touched, so `cargo test` and the C-core
host test are unaffected.

- Crate & research READMEs: title + defining line now "WiFi Veil (codename VEIL — …)".
- Cargo.toml / package.json / plugin.json descriptions: "WiFi Veil …".
- Console UI (veil-console.html): title, brand, and copy say "WiFi Veil".
- Firmware tree (README, per-provider READMEs, BUILD/INTEGRATION/MEASUREMENT):
  "WiFi Veil protector/core/shield".
- Harness manifest: recomputed SHA-256 digests for the four changed packaged
  files (README, package.json, CLAUDE.md, plugin.json) — all verified consistent.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01WEXNqzs7UsfNFBcP5yW21p
This commit is contained in:
Claude
2026-08-09 16:52:40 +00:00
parent b827dc40b1
commit 1c2b383075
17 changed files with 90 additions and 88 deletions
+13 -12
View File
@@ -1,10 +1,11 @@
# Privacy Shield Research Bundle — VEIL
# Privacy Shield Research Bundle — WiFi Veil
**VEIL** (Verifiable Emission-shaping for Identity-Leakage prevention) is a
privacy *firewall* for WiFi sensing: it prevents unauthorized identity and
**WiFi Veil** (codename **VEIL** Verifiable Emission-shaping for
Identity-Leakage prevention) is a privacy *firewall* for WiFi sensing: it
prevents unauthorized identity and
activity inference from a room's WiFi while preserving normal communications. It
is the **countermeasure** counterpart to [BFLD](../BFLD/) — where BFLD *detects*
when beamforming feedback becomes identifying, VEIL *acts* by shaping the node's
when beamforming feedback becomes identifying, WiFi Veil *acts* by shaping the node's
own compliant waveform (channel sounding, precoder phase, beam/feedback
schedules) so identity and activity inference fail, while a legitimate receiver
sees an essentially unchanged link.
@@ -21,14 +22,14 @@ transmission (the statutory definition of jamming, 47 U.S.C. §333/§302a).
| File | Purpose |
|------|---------|
| [01-sota-survey.md](01-sota-survey.md) | State of the art: identity/activity inference attacks (BFI + CSI), the IEEE 802.11bf-2025 standard, and privacy-preserving countermeasures |
| [02-threat-model.md](02-threat-model.md) | Adversary classes, what VEIL defends and what it explicitly does not, trust boundary |
| [02-threat-model.md](02-threat-model.md) | Adversary classes, what WiFi Veil defends and what it explicitly does not, trust boundary |
| [03-countermeasure-design.md](03-countermeasure-design.md) | The compliant waveform controls, the separable-subspace principle, keyed Givens-rotation shield, and how it maps to the crate |
| [04-compliance-and-regulatory.md](04-compliance-and-regulatory.md) | The legal line between compliant waveform control and jamming, with statutory citations |
| [05-experiment-protocol.md](05-experiment-protocol.md) | The attacker-vs-protector experiment: metrics, acceptance bar, reproducer, and results |
| [06-market-and-buyers.md](06-market-and-buyers.md) | First buyers, procurement drivers, competitive landscape, and the standards-body gap |
| [07-implementation-and-roadmap.md](07-implementation-and-roadmap.md) | Crate layout, reuse map, hardware path, phased rollout, and open problems |
| [08-optimization.md](08-optimization.md) | Hyper-optimization: throughput-optimal feedback resolution, minimum robust mixing budget, Pareto frontier, and the adopted config |
| [09-sota-update-2026.md](09-sota-update-2026.md) | 20252026 SOTA update (verified, cited): stronger attacks (BFI→CSI reconstruction, through-wall vitals, keystroke), validated compliant defenses, and the derived VEIL improvement backlog |
| [09-sota-update-2026.md](09-sota-update-2026.md) | 20252026 SOTA update (verified, cited): stronger attacks (BFI→CSI reconstruction, through-wall vitals, keystroke), validated compliant defenses, and the derived WiFi Veil improvement backlog |
Formal decision: [ADR-288](../../adr/ADR-288-veil-privacy-shield-compliant-waveform.md).
Reference implementation: [`v2/crates/wifi-densepose-privshield`](../../../v2/crates/wifi-densepose-privshield).
@@ -60,9 +61,9 @@ Reference implementation: [`v2/crates/wifi-densepose-privshield`](../../../v2/cr
cannot coexist with wanted WiFi. The whitespace is a **selective, coexisting,
software/PHY** shield.
4. **The VEIL mechanism.** Identity leaks through the *fine* cross-subcarrier
4. **The WiFi Veil mechanism.** Identity leaks through the *fine* cross-subcarrier
phase structure of a beamforming report; throughput rides the *dominant*
beam direction. These are (mostly) separable subspaces. VEIL composes extra
beam direction. These are (mostly) separable subspaces. WiFi Veil composes extra
**keyed Givens rotations** over the fine subspace only. The rotation is
*orthogonal* (energy-preserving ⇒ not jamming), *keyed per session* (the
legitimate receiver inverts it ⇒ throughput preserved), and *fresh each
@@ -79,9 +80,9 @@ Reference implementation: [`v2/crates/wifi-densepose-privshield`](../../../v2/cr
[08-optimization.md](08-optimization.md)). Reproduce:
`cargo test -p wifi-densepose-privshield`.
6. **Scope, honestly.** VEIL defends against a *third-party passive sniffer*. It
6. **Scope, honestly.** WiFi Veil defends against a *third-party passive sniffer*. It
does **not** hide identity from the associated AP (that party holds the key)
— that is BFLD's detection/policy problem. VEIL is a reference model, not
— that is BFLD's detection/policy problem. WiFi Veil is a reference model, not
hardware: real-silicon validation (per CLAUDE.md) is future work with a
captured-log witness.
@@ -94,8 +95,8 @@ Per repository policy, every quantitative claim is tagged:
- **MEASURED** — from a cited primary source with its metric and conditions.
- **CLAIMED** — asserted by a source (vendor PR, press, standards minutes)
without an independent measurement.
- **SYNTHETIC** — produced by VEIL's own deterministic model; reproduced by
- **SYNTHETIC** — produced by WiFi Veil's own deterministic model; reproduced by
`cargo test`, describing the model and not real hardware.
WiFi sensing is never presented here as camera-grade, and no VEIL result implies
WiFi sensing is never presented here as camera-grade, and no WiFi Veil result implies
a defense guarantee on real silicon until a hardware witness exists.
+7 -7
View File
@@ -1,8 +1,8 @@
# VEIL privacy shield — end-to-end hardware implementation
# WiFi Veil privacy shield — end-to-end hardware implementation
This tree is the **hardware/firmware realization** of the VEIL compliant-waveform
This tree is the **hardware/firmware realization** of the WiFi Veil compliant-waveform
privacy shield (crate `wifi-densepose-privshield`, ADR-288; hardware program
ADR-290). It takes VEIL from a synthetic reference model toward real silicon
ADR-290). It takes WiFi Veil from a synthetic reference model toward real silicon
across multiple hardware providers.
> **Evidence discipline (read this first).** Everything here is **build-only /
@@ -64,19 +64,19 @@ across multiple hardware providers.
## Feasibility matrix
Grades reflect *capability to actually shape the beamforming-feedback surface*
(the waveform VEIL must touch), **not** effort. Each grade is taken from that
(the waveform WiFi Veil must touch), **not** effort. Each grade is taken from that
provider's own README, produced by a hardware research agent; the effort/blocker
reality is in the "Why" column. All rows are `SYNTHETIC / L0` — build-only, no
silicon, no captured log.
| Provider | Grade | Can it shape the BF-feedback surface? | Why |
|---|:---:|---|---|
| **openwifi** (Zynq + AD9361, open PHY/MAC) | **B** | **Yes — the only full path.** Capability ceiling **A**; graded B for effort **D**. | Only platform exposing the whole PHY/MAC on FPGA, so a keyed rotation *and its inverse* are physically reachable. But it ships SISO 802.11a/g/n with **no native explicit beamforming** (no NDP sounding, no SVD `V`, no compressed report), so VEIL is realized as the client-transparent per-packet keyed unitary on the TX spatial-mapping stage — which requires **new HDL + a 2nd TX chain + a Vivado rebuild**. Carries the P5 measurement protocol. |
| **openwifi** (Zynq + AD9361, open PHY/MAC) | **B** | **Yes — the only full path.** Capability ceiling **A**; graded B for effort **D**. | Only platform exposing the whole PHY/MAC on FPGA, so a keyed rotation *and its inverse* are physically reachable. But it ships SISO 802.11a/g/n with **no native explicit beamforming** (no NDP sounding, no SVD `V`, no compressed report), so WiFi Veil is realized as the client-transparent per-packet keyed unitary on the TX spatial-mapping stage — which requires **new HDL + a 2nd TX chain + a Vivado rebuild**. Carries the P5 measurement protocol. |
| **openwrt** (Linux `mac80211`; mt76 / ath9k / ath1x) | **C** | **Partial — coarse compliant knobs only.** | The per-packet keyed unitary on the compressed-BF angles / LTF precoder is generated **inside the WiFi MCU firmware blob** on every mainstream AP part (Qualcomm ath10k/11k/12k, MediaTek mt76/mt7915) — userspace never touches the pre-TX `V`. Reachable from userspace: TX antenna-map perturbation, hostapd sounding-cadence jitter, beamformer-capability toggles. **ath9k** (802.11n, register-open) is the one credible driver-patch route toward B. |
| **nexmon** (Broadcom/Cypress C-firmware patch; e.g. BCM43455c0) | **C** | **Read = A (solved); write = C/C-.** | *Reading* the compressed-BF angles is already solved (nexmon_csi + Wi-BFI, no firmware change). *Shaping the transmitted* report is graded C: the report is emitted by the proprietary **D11 real-time core** ~10 µs after the NDP, from hardware-updated internal memory — *below* the ARM firmware where Nexmon's C hooks live. Plausible, deep, firmware-version-specific, unproven here. |
| **esp32** (Espressif ESP-IDF) | **F** / **B** | **F** as a self-protecting node; **B** as a supporting device. | The BF-report is emitted by the **closed `esp-phy-lib` blob** with no ESP-IDF hook to intercept or rotate it (`esp_wifi_80211_tx` won't hand-craft sounding feedback) — so **F (infeasible)** for shaping its own feedback. It earns **B (build-only)** in three legitimate, compliance-only supporting roles: **sensing detector** (CSI-rate trigger for the AP-side shield) and **RIS controller** (drive an external passive reconfigurable surface — the honest way ESP32 "helps scramble", via an external surface, never its own PHY). |
**Reading the grades.** Only **openwifi** can host the full keyed-reversible VEIL
**Reading the grades.** Only **openwifi** can host the full keyed-reversible WiFi Veil
design end-to-end (and only after real HDL work). **openwrt** and **nexmon** are
partial: the exact angles are blob-/ucode-locked on commodity silicon, leaving
either coarse compliant perturbations (openwrt) or a deep, unproven ucode-adjacent
@@ -88,7 +88,7 @@ external surface — never by shaping its own transmission.**
## Two firmware variants
- **Keyed-reversible** (VEIL's ~98%-throughput design): the protector rotates and
- **Keyed-reversible** (WiFi Veil's ~98%-throughput design): the protector rotates and
the associated receiver undoes it with the shared key — needs changes on
**both** ends + key agreement. Best result; needs an open PHY (openwifi) for a
true demo, or the client-transparent AP-side variant below.
+7 -7
View File
@@ -1,4 +1,4 @@
# VEIL on ESP32 — feasibility and honest scope
# WiFi Veil on ESP32 — feasibility and honest scope
**Status: `SYNTHETIC / L0` (build-only).** Everything in this directory is an
ESP-IDF component *skeleton*. Nothing here has been flashed, run, or captured on
@@ -18,7 +18,7 @@ surface*.
supporting roles.**
The ESP32 **cannot shape its own transmitted 802.11 beamforming feedback.** The
VEIL shield works by perturbing the *compressed beamforming feedback report* (the
WiFi Veil shield works by perturbing the *compressed beamforming feedback report* (the
Givens/phi-psi angles a station sends back to an AP) with a keyed orthogonal
rotation. On the ESP32 that report is generated **inside the closed Espressif
Wi-Fi PHY/MAC binary blob** (`esp-phy-lib`, shipped in object form; the Wi-Fi
@@ -30,23 +30,23 @@ and action* frames with the PHY choosing the actual precoding — it will not le
you hand-craft the VHT/HE sounding-feedback subtype with a chosen precoder. So
the ESP32 is **not** a beamforming-feedback protector.
**Feasibility grade for "ESP32 as a self-protecting VEIL node": F (infeasible).**
**Feasibility grade for "ESP32 as a self-protecting WiFi Veil node": F (infeasible).**
The one waveform we need to touch is behind a blob with no hook.
**Feasibility grade for "ESP32 as a VEIL supporting device": B (feasible,
**Feasibility grade for "ESP32 as a WiFi Veil supporting device": B (feasible,
build-only).** Three legitimate roles below, best-first.
---
## What the ESP32 can and cannot do
| Capability | ESP-IDF surface | VEIL-relevant? | Verdict |
| Capability | ESP-IDF surface | WiFi Veil-relevant? | Verdict |
|---|---|---|---|
| Read CSI (channel state) | `esp_wifi_set_csi_config` / `esp_wifi_set_csi_rx_cb` / `esp_wifi_set_csi` | Yes — detect *being sensed* | **CAN** (observe only) |
| Promiscuous / sniffer RX | `esp_wifi_set_promiscuous` | Yes — more CSI, frame cadence | **CAN** (observe only) |
| Inject raw mgmt/data frames | `esp_wifi_80211_tx` (beacon, probe, action, non-QoS data only) | Marginal; not for BF feedback | **CAN (limited)** |
| Drive external GPIO/SPI hardware | `gpio_*`, `spi_master_*` | Yes — control an external RIS | **CAN** |
| Shape its own **beamforming feedback** (compressed BF report angles) | *none* — generated in closed PHY blob | This is the actual VEIL waveform | **CANNOT** |
| Shape its own **beamforming feedback** (compressed BF report angles) | *none* — generated in closed PHY blob | This is the actual WiFi Veil waveform | **CANNOT** |
| Choose/replace its own **precoding matrix** | *none* — PHY-internal | Yes, but inaccessible | **CANNOT** |
| Modify the Wi-Fi PHY / `esp-phy-lib` | *none* — object-only, NDA | — | **CANNOT** |
@@ -63,7 +63,7 @@ it does so without the ESP32 emitting any RF of its own.
### 1. `veil_sensing_detector/` — sensing-solicitation detector (strongest, clearly compliant)
Uses the CSI callback (+ promiscuous RX) to estimate how often the node is being
sounded/solicited, and raises an engage **trigger** (GPIO / MQTT / ESP-NOW) that
tells the *AP-side* VEIL shield (running the portable `../core/veil_shield.c`) to
tells the *AP-side* WiFi Veil shield (running the portable `../core/veil_shield.c`) to
turn on. Pure observe-plus-control-signal; the ESP32 shapes nothing on air. This
is the role we would actually build first.
+2 -2
View File
@@ -1,4 +1,4 @@
# Building the VEIL Nexmon patch — **UNTESTED**
# Building the WiFi Veil Nexmon patch — **UNTESTED**
> **This procedure has never been run.** It has not been built with the Nexmon
> toolchain, not flashed, and not captured on air. Addresses/symbols in
@@ -53,7 +53,7 @@ The core is `no_std`-style C99: no malloc, no libc I/O, only `<math.h>`
- link a small `libm`/`compiler-rt` for `arm-none-eabi`;
- or replace the trig with a fixed-point / CORDIC Givens rotation
(`TODO(reverse-engineer)`), which also avoids float on parts without an FPU.
3. All VEIL working storage is stack-bounded (`VEIL_MAX_FINE`, `CACHE` in the
3. All WiFi Veil working storage is stack-bounded (`VEIL_MAX_FINE`, `CACHE` in the
core) — no heap is introduced on-chip.
## Build
+4 -4
View File
@@ -1,6 +1,6 @@
# VEIL protector — Nexmon (Broadcom/Cypress) path
# WiFi Veil protector — Nexmon (Broadcom/Cypress) path
C-firmware-patch adapter that would call the portable VEIL core
C-firmware-patch adapter that would call the portable WiFi Veil core
(`../core/veil_shield.{h,c}`) on the compressed-beamforming-feedback **angles
before transmission**, using the [Nexmon](https://github.com/seemoo-lab/nexmon)
patching framework on a Broadcom/Cypress WiFi chip.
@@ -35,7 +35,7 @@ core**, a proprietary microcontroller running a programmable state machine
("ucode"). Published reverse-engineering of these chips reports that the D11
generates the **VHT/HE compressed beamforming report ~10 µs after the NDP**, with
its contents fetched from an **internal memory updated directly by the hardware**
on NDP reception. In other words, the angles VEIL wants to touch are staged and
on NDP reception. In other words, the angles WiFi Veil wants to touch are staged and
emitted inside the ucode/PHY path on a microsecond deadline — *below* the ARM
"wl" driver firmware where Nexmon's C hooks (`__attribute__((at(addr, ...)))`
flashpatches / branch hooks) live most reliably. Reaching them means either a
@@ -83,7 +83,7 @@ The skeleton wires candidate **#1** and leaves #2/#3 documented but unimplemente
## What is realistic
- **Realistic now:** verify VEIL's *effect* by reading — capture the shaped vs.
- **Realistic now:** verify WiFi Veil's *effect* by reading — capture the shaped vs.
unshaped report with `nexmon_csi`/Wi-BFI and confirm the fine subspace changed
while energy (SNR/norm) is preserved. This validates the math, not the TX hook.
- **Realistic with serious RE effort:** candidate #1, on one pinned firmware, as
+3 -3
View File
@@ -1,10 +1,10 @@
# P5 measurement protocol — openwifi VEIL end-to-end
# P5 measurement protocol — openwifi WiFi Veil end-to-end
> **STATUS: SYNTHETIC / L0 — this is a PLAN, not a result. No hardware has been
> run; no capture, log, or number in this repo is real.** This document defines
> exactly what must be executed and captured to earn the first `MEASURED` claim
> under CLAUDE.md's hardware-evidence rule. Until the witness artifact below
> exists, every accuracy/throughput/energy statement about openwifi VEIL is
> exists, every accuracy/throughput/energy statement about openwifi WiFi Veil is
> `SYNTHETIC` and must be labelled so. **Compliant waveform controls only —
> orthogonal, energy-preserving; never jamming.**
@@ -47,7 +47,7 @@ per-packet keying uses `(key, packet_counter)` as in `HDL_NOTES.md`.
## Procedure
Run every condition **twice**: VEIL **OFF** (baseline) and **ON**. Same
Run every condition **twice**: WiFi Veil **OFF** (baseline) and **ON**. Same
positions, same MCS, same duration, same seed for the attacker model.
1. **Correctness precondition (not a defense claim).** Confirm on-FPGA
+2 -2
View File
@@ -1,4 +1,4 @@
# VEIL protector — openwifi (Xilinx Zynq + AD9361, open PHY/MAC)
# WiFi Veil protector — openwifi (Xilinx Zynq + AD9361, open PHY/MAC)
> **STATUS: SYNTHETIC / L0 — build-only scaffold. No hardware, no flash, no
> capture. Nothing here has run on silicon.** Per CLAUDE.md, none of this is a
@@ -31,7 +31,7 @@ highest-*effort* path:
fmcomms2/3 has two DACs) plus a new spatial-mapping RTL stage and a Vivado
rebuild — days-to-weeks of FPGA work, not a driver patch.
Because of (1), on openwifi VEIL is realized as the **client-transparent
Because of (1), on openwifi WiFi Veil is realized as the **client-transparent
per-packet keyed unitary** (LeakyBeam family) applied at the TX spatial-mapping
stage, with the legitimate STA (a second openwifi node sharing the key)
inverting it — **not** as obfuscation of a compressed-BF report the hardware
+3 -3
View File
@@ -1,4 +1,4 @@
# VEIL ↔ `mac80211` / driver integration map
# WiFi Veil ↔ `mac80211` / driver integration map
> **`SYNTHETIC / L0` — BUILD-ONLY, UNTESTED ON HARDWARE.** These are hook-point
> designs derived from public API/source, not validated on silicon. Function and
@@ -47,7 +47,7 @@ Legend: **US** = userspace-reachable today · **DP** = needs driver patch ·
firmware change to honor an externally supplied grouping. Not reachable without
both a driver and firmware patch.
## 4. Per-packet keyed unitary (the core VEIL transform) — **FW** (blob-blocked)
## 4. Per-packet keyed unitary (the core WiFi Veil transform) — **FW** (blob-blocked)
- **Daemon:** `veil_apply_keyed_rotation()` → `veil_shield_apply(fine, n, key,
passes)` from the portable core. Orthogonal / energy-preserving (the
@@ -85,7 +85,7 @@ Legend: **US** = userspace-reachable today · **DP** = needs driver patch ·
## Summary of the effort boundary
| Control | Effort to reach full VEIL fidelity |
| Control | Effort to reach full WiFi Veil fidelity |
|---|---|
| TX antenna map | Ready now (US), coarse only |
| Sounding cadence jitter | Wire hostapd `ctrl_iface` (US), coarse only |
+6 -6
View File
@@ -1,4 +1,4 @@
# VEIL — OpenWRT / Linux `mac80211` adapter
# WiFi Veil — OpenWRT / Linux `mac80211` adapter
> **STATUS: `SYNTHETIC / L0` — BUILD-ONLY, UNTESTED ON HARDWARE.**
> No radio was driven, no CSI captured, no log produced on silicon. Every
@@ -6,7 +6,7 @@
> adapter uses **compliant waveform controls only** — it never jams and emits
> no denial energy.
This directory is the OpenWRT/`mac80211` platform adapter for the VEIL privacy
This directory is the OpenWRT/`mac80211` platform adapter for the WiFi Veil privacy
shield. It links the validated portable core
(`../core/veil_shield.{h,c}` — the keyed Givens rotation over the identity-bearing
"fine" subspace of 802.11 compressed beamforming feedback) and drives the subset
@@ -16,7 +16,7 @@ of controls that Linux userspace/`mac80211` can actually reach on commodity APs.
## Feasibility grade: **C** (partial — coarse compliant controls only)
**Why C, not higher.** VEIL's defining action is a *per-packet keyed unitary* on
**Why C, not higher.** WiFi Veil's defining action is a *per-packet keyed unitary* on
the compressed beamforming-feedback angles (equivalently, a keyed Q on the LTF
spatial mapping / precoder). On every mainstream OpenWRT AP chipset
(Qualcomm ath10k/ath11k/ath12k, MediaTek mt76 / mt7915), that report is generated
@@ -25,7 +25,7 @@ open driver never touch the pre-transmit V matrix. So the full keyed-rotation pa
is **blob-blocked** from OpenWRT. What remains reachable is a set of *coarse*
compliant knobs that perturb, but do not cryptographically obfuscate, the CSI a
sensor observes. That is a real, honest defense-in-depth layer — hence C, not D —
but it is not the full VEIL transform.
but it is not the full WiFi Veil transform.
**Why not D.** Some controls genuinely work from userspace (TX antenna map;
hostapd-mediated sounding/beamformer capability), and one chipset family
@@ -38,14 +38,14 @@ A-grade keyed rotation, but those are **separate adapters**, not OpenWRT.
## What is FEASIBLE vs. BLOB-BLOCKED from OpenWRT
| VEIL control | Reachable from OpenWRT? | Mechanism (real API / knob) | Notes |
| WiFi Veil control | Reachable from OpenWRT? | Mechanism (real API / knob) | Notes |
|---|---|---|---|
| **TX antenna-map perturbation** | ✅ Feasible | `NL80211_CMD_SET_WIPHY` + `NL80211_ATTR_WIPHY_ANTENNA_TX` / `_RX` | Coarse static spatial-mapping change. Many drivers require phy DOWN and symmetric masks. Compliant. |
| **NDP sounding-cadence jitter** | 🟡 Indirect | hostapd `ctrl_iface` (rewrite `SOUNDING-DIMENSION`, toggle `[SU-BEAMFORMER]`, `RECONFIGURE`) | No `nl80211` "set sounding interval" exists; the per-NDP timer lives in driver/firmware. We can only jitter the *offered* capability. |
| **Beamformer/beamformee capability toggle** | ✅ Feasible | hostapd `vht_capab` / `he_su_beamformer` etc. | Standards-compliant advertisement. Coarse on/off, not per-packet. |
| **Spatial-stream → antenna mapping (static Q)** | 🟡 Driver-patch (ath9k only) | ath9k PHY spatial-mapping registers (`AR_PHY_*`) | Open enough to patch on ath9k; opaque/firmware on ath10k+/mt76. Not a stock userspace knob. |
| **MU-MIMO group shuffling** | ❌ Blob-blocked | would need `NL80211_CMD_VENDOR` subcmd that upstream mt76/ath do **not** expose | Group formation + steering matrices computed in MCU firmware. |
| **Per-packet keyed unitary on LTF / precoder** | ❌ Blob-blocked | — | The core VEIL transform. Lives in firmware on all commodity AP parts. Requires firmware patch, or use openwifi / Nexmon adapters. |
| **Per-packet keyed unitary on LTF / precoder** | ❌ Blob-blocked | — | The core WiFi Veil transform. Lives in firmware on all commodity AP parts. Requires firmware patch, or use openwifi / Nexmon adapters. |
| **Compressed-BF-report angle edit (φ/ψ)** | ❌ Blob-blocked | — | Report is generated in firmware/PHY; not exposed pre-TX on OpenWRT. |
| **External sensing-solicitation detection (NDPA cadence)** | 🟡 Partial | `NL80211_CMD_FRAME` + `NL80211_CMD_REGISTER_FRAME`, or monitor-mode capture | Commodity drivers do not forward raw NDPA to userspace by default. |
@@ -1,7 +1,7 @@
{
"name": "wifi-densepose-privshield-harness",
"version": "0.1.0",
"description": "Harness for wifi-densepose-privshield (VEIL privacy shield)",
"description": "Harness for wifi-densepose-privshield (WiFi Veil privacy shield)",
"author": {
"displayName": "Generated by metaharness",
"url": "https://www.npmjs.com/package/metaharness"
@@ -5,17 +5,17 @@
"template_version": "0.0.0",
"vars": {
"name": "wifi-densepose-privshield-harness",
"description": "Harness for wifi-densepose-privshield (VEIL privacy shield)",
"description": "Harness for wifi-densepose-privshield (WiFi Veil privacy shield)",
"host": "claude-code"
},
"hosts": ["claude-code"],
"files": {
".claude/settings.json": "fedb60921a0e3c78848f43edddd75f448819594c680d48ff2033ef8f1588da3f",
".claude-plugin/plugin.json": "7831dc3d1b9b5363130a59ce680794bfe0b6ca09c73d77a7ce78aa6ec3921c5a",
".claude-plugin/plugin.json": "8b155a3130d212c88dd8b631d9bd6dd1b4eacb52e5eb282fddbe08576ae23be2",
"bin/cli.js": "1133e7a47accada1c9b2184873776d8ca0d028f9b76dd55f467dfe38bb9ce609",
"CLAUDE.md": "c5bd71bfc0699021a284a54ffa70f4784b8238774c6d6fcfedf836f5e37d10f8",
"package.json": "e32acd6e5e630b0db9abccc5f5f58f86f291ccfc23b4c8410b380c01024a23df",
"README.md": "be5b0a17cd051dafe8cd825ddf778c91971993419f9e33c0898e21140249f72a",
"CLAUDE.md": "f9ccf20c341ff0296b2e64ce692103572d61e856ae0df8a8bc4c35a7ac8b2ff5",
"package.json": "1ccedf0e62b0ed884431a2a9192a3865b525a2dad72fa6491569b9001e7dd24f",
"README.md": "688e207f95e4f58eeade84f149c38fa8ec048796556a7b1bd75f08ee1945edba",
"src/init.ts": "f05d6905d8681f45f610ff5b6e9d425dfa66183acdfe7857248e50e3583e13b8",
"src/router.ts": "4545b42d1423db21bcfe6ab6bf132b805ba383937d142997cb7256e835c245e4",
"src/flywheel.ts": "aab56d82c4f018ddc83923c877a66acdf9c624214307d0a9c4bf930ddb00599a",
+6 -6
View File
@@ -1,7 +1,7 @@
# wifi-densepose-privshield-harness
Harness for [`wifi-densepose-privshield`](../../v2/crates/wifi-densepose-privshield)
(VEIL — the compliant-waveform WiFi-sensing privacy shield, ADR-288). This
(WiFi Veil — the compliant-waveform WiFi-sensing privacy shield, ADR-288). This
package is defined by ADR-289.
> Advanced Coding harness · domain: `software-engineering`. Modeled on the
@@ -13,18 +13,18 @@ package is defined by ADR-289.
- Use the harness's tools for orchestration; memory and routing are handled by
the kernel.
- Defer destructive operations to the user.
- **Never present WiFi sensing as camera-grade, and never relabel VEIL's
- **Never present WiFi sensing as camera-grade, and never relabel WiFi Veil's
SYNTHETIC/L0 results as MEASURED** — a hardware witness is required first
(CLAUDE.md hardware rule; ADR-282 ladder). The harness is a development aid;
it does not run a radio and cannot emit RF.
- VEIL uses compliant waveform controls only — **never jamming.** Do not add,
- WiFi Veil uses compliant waveform controls only — **never jamming.** Do not add,
suggest, or scaffold interference-based "defenses."
## Commands
- `init` — boot the kernel + host adapter.
- `doctor` — verify the install end-to-end (kernel, host, guidance map).
- `guidance --topic <t> [--query <q>]` — read-only VEIL capability map
- `guidance --topic <t> [--query <q>]` — read-only WiFi Veil capability map
(dependency-free; topics: `overview`, `threat`, `countermeasure`,
`compliance`, `optimization`, `experiment`). Source-cited and
evidence-labelled; navigation only, not authority.
@@ -58,8 +58,8 @@ installed.
## Relationship to the crate
This harness assists development *on* the VEIL crate; it does not replace the
crate's own gates. The authoritative validation for a VEIL change is still:
This harness assists development *on* the WiFi Veil crate; it does not replace the
crate's own gates. The authoritative validation for a WiFi Veil change is still:
```bash
cargo test -p wifi-densepose-privshield --no-default-features
+7 -7
View File
@@ -1,11 +1,11 @@
# wifi-densepose-privshield-harness
A metaharness (contributor harness) for
[`wifi-densepose-privshield`](../../v2/crates/wifi-densepose-privshield) — **VEIL**,
[`wifi-densepose-privshield`](../../v2/crates/wifi-densepose-privshield) — **WiFi Veil**,
the compliant-waveform WiFi-sensing privacy shield (ADR-288). Defined by ADR-289.
> **Advanced Coding** — architect → implement → review → test, plus a
> dependency-free VEIL guidance surface. Modeled on `wifi-densepose-sar-harness`
> dependency-free WiFi Veil guidance surface. Modeled on `wifi-densepose-sar-harness`
> (ADR-286). Multi-host scaffold with a kernel that resolves native → wasm → js.
## Install
@@ -27,7 +27,7 @@ npx wifi-densepose-privshield-harness guidance --topic overview
|---|---|---|
| `init` | kernel + host | Boot the kernel + host adapter |
| `doctor` | kernel + host | Verify the install end-to-end |
| `guidance --topic <t>` | **none** | Read-only VEIL capability map (source-cited, evidence-labelled) |
| `guidance --topic <t>` | **none** | Read-only WiFi Veil capability map (source-cited, evidence-labelled) |
| `route <e0..e3>` | router + `npm run build` | Cost-optimal model routing |
| `flywheel [gens]` | flywheel + `npm run build` | SYNTHETIC self-improvement demo |
@@ -35,9 +35,9 @@ npx wifi-densepose-privshield-harness guidance --topic overview
`optimization`, `experiment`. It needs no dependencies or build step, so it
works offline and in CI before `npm install`.
## What VEIL is
## What WiFi Veil is
VEIL shapes a node's **own** beamforming feedback with keyed Givens rotations so
WiFi Veil shapes a node's **own** beamforming feedback with keyed Givens rotations so
a third-party passive sniffer cannot re-identify people, while a keyed receiver
sees an essentially unchanged link. **Compliant waveform controls only — never
jamming.** Reference results are **SYNTHETIC / evidence level L0** (reproduced by
@@ -59,9 +59,9 @@ for what is real wiring vs. illustrative/synthetic data.
## Scope
The harness is a **development aid**. It does not run a VEIL radio, does not
The harness is a **development aid**. It does not run a WiFi Veil radio, does not
emit RF, and cannot jam. It does not replace the crate's own gates — the
authoritative check for a VEIL change is `cargo test -p wifi-densepose-privshield`.
authoritative check for a WiFi Veil change is `cargo test -p wifi-densepose-privshield`.
## License
@@ -1,7 +1,7 @@
{
"name": "wifi-densepose-privshield-harness",
"version": "0.1.0",
"description": "Harness for wifi-densepose-privshield (VEIL — compliant-waveform WiFi-sensing privacy shield, ADR-288/289)",
"description": "Harness for wifi-densepose-privshield (WiFi Veil — compliant-waveform WiFi-sensing privacy shield, ADR-288/289)",
"license": "MIT",
"type": "module",
"bin": {
@@ -1,6 +1,6 @@
[package]
name = "wifi-densepose-privshield"
description = "VEIL privacy shield (ADR-288): compliant-waveform countermeasure against unauthorized WiFi sensing. Deterministic attacker-vs-protector experiment that drives beamforming-feedback identity inference toward chance while preserving link throughput. Std-only pure-compute leaf, no async/server/RF-hardware deps; SYNTHETIC data only."
description = "WiFi Veil privacy shield (ADR-288): compliant-waveform countermeasure against unauthorized WiFi sensing. Deterministic attacker-vs-protector experiment that drives beamforming-feedback identity inference toward chance while preserving link throughput. Std-only pure-compute leaf, no async/server/RF-hardware deps; SYNTHETIC data only."
version = "0.1.0"
edition.workspace = true
authors.workspace = true
@@ -12,7 +12,7 @@ categories.workspace = true
readme = "README.md"
# Intentionally dependency-free (mirrors `wifi-densepose-aether`, ADR-185 §13).
# VEIL is a pure-compute experiment/reference: no `rand` (its own deterministic
# WiFi Veil is a pure-compute experiment/reference: no `rand` (its own deterministic
# PRNG), no `std::time`/`std::fs`/`std::env`/threads, so it builds unchanged for
# `wasm32-unknown-unknown` and can never emit RF or touch a radio. The shield
# *models* compliant waveform controls; it does not drive hardware.
+12 -11
View File
@@ -1,11 +1,12 @@
![VEIL Console — the shield engaged, with the room's WiFi identity clusters collapsed to the chance floor (re-ID 4.7%, throughput preserved, compliant)](docs/veil-console.png)
![WiFi Veil Console — the shield engaged, with the room's WiFi identity clusters collapsed to the chance floor (re-ID 4.7%, throughput preserved, compliant)](docs/veil-console.png)
# wifi-densepose-privshield — VEIL
# wifi-densepose-privshield — WiFi Veil
**VEIL** (Verifiable Emission-shaping for Identity-Leakage prevention) is the
compliant-waveform **countermeasure** counterpart to
**WiFi Veil** (codename **VEIL** Verifiable Emission-shaping for
Identity-Leakage prevention) is the compliant-waveform **countermeasure**
counterpart to
[BFLD](../wifi-densepose-bfld) (ADR-118/121). BFLD *detects* when beamforming
feedback becomes identifying; VEIL *acts* — it shapes a node's own outgoing
feedback becomes identifying; WiFi Veil *acts* — it shapes a node's own outgoing
beamforming feedback so that an unauthorized passive sniffer cannot
re-identify people or infer activity, while a legitimate receiver (which shares
the per-session key) sees an essentially unchanged link.
@@ -33,7 +34,7 @@ and the 2025 sensing standard (802.11bf) added the capability but **no privacy
protection**. Because the attacker only listens, you get no indication it is
happening.
**The defense — scramble the fingerprint, keep the link.** VEIL adds a secret,
**The defense — scramble the fingerprint, keep the link.** WiFi Veil adds a secret,
**per-session "twist"** to your own outgoing feedback, built from the same
rotation math (Givens rotations) the report already uses:
@@ -47,7 +48,7 @@ rotation math (Givens rotations) the report already uses:
the signal's energy exactly (`energy in = energy out`), so it is **compliant,
never jamming.** It never floods the air or blocks anyone else.
**What it does *not* do (kept honest).** VEIL defends against a *third-party
**What it does *not* do (kept honest).** WiFi Veil defends against a *third-party
sniffer*, not the access point you are connected to (that party holds the key —
protecting against a malicious AP is BFLD's detection job). It targets identity
re-identification; coarse motion obfuscation is future work. And every figure in
@@ -63,7 +64,7 @@ captured hardware log.
Identity leaks through the **fine** cross-subcarrier phase structure of a
compressed beamforming report; data throughput rides the **dominant** beam
direction. These live in (mostly) separable subspaces. VEIL composes extra
direction. These live in (mostly) separable subspaces. WiFi Veil composes extra
**keyed Givens rotations** — the exact primitive the report is already built
from — over the *fine* subspace only:
@@ -90,7 +91,7 @@ unconstrained model optimum is 3-bit, matching the DySPAN-2026 finding.
## Threat model & scope (stated plainly)
VEIL defends against a **third-party passive sniffer** capturing plaintext
WiFi Veil defends against a **third-party passive sniffer** capturing plaintext
beamforming feedback. It does **not** hide identity from the AP a node is
associated with (that party holds the key by construction) — that is BFLD's
detection/policy problem, not this shield's. It is **compliant by
@@ -123,7 +124,7 @@ cargo run -p wifi-densepose-privshield --bin veil -- doctor # self-check, exit
```text
┌──────────────────────────────────────────────────────────
VEIL · wifi-sensing privacy shield ● PROTECTED
WiFi Veil · wifi-sensing privacy shield ● PROTECTED
│ re-ID off 100.0% re-ID on 4.7% (chance 6.25%)
│ throughput 97.6% emission 1.000× · not jamming
@@ -140,7 +141,7 @@ In the TUI, type commands to steer the shield live: `on`/`off`, `passes <n>`,
`preset scif|board|ward|hotel`, `optimize`, `proof`, `quit`. All readouts are
**SYNTHETIC / L0**.
A self-contained graphical **VEIL Console** web dashboard mirrors this same
A self-contained graphical **WiFi Veil Console** web dashboard mirrors this same
instrument — it ships in [`ui/veil-console.html`](ui/veil-console.html) (open it
in any browser; no build, no network). `veil` is the terminal-native version.
@@ -1,4 +1,4 @@
<title>VEIL Console — WiFi-Sensing Privacy Shield</title>
<title>WiFi Veil Console — WiFi-Sensing Privacy Shield</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<style>
/* ---- Theme tokens: light is the bare :root; dark redefined twice ---- */
@@ -358,7 +358,7 @@
<svg viewBox="0 0 24 24" fill="none" stroke="var(--accent-2)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l7 3v5c0 4.4-3 7.6-7 9-4-1.4-7-4.6-7-9V6l7-3z"/><path d="M8.5 12.2l2.2 2.2 4.8-4.8"/></svg>
</span>
<span class="brand-txt">
<b>VEIL&nbsp;Console</b>
<b>WiFi Veil&nbsp;Console</b>
<span>WiFi-sensing shield</span>
</span>
</div>
@@ -419,7 +419,7 @@
<div class="how-step how-shield">
<span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="var(--accent-2)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l7 3v5c0 4.4-3 7.6-7 9-4-1.4-7-4.6-7-9V6l7-3z"/><path d="M8.5 12.2l2.2 2.2 4.8-4.8"/></svg></span>
<span class="eyebrow">The shield</span>
<p>VEIL <b>scrambles that fingerprint</b> on every report with a secret twist only your own router can undo. An outside listener sees a <b>different scramble each time</b> and can't tie it to a person — their guess of "who's here" drops to <b>pure chance</b>.</p>
<p>WiFi Veil <b>scrambles that fingerprint</b> on every report with a secret twist only your own router can undo. An outside listener sees a <b>different scramble each time</b> and can't tie it to a person — their guess of "who's here" drops to <b>pure chance</b>.</p>
</div>
<div class="how-step how-honest">
<span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="var(--good)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 12l2 2 4-4"/><path d="M12 3l7 3v5c0 4.4-3 7.6-7 9-4-1.4-7-4.6-7-9V6l7-3z"/></svg></span>
@@ -524,7 +524,7 @@
identity while the associated receiver, holding the key, decodes normally. All figures are
<b>SYNTHETIC / evidence-level&nbsp;L0</b> from the reference model — not measured on hardware.
<div class="foot-links">
<a href="#" onclick="return false">ADR-288 · VEIL</a>
<a href="#" onclick="return false">ADR-288 · WiFi Veil</a>
<a href="#" onclick="return false">ADR-289 · harness</a>
<a href="#" onclick="return false">docs/research/privacy-shield</a>
</div>
@@ -559,7 +559,7 @@
const clamp = (v,a,b) => Math.max(a, Math.min(b, v));
const css = (n) => getComputedStyle(document.documentElement).getPropertyValue(n).trim();
/* ---------- VEIL model (mirrors the crate) ---------- */
/* ---------- WiFi Veil model (mirrors the crate) ---------- */
// re-ID collapse vs mixing passes: piecewise-linear over the crate's measured
// N=16 shield-on points (optimize.rs). Collapse is ~N-independent (finding),
// so other N just shift by the chance-floor difference (1/N 1/16).
@@ -876,7 +876,7 @@
return '<div class="modal-h"><span class="mglyph">'+SHIELD+'</span>'
+'<div><div class="eyebrow">Welcome</div><h3>Your Wi-Fi privacy shield</h3></div>'
+'<button class="m-close" data-act="close" aria-label="Close">×</button></div>'
+'<p>Ordinary Wi-Fi can quietly <b>recognise who is in a room</b> — no camera, no app, nothing you carry. VEIL scrambles that leak while your Wi-Fi keeps working normally. This console lets you <b>see it, tune it, and prove it</b>.</p>'
+'<p>Ordinary Wi-Fi can quietly <b>recognise who is in a room</b> — no camera, no app, nothing you carry. WiFi Veil scrambles that leak while your Wi-Fi keeps working normally. This console lets you <b>see it, tune it, and prove it</b>.</p>'
+'<ul class="points">'
+'<li><span class="pi">'+SHIELD+'</span><div><b>Watch it work</b><small>The panel up top shows people as dots. Shield on → they blur together and can\'t be told apart.</small></div></li>'
+'<li><span class="pi">%</span><div><b>Read the scorecard</b><small>Live numbers for how well you\'re hidden and how much Wi-Fi speed you keep.</small></div></li>'
@@ -888,12 +888,12 @@
function openWelcome(){ openModal(welcomeHTML()); markSeen(); }
const EXPLAIN={
protect:{t:"How this protects you",p:"Unauthorized Wi-Fi surveillance, and what VEIL does about it — in plain terms.",pts:[
protect:{t:"How this protects you",p:"Unauthorized Wi-Fi surveillance, and what WiFi Veil does about it — in plain terms.",pts:[
["What can spy on you","Since Wi-Fi 5, your device tells the router how to aim its signal by sending back “beamforming feedback” — sent unencrypted. Anyone in range can capture it passively and, from the tiny stable details, tell people apart (published work re-identifies individuals, detects occupancy through walls, even reads activity)."],
["Why you can't tell","There's no light, no app, no device on you, and the snoop only listens — so this happens silently. The Wi-Fi standard (802.11bf, 2025) added the sensing feature but no privacy protection."],
["What VEIL changes","Your router already reshapes its signal legitimately. VEIL adds a secret, per-session “twist” to that feedback (built from the same math the report already uses). Your own router shares the key and undoes it instantly; an outside listener sees a fresh random twist every session and can't average it into a stable fingerprint."],
["What WiFi Veil changes","Your router already reshapes its signal legitimately. WiFi Veil adds a secret, per-session “twist” to that feedback (built from the same math the report already uses). Your own router shares the key and undoes it instantly; an outside listener sees a fresh random twist every session and can't average it into a stable fingerprint."],
["The result","Across sessions the snoop's identity guess collapses to chance (~1-in-N, no better than guessing), while your link keeps ~98% of its speed — because the twist preserves the signal's energy and the data beam is untouched."],
["Not jamming","VEIL only shapes your own, standards-legal transmissions. It never floods the air or blocks anyone (that would be illegal jamming). The energy in = energy out meter proves it."],
["Not jamming","WiFi Veil only shapes your own, standards-legal transmissions. It never floods the air or blocks anyone (that would be illegal jamming). The energy in = energy out meter proves it."],
["Honest limits","It defends against outside snoops — not the router you're connected to (that party holds the key). It doesn't yet hide coarse motion, and every number here is simulated (evidence level L0) until validated on real hardware."]]},
kpis:{t:"Your live scorecard",p:"Four numbers that update the moment you change a setting.",pts:[
["Re-ID · off","How often an eavesdropper picks the right person with no shield. 100% = they always win."],