Files
n_signer/firmware/kb2040_hidden_signer

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.

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.

Use this exact command when flashing from CLI:

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:
arduino-cli board list

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 = 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.