Skip to content

Phase 7: Bluetooth offline pairing (v0.2.0) - #12

Merged
xuandung38 merged 7 commits into
mainfrom
feat/p07-ghep-bluetooth-offline
Oct 30, 2026
Merged

xuandung38 merged 7 commits into
mainfrom
feat/p07-ghep-bluetooth-offline

Conversation

@xuandung38

Copy link
Copy Markdown
Contributor

Ghep doi Bluetooth lan dau khong can mang (QR luong B, PIN luong C dung CPace-X25519-SHA512), nhan 'Connected via Bluetooth'. Bao cao bao mat PASS o hub reports/security-scan-0.2.0-2026-10-30.md. Merge bang 'Create a merge commit'.

…venvs

Runs outside the sandbox (needs network): downloads the latest
draft-irtf-cfrg-cpace text from the IETF datatracker into
tools/vectors/.refs/ (gitignored), then creates an isolated .venv next to
every requirements*.txt under tools/ and installs it.
Adds step 3 to run verify_vectors.py, check_schemas.py, and check_strings.py
using the newly created .venv for each tool. Reports clear success/failure for
each step and exits with correct code (0 on success, 1 on any failure).
bt-pairing.json: K_bt_pdisc/K_bt_plink/pr_bt derivation and the Noise
_NNpsk0_25519_ChaChaPoly_SHA256 first-frame MAC for QR pairing links
over Bluetooth (00-common-specs.md 0.4.5), with negative vectors for
a wrong psk, a tampered tag/message and a replayed n_s.

cpace.json: the draft-irtf-cfrg-cpace-21 CPACE-X25519-SHA512 vectors
(Appendix B.1, calculate_generator/message/K/ISK), then HandLive's PIN
pairing case (fixed n_s, PIN with a leading zero, K_bt_pinlink/K_bt_pin
from ISK), plus negative vectors for a low-order Ya/Yb, a sid mismatch
and a wrong PIN on one side.
bt-link.json: K_bt_disc/K_bt_link from PRK, the rotating discovery
hint, and the full link-security handshake (challenge, noise1, noise2,
Split) for an already-paired Bluetooth link (00-common-specs.md 0.4.5),
extending noise_nnpsk0.py with message 2 ("e, ee") and Split().

bt-frame.json: the pre-auth and transport record codec (rlen bounds,
chan/flags/dlen/padding, encrypted with bt-link.json's c1), with
negative vectors for every bound in 0.4.5/S7.1a: rlen out of bounds,
an oversized pre-auth record, an unknown chan, more without long, a
long-lane fragment over BT_BULK_FRAGMENT_MAX, a message over
BT_MESSAGE_MAX.

bt-advertisement.json: the app-controlled scan-response service data
(ver/psm/hints) for 0/1/2 hints and the BT_PIN_HINT marker, with
negative vectors for a wrong version and a hint outside the accepted
epoch window.

Also: sync error.schema.json/envelope.schema.json with the Phase 7
additions to 00-common-specs.md 0.8.1/0.7.1 (DIRECT_WIFI_UNAVAILABLE,
bulk/direct); pin noiseprotocol==0.3.1 and cross-check the bt-link.json
handshake against it (needs a real pip install to run); add bench
events bt_seen/bt_lost/wifi_assoc and their reconnect_time.py trigger;
add the Bluetooth permission/status UI strings (01-setup-settings.md
SET-01/SET-03).
Noise rev. 34 §9.2: in a psk-modified pattern, every "e" token does
MixHash(e.public_key) and then ALSO MixKey(e.public_key) — unlike a
plain pattern, where "e" only does MixHash. noise_nnpsk0.py only did
the MixHash half, so message 1 encrypted its payload with the "psk"
token's key instead of the key that follows "e"'s own MixKey, and the
chaining key carried into message 2's "ee" step (and from there into
Split()) was wrong throughout, even though e/e.pub themselves never
changed on the wire.

Caught by cross-checking bt-link.json's handshake against the real
`noiseprotocol` library (message1/message2 tag mismatch, e matched);
message1, message2, handshake_hash and both Split() keys now agree
byte-exact with that independent implementation. Fixes both message 1
("psk, e", shared with bt-pairing.json's first frame) and message 2
("e, ee", bt-link.json only); bt-frame.json's transport records are
regenerated too since they are encrypted with bt-link.json's c1.
Add two new catalog keys for Bluetooth connections:
- status.connected_bluetooth: "Connected via Bluetooth"
- status.connected_bluetooth_to: "Connected via Bluetooth to {device_name}"

Spec 0.11 (route .bluetooth), new for Phase 7 (S7.1)
Drop claims with no matching code or test vectors (Wi-Fi Direct SSID/
passphrase format, K_bulk bulk-lane stream keys, AUTH_FAILED/LINK_FAILED
as new codes) into a Specs section; credit the strings and schema
additions that exist but are not wired into any platform UI yet
(permission primer, Bluetooth-off/denied status lines, settings label).
@xuandung38
xuandung38 merged commit 6e44aa1 into main Oct 30, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant