docs(manual): batch 3 review — Argon2id memory was 46080 KiB but the code is 47104
The Argon2id parameter block said:
- memory: 46 MiB (46080 KiB)
- iterations: 3
- parallelism: 1
But the source constant in RecoveryKeyManager.kt is:
private const val ARGON2_MEMORY_KB = 46 * 1024
46 * 1024 = 47104, not 46080 (a slipped digit). 46080 KiB would be
45 MiB. The iOS-side docstring in CoupleEncryptionManager.swift
already says 46 MiB = 47104 KiB, so this is the Android-side drift.
Replaced the parameter block with the source-of-truth constant names
(ARGON2_MEMORY_KB, ARGON2_ITERATIONS, ARGON2_PARALLELISM) and the
correct KiB value (47104) so the next reader can grep the code.
Other Batch 3 claims verified clean:
- Encryption version table: EncryptionVersion.STRICT=2, acceptInviteCallable
hardcodes 2, throws if any of wrappedCoupleKey/kdfSalt/kdfParams is null.
- Tink AEAD wire formats: enc:v1:base64, sealed:v1:urlsafe-base64-no-padding,
keybox:v1:urlsafe-base64-no-padding, pub:v1:urlsafe-base64-no-padding,
sha256:urlsafe-base64-no-padding (43 chars). All match the source constants.
- AAD: FieldEncryptor uses coupleId; SealedAnswerEncryptor uses
coupleId|questionId|userId; both match.
- ECIES P-256: UserKeyManager uses
HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM;
ReleaseKeyEncryptor contextInfo is coupleId|questionId|senderUserId|recipientUserId.
- All 5 firestore.rules regex helpers match the manual's reference table.
- wrapReleaseKeyCallable reads the recipient public key from
users/{uid}/devices/primary (verified in function source).
- CoupleKeyStore persists Tink keyset handles in EncryptedSharedPreferences
(Keystore-backed) via SecurePreferencesFactory.
This commit is contained in:
parent
1b36eba692
commit
0af6f24ab8
|
|
@ -396,9 +396,9 @@ The couple keyset is a Tink AES-256-GCM keyset generated once per couple.
|
||||||
|
|
||||||
- `RecoveryKeyManager.newCoupleKeyset()` creates the keyset.
|
- `RecoveryKeyManager.newCoupleKeyset()` creates the keyset.
|
||||||
- `RecoveryKeyManager.wrap(keyset, phrase)` derives a 32-byte key with Argon2id:
|
- `RecoveryKeyManager.wrap(keyset, phrase)` derives a 32-byte key with Argon2id:
|
||||||
- **memory**: 46 MiB (`46080` KiB)
|
- **memory**: 46 MiB (`46 * 1024 = 47104` KiB; constant `ARGON2_MEMORY_KB`)
|
||||||
- **iterations**: 3
|
- **iterations**: 3 (`ARGON2_ITERATIONS`)
|
||||||
- **parallelism**: 1
|
- **parallelism**: 1 (`ARGON2_PARALLELISM`)
|
||||||
- **salt**: 16 random bytes
|
- **salt**: 16 random bytes
|
||||||
- The keyset plaintext is encrypted with AES-256-GCM using the derived key. AAD is the fixed string `"closer_couple_key"` so the blob is portable across invite-code reconciliation.
|
- The keyset plaintext is encrypted with AES-256-GCM using the derived key. AAD is the fixed string `"closer_couple_key"` so the blob is portable across invite-code reconciliation.
|
||||||
- The wrapped result is stored on the couple document as `wrappedCoupleKey`, `kdfSalt`, `kdfParams`.
|
- The wrapped result is stored on the couple document as `wrappedCoupleKey`, `kdfSalt`, `kdfParams`.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue