KB2040 Hidden Signer (HID + WebUSB)
This directory contains an Arduino firmware scaffold that implements the kb2040_hidden_signer plan on top of a TinyUSB composite device.
- Firmware:
kb2040_hidden_signer.ino - Host client:
examples/kb2040_hidden_signer_client.py
What is implemented
- Composite USB device with two active interfaces:
- HID Consumer Control (media keys)
- Vendor/WebUSB transport (framed JSON)
- Default media mode:
- Play/Pause, Next, Previous buttons emit HID consumer usages
- Rotary encoder emits volume up/down
- Hidden mode toggle:
- Hold PLAY + NEXT for 3 seconds to toggle media/signer mode
- WebUSB framed transport:
- 4-byte big-endian length + JSON payload
- Signer RPC scaffold methods:
pingget_statusset_mnemonicset_auto_approveget_public_key(deterministic placeholder pubkey)sign_event(approval gate + placeholder signature)
What remains to reach production n_signer parity
- Replace placeholder crypto with real
n_signercore integration:- mnemonic -> seed -> key derivation
- secp256k1 schnorr signing
- full auth envelope verification
- Replace naive JSON parsing with robust parsing (e.g.
ArduinoJsonor cJSON port). - Wire exact
keyboard_modulespin mapping and display abstraction. - Add secure memory wiping and persistent policy storage if required.
Arduino setup
- Install Adafruit board index in Arduino IDE.
- Install Adafruit RP2040 boards package.
- Select board Adafruit KB2040.
- Set Tools -> USB Stack -> Adafruit TinyUSB.
- Install library Adafruit TinyUSB Library.
- Open and flash
kb2040_hidden_signer.ino.
Host validation
Install dependency:
pip install pyusb
Basic dual-interface verification:
python3 tests/test_kb2040_dual.py
Signer RPC flow (WebUSB/vendor interface):
python3 examples/kb2040_hidden_signer_client.py status
python3 examples/kb2040_hidden_signer_client.py set-mnemonic --mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
python3 examples/kb2040_hidden_signer_client.py get-public-key
python3 examples/kb2040_hidden_signer_client.py sign-event --event '{"kind":1,"content":"hello"}'
Pin mapping
Current defaults in kb2040_hidden_signer.ino:
PIN_BTN_PLAY = 2PIN_BTN_NEXT = 3PIN_BTN_PREV = 4PIN_ENC_A = 5PIN_ENC_B = 6PIN_ENC_SW = 7
Update these constants to match your physical keyboard_modules build.