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 **WiFi Veil** (codename **VEIL** Verifiable Emission-shaping for
privacy *firewall* for WiFi sensing: it prevents unauthorized identity and 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 activity inference from a room's WiFi while preserving normal communications. It
is the **countermeasure** counterpart to [BFLD](../BFLD/) — where BFLD *detects* 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 own compliant waveform (channel sounding, precoder phase, beam/feedback
schedules) so identity and activity inference fail, while a legitimate receiver schedules) so identity and activity inference fail, while a legitimate receiver
sees an essentially unchanged link. sees an essentially unchanged link.
@@ -21,14 +22,14 @@ transmission (the statutory definition of jamming, 47 U.S.C. §333/§302a).
| File | Purpose | | 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 | | [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 | | [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 | | [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 | | [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 | | [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 | | [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 | | [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). 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). 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, cannot coexist with wanted WiFi. The whitespace is a **selective, coexisting,
software/PHY** shield. 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* 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 **keyed Givens rotations** over the fine subspace only. The rotation is
*orthogonal* (energy-preserving ⇒ not jamming), *keyed per session* (the *orthogonal* (energy-preserving ⇒ not jamming), *keyed per session* (the
legitimate receiver inverts it ⇒ throughput preserved), and *fresh each 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: [08-optimization.md](08-optimization.md)). Reproduce:
`cargo test -p wifi-densepose-privshield`. `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) 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 hardware: real-silicon validation (per CLAUDE.md) is future work with a
captured-log witness. 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. - **MEASURED** — from a cited primary source with its metric and conditions.
- **CLAIMED** — asserted by a source (vendor PR, press, standards minutes) - **CLAIMED** — asserted by a source (vendor PR, press, standards minutes)
without an independent measurement. 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. `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. 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 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. across multiple hardware providers.
> **Evidence discipline (read this first).** Everything here is **build-only / > **Evidence discipline (read this first).** Everything here is **build-only /
@@ -64,19 +64,19 @@ across multiple hardware providers.
## Feasibility matrix ## Feasibility matrix
Grades reflect *capability to actually shape the beamforming-feedback surface* 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 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 reality is in the "Why" column. All rows are `SYNTHETIC / L0` — build-only, no
silicon, no captured log. silicon, no captured log.
| Provider | Grade | Can it shape the BF-feedback surface? | Why | | 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. | | **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. | | **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). | | **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 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 partial: the exact angles are blob-/ucode-locked on commodity silicon, leaving
either coarse compliant perturbations (openwrt) or a deep, unproven ucode-adjacent 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 ## 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 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 **both** ends + key agreement. Best result; needs an open PHY (openwifi) for a
true demo, or the client-transparent AP-side variant below. 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 **Status: `SYNTHETIC / L0` (build-only).** Everything in this directory is an
ESP-IDF component *skeleton*. Nothing here has been flashed, run, or captured on ESP-IDF component *skeleton*. Nothing here has been flashed, run, or captured on
@@ -18,7 +18,7 @@ surface*.
supporting roles.** supporting roles.**
The ESP32 **cannot shape its own transmitted 802.11 beamforming feedback.** The 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 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 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 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 you hand-craft the VHT/HE sounding-feedback subtype with a chosen precoder. So
the ESP32 is **not** a beamforming-feedback protector. 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. 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. build-only).** Three legitimate roles below, best-first.
--- ---
## What the ESP32 can and cannot do ## 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) | | 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) | | 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)** | | 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** | | 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** | | 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** | | 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) ### 1. `veil_sensing_detector/` — sensing-solicitation detector (strongest, clearly compliant)
Uses the CSI callback (+ promiscuous RX) to estimate how often the node is being 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 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 turn on. Pure observe-plus-control-signal; the ESP32 shapes nothing on air. This
is the role we would actually build first. 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 > **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 > 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`; - link a small `libm`/`compiler-rt` for `arm-none-eabi`;
- or replace the trig with a fixed-point / CORDIC Givens rotation - or replace the trig with a fixed-point / CORDIC Givens rotation
(`TODO(reverse-engineer)`), which also avoids float on parts without an FPU. (`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. core) — no heap is introduced on-chip.
## Build ## 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 (`../core/veil_shield.{h,c}`) on the compressed-beamforming-feedback **angles
before transmission**, using the [Nexmon](https://github.com/seemoo-lab/nexmon) before transmission**, using the [Nexmon](https://github.com/seemoo-lab/nexmon)
patching framework on a Broadcom/Cypress WiFi chip. 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 ("ucode"). Published reverse-engineering of these chips reports that the D11
generates the **VHT/HE compressed beamforming report ~10 µs after the NDP**, with 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** 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 emitted inside the ucode/PHY path on a microsecond deadline — *below* the ARM
"wl" driver firmware where Nexmon's C hooks (`__attribute__((at(addr, ...)))` "wl" driver firmware where Nexmon's C hooks (`__attribute__((at(addr, ...)))`
flashpatches / branch hooks) live most reliably. Reaching them means either a 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 ## 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 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. 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 - **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 > **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 > 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 > 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 > 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 — > `SYNTHETIC` and must be labelled so. **Compliant waveform controls only —
> orthogonal, energy-preserving; never jamming.** > orthogonal, energy-preserving; never jamming.**
@@ -47,7 +47,7 @@ per-packet keying uses `(key, packet_counter)` as in `HDL_NOTES.md`.
## Procedure ## 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. positions, same MCS, same duration, same seed for the attacker model.
1. **Correctness precondition (not a defense claim).** Confirm on-FPGA 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 > **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 > 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 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. 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 per-packet keyed unitary** (LeakyBeam family) applied at the TX spatial-mapping
stage, with the legitimate STA (a second openwifi node sharing the key) stage, with the legitimate STA (a second openwifi node sharing the key)
inverting it — **not** as obfuscation of a compressed-BF report the hardware 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 > **`SYNTHETIC / L0` — BUILD-ONLY, UNTESTED ON HARDWARE.** These are hook-point
> designs derived from public API/source, not validated on silicon. Function and > 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 firmware change to honor an externally supplied grouping. Not reachable without
both a driver and firmware patch. 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, - **Daemon:** `veil_apply_keyed_rotation()` → `veil_shield_apply(fine, n, key,
passes)` from the portable core. Orthogonal / energy-preserving (the 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 ## 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 | | TX antenna map | Ready now (US), coarse only |
| Sounding cadence jitter | Wire hostapd `ctrl_iface` (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.** > **STATUS: `SYNTHETIC / L0` — BUILD-ONLY, UNTESTED ON HARDWARE.**
> No radio was driven, no CSI captured, no log produced on silicon. Every > 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 > adapter uses **compliant waveform controls only** — it never jams and emits
> no denial energy. > 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 shield. It links the validated portable core
(`../core/veil_shield.{h,c}` — the keyed Givens rotation over the identity-bearing (`../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 "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) ## 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 the compressed beamforming-feedback angles (equivalently, a keyed Q on the LTF
spatial mapping / precoder). On every mainstream OpenWRT AP chipset spatial mapping / precoder). On every mainstream OpenWRT AP chipset
(Qualcomm ath10k/ath11k/ath12k, MediaTek mt76 / mt7915), that report is generated (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* 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 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 — 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; **Why not D.** Some controls genuinely work from userspace (TX antenna map;
hostapd-mediated sounding/beamformer capability), and one chipset family 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 ## 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. | | **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. | | **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. | | **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. | | **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. | | **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. | | **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. | | **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", "name": "wifi-densepose-privshield-harness",
"version": "0.1.0", "version": "0.1.0",
"description": "Harness for wifi-densepose-privshield (VEIL privacy shield)", "description": "Harness for wifi-densepose-privshield (WiFi Veil privacy shield)",
"author": { "author": {
"displayName": "Generated by metaharness", "displayName": "Generated by metaharness",
"url": "https://www.npmjs.com/package/metaharness" "url": "https://www.npmjs.com/package/metaharness"
@@ -5,17 +5,17 @@
"template_version": "0.0.0", "template_version": "0.0.0",
"vars": { "vars": {
"name": "wifi-densepose-privshield-harness", "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" "host": "claude-code"
}, },
"hosts": ["claude-code"], "hosts": ["claude-code"],
"files": { "files": {
".claude/settings.json": "fedb60921a0e3c78848f43edddd75f448819594c680d48ff2033ef8f1588da3f", ".claude/settings.json": "fedb60921a0e3c78848f43edddd75f448819594c680d48ff2033ef8f1588da3f",
".claude-plugin/plugin.json": "7831dc3d1b9b5363130a59ce680794bfe0b6ca09c73d77a7ce78aa6ec3921c5a", ".claude-plugin/plugin.json": "8b155a3130d212c88dd8b631d9bd6dd1b4eacb52e5eb282fddbe08576ae23be2",
"bin/cli.js": "1133e7a47accada1c9b2184873776d8ca0d028f9b76dd55f467dfe38bb9ce609", "bin/cli.js": "1133e7a47accada1c9b2184873776d8ca0d028f9b76dd55f467dfe38bb9ce609",
"CLAUDE.md": "c5bd71bfc0699021a284a54ffa70f4784b8238774c6d6fcfedf836f5e37d10f8", "CLAUDE.md": "f9ccf20c341ff0296b2e64ce692103572d61e856ae0df8a8bc4c35a7ac8b2ff5",
"package.json": "e32acd6e5e630b0db9abccc5f5f58f86f291ccfc23b4c8410b380c01024a23df", "package.json": "1ccedf0e62b0ed884431a2a9192a3865b525a2dad72fa6491569b9001e7dd24f",
"README.md": "be5b0a17cd051dafe8cd825ddf778c91971993419f9e33c0898e21140249f72a", "README.md": "688e207f95e4f58eeade84f149c38fa8ec048796556a7b1bd75f08ee1945edba",
"src/init.ts": "f05d6905d8681f45f610ff5b6e9d425dfa66183acdfe7857248e50e3583e13b8", "src/init.ts": "f05d6905d8681f45f610ff5b6e9d425dfa66183acdfe7857248e50e3583e13b8",
"src/router.ts": "4545b42d1423db21bcfe6ab6bf132b805ba383937d142997cb7256e835c245e4", "src/router.ts": "4545b42d1423db21bcfe6ab6bf132b805ba383937d142997cb7256e835c245e4",
"src/flywheel.ts": "aab56d82c4f018ddc83923c877a66acdf9c624214307d0a9c4bf930ddb00599a", "src/flywheel.ts": "aab56d82c4f018ddc83923c877a66acdf9c624214307d0a9c4bf930ddb00599a",
+6 -6
View File
@@ -1,7 +1,7 @@
# wifi-densepose-privshield-harness # wifi-densepose-privshield-harness
Harness for [`wifi-densepose-privshield`](../../v2/crates/wifi-densepose-privshield) 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. package is defined by ADR-289.
> Advanced Coding harness · domain: `software-engineering`. Modeled on the > 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 - Use the harness's tools for orchestration; memory and routing are handled by
the kernel. the kernel.
- Defer destructive operations to the user. - 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 SYNTHETIC/L0 results as MEASURED** — a hardware witness is required first
(CLAUDE.md hardware rule; ADR-282 ladder). The harness is a development aid; (CLAUDE.md hardware rule; ADR-282 ladder). The harness is a development aid;
it does not run a radio and cannot emit RF. 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." suggest, or scaffold interference-based "defenses."
## Commands ## Commands
- `init` — boot the kernel + host adapter. - `init` — boot the kernel + host adapter.
- `doctor` — verify the install end-to-end (kernel, host, guidance map). - `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`, (dependency-free; topics: `overview`, `threat`, `countermeasure`,
`compliance`, `optimization`, `experiment`). Source-cited and `compliance`, `optimization`, `experiment`). Source-cited and
evidence-labelled; navigation only, not authority. evidence-labelled; navigation only, not authority.
@@ -58,8 +58,8 @@ installed.
## Relationship to the crate ## Relationship to the crate
This harness assists development *on* the VEIL crate; it does not replace the This harness assists development *on* the WiFi Veil crate; it does not replace the
crate's own gates. The authoritative validation for a VEIL change is still: crate's own gates. The authoritative validation for a WiFi Veil change is still:
```bash ```bash
cargo test -p wifi-densepose-privshield --no-default-features cargo test -p wifi-densepose-privshield --no-default-features
+7 -7
View File
@@ -1,11 +1,11 @@
# wifi-densepose-privshield-harness # wifi-densepose-privshield-harness
A metaharness (contributor harness) for 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. the compliant-waveform WiFi-sensing privacy shield (ADR-288). Defined by ADR-289.
> **Advanced Coding** — architect → implement → review → test, plus a > **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. > (ADR-286). Multi-host scaffold with a kernel that resolves native → wasm → js.
## Install ## Install
@@ -27,7 +27,7 @@ npx wifi-densepose-privshield-harness guidance --topic overview
|---|---|---| |---|---|---|
| `init` | kernel + host | Boot the kernel + host adapter | | `init` | kernel + host | Boot the kernel + host adapter |
| `doctor` | kernel + host | Verify the install end-to-end | | `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 | | `route <e0..e3>` | router + `npm run build` | Cost-optimal model routing |
| `flywheel [gens]` | flywheel + `npm run build` | SYNTHETIC self-improvement demo | | `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 `optimization`, `experiment`. It needs no dependencies or build step, so it
works offline and in CI before `npm install`. 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 a third-party passive sniffer cannot re-identify people, while a keyed receiver
sees an essentially unchanged link. **Compliant waveform controls only — never sees an essentially unchanged link. **Compliant waveform controls only — never
jamming.** Reference results are **SYNTHETIC / evidence level L0** (reproduced by jamming.** Reference results are **SYNTHETIC / evidence level L0** (reproduced by
@@ -59,9 +59,9 @@ for what is real wiring vs. illustrative/synthetic data.
## Scope ## 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 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 ## License
@@ -1,7 +1,7 @@
{ {
"name": "wifi-densepose-privshield-harness", "name": "wifi-densepose-privshield-harness",
"version": "0.1.0", "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", "license": "MIT",
"type": "module", "type": "module",
"bin": { "bin": {
@@ -1,6 +1,6 @@
[package] [package]
name = "wifi-densepose-privshield" 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" version = "0.1.0"
edition.workspace = true edition.workspace = true
authors.workspace = true authors.workspace = true
@@ -12,7 +12,7 @@ categories.workspace = true
readme = "README.md" readme = "README.md"
# Intentionally dependency-free (mirrors `wifi-densepose-aether`, ADR-185 §13). # 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 # 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 # `wasm32-unknown-unknown` and can never emit RF or touch a radio. The shield
# *models* compliant waveform controls; it does not drive hardware. # *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 **WiFi Veil** (codename **VEIL** Verifiable Emission-shaping for
compliant-waveform **countermeasure** counterpart to Identity-Leakage prevention) is the compliant-waveform **countermeasure**
counterpart to
[BFLD](../wifi-densepose-bfld) (ADR-118/121). BFLD *detects* when beamforming [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 beamforming feedback so that an unauthorized passive sniffer cannot
re-identify people or infer activity, while a legitimate receiver (which shares re-identify people or infer activity, while a legitimate receiver (which shares
the per-session key) sees an essentially unchanged link. 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 protection**. Because the attacker only listens, you get no indication it is
happening. 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 **per-session "twist"** to your own outgoing feedback, built from the same
rotation math (Givens rotations) the report already uses: 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, the signal's energy exactly (`energy in = energy out`), so it is **compliant,
never jamming.** It never floods the air or blocks anyone else. 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 — 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 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 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 Identity leaks through the **fine** cross-subcarrier phase structure of a
compressed beamforming report; data throughput rides the **dominant** beam 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 **keyed Givens rotations** — the exact primitive the report is already built
from — over the *fine* subspace only: 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) ## 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 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 associated with (that party holds the key by construction) — that is BFLD's
detection/policy problem, not this shield's. It is **compliant by 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 ```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%) │ re-ID off 100.0% re-ID on 4.7% (chance 6.25%)
│ throughput 97.6% emission 1.000× · not jamming │ 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 `preset scif|board|ward|hotel`, `optimize`, `proof`, `quit`. All readouts are
**SYNTHETIC / L0**. **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 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. 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" /> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<style> <style>
/* ---- Theme tokens: light is the bare :root; dark redefined twice ---- */ /* ---- 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> <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>
<span class="brand-txt"> <span class="brand-txt">
<b>VEIL&nbsp;Console</b> <b>WiFi Veil&nbsp;Console</b>
<span>WiFi-sensing shield</span> <span>WiFi-sensing shield</span>
</span> </span>
</div> </div>
@@ -419,7 +419,7 @@
<div class="how-step how-shield"> <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="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> <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>
<div class="how-step how-honest"> <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> <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 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. <b>SYNTHETIC / evidence-level&nbsp;L0</b> from the reference model — not measured on hardware.
<div class="foot-links"> <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">ADR-289 · harness</a>
<a href="#" onclick="return false">docs/research/privacy-shield</a> <a href="#" onclick="return false">docs/research/privacy-shield</a>
</div> </div>
@@ -559,7 +559,7 @@
const clamp = (v,a,b) => Math.max(a, Math.min(b, v)); const clamp = (v,a,b) => Math.max(a, Math.min(b, v));
const css = (n) => getComputedStyle(document.documentElement).getPropertyValue(n).trim(); 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 // 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), // 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). // 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>' return '<div class="modal-h"><span class="mglyph">'+SHIELD+'</span>'
+'<div><div class="eyebrow">Welcome</div><h3>Your Wi-Fi privacy shield</h3></div>' +'<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>' +'<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">' +'<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">'+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>' +'<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(); } function openWelcome(){ openModal(welcomeHTML()); markSeen(); }
const EXPLAIN={ 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)."], ["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."], ["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."], ["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."]]}, ["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:[ 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."], ["Re-ID · off","How often an eavesdropper picks the right person with no shield. 100% = they always win."],