This page states what Favilla KEY does. Every statement has been traced to a specific path in the firmware source and the manufacturing tooling. Where a protection has a limit, the limit is stated with the same weight as the protection. Where something is a production commitment rather than a property of the units that exist today, it is labelled as one.
Your keys are generated on the device, during setup, and are never transmitted. You choose where the randomness comes from.
Two chips draws one 16×16 grid from the SE051's certified true random number generator and another from the camera sensor, shows you both on the screen, and XORs them into the value it hashes — so neither chip vendor can determine your key alone, and you can repeat the mixing step by hand at Seed check. The secure element is a sealed box whose certificate you are trusting; the camera is a sensor whose output you can see. Together, a backdoor in either one has to also beat the other. Dice lets you roll a standard d6; the seed is a published function of your rolls with no device secret in it, so you can recompute the same result on any offline machine and confirm the device used your rolls and nothing else.
Nothing else goes in. The firmware does not mix in the ESP32-S3's own generator: the radios are off during setup, the condition its vendor documents as degraded, and we would rather leave it out than count on it. There is no silent fallback either — a camera layer below its 128-bit pass line, or two layers that both come back flat, stops seed generation with an error rather than being quietly replaced. (A flat secure-element layer on its own does not: XOR with a constant changes nothing, so the camera simply carries the seed — and you would see the flat grid on the screen.)
We measured these sources on our own hardware and two of the results contradicted what we believed. The write-up is in Three questions about randomness.
From one standard BIP-39 recovery phrase (12 or 24 words), your Nostr identity derives via NIP-06 and your Bitcoin wallet derives via BIP-84 for single-sig and BIP-48 as a multisig cosigner. One phrase, written down once, restores everything. An optional BIP-39 passphrase can be added at setup or at restore, typed on the buttons or scanned from a QR — either baked into the sealed seed, or asked for at each Bitcoin session so one set of words carries any number of wallets. Either way the device shows you the wallet fingerprint so you can confirm which wallet you are in. You can also import an existing nsec — the device then operates as a Nostr-only signer, since an nsec alone carries no Bitcoin seed.
Your Nostr key and your Bitcoin seed are stored as AES-256 ciphertext, wrapped twice. The outer key lives inside the SE051 secure element; the inner key lives inside the isolated signing processor (see 03). Neither can be read out — by you, by us, or by anyone who opens the device. The wrapped Nostr key is kept inside the secure element itself, released only to the signing processor's own authenticated session and only while your PIN has unlocked the gate; the wrapped seed sits in the main chip's flash and is likewise unwrapped only by the signing processor, only in Bitcoin mode (see 04). The plain key exists in neither the flash nor the network-facing chip.
A raw dump of the device's flash yields ciphertext and public data. Nothing more.
A Nostr identity key has to be live. It signs the moment something happens on a relay, so the chip that signs is, by design, connected to Wi-Fi. That is exactly what makes a software key fragile: when the key lives in the same processor that parses untrusted network traffic, any remote compromise of that processor can read the key straight out of memory. A stolen identity key is permanent — it cannot be revoked, only abandoned.
So we don't keep it there. The Nostr key lives on a dedicated signing processor — a second, deliberately simple chip with no radios and no network stack. The internet-facing processor never holds the key. When a signature is needed, it hands the signer a 32-byte hash in a fixed-length command, and receives a finished signature back. The signer accepts only fixed-length commands, so there is no malformed input that can break it, and it has no command that returns the key. The one thing it decodes is the encrypted channel to the secure element, which is fixed-format and fuzzed. The one time the key exists on the main chip is setup: generated with the radios off, sealed into the signer, and wiped.
The Bitcoin seed gets the same treatment. It is unsealed only inside the signing processor, which derives the keys and signs each input's hash itself; the main chip hands it a fixed-size request per input, recomputes every hash independently, and refuses any signature whose hash or public key does not match. After setup, the seed never enters the network-facing chip's memory.
The result is a property most signers cannot offer: a remote attacker who fully compromised the connected side still could not extract your Nostr key. The key stays on a chip that has no command to reveal it — the worst they could do is ask the signer to sign while they hold that access, bounded by your on-device policy. And that access is not permanent: a physical power cycle evicts an attacker living in memory; one that has written itself into flash is what Secure Boot (08) exists to stop. This holds while Wi-Fi is active, which is the whole point — it is not cold storage, it is a live key that stays isolated even in use.
Being honest about the bar: no connected device is unbreakable, but this one should be harder to compromise than the phone or computer you would otherwise sign on. Those run a full operating system, a browser, and thousands of lines of third-party code, with your key sitting in the same memory. This device runs a small, purpose-built firmware, and the signer that holds your key has no radios, no network stack, and no parser — only fixed-length commands. Less surface means fewer ways in — and even a way in does not reach the key.
The device has two modes, and you pick one each time it powers on. Nostr mode, opened with the Nostr PIN, is daily life: signing, messages, the client, remote signing. It has no Bitcoin surface at all — no balance, no addresses, no Bitcoin API. Bitcoin mode, opened with the BTC PIN on the device's own buttons, is signing only: no Wi-Fi, no hotspot, no network path of any kind. The BTC PIN never travels over any network, and there is no API that accepts it.
One mode per power cycle — and that's not a policy setting. Choosing Nostr closes the Bitcoin door for that power-on life, and choosing Bitcoin closes Nostr — latched inside the secure element and remembered by the signing processor, which boots only on a real loss of power. The only way between them is a physical power cycle — holding the two left buttons together cuts power to both processors in hardware, not software. The secure element releases the seed's wrap key only against a mode value that the signing processor alone can mint, once it has witnessed that power cycle — and the value is burned again the instant each unwrap completes. So a remote spend is impossible by construction. Wrong PIN attempts trip a hardware counter with escalating delays: nine on the device; three over the network, after which remote unlock is disabled until you unlock on the device; and each PIN has its own budget.
Nostr events are signed as standard BIP-340 Schnorr signatures — computed on the isolated signing processor, so the key never enters the network-facing chip (see 03). Whether events sign automatically or require a physical button press is your choice, and the policy is enforced by the device firmware. A client cannot override it.
Bitcoin signing is air-gapped only. There is no connected signing path — none. Bitcoin exists only in Bitcoin mode, where no radio is ever brought up; moving funds happens exclusively across the camera and screen. The device scans a ur:crypto-psbt QR, you confirm the destination, amount and fee on its own screen, enter the BTC PIN on its buttons, and it displays the signed transaction back as a QR. The transaction crosses the room as light, both ways.
Multisig is supported as a BIP-48 cosigner. Register the wallet descriptor on the device once; it derives and verifies addresses against that quorum, signs its own inputs, and hands anything it cannot prove is yours back unsigned. Single-sig and multisig transactions are kept separate — a mixed PSBT is refused. It is the posture we recommend: with a second signer in the quorum, the KEY never spends alone, and no single device — ours included — is the whole story.
A Bitcoin session starts from a physical power cycle — not a soft reboot that compromised firmware could fake — so nothing from a previous session can be resident when the door opens. The seed is unsealed only inside the signing processor, which derives the keys and signs each input itself; the main chip hands it a fixed-size request per input, recomputes every hash independently, and refuses any signature that does not match. Each signature asks for the BTC PIN again, and the signing processor re-mints the mode value for it. When you are done the device sleeps; waking it returns to the Bitcoin session, and Nostr stays closed until the next power cycle. Before any of that, the device re-derives every input's key and every change output from your own keys, and anything it cannot prove is yours comes back unsigned.
Pairing takes two codes and one glance. Your phone first scans the device's own QR to reach it — on your home network or on the device's hotspot. Then the browser displays a QR code and the device scans it with its camera — the pairing secret crosses the room as light, not as network traffic. Then both sides independently compute a six-digit confirmation code from the freshly negotiated session key, and both screens show it. Pairing completes only when you confirm on the device that the codes match. If anyone interfered with the exchange, the two sides hold different keys and the codes cannot match. A scanned code alone enrols nothing — a browser that doesn't hold the matching private key can't complete the handshake at all.
After pairing, every sensitive request — unlock, signing, messages, status — is individually encrypted and authenticated under the session key, with a per-message counter that blocks replay and a binding to its exact endpoint that blocks reuse. The session key is derived independently on both ends from a secp256k1 handshake, is never transmitted, lives only in memory, and is forward-secret. Your unlock PIN is accepted only over this channel — never in the clear, under any circumstances.
The browser's message cache is encrypted at rest under a key that only your unlocked device can produce — held in browser memory only, never written to disk. A phone that's lost or taken cannot decrypt its cached message history without a live connection to your unlocked KEY. This applies to the client served from the device; the remote client's cache is not protected this way.
Remote signing uses NIP-46 with one-time pairing tokens. Each bunker link works exactly once: presenting it enrols that app's key and destroys the token in the same operation. A link that has been used is worthless — it cannot pair anything, for anyone, ever again. The web form of the link carries its secret in the URL fragment, which browsers do not send to servers.
You can mint new app links and revoke any app at any time, including remotely — with one deliberate exception: the pairing that controls the others can be changed only on the device, so a compromised app can never lock you out of your own hardware. And whatever a remote app requests is bounded by the same on-device signing policy as everything else.
The network surface, in one sentence: nothing sensitive answers without a paired, sealed session; the only thing that session can unlock is Nostr mode, three attempts before remote unlock is disabled; and Bitcoin signing, PIN changes, seed display, and factory reset exist only on the device's physical buttons.
Every production Favilla KEY will leave manufacturing with Secure Boot V2 permanently enabled. The device will only ever run firmware cryptographically signed by Favilla's RSA-3072 production keys — the key digests are burned into eFuses, verified byte-for-byte before commit, and the provisioning station, which is permanently air-gapped, refuses any board that isn't factory-virgin. Firmware authenticity is enforced by the boot ROM from the first instruction, on every boot, for the life of the device. An attacker with physical USB access cannot load modified firmware.
Production units additionally ship with hardware flash encryption permanently enabled: the firmware and entire boot chain are encrypted on the flash with XTS-AES under a key unique to each unit, burned into eFuses that can never be read out — by anyone, including us. Each unit carries its own key, so no single key exists whose compromise would expose more than one device. Your key material is already ciphertext before this layer even applies. The signing processor gets its own one-way lock: its debug port is permanently disabled, sealing the inner wrap key inside it.
Where this stands today: these fuses are one-way, so they are burned once the firmware is final and not before. The prototype and development units that exist now do not carry them. What stands between a flash dump and your keys on those units is the at-rest design in 02, which does not depend on this layer.
Every security product has limits. Most vendors hope you won't ask. We'd rather you read ours here than discover them in someone else's teardown.
Our firmware refuses to generate a seed if the camera layer falls below its 128-bit pass line, or if both layers come back flat — it stops rather than falling back to something weaker, and we test that path deliberately. But we want to be precise about what that proves: it catches a source that is dead. It cannot catch a source that is alive and weak. This is not a gap in our implementation; it is a property of the problem. Any generator that produces uniform-looking output passes every statistical test ever written, including the one that just cost Coldcard users their coins. That limit is exactly why the camera is in the seed path, as a second chip the first would have to collude with, and why we ship a dice option: dice is the only path where you can check the result yourself instead of trusting our checks.
We published raw min-entropy measurements for the accelerometer and the camera, including two results that were worse than we expected and one feature we decided not to ship because of them. Those numbers come from one unit, at one temperature, using estimators we wrote ourselves rather than NIST's reference tool. They are strong enough to have changed our design — the camera's result is why it sits in the seed path, as one half of an XOR with the secure element — and they are not strong enough to budget bits against on their own, so the design does not: if the camera layer were worthless, the secure element still carries the seed, and the reverse. The accelerometer does not contribute to your seed, and the part we measured has since been replaced.
A BIP-39 passphrase is supported, and you choose how it behaves when the wallet is created or restored. Bake it in: the passphrase is applied once, the derived seed is sealed, and the device never asks again — the words plus the passphrase are your backup. Ask each Bitcoin session: the words alone are sealed, and the Bitcoin door asks for a passphrase after the BTC PIN; the signing processor derives the wallet from it on the spot. Every passphrase is a valid wallet, so one set of words carries as many wallets as you have passphrases, and an answer of none, or a decoy, opens a different wallet from the real one. Your Nostr identity comes from the words alone in either mode. The limit to understand: the device cannot tell you a passphrase is wrong, because there is no wrong one. It shows you the wallet fingerprint instead — check it against the one you wrote down before you fund anything or sign.
The signing processor signs the transaction hashes it is handed and never sees the transaction — that is what keeps it parser-free. The consequence: compromised firmware on the main chip could, during a signing session you approved, hand it hashes for a different transaction than the one on the screen. Secure Boot (08) is what stops compromised firmware running at all; the main chip cross-checks every hash it sends; the PSBT parser on the main chip is the component we test and fuzz the hardest. And the practical defence is the one we recommend regardless: verify the outputs in your coordinator before broadcast, and use multisig, so the KEY never spends alone.
The isolation described here defeats remote attacks — an attacker on the network cannot extract either key. It is not the same as defeating an attacker who opens the enclosure of a powered, unlocked device and probes its internal wiring with equipment. Both keys reach the signing processor over an encrypted session the main chip cannot read, and the plain seed exists only inside that processor. A determined physical attacker who can probe the signing processor itself, or the secure element, is outside what this design claims to resist. The enclosure, the PINs, the motion lock and the air-gapped path raise the cost of physical attacks; they do not claim to make them impossible.
The six-digit code makes interference visible; it cannot make you look. Confirming without comparing the codes forfeits the protection — the inherent ceiling of every code-comparison scheme, ours included.
Your browser learns the device's identity key on its very first connection and pins it thereafter. An active attacker present on your network at that exact first moment could impersonate the device to the browser; from the second connection on, the pinned key closes this.
Within your chosen signing policy, a paired browser in an unlocked session can request signatures and read messages — that is what pairing means. The physical-button policy, the spend PIN, and revocation are the instruments that bound it.
Locking occurs on motion, on sleep, on command, and when a Bitcoin session ends. By default the device sleeps after five minutes and drops its hotspot after two, and sleep wipes the working keys — so an idle device does lock, by going to sleep. A stationary, unlocked device with sleep disabled stays unlocked until told otherwise. Nostr signing does not lock the device; only a Bitcoin session closes its door.
The network stack comes up when the device boots into Nostr mode, before the Nostr PIN has been entered, so a locked device is already reachable on the network. Nothing can be unlocked from there without a paired session and the PIN, and the Bitcoin door is closed regardless — but it is surface, and we say so.
The device's hotspot password is generated per device on first use and shown on its screen. It exists so your browser can reach the device, not as a security boundary — the boundary is the pairing and the encrypted channel, which is why joining the hotspot grants nothing.
Every statement on this page is written to be checked against the firmware source and the manufacturing tooling, which are published with the first release. When the facts change, this page changes.