Skip to content

Repository files navigation

Bitwarden Passkey PRF Portability

Preserve one PRF-capable passkey across Credential Exchange, official Bitwarden Cloud sync, Android, and iOS without changing the derived Nuri wallet.

Important

Current checkpoint — 29 July 2026: the GPM import stack and Android picker-timeout fix are merged, the pinned APK is green, but the final same-PRF wallet comparison is not complete.

Resume here: CURRENT_STATUS.mddevice-proof issue #87.

New developer: start in three steps

  1. Read CURRENT_STATUS.md. It contains exact repository heads, proven boundaries, device state, known traps, and copy/paste resume commands.
  2. Read the fixed Nuri PRF contract and security rules.
  3. Continue #87: capture the Google baseline, clean only the Bitwarden test vault, import once, and compare Android before continuing to iOS.

Do not delete Google source passkeys. Do not accept signing success as proof: credential-ID fingerprint, PRF fingerprint, and public wallet identity must all match.

Current result

Area State
Real GPM Credential Exchange import ✅ Completed
Negative timestamp and unrelated extension parsing ✅ Fixed
PRF state inside opaque Cipher.data through official Cloud ✅ Implemented
Android Credential Manager response before timeout ✅ Proven
Pinned Android build Run 29912811796
Google vs Bitwarden exact PRF/wallet match ❌ Pending in #87
Same synced item on iOS ❌ Pending after Android proof

See CHANGELOG.md for the chronological implementation record. No production-ready release exists yet; GitHub releases are labeled checkpoints until the physical proof is green.

Goal

A Nuri user can:

  1. create or hold a PRF-capable nuri.com passkey in a platform password manager;
  2. transfer that exact passkey into Bitwarden through Credential Exchange;
  3. sync it through official Bitwarden Cloud as an opaque encrypted cipher;
  4. use Bitwarden as the Android/iOS passkey provider; and
  5. recover the same Bitcoin, Ethereum, Nostr, and SwapKit public identities.

The portable object is the passkey itself: credential ID, signing key, user handle, RP ID, algorithm, and PRF/HMAC seed state. Bitwarden evaluates PRF on demand and must never store a Nuri-specific PRF output.

Architecture

Credential Exchange exporter
          │
          ▼
  Bitwarden mobile importer
          │ explicit blob encryption
          ▼
 authenticated Cipher.data ── official Bitwarden Cloud
          │
          ▼
 Bitwarden credential provider
          │ WebAuthn PRF (UV required)
          ▼
       pwa.nuri.com ── public wallet continuity proof

The server treats Cipher.data as opaque. No custom Nuri backend or Nuri-specific Bitwarden runtime behavior is required.

Repositories

Responsibility Repository
Contract, status, vectors, evidence nuri-com/bitwarden-passkey-prf
Rust SDK, CXF, blob encryption, PRF authenticator nuri-com/sdk-internal
Android importer and credential provider nuri-com/android
iOS importer and credential provider nuri-com/ios
Swift SDK package nuri-com/sdk-swift
Legacy-format compatibility research only nuri-com/server

Program documents

Security boundary

Never commit or attach a real CXF payload, passkey signing key, credential ID, HMAC seed, raw PRF result, derived wallet private key, password, PIN, or biometric data. Real-device evidence uses hashes and public identities only. Missing or changed PRF state must fail before Nuri commits a different wallet.

About

Upstream-first PRF-capable passkey portability for Bitwarden iOS and Android

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages