Keybase-Inspired Features — Architecture Documentation
System Architecture
┌─────────────────────────────────────────────────────────────────┐
│ brightchain-react (UI) │
│ PaperKeyWizard │ DeviceManager │ IdentityProofWizard │ ... │
├─────────────────────────────────────────────────────────────────┤
│ brightchain-api-lib (Controllers) │
│ DeviceController │ IdentityProofController │ WalletController │
│ DirectoryController │ GitController │ ExplodingMsgController │
│ ExpirationScheduler (Node.js-specific) │
├─────────────────────────────────────────────────────────────────┤
│ brightchain-lib (Core Services) │
│ MemberPaperKeyService │ SplitPaperKeyService │
│ DeviceProvisioningService │ MemberIdentityProofService │
│ PublicKeyDirectoryService │ EthereumWalletService │
│ GitSigningService │ ExplodingMessageService │
├─────────────────────────────────────────────────────────────────┤
│ External Dependencies │
│ bip39 │ @scure/bip32 │ secp256k1 │ @noble/hashes │
│ @digitaldefiance/secrets │ @digitaldefiance/ecies-lib │
└─────────────────────────────────────────────────────────────────┘
Design Principles
- Platform Agnosticism: All core logic lives in brightchain-lib and runs in both Node.js and browsers.
- Generic DTO Pattern: Interfaces use
<TId = string>so frontends use string IDs while backends can useGuidV4Buffer. - Stateless Services: Services are pure functions operating on data — no internal state, no singletons.
- Deterministic Key Derivation: All keys (device, wallet, git) are derived from the member’s BIP39 mnemonic via BIP32 HD paths.
- No Centralized Trust: Identity proofs are self-verifying via ECDSA signatures; no server is trusted for verification.
Data Flow Diagrams
Paper Key Generation & Recovery
User → PaperKeyWizard → MemberPaperKeyService.generatePaperKey()
├── bip39.generateMnemonic(256)
└── Returns 24-word phrase
User → PaperKeyRecovery → MemberPaperKeyService.recoverFromPaperKey()
├── bip39.mnemonicToSeedSync()
├── HDKey.fromMasterSeed()
└── Reconstructs Member identity
Split Paper Key (Shamir’s Secret Sharing)
Paper Key → SplitPaperKeyService.split(key, totalShares, threshold)
├── @digitaldefiance/secrets.share()
├── Produces N shares, any T can reconstruct
└── Each share → QR code template
Any T shares → SplitPaperKeyService.reconstruct(shares)
├── @digitaldefiance/secrets.combine()
└── Returns original paper key
Device Provisioning
Member + Paper Key → DeviceProvisioningService.provisionDevice()
├── Validate paper key
├── Derive device key: m/44'/60'/0'/1/<deviceIndex>
├── Generate IDeviceMetadata
└── Register device on member
Device Revocation → DeviceProvisioningService.revokeDevice()
├── Mark device as revoked
├── Set revokedAt timestamp
└── Device keys become permanently invalid
Identity Proof Creation & Verification
Member + Platform → MemberIdentityProofService.create()
├── Build proof statement (JSON)
├── ECDSA sign with member's private key
├── Return signed proof + instructions
└── User posts to platform
Proof URL → MemberIdentityProofService.verify()
├── Fetch proof from URL
├── Extract signature
├── ECDSA verify against member's public key
└── Return verified/failed
Ethereum Wallet Derivation
Mnemonic → EthereumWalletService.deriveAddress()
├── bip39.mnemonicToSeedSync()
├── HDKey.fromMasterSeed(seed)
├── Derive path m/44'/60'/0'/0/0
├── secp256k1 public key
├── keccak256(publicKey)
└── Last 20 bytes → 0x-prefixed Ethereum address
Message → EthereumWalletService.signMessage()
├── EIP-191 prefix: "\x19Ethereum Signed Message:\n"
├── keccak256(prefixed message)
├── secp256k1.sign(hash, privateKey)
└── Returns {r, s, v} signature
Git Signing
Commit Content → GitSigningService.signCommit()
├── SHA-256 hash of content
├── secp256k1.sign(hash, gitSigningKey)
├── DER-encode signature
└── Wrap in GPG-compatible armor block
Public Key → GitSigningService.exportPublicKey()
├── Derive git signing key (m/44'/60'/0'/2/0)
├── Get compressed public key
└── Wrap in GPG PUBLIC KEY BLOCK armor
Exploding Messages
Message + Duration → ExplodingMessageService.setExpiration()
├── Set expiresAt = now + duration
└── Mark as exploding
Message + Read → ExplodingMessageService.markRead()
├── Add reader to readBy map
├── Increment readCount
└── Check if maxReads exceeded
Scheduler (Node.js) → ExpirationScheduler.start()
├── Periodic check (configurable interval)
├── ExplodingMessageService.checkExpiration()
├── ExplodingMessageService.explode()
└── Emit MESSAGE_EXPIRED / MESSAGE_EXPLODED events
Security Considerations
Key Management
- BIP39 Entropy: Paper keys use 256-bit entropy (24 words), providing 2^256 possible keys.
- BIP32 Derivation: Hardened derivation (
') is used for all purpose-level paths, preventing child key compromise from leaking parent keys. - Device Isolation: Each device has its own derived key. Revoking a device does not affect other devices or the master identity.
Cryptographic Primitives
| Operation | Algorithm | Library | Security Level |
|---|---|---|---|
| Key derivation | BIP32 HD | @scure/bip32 | 256-bit |
| Signing (identity) | ECDSA secp256k1 | secp256k1 | 128-bit |
| Hashing (Ethereum) | Keccak-256 | @noble/hashes/sha3 | 256-bit |
| Hashing (Git) | SHA-256 | @noble/hashes/sha256 | 256-bit |
| Secret sharing | Shamir’s SSS | @digitaldefiance/secrets | Information-theoretic |
| Mnemonic | BIP39 | bip39 | 256-bit entropy |
Threat Model
| Threat | Mitigation |
|---|---|
| Paper key theft | Split custody via Shamir’s Secret Sharing; physical storage guidance |
| Device compromise | Per-device keys with revocation; compromised device cannot access other device keys |
| Identity proof forgery | ECDSA signatures tied to member’s secp256k1 key; proofs are self-verifying |
| Message persistence | Exploding messages with server-side scheduled cleanup; content replaced on expiration |
| Key derivation attack | Hardened BIP32 derivation prevents child-to-parent key recovery |
| Replay attacks | Timestamps and nonces in signed proof statements |
Comparison with Keybase Security Model
- Keybase: Relies on centralized servers for key distribution, proof verification, and device management. Server compromise could forge proofs or intercept device provisioning.
- BrightChain: All verification is cryptographic and peer-to-peer. No server is trusted for proof validity. Device keys are derived deterministically, not distributed by a server. Shamir’s Secret Sharing provides organizational key recovery without any single custodian having full access.
Interface Design (Generic DTO Pattern)
All interfaces follow the generic <TId> pattern for cross-platform compatibility:
// brightchain-lib — shared interface
interface IDeviceMetadata<TId = string> {
id: TId;
memberId: TId;
name: string;
type: DeviceType;
publicKey: string;
createdAt: Date;
lastSeenAt: Date;
revoked: boolean;
revokedAt?: Date;
}
// Frontend usage: IDeviceMetadata<string>
// Backend usage: IDeviceMetadata<GuidV4Buffer>
This pattern is applied consistently across all Keybase feature interfaces:
IDeviceMetadata<TId>IIdentityProof<TId>IPublicProfile<TId>IGitSignature<TId>ICommunicationMessage<TId>(extended with exploding fields)