Update project version to 5 and add Release configuration for build lanes; introduce encryption specification and color palette documentation
This commit is contained in:
@@ -264,7 +264,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 6;
|
||||
CURRENT_PROJECT_VERSION = 5;
|
||||
DEVELOPMENT_TEAM = QN8Z263QGX;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -302,7 +302,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 6;
|
||||
CURRENT_PROJECT_VERSION = 5;
|
||||
DEVELOPMENT_TEAM = QN8Z263QGX;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
|
||||
93
docs/color-palette.md
Normal file
93
docs/color-palette.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Rosetta Color Palette
|
||||
|
||||
## Brand Colors
|
||||
| Name | Hex | Usage |
|
||||
|------|-----|-------|
|
||||
| Primary Blue | `#248AE6` | Main accent, buttons, links |
|
||||
| Primary Blue Dark | `#238BE6` | Dark theme primary |
|
||||
| Primary Blue Pressed | `#2B7CD3` | Button pressed state |
|
||||
| Primary Blue Disabled | `#9BCDFF` | Disabled state |
|
||||
|
||||
## Light Theme (not implemented yet)
|
||||
| Token | Hex | Usage |
|
||||
|-------|-----|-------|
|
||||
| background | `#FFFFFF` | Main background |
|
||||
| backgroundSecondary | `#F2F3F5` | Grouped sections |
|
||||
| surface | `#F5F5F5` | Cards, inputs |
|
||||
| text | `#000000` | Primary text |
|
||||
| textSecondary | `#666666` | Subtitle, caption |
|
||||
| textTertiary | `#999999` | Placeholder, hint |
|
||||
| border | `#E0E0E0` | Borders |
|
||||
| divider | `#EEEEEE` | List separators |
|
||||
| messageBubble | `#F5F5F5` | Incoming message |
|
||||
| messageBubbleOwn | `#DCF8C6` | Own message (green) |
|
||||
| inputBackground | `#F2F3F5` | Text input bg |
|
||||
|
||||
## Dark Theme (active)
|
||||
| Token | Hex | Usage |
|
||||
|-------|-----|-------|
|
||||
| background | `#000000` | Main background (Color.black) |
|
||||
| backgroundSecondary | `#2A2A2A` | Grouped sections |
|
||||
| surface | `#242424` | Cards, inputs |
|
||||
| text | `#FFFFFF` | Primary text |
|
||||
| textSecondary | `#8E8E93` | Subtitle, caption |
|
||||
| textTertiary | `#666666` | Placeholder, hint |
|
||||
| border | `#2E2E2E` | Borders |
|
||||
| divider | `#333333` | List separators |
|
||||
| messageBubble | `#2A2A2A` | Incoming message |
|
||||
| messageBubbleOwn | `#263341` | Own message (dark blue) |
|
||||
| inputBackground | `#2A2A2A` | Text input bg |
|
||||
|
||||
## Semantic Colors
|
||||
| Token | Hex | Usage |
|
||||
|-------|-----|-------|
|
||||
| error | `#FF3B30` | Errors, destructive |
|
||||
| success | `#34C759` | Success, online |
|
||||
| warning | `#FF9500` | Warnings |
|
||||
| accent | `#E91E63` | Secondary accent (pink) |
|
||||
| online | `#34C759` | Online indicator |
|
||||
|
||||
## Avatar Colors (hash-based, 11 variants — Mantine v8 "light" variant)
|
||||
|
||||
Rendering: dark mode = opaque `#1A1B1E` base + shade-6 at 15% opacity + shade-3 text.
|
||||
Light mode = white base + shade-6 at 10% opacity + shade-6 text.
|
||||
|
||||
| Index | Shade-6 (tint) | Shade-3 (text dark) | Name |
|
||||
|-------|---------------|---------------------|------|
|
||||
| 0 | `#228be6` | `#74c0fc` | Blue |
|
||||
| 1 | `#15aabf` | `#66d9e8` | Cyan |
|
||||
| 2 | `#be4bdb` | `#e599f7` | Grape |
|
||||
| 3 | `#40c057` | `#8ce99a` | Green |
|
||||
| 4 | `#4c6ef5` | `#91a7ff` | Indigo |
|
||||
| 5 | `#82c91e` | `#c0eb75` | Lime |
|
||||
| 6 | `#fd7e14` | `#ffc078` | Orange |
|
||||
| 7 | `#e64980` | `#faa2c1` | Pink |
|
||||
| 8 | `#fa5252` | `#ffa8a8` | Red |
|
||||
| 9 | `#12b886` | `#63e6be` | Teal |
|
||||
| 10 | `#7950f2` | `#b197fc` | Violet |
|
||||
|
||||
Hash input = display name (NOT public key). Fallback when name empty = `publicKey.prefix(7)` (server sends first 7 chars as default title). Index = `abs(hashCode(input)) % 11`. Hash algorithm: `hash = (hash << 5) - hash + charCode` (same as Java's String.hashCode, 32-bit signed).
|
||||
|
||||
## Background Blur Solid Presets
|
||||
| Name | Hex |
|
||||
|------|-----|
|
||||
| solid_blue | `#0D8CF4` |
|
||||
| solid_green | `#4CAF50` |
|
||||
| solid_orange | `#FF9800` |
|
||||
| solid_red | `#E53935` |
|
||||
| solid_purple | `#7C4DFF` |
|
||||
| solid_teal | `#009688` |
|
||||
| solid_pink | `#E91E63` |
|
||||
| solid_grey | `#78909C` |
|
||||
|
||||
## Background Blur Gradient Presets
|
||||
| Name | Start | End |
|
||||
|------|-------|-----|
|
||||
| grad_blue_cyan | `#2979FF` | `#00BCD4` |
|
||||
| grad_green_lime | `#4CAF50` | `#CDDC39` |
|
||||
| grad_orange_yellow | `#FF9800` | `#FFEB3B` |
|
||||
| grad_red_pink | `#E53935` | `#FF4081` |
|
||||
| grad_purple_blue | `#7C4DFF` | `#536DFE` |
|
||||
| grad_teal_green | `#009688` | `#69F0AE` |
|
||||
| grad_pink_magenta | `#E91E63` | `#CE93D8` |
|
||||
| grad_mono | `#546E7A` | `#B0BEC5` |
|
||||
87
docs/crypto-spec.md
Normal file
87
docs/crypto-spec.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# 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
|
||||
@@ -30,6 +30,7 @@ platform :ios do
|
||||
build_app(
|
||||
project: "Rosetta.xcodeproj",
|
||||
scheme: "Rosetta",
|
||||
configuration: "Release",
|
||||
export_method: "app-store",
|
||||
clean: true
|
||||
)
|
||||
@@ -56,6 +57,7 @@ platform :ios do
|
||||
build_app(
|
||||
project: "Rosetta.xcodeproj",
|
||||
scheme: "Rosetta",
|
||||
configuration: "Release",
|
||||
export_method: "app-store",
|
||||
clean: true
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user