Security

Every claim, traced
to the code.

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. Nothing here is aspirational.

01 · Key generation

One phrase.
Both identities.

Your keys are generated on the device, during setup, and are never transmitted. You choose where the randomness comes from.

Secure element draws from the SE051's certified true random number generator. Instant, no effort — and you are trusting the certificate, because a sealed chip cannot be checked from the outside. 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.

The secure-element path also folds in the ESP32-S3's own generator as extra margin. We do not count it toward the entropy claim. The radios are off during setup — the condition its own vendor documents as degraded — and we cannot prove its quality, so it is there to help, never to be relied on.

In development: a third path that draws one grid from the secure element and one from the camera, shows you both, 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. The tool that checks it is live at Seed check; the firmware is not in a shipping release yet.

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. One phrase, written down once, restores everything. You can also import an existing nsec — the device then operates as a Nostr-only signer, since an nsec alone carries no Bitcoin seed.

FIG. 01 / KEY DERIVATIONONE PHRASE → TWO KEYS
SE051 TRNG certified · instant · trusted YOUR DICE 99 rolls · you can check it — you choose — SHA-256 construction BIP-39 PHRASE 12 / 24 words · your backup NIP-06 BIP-84 NOSTR identity key BITCOIN wallet seed LOSE THE DEVICE? this phrase restores both — on a new KEY
One source — the one you pick — feeds one BIP-39 phrase. Nostr (NIP-06) and Bitcoin (BIP-84) both derive from it — so one backup, made once at setup, recovers your entire identity and wallet on a replacement device.
02 · Storage at rest

Never in plain form.
Anywhere.

Your Nostr key and your Bitcoin seed are stored as AES-256 ciphertext. The keys that decrypt them live inside the SE051 secure element, where they cannot be read out — by you, by us, or by anyone who opens the device. The secure element releases a decryption only inside a session authenticated by your PIN.

A raw dump of the device's flash yields ciphertext and public data. Nothing more.

FIG. 02 / AT RESTFLASH · SECURE ELEMENT · PIN
ESP32 FLASH NOSTR KEY · AES-256 ciphertext unreadable without SE session BITCOIN SEED · AES-256 ciphertext unreadable without SE session SE051 · EAL 6+ DECRYPTION KEYS · never leave silicon PIN VERIFY · hardware retry counter 10 wrong attempts → permanent lock recovery = your phrase unlocks only in PIN session FLASH DUMP = CIPHERTEXT ONLY
Secrets on flash, keys in silicon. The blobs and the keys that open them live in different chips — and the chip holding the keys is a certified secure element that only answers to your PIN, with a hardware counter that locks permanently after ten wrong attempts.
03 · The isolated Nostr signer

Your identity key
never touches the internet chip.

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 and nothing else, and receives a finished signature back. The signer parses no messages, so there is no malformed input that can break it, and it has no command that returns the key.

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 they have no path to — 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: Secure Boot and a reboot return the device to known-good firmware, removing the attacker. 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 at all. Less surface means fewer ways in — and even a way in does not reach the key.

FIG. 03 / ISOLATED SIGNERKEY OFF THE NETWORK CHIP
UNTRUSTED · WI-FI ACTIVE NETWORK PROCESSOR relays · parsing · radios holds no Nostr key RCE here finds nothing to steal ISOLATED · NO NETWORK SIGNING PROCESSOR no radios · no parser holds the Nostr key signs · never reveals it 32-byte hash → ← signature THE KEY NEVER CROSSES THE BOUNDARY
Compromise the network chip and the key still isn't there. It lives on a separate processor that only ever receives a hash and returns a signature — never the key.
04 · Two PINs, two doors

Daily life and spending
are different doors.

The daily PIN opens Nostr signing and watch-only Bitcoin — you can see your balance and addresses, but nothing can move. The spend PIN is required to sign a Bitcoin transaction, and it's entered on the device's own buttons. It never travels over any network, and there is no API path that accepts it.

There is no remote spend path — and that's not a policy setting. The seed's decryption key is bound in silicon to the spend PIN, and the spend PIN has no network entry point. Wrong attempts trip a hardware counter with escalating lockouts, enforced identically on-device and over the network, so neither path can be used to race the other.

FIG. 04 / THE TWO DOORSDAILY VS SPEND
DOOR 1 · DAILY PIN ✓ Nostr signing ✓ Encrypted messages ✓ Bitcoin watch-only · balance & receive entered on device or over the encrypted channel — nothing can move funds DOOR 2 · SPEND PIN ✓ Bitcoin transaction signing — only this DEVICE BUTTONS ONLY no network path · no API accepts it seed key bound to this PIN in silicon — remote spend is impossible, not just disabled unlocking Door 1 never opens Door 2 · escalating hardware lockouts on both
One unlock is never both. Your daily key can post and read all day without your Bitcoin ever being exposed — the spend door physically cannot be opened from the network.
05 · Signing

It refuses to sign what it
can't prove is yours.

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. Over the network you can watch your wallet (balance and receive addresses), but moving funds happens exclusively across the camera and screen, with no radio involved at any point. The device scans a ur:crypto-psbt QR, you confirm the destination, amount and fee on its own screen, enter the spend PIN on its buttons, and it displays the signed transaction back as a QR. The transaction crosses the room as light, both ways.

Every signing is bracketed by an automatic reboot — enforced by firmware, not left to you. The device reboots into Secure-Boot-verified firmware before the seed is ever decrypted, so no attacker from a previous session can be resident when it appears; and it reboots again after signing, destroying all state. The seed exists in the clear only for the single signature, inside a spend-PIN session, on a freshly-booted device with the radios off. Before that, the device re-derives every input's key and every change output from your own seed and refuses to sign anything it cannot prove is yours.

FIG. 05 / AIRGAP SIGNINGQR IN · VERIFY · QR OUT
YOUR WALLET Sparrow · BlueWallet shows PSBT QR light only FAVILLA KEY 1 · camera scans QR 2 · re-derives & verifies inputs + change 3 · screen: destination · amount · fee 4 · spend PIN → sign → seed zeroed light only SIGNED TX QR wallet scans & broadcasts NO NETWORK TOUCHES THE DEVICE AT ANY POINT
The transaction crosses the room as light. Validated round-trip against Sparrow and BlueWallet on mainnet.
06 · Pairing & the encrypted channel

Paired by light.
Confirmed by you.

To pair a browser, it 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.

FIG. 06 / PAIRINGQR + SIX-DIGIT CONFIRM
BROWSER pairing QR on screen camera reads it light · not network FAVILLA KEY secp256k1 handshake → session key both screens show the code: 4 8 1 · 9 2 3 codes match? → you confirm on the device → session enrolled any interference = different keys = codes can't match
Man-in-the-middle attacks make the numbers disagree. The six-digit check turns a cryptographic property into something you can verify with your eyes.
07 · Remote signing

Links that work exactly once.

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 — or all of them — at any time, including remotely. The device shows you on its screen when a remote mint or revocation occurs. And whatever a remote app requests is bounded by the same on-device signing policy as everything else.

The network surface, in one sentence: every API request is origin-restricted to local and private addresses; the only sensitive action reachable over the network is a daily unlock over the encrypted channel; and Bitcoin spending, PIN changes, seed display, and factory reset exist only on the device's physical buttons.

08 · Manufacturing & firmware integrity

Locked at the factory.
For life.

Every Favilla KEY leaves 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 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.

09 · What we do not claim

The limits, stated with
the same weight.

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.

A health check cannot tell you a random source is good.

Our firmware refuses to generate a seed if the secure element does not answer — 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 we ship a dice option: it is the only path where you can check the result yourself instead of trusting our checks.

We have measured two of our sensors. It is not enough yet.

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; they are not strong enough to budget bits against, and we do not budget bits against them. Neither sensor contributes to your seed today.

There is no BIP-39 passphrase option yet.

A passphrase is the standard escape hatch if a seed-generation flaw is ever found in a device you already own — it was the mitigation Coinkite offered affected Coldcard owners. We do not support one today. The dice path covers the same ground differently, by letting you verify generation rather than adding a secret afterwards, but the two are not equivalent and we would rather say so than let you assume otherwise.

The Bitcoin seed is a software secret for one fresh boot.

The Nostr key signs on the isolated signing processor and never enters the network-facing chip. The Bitcoin seed is different: standard wallet derivation requires it in the main processor's RAM for the duration of a signature. We bound that exposure tightly — Bitcoin signs air-gapped only, on a device that automatically reboots into verified firmware immediately before the seed is decrypted and again immediately after, with the radios off throughout. This removes any attacker resident from a previous session and any network path for data to leave. The residual is narrow but real: a malicious transaction that exploited the parser within that single fresh boot could reach the seed while it is in memory. That parser is therefore the component we test and fuzz the hardest. At-rest protection remains absolute against flash extraction.

Physical access to a powered, unlocked device is a different threat.

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. The traffic that carries the Nostr key to its signer is encrypted, but the Bitcoin seed still transits the main bus during a signature, and a determined physical attacker with an unlocked, mid-signing device could target that. 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 pairing check is yours to perform.

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.

First contact is trust-on-first-use, in one direction.

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.

An unlocked device trusts its paired client.

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.

The device does not re-lock on idle.

Locking occurs on motion, on sleep, on command, and after signing. A stationary, unlocked device with sleep disabled stays unlocked until told otherwise.

The access point password is not a secret.

The device's hotspot uses a fixed, published password. 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 verifiable against the firmware source and the manufacturing tooling for the stated revision. When the facts change, this page changes.

Questions this
didn't answer?

The FAQ takes on the hard ones directly.

Read the FAQ →