UltraWideLock
Walk up. It Unlocks.
One timestamp tick is 15.65 ps, which light crosses in
4.692 mm. The bound is ULTRAWIDELOCK_UNLOCK_RANGE_CM.
A relay can add delay and nothing else, which is why arming one moves the
measurement away from the door rather than toward it.
Install
A C compiler and
python3 run the whole host suite.
git clone https://github.com/ultrawidelock/ultrawidelock.git
cd ultrawidelock
make check # 18 suites, 9,608 checks
Five commands take a Qorvo DWM3001CDK from clone to a lock on the bench.
make dfu-key # once per clone · image-signing key
make bootstrap # once per machine · NCS v3.3.0
make build # -> build/cdk-matter
make flash # over the on-board J-Link
make monitor # console, over RTT
The web flasher installs a prebuilt ESP32 image over WebSerial, with no toolchain.
How a door opens
Five steps, in the order they happen.
- 1BLE
the phone finds the credential service
0xFFF2 - 2auth AUTH0, AUTH1, EXCHANGE, and both ends hold the URSK
- 3UWB key ladder to STS, then the DS-TWR round above
- 4gate a trusted range moves the bolt
- 5Matter lock state over Thread, into Apple Home
The credential is verified on the lock itself, so there is no remote verifier to compromise.
All of it on one nRF52833
512 KB of flash and 128 KB of RAM carry the reader, the DW3110 radio, an OpenThread MTD and a Matter node at the same time. A hand-written Matter node, rather than CHIP, is what makes it fit.
- readerAUTH0 / AUTH1 / EXCHANGE, key ladder, STS, DS-TWR
- matterhand-written node, Door Lock cluster, five fabrics
- threadOpenThread MTD, joins a real network
- classifierline-of-sight vs obstructed, 776 B of flash
Both bars are amber because both are tight; flash is the
tighter. make cdk-size reports them.
| Toolchain | NCS v3.3.0, Zephyr 4.3.99 |
|---|---|
| Signing | ECDSA-P256, verified by MCUboot |
Repository defaults are bench defaults. Keys and identities in the tree are for development. Do not secure valuables with it.
Obstruction detection
A phone in a hand and a phone through a wall both measure one metre. The shape of the arrival separates them: a direct path lands as one sharp edge, a path through a door arrives late, spread and weaker.
A decision tree reads the DW3000's own receive diagnostics in 776 bytes of flash, with no interpreter and no allocation.
| Model | depth-2 decision tree, generated by emlearn |
|---|---|
| Cost | 776 B flash, 0 B RAM, 28 B stack |
| Input | five CIA registers plus the measured range |
| Gate | the host suite certifies the C matches the trained model |
Side of the door
A phone on the couch and a phone on the porch can be the same distance from the door. Only one of them should open it.
The satellite joins the phone’s own ranging round as responder 1, so both distances come from one round rather than two guesses stitched together. It reports its distance sealed and bound to the block it was measured in, and the lock fuses the pair only when both halves carry the same block. It builds for the DWM3001CDK, the nRF5340 DK, and the ESP32 tier over an ESP-NOW carrier.
make anchorlink # the lock half
make sat-build SAT_THREAD=1 # the satellite half
One nRF52840 dongle inside, one outside, a differential read consulted at the one moment it is reliable, and a door-transition latch that holds the answer between crossings. One image, role set at install.
make witness-build
make witness-flash # over USB DFU, no probe
The side gate fails closed for passive unlock: no agreeing second opinion, no walk-up open. A dead dongle, a dropped mesh, a reboot or corrupt storage each leave the lock refusing to open from inside. Outside, the recovery is a retry, an NFC tap, or the app.
Hardware targets
| Application | Hardware | Connectivity |
|---|---|---|
dwm3001cdk-lock | DWM3001CDK, nRF52833 + DW3110 | UWB, Matter over Thread |
dwm3001cdk-lock-freertos | the same board, no Zephyr | UWB, Matter over Thread |
nrf5340dk-lock | nRF5340 DK, DWM3000EVB, NFC12A1 | UWB and NFC, Matter over Thread |
esp32-matter-lock | ESP32-S3 / C5 / C6 with DWM3000EVB | UWB, Matter over Wi-Fi |
satellite | CDK, nRF5340 DK, or the ESP32 tier | UWB responder, sealed link to the lock |
Update over the air
Either chip, from a browser. The flash page finds the board, reads what it is running, and sends the one update that applies.
| DWM3001CDK | ESP32-S3 / C5 / C6 | |
|---|---|---|
| Transport | mcumgr, over BLE or USB | native GATT frames |
| Payload | signed delta, about 11 KB | signed whole image, about 2 MB |
| Why | one MCUboot slot in 512 KB | two full OTA slots |
| Time | seconds | several minutes over BLE |
Writing starts once the update window is open on the board: SW2 on the CDK, a double-click on the ESP32’s button. That press is the whole availability gate; authenticity is a P-256 signature, checked before the first byte is written and again by the bootloader. The CDK can also be reinstalled whole over the cable through MCUboot serial recovery, which runs from the bootloader alone.
Chrome or Edge on a computer, or Chrome on Android. Neither Web Bluetooth nor WebSerial exists in Safari, so not from an iPhone.
Try it without hardware
The untouched ultrawidelock_uwb sources, compiled to WASM against the
same shim the host suite links. Every block is a real CCM*-encrypted exchange decoded
by the firmware’s own RX state machine. Walk a phantom phone, add noise, fire a
Ghost-Peak spoof, single-step a DS-TWR round.
Plug an ESP32-S3, C5 or C6 into USB and install a merged image from this page, with no toolchain and no command line. The page detects the chip, and updates either board over the air once one is running.
What depends on what, extracted from the source tree: 17 subsystems and 49 edges, or 393 files with their symbols and 703 links.
Specification
| UWB | DS-TWR under an STS session, channels 5 and 9 |
|---|---|
| Resolution | one tick is about 15.65 ps, roughly 4.692 mm |
| BLE | credential service 0xFFF2, AUTH0 / AUTH1 / EXCHANGE |
| NFC | ECP, on the nRF5340 DK target |
| Side of door | a second UWB anchor in the same round, or two BLE witnesses |
| Matter | hand-written node over Thread, or over Wi-Fi on ESP32 |
| Door Lock | LockOperation events, AutoRelockTime, DoorLockAlarm, Approach Direction |
| Matter client | CASE as initiator and the Binding cluster, to open a second lock. Off by default |
| Updates | signed delta over BLE or USB, applied from inside MCUboot; whole signed image on ESP32 |
| Ports | Zephyr, ESP-IDF, and a Zephyr-free FreeRTOS port |
| Tests | 9,608 host checks across 18 suites, no hardware needed |
| License | ISC. The vendored Qorvo UWB driver is LicenseRef-QORVO-2 |