From 34633af5392f627981c4cc87ead69d1d07a71488 Mon Sep 17 00:00:00 2001 From: kccleoc Date: Wed, 28 Jan 2026 02:56:26 +0800 Subject: [PATCH] Update and rename _GPT-Suggestion.md to DEVELOPMENT.md --- DEVELOPMENT.md | 291 +++++++++++++++++++++++++++++++++++++++++++++ _GPT-Suggestion.md | 10 -- 2 files changed, 291 insertions(+), 10 deletions(-) create mode 100644 DEVELOPMENT.md delete mode 100644 _GPT-Suggestion.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..ccc397f --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,291 @@ +Here's your `DEVELOPMENT.md`: + +```markdown +# Development Guide - SeedPGP v1.1.0 + +## Architecture Quick Reference + +### Core Types + +```typescript +// src/lib/types.ts +interface SeedPgpPlaintext { + v: number; // Version (always 1) + t: string; // Type ("bip39") + w: string; // Mnemonic words (normalized) + l: string; // Language ("en") + pp: number; // BIP39 passphrase used? (0 or 1) + fpr?: string[]; // Optional recipient fingerprints +} + +interface ParsedSeedPgpFrame { + kind: "single"; // Frame type + crc16: string; // 4-digit hex checksum + b45: string; // Base45 payload +} +``` + +### Frame Format + +``` +SEEDPGP1:0:ABCD:BASE45DATA + +SEEDPGP1 - Protocol identifier + version +0 - Frame number (single frame) +ABCD - CRC16-CCITT-FALSE checksum (4 hex digits) +BASE45 - Base45-encoded PGP binary message +``` + +### Key Functions + +#### Encryption Flow +```typescript +buildPlaintext(mnemonic, bip39PassphraseUsed, recipientFingerprints?) + → SeedPgpPlaintext + +encryptToSeedPgp({ plaintext, publicKeyArmored?, messagePassword? }) + → { framed: string, pgpBytes: Uint8Array, recipientFingerprint?: string } +``` + +#### Decryption Flow +```typescript +decryptSeedPgp({ frameText, privateKeyArmored?, privateKeyPassphrase?, messagePassword? }) + → SeedPgpPlaintext + +frameDecodeToPgpBytes(frameText) + → Uint8Array (with CRC16 validation) +``` + +#### Encoding/Decoding +```typescript +frameEncode(pgpBinary: Uint8Array) → "SEEDPGP1:0:CRC16:BASE45" +frameParse(text: string) → ParsedSeedPgpFrame +frameDecodeToPgpBytes(frameText: string) → Uint8Array +``` + +### Dependencies + +```json +{ + "openpgp": "^6.3.0", // PGP encryption (curve25519Legacy) + "bun-types": "latest", // Bun runtime types + "react": "^18.x", // UI framework + "vite": "^5.x" // Build tool +} +``` + +### OpenPGP.js v6 Quirks + +⚠️ **Important compatibility notes:** + +1. **Empty password array bug**: Never pass `passwords: []` to `decrypt()`. Only include if non-empty: + ```typescript + if (msgPw) { + decryptOptions.passwords = [msgPw]; + } + ``` + +2. **Curve naming**: Use `curve25519Legacy` (not `curve25519`) in `generateKey()` + +3. **Key validation**: Always call `getEncryptionKey()` to verify public key has usable subkeys + +## Project Structure + +``` +seedpgp-web/ +├── src/ +│ ├── lib/ +│ │ ├── seedpgp.ts # Core encrypt/decrypt logic +│ │ ├── seedpgp.test.ts # Test vectors (15 tests) +│ │ ├── base45.ts # Base45 encoder/decoder +│ │ ├── crc16.ts # CRC16-CCITT-FALSE +│ │ └── types.ts # TypeScript interfaces +│ ├── App.tsx # React UI entry +│ └── main.tsx # Vite bootstrap +├── package.json +├── tsconfig.json +├── vite.config.ts +├── README.md +└── DEVELOPMENT.md # This file +``` + +## Development Workflow + +### Running Tests + +```bash +# All tests +bun test + +# Watch mode +bun test --watch + +# Verbose output +bun test --verbose +``` + +### Development Server + +```bash +bun run dev # Start Vite dev server +bun run build # Production build +bun run preview # Preview production build +``` + +### Adding Features + +1. **Write tests first** in `seedpgp.test.ts` +2. **Implement in** `src/lib/seedpgp.ts` +3. **Update types** in `types.ts` if needed +4. **Run full test suite**: `bun test` +5. **Commit with conventional commits**: `feat: add QR generation` + +## Feature Agenda + +### 🚧 v1.2.0 - QR Code Round-Trip + +**Goal**: Read back QR code and decrypt with user-provided credentials + +**Tasks**: +- [ ] Add QR code generation from `encrypted.framed` + - Library: `qrcode` or `qr-code-styling` + - Input: SEEDPGP1 frame string + - Output: QR code image/canvas/SVG + +- [ ] Add QR code scanner UI + - Library: `html5-qrcode` or `jsqr` + - Camera/file upload input + - Parse scanned text → `frameText` + +- [ ] Build decrypt UI form + - Input fields: + - Scanned QR text (auto-filled) + - Private key (file upload or paste) + - Key passphrase (password input) + - OR message password (alternative) + - Call `decryptSeedPgp()` + - Display recovered mnemonic + metadata + +- [ ] Add visual feedback + - CRC16 validation status + - Key fingerprint match indicator + - Decryption success/error states + +**API Usage**: +```typescript +// Generate QR +import QRCode from 'qrcode'; +const { framed } = await encryptToSeedPgp({ ... }); +const qrDataUrl = await QRCode.toDataURL(framed); + +// Scan and decrypt +const scannedText = "SEEDPGP1:0:ABCD:..."; // from scanner +const decrypted = await decryptSeedPgp({ + frameText: scannedText, + privateKeyArmored: userKey, + privateKeyPassphrase: userPassword, +}); +console.log(decrypted.w); // Recovered mnemonic +``` + +**Security Notes**: +- Never log decrypted mnemonics in production +- Clear sensitive data from memory after use +- Validate CRC16 before attempting decrypt +- Show key fingerprint for user verification + +--- + +### 🔮 Future Ideas (v1.3+) + +- [ ] Multi-frame support (for larger payloads) +- [ ] Password-only (SKESK) encryption flow +- [ ] Shamir Secret Sharing integration +- [ ] Hardware wallet key generation +- [ ] Mobile companion app (React Native) +- [ ] Printable paper backup templates +- [ ] Encrypted cloud backup with PBKDF2 +- [ ] BIP85 child mnemonic derivation + +## Debugging Tips + +### Enable verbose PGP logging + +Uncomment in `seedpgp.ts`: +```typescript +console.log("Raw PGP hex:", Array.from(pgpBytes).map(...)); +console.log("SeedPGP: message packets:", ...); +console.log("SeedPGP: encryption key IDs:", ...); +``` + +### Test with known vectors + +Use Trezor vectors from test file: +```bash +bun test "Trezor" # Run only Trezor tests +``` + +### Validate frame manually + +```typescript +import { frameParse } from "./lib/seedpgp"; +const parsed = frameParse("SEEDPGP1:0:ABCD:..."); +console.log(parsed); // Check structure +``` + +## Code Style + +- **Functions**: Async by default, explicit return types +- **Errors**: Throw descriptive Error objects with context +- **Naming**: `camelCase` for functions, `PascalCase` for types +- **Comments**: Only for non-obvious crypto/encoding logic +- **Testing**: One test per edge case, descriptive names + +## Git Workflow + +```bash +# Feature branch +git checkout -b feat/qr-generation + +# Conventional commits +git commit -m "feat(qr): add QR code generation" +git commit -m "test(qr): add QR round-trip test" + +# Tag releases +git tag -a v1.2.0 -m "Release v1.2.0 - QR round-trip" +git push origin main --tags +``` + +## Questions for Next Session + +When continuing development, provide: + +1. **Feature context**: "Adding QR code generation for v1.2.0" +2. **Current code**: Paste relevant files you're modifying +3. **Specific question**: "How should I structure the QR scanner component?" + +Example starter prompt: +``` +I'm working on seedpgp-web v1.1.0 (BIP39 PGP encryption tool). + +[Paste this DEVELOPMENT.md section] +[Paste relevant source files] + +I want to add QR code generation. Here's my current seedpgp.ts... +``` + +--- + +**Last Updated**: 2026-01-28 +**Maintainer**: @kccleoc +``` + +Now commit it: + +```bash +git add DEVELOPMENT.md +git commit -m "docs: add development guide with v1.2.0 QR agenda" +git push origin main +``` + +Ready for your next feature sprint! 🚀📋 diff --git a/_GPT-Suggestion.md b/_GPT-Suggestion.md deleted file mode 100644 index 4a1ceb0..0000000 --- a/_GPT-Suggestion.md +++ /dev/null @@ -1,10 +0,0 @@ -Next steps (optional): -QR code generation - Add library to generate QR codes from encrypted.framed - -UI integration - Connect to your React components - -Multi-frame support - If you need to handle larger payloads (though mnemonics fit in single frame) - -Password-only mode - Test SKESK-only encryption for backup scenarios - -Your crypto wallet backup tool has a solid foundation! 🔐✨