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

2.9 KiB
Raw Blame History

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