Files
mobile-ios/docs/crypto-spec.md

88 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Rosetta Encryption Specification
All encryption must be **cross-platform compatible** with the Android and Desktop versions.
## Message Encryption: XChaCha20-Poly1305
```
Encrypt:
1. Generate random 32-byte key + 24-byte nonce
2. HChaCha20(key, nonce[0:16]) → 32-byte subkey
3. ChaCha20 nonce = [0,0,0,0] + nonce[16:24]
4. Generate Poly1305 key from first 64 bytes of keystream
5. ChaCha20 encrypt plaintext (counter starts at 1)
6. Compute Poly1305 tag over ciphertext (padded to 16-byte boundaries)
7. Output: ciphertext + 16-byte tag (hex encoded)
Decrypt:
1. Extract 16-byte tag from end of ciphertext
2. Verify Poly1305 tag (reject if invalid)
3. Decrypt with ChaCha20
```
## Key Exchange: ECDH (secp256k1)
```
Encrypt key for recipient:
1. Generate random ephemeral private key (32 bytes)
2. Compute ephemeral public key = G × ephemeralPrivateKey (secp256k1)
3. Compute shared secret = recipientPublicKey × ephemeralPrivateKey
4. Use x-coordinate (32 bytes) as AES key
5. Generate random IV (16 bytes)
6. AES-256-CBC encrypt (key + nonce) with shared secret
7. Output: Base64(IV : ciphertext : ephemeralPrivateKey)
Decrypt key:
1. Parse ephemeralPrivateKey from Base64
2. Compute ephemeralPublicKey = G × ephemeralPrivateKey
3. Compute shared secret = ephemeralPublicKey × myPrivateKey
4. AES-256-CBC decrypt with shared secret + IV
5. Extract 32-byte key + 24-byte nonce
```
## Key Generation (from Seed Phrase)
```
1. BIP39 mnemonicToSeed(phrase, "") → PBKDF2-SHA512, 2048 iterations, salt="mnemonic" → 64 bytes
2. Convert bytes to hex string (128 characters)
3. SHA256(hexSeed) → 32-byte private key
4. secp256k1: publicKey = G × privateKey (compressed, 33 bytes)
```
## Password-Based Encryption (Account Storage)
```
1. zlib deflate compress the data
2. PBKDF2-HMAC-SHA256: password, salt="rosetta", 1000 iterations → 32-byte key
3. Generate random IV (16 bytes)
4. AES-256-CBC encrypt compressed data
5. Output: Base64(IV) : Base64(ciphertext)
6. For data > 10MB: split into 10MB chunks, prefix with "CHNK:"
```
## Attachment Encryption
```
1. Compress with zlib deflate
2. Convert plainKeyAndNonce bytes to UTF-8 string (JS Buffer compatibility)
3. PBKDF2-HMAC-SHA256: keyAndNonce string, salt="rosetta", 1000 iterations
4. Generate random IV (16 bytes)
5. AES-256-CBC encrypt
6. Output: Base64(IV) : Base64(ciphertext)
```
## Biometric Auth (iOS Keychain)
```
- Store password in iOS Keychain with biometric access control
- Use kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
- SecAccessControlCreateFlags: .biometryCurrentSet
- Encrypt with Secure Enclave where available
```
## iOS Crypto Libraries
- **CryptoKit** — for SHA256, HMAC, AES-GCM
- **Security.framework** — for Keychain, SecKey, Secure Enclave
- **secp256k1.swift** (via SPM) or **libsecp256k1** — for elliptic curve operations
- **Custom XChaCha20-Poly1305** — implement or use a Swift wrapper around libsodium