# SHINOBU — Cryptographic Specification
### Version 1.0 — July 2026

---

## 1. Algorithms

| Component | Specification |
|-----------|---------------|
| Symmetric cipher | AES-256-GCM |
| Key derivation | PBKDF2-SHA256 |
| Key length | 256 bits (derived from 128-bit input) |
| Salt | 16 bytes, random per message |
| IV / nonce | 12 bytes, random per message |
| Random generation | crypto.getRandomValues() (CSPRNG) |
| Transport | TLS 1.3 (HTTPS) |

---

## 2. Key Generation

- 128-bit encryption key generated via `crypto.getRandomValues(new Uint8Array(16))`
- Encoded as URL-safe base64 for storage and sharing
- Key space: 2^128 ≈ 3.4 × 10^38 possible keys
- Brute-force at 1 billion keys/second: ~10^22 years

---

## 3. Key Derivation

- Algorithm: PBKDF2-SHA256
- Iterations: 100,000
- Salt: 16 bytes, randomly generated per encryption operation
- Input: 128-bit user key string (UTF-8 encoded)
- Output: 256-bit AES key

---

## 4. Encryption Flow — Text Messages

1. User types plaintext message
2. Random 16-byte salt generated
3. Random 12-byte IV generated
4. Key derived via PBKDF2-SHA256 (100k iterations)
5. Plaintext encrypted with AES-256-GCM
6. Ciphertext, IV, and salt base64-encoded
7. Encrypted object stored in database
8. Server never sees plaintext or encryption key

---

## 5. Encryption Flow — File Attachments

1. User selects file
2. Image files compressed (max 1200px, JPEG 80%)
3. File converted to base64
4. Base64 decoded to raw bytes (ArrayBuffer)
5. Random salt and IV generated
6. Raw bytes encrypted with AES-256-GCM via PBKDF2-derived key
7. Encrypted object `{ciphertext, iv, salt}` stored in database
8. On receive: decrypted with same key, converted back to base64 for display

---

## 6. Key Separation Model

| Component | Stored Where | Encrypted | Purpose |
|-----------|-------------|-----------|---------|
| Room code | Server (RTDB/Firestore) | No | Public identifier |
| Encryption key | Client only (localStorage + URL fragment) | N/A | Secret — never sent to server |
| Message content | Server (RTDB/Firestore) | Yes (AES-256-GCM) | E2E encrypted |
| File attachments | Server (RTDB/Firestore) | Yes (AES-256-GCM) | E2E encrypted |

---

## 7. Room Code Entropy

- Auto-generated room codes: 12 characters from 55-character alphabet
- Entropy: 12 × log2(55) ≈ 71 bits
- Auto-generated mailbox codes: 16 characters
- Entropy: 16 × log2(55) ≈ 94 bits
- User-chosen codes: minimum 8 characters

---

## 8. Safety Numbers

- Derived from shared encryption key via PBKDF2 (1,000 iterations, SHA-256)
- 6-emoji visual hash from 30-emoji alphabet
- Purpose: Verify both parties share the same key (man-in-the-middle detection)
- Verification method: out-of-band (voice call, in-person)

---

## 9. Metadata Mitigation

- All timestamps rounded to nearest minute (60,000ms precision)
- Prevents precise timing analysis of communication patterns
- Presence status stored without exact timestamps
- Read receipts use rounded timestamps

---

## 10. Threat Coverage

| Threat | Protection |
|--------|-----------|
| Server compromise | E2E encryption — server sees only ciphertext |
| Network tapping | TLS 1.3 + AES-256-GCM |
| Screen capture | getDisplayMedia() hook — notifies other participant |
| Wrong key access | Key validation (3 attempts) before granting access |
| Panic situations | Ctrl+Shift+X — destroys all local data |
| Metadata analysis | Timestamps rounded to nearest minute |
| File tampering | AES-GCM authenticated encryption detects modifications |
