Files
nostr_quantum_preparation/research/amber_integration_analysis.md
T

12 KiB

Amber Integration Analysis for PQ Nostr Web App

⚠️ Design-only research document. This is an analysis of a possible integration, not an implemented feature. The current system is a research prototype and does not make Nostr identities post-quantum secure by itself.

Amber Capabilities (from source code analysis)

Amber is an Android Nostr event signer that keeps the nsec segregated in a dedicated app. Based on source code inspection:

Seed Phrase Support ✅

  • NIP-06 key derivation: Uses com.vitorpamplona.quartz.nip06KeyDerivation.Bip39Mnemonics and Nip06 for deriving secp256k1 keys from mnemonics
  • Stores seed words: DataStoreAccess.SEED_WORDS persists the mnemonic in Android encrypted storage (DataStoreAccess.kt)
  • Generates new seeds: Login screen generates random entropy → Bip39Mnemonics.toMnemonics(entropy) (LoginScreen.kt)
  • Mnemonic login: UI supports 12 or 24 word entry with account index selection (MnemonicLoginInput.kt)
  • Seed backup: Account export includes encrypted seed words (AccountExportService.kt)

Signing Operations ✅

Amber supports these signer types (SignerType.kt):

  • SIGN_EVENT — sign any Nostr event
  • GET_PUBLIC_KEY — return npub
  • NIP04_ENCRYPT / NIP04_DECRYPT
  • NIP44_ENCRYPT / NIP44_DECRYPT
  • NIP44_V3_ENCRYPT / NIP44_V3_DECRYPT (new v3 cipher with kind+scope context)
  • DECRYPT_ZAP_EVENT

NIP-46 Remote Signing ✅

  • Amber acts as a NIP-46 signing device — "your smartphone act as a NIP-46 signing device without any need for servers or additional hardware"
  • Web apps can connect to Amber via NIP-46 (nostrconnect:// URI)
  • Supports permission management per-app

Multiple Accounts ✅

  • Supports multiple accounts, each with its own nsec/seed words

How Amber Fits the PQ Web App Vision

The Key Insight

Amber already stores the seed phrase (BIP39 mnemonic) and uses it to derive secp256k1 keys via NIP-06. The seed phrase is algorithm-agnostic — it's just 128/256 bits of entropy. Our plan's Component 1 (seed phrase as root of trust) means PQ keys can be derived from the same seed using different derivation paths.

Three Architecture Options

Option A: Web App + Amber Signing (Minimal Amber Changes)

┌─────────────────┐     NIP-46      ┌──────────────────┐
│   Web App       │ ◄──────────────► │     Amber        │
│  (browser)      │                  │   (Android)      │
│                 │                  │                  │
│ 1. User enters  │  getPublicKey    │ Returns npub     │
│    seed phrase  │ ──────────────►  │                  │
│    (client-side │                  │                  │
│    only, WASM)  │  signEvent       │ Signs key-link   │
│                 │  (key-link)      │ event with       │
│ 2. Derives PQ   │ ──────────────►  │ secp256k1        │
│    keys from    │                  │                  │
│    seed (WASM)  │                  │                  │
│                 │                  │                  │
│ 3. PQ-signs     │                  │                  │
│    key-link     │                  │                  │
│    client-side  │                  │                  │
│                 │                  │                  │
│ 4. Assembles &  │                  │                  │
│    publishes    │                  │                  │
│    key-link     │                  │                  │
│    event        │                  │                  │
└─────────────────┘                  └──────────────────┘

Flow:

  1. User connects to Amber via NIP-46 for secp256k1 signing
  2. User enters their seed phrase in the web app (client-side only, WASM, never sent to server)
  3. Web app derives PQ keys (ML-DSA, ML-KEM, SLH-DSA) from seed using liboqs-WASM
  4. Web app requests Amber to sign the key-link event content with secp256k1
  5. Web app PQ-signs the key-link event content client-side
  6. Web app assembles the complete key-link event (secp256k1 sig + PQ sigs) and publishes to relays
  7. Web app requests OpenTimestamps attestation via NIP-03

Pros: No Amber modifications needed. Full PQ key derivation in browser. Cons: User must enter seed phrase in browser (even though client-side only). Trust model requires user to verify the web app isn't exfiltrating the seed.

Option B: Extend Amber for PQ Key Derivation (Best Security)

┌─────────────────┐     NIP-46      ┌──────────────────┐
│   Web App       │ ◄──────────────► │     Amber        │
│  (browser)      │                  │   (Android)      │
│                 │                  │                  │
│ 1. Connect to   │  new method:     │ Derives PQ keys  │
│    Amber via    │  pq_derive_keys  │ from stored seed │
│    NIP-46       │  ──────────────► │ (liboqs native)  │
│                 │                  │                  │
│ 2. Requests PQ  │  Returns PQ      │ Returns PQ       │
│    pubkey list  │  ◄──────────────  │ pubkeys only     │
│                 │                  │ (privkeys stay   │
│ 3. Requests     │  new method:     │ in Amber)        │
│    key-link     │  pq_sign         │                  │
│    signing      │  ──────────────► │ PQ-signs event   │
│                 │                  │ with PQ privkeys │
│ 4. Requests     │  signEvent       │                  │
│    secp256k1    │  (existing)      │ secp256k1 signs  │
│    signing      │  ──────────────► │                  │
│                 │                  │                  │
│ 5. Assembles &  │                  │                  │
│    publishes    │                  │                  │
└─────────────────┘                  └──────────────────┘

Flow:

  1. User connects to Amber via NIP-46
  2. Web app calls new NIP-46 method pq_derive_keys — Amber derives PQ keys from its stored seed phrase using liboqs (native Android)
  3. Amber returns only the PQ public keys (private keys never leave Amber)
  4. Web app constructs the key-link event content with all pubkeys
  5. Web app calls pq_sign — Amber PQ-signs the event content with each PQ private key
  6. Web app calls signEvent — Amber secp256k1-signs the event
  7. Web app assembles and publishes the complete key-link event

Pros: Seed phrase never leaves Amber. PQ private keys never leave Amber. Best security model — consistent with Amber's philosophy of "private keys should be exposed to as few systems as possible." Cons: Requires Amber modifications (new NIP-46 methods, liboqs integration for Android).

Option C: Hybrid (Pragmatic)

┌─────────────────┐     NIP-46      ┌──────────────────┐
│   Web App       │ ◄──────────────► │     Amber        │
│  (browser)      │                  │   (Android)      │
│                 │                  │                  │
│ User chooses:   │                  │                  │
│                 │                  │                  │
│ Path 1 (Amber   │  signEvent       │ Signs with       │
│  has seed):     │  ──────────────► │ secp256k1        │
│ Request secp    │                  │                  │
│ sig from Amber  │                  │                  │
│ Enter seed in   │                  │                  │
│ web app for PQ  │                  │                  │
│ key derivation  │                  │                  │
│ (client-side)   │                  │                  │
│                 │                  │                  │
│ Path 2 (raw     │  signEvent       │ Signs with       │
│  nsec, no seed  │  ──────────────► │ secp256k1        │
│  in Amber):     │                  │                  │
│ Generate new    │                  │                  │
│ seed in web app │                  │                  │
│ (client-side),  │                  │                  │
│ derive PQ keys, │                  │                  │
│ request secp    │                  │                  │
│ sig from Amber  │                  │                  │
└─────────────────┘                  └──────────────────┘

Pros: Works for both existing seed-phrase users and raw-nsec users. No Amber changes required for initial launch. Can upgrade to Option B later. Cons: Seed phrase still enters browser for PQ derivation. Two code paths.


Recommendation: Option B (Extend Amber)

This aligns with:

  1. Amber's security philosophy: "Private keys should be exposed to as few systems as possible"
  2. Our plan's Component 1: Seed phrase as algorithm-agnostic root of trust — Amber already stores it
  3. Our plan's Component 2: Cross-signed key-link events — Amber can sign with both secp256k1 and PQ keys
  4. Community discussion (Issue #1971): trbouma and mikedilger both advocate for HSM/enclave-based PQ key storage

Required Amber Changes

  1. Add liboqs dependency: Native library for PQ algorithms (ML-DSA, ML-KEM, SLH-DSA)
  2. PQ key derivation from seed: New function that takes the stored BIP39 seed and derives PQ keys using a deterministic scheme (e.g., HKDF(seed, "nostr-pq-ml-dsa-44") → PQ private key)
  3. New NIP-46 methods:
    • pq_get_public_keys — return array of PQ public keys with algorithm identifiers
    • pq_sign — sign a message with a specified PQ algorithm's private key
  4. Permission management: New permission types for PQ signing operations
  5. UI updates: Show PQ key information, approval screens for PQ signing requests

Required Web App Components

  1. NIP-46 client: Connect to Amber, send signing requests
  2. Key-link event builder: Construct the event content with all pubkeys, request signatures, assemble final event
  3. OpenTimestamps client: Request OTS attestation for the key-link event (NIP-03)
  4. Relay publisher: Publish the key-link event to relays
  5. Verification UI: Show the user what was created, verify the key-link event is valid
  6. No server-side secrets: The web app is a static site — no backend that could intercept keys

For Users Without Amber (or Without Seed Phrase in Amber)

The web app should also support:

  • NIP-07 browser extension signing (nos2x, etc.) for secp256k1 signatures
  • Client-side seed phrase entry (WASM, never transmitted) for users who want to derive PQ keys in-browser
  • New seed generation for users who don't have a seed phrase yet (Component 4: migrating existing users with raw nsec)