Add Gem Keystore - #467
Merged
Merged
Conversation
0xh3rman
force-pushed
the
gem-keystore
branch
3 times, most recently
from
June 8, 2026 12:20
b66a163 to
7c37d35
Compare
0xh3rman
marked this pull request as ready for review
June 8, 2026 13:23
gemcoder21
reviewed
Jun 9, 2026
| do { | ||
| _ = try await keystore.migrateV3Keystore(for: wallet) | ||
| } catch { | ||
| os_log( |
- v4 encrypted keystore: Argon2id KDF + AES-256-GCM (RustCrypto aes-gcm), deterministic UUIDv5 id, atomic writes, process-global serialization - keystore-internal signing, message signing, and device auth (gem_auth Ed25519); the decrypted private key never crosses the FFI boundary - address derivation from the public key; recovery-phrase entropy via getrandom - v3 (WalletCore) migration reader; remove Wallet Core from core signing, address validation, and fee estimation - crypto deps on the RustCrypto new generation (aes 0.9 / aes-gcm 0.11 / scrypt 0.12 / ctr 0.10 / getrandom 0.4 / ripemd 0.2)
- high-level keystore operators via withGemKeystore; transaction signing, message signing, and device auth run in Rust - v3 to v4 migration leaves the v3 file in place (downgrade-safe), keyed on v4 presence; wallet deletion removes every on-disk copy - remove the Trust Wallet Core dependency
- LocalKeystore sign / signMessage / signAuthMessageHash via the Rust keystore; the old getPrivateKey / ChainSigner / SwapSigner paths are removed - v3 to v4 migration leaves the v3 file in place (downgrade-safe), keyed on v4 presence; wallet deletion removes every on-disk copy - remove the WalletCore SPM package
…at, testdata vectors - Reject empty keystore passwords at the platform choke points (iOS withV4Password, Android withGemKeystore) instead of failing deep in Rust - Replace release-build os_log of migration failures with debugLog - Rewrite Android String.words() without regex (Unicode whitespace, matches Rust split_whitespace) and cover it with a unit test - Move gem_derivation mnemonic test vectors to testdata JSON per repo pattern - Remove gemk header created_at (and the timestamp plumbing), update docs, README, and dump script; corrupt a KDF salt byte in the tamper test instead - Hoist ".gemk" into FILE_EXTENSION const - Inline phrase-discarding import_mnemonic_wallet into preview_import - Drop unused legacyAndroidV3PasswordBytes and redundant v3_migrated test assertions; remove behavior-restating comments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Design
Replace Wallet Core's keystore with a Rust-owned Gem keystore: the wallet private key stays inside Rust. Signing, message-signing, and device auth all run in core — the apps only call high-level keystore operations, and no raw key crosses the FFI/JNI boundary.
3 commits, one per platform — please review commit-by-commit (the combined diff is large).
corelands first since the apps build on its regenerated UniFFI bindings (bindings are gitignored, so the app commits aren't independently buildable without a stone regen).1.
core— gem keystore (Rust-owned v4)gem_authEd25519) — the decrypted private key never crosses the FFI boundary; raw-key signers dropped from the UniFFI surface.getrandom(direct OS CSPRNG).aes-gcm 0.11-rc/aes 0.9/scrypt 0.12/getrandom 0.4/ripemd 0.2).2.
android— migrate to gem keystorewithGemKeystore(decode + zeroize password); transaction signing, message signing, and device auth run in Rust; raw-keySignClient/SignServiceremoved.3.
ios— migrate to gem keystoreLocalKeystore.sign/signMessage/signAuthMessageHashvia the Rust keystore; oldgetPrivateKey/ChainSigner/SwapSignerpaths removed.