docs(manual): batch 9 review — Tink template name was SHA128 (typo), should be SHA256

The iOS CryptoKit guidance paragraph said:
  'Tink's ECIES_P256_HKDF_HMAC_SHA128_GCM is not bit-compatible with
   raw CryptoKit...'

But the actual Tink template is ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM
(SHA-256, not SHA-128). Verified in
app/src/main/java/app/closer/crypto/UserKeyManager.kt:
  HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM

The iOS->Android sealed-answer bridge section above the typo already
had the correct SHA256 name. Fixed the CryptoKit guidance to match.

Other Batch 9 claims verified clean:
- CloserApp.swift @main is CloserApp, with @StateObject AppState.
- AppState is @MainActor final ObservableObject with @Published
  authState / currentUser / currentCouple / currentPartner / isPremium.
- iOS deployment target: 17.0 (iphone/project.yml).
- NavigationStack + .navigationDestination, no DI framework, .shared
  singletons (AuthService.shared, FirestoreService.shared,
  BillingService.shared) - matches.
- CloserTheme.swift color tokens: closerPrimary light=B98AF4
  /dark=CFA7FF, closerSecondary light=E7A2D1 /dark=FFAFD9,
  closerBackground light=FFFBFE /dark=18111E - matches the brand
  primary/secondary stated in MEMORY.md.
- docs/brand/visual-identity.md and docs/copy-guide.md both exist.
- XcodeGen project name = Closer (iphone/project.yml).
- Project.yml deploymentTarget iOS: 17.0.
- All PARTNER_ANSWERED / REVEAL_READY / gameRouteForType / wheelComplete
  / thisOrThatReplay / PARTNER_JOINED_GAME / PARTNER_COMPLETED_PART
  / fromRemoteType branches exist in PartnerNotificationManager.kt and
  match the manual's deep-link routing table.
This commit is contained in:
null 2026-07-08 23:29:37 -05:00
parent 29cc39aa42
commit 9330c0c452
1 changed files with 1 additions and 1 deletions

View File

@ -1094,7 +1094,7 @@ The iOS port now implements the strict-E2EE pairing path:
The iOS CryptoKit implementation follows these rules of parity with Android:
- Use CryptoKit's `AES.GCM` for symmetric encryption. AAD binding must match Android exactly.
- Use `P256.KeyAgreement` + `HKDF` + `AES.GCM` for the iOS-native Path A ECIES envelope. Tink's `ECIES_P256_HKDF_HMAC_SHA128_GCM` is not bit-compatible with raw CryptoKit, so iOS→Android sealed-answer key release goes through the server-side `wrapReleaseKeyCallable` (see [iOS → Android sealed-answer bridge](#ios-android-sealed-answer-bridge-wrapreleasekeycallable)). iOS↔iOS releases use the native Path A envelope.
- Use `P256.KeyAgreement` + `HKDF` + `AES.GCM` for the iOS-native Path A ECIES envelope. Tink's `ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM` is not bit-compatible with raw CryptoKit, so iOS→Android sealed-answer key release goes through the server-side `wrapReleaseKeyCallable` (see [iOS → Android sealed-answer bridge](#ios-android-sealed-answer-bridge-wrapreleasekeycallable)). iOS↔iOS releases use the native Path A envelope.
- Use `SecItemAdd` / `SecItemCopyMatching` for keychain storage. Store the couple key as a generic password item with `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly` and `kSecAttrSynchronizable=false` so it is device-bound and not included in iCloud backup.
- For Argon2id, use `swift-sodium` (libsodium) rather than an unaudited pure-Swift implementation. Verify byte output against the Android BouncyCastle reference before shipping.