Files
nostr_quantum_preparation/research/amber_integration_analysis.md

191 lines
12 KiB
Markdown

# 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](https://github.com/greenart7c3/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`](../Amber/app/src/main/java/com/greenart7c3/nostrsigner/DataStoreAccess.kt:41))
- **Generates new seeds**: Login screen generates random entropy → `Bip39Mnemonics.toMnemonics(entropy)` ([`LoginScreen.kt`](../Amber/app/src/main/java/com/greenart7c3/nostrsigner/ui/LoginScreen.kt:428))
- **Mnemonic login**: UI supports 12 or 24 word entry with account index selection ([`MnemonicLoginInput.kt`](../Amber/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MnemonicLoginInput.kt:48))
- **Seed backup**: Account export includes encrypted seed words ([`AccountExportService.kt`](../Amber/app/src/main/java/com/greenart7c3/nostrsigner/service/AccountExportService.kt:193))
### Signing Operations ✅
Amber supports these signer types ([`SignerType.kt`](../Amber/app/src/main/java/com/greenart7c3/nostrsigner/models/SignerType.kt:5)):
- `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)