# 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`](./kb2040_hidden_signer.ino) - Host client: [`examples/kb2040_hidden_signer_client.py`](../../examples/kb2040_hidden_signer_client.py) ## What is implemented 1. Composite USB device with two active interfaces: - HID Consumer Control (media keys) - Vendor/WebUSB transport (framed JSON) 2. Default media mode: - Play/Pause, Next, Previous buttons emit HID consumer usages - Rotary encoder emits volume up/down 3. Hidden mode toggle: - Hold PLAY + NEXT for 3 seconds to toggle media/signer mode 4. WebUSB framed transport: - 4-byte big-endian length + JSON payload 5. Signer RPC scaffold methods: - `ping` - `get_status` - `set_mnemonic` - `set_auto_approve` - `get_public_key` (deterministic placeholder pubkey) - `sign_event` (approval gate + placeholder signature) ## What remains to reach production n_signer parity 1. Replace placeholder crypto with real `n_signer` core integration: - mnemonic -> seed -> key derivation - secp256k1 schnorr signing - full auth envelope verification 2. Replace naive JSON parsing with robust parsing (e.g. `ArduinoJson` or cJSON port). 3. Wire exact `keyboard_modules` pin mapping and display abstraction. 4. Add secure memory wiping and persistent policy storage if required. ## Arduino setup (IDE) 1. Install Adafruit board index in Arduino IDE. 2. Install **Adafruit RP2040** boards package. 3. Select board **Adafruit KB2040**. 4. Set **Tools -> USB Stack -> Adafruit TinyUSB**. 5. Install library **Adafruit TinyUSB Library**. 6. Open and flash [`kb2040_hidden_signer.ino`](./kb2040_hidden_signer.ino). ## Arduino CLI flashing (recommended repeatable command) Use this exact command when flashing from CLI: ```bash arduino-cli compile --upload -p /dev/ttyACM0 \ --fqbn rp2040:rp2040:adafruit_kb2040:usbstack=tinyusb \ firmware/kb2040_hidden_signer ``` Notes: - `usbstack=tinyusb` is **required** for this firmware (TinyUSB composite device). - If you omit that option, build fails with `TinyUSB is not selected`. - If `/dev/ttyACM0` changes, find the current port with: ```bash arduino-cli board list ``` ## Host validation Install dependency: ```bash pip install pyusb ``` Basic dual-interface verification: ```bash python3 tests/test_kb2040_dual.py ``` Signer RPC flow (WebUSB/vendor interface): ```bash 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`](./kb2040_hidden_signer.ino): - `PIN_BTN_PLAY = 2` - `PIN_BTN_NEXT = 3` - `PIN_BTN_PREV = 4` - `PIN_ENC_A = 5` - `PIN_ENC_B = 6` - `PIN_ENC_SW = 7` Update these constants to match your physical `keyboard_modules` build.