Skip to content

tech-debt(android): replace react-native-fast-crypto with react-native-quick-crypto scrypt#30716

Draft
tommasini wants to merge 3 commits into
mainfrom
chore/remove-rn-fast-crypto
Draft

tech-debt(android): replace react-native-fast-crypto with react-native-quick-crypto scrypt#30716
tommasini wants to merge 3 commits into
mainfrom
chore/remove-rn-fast-crypto

Conversation

@tommasini

Copy link
Copy Markdown
Contributor

Description

react-native-fast-crypto@2.2.0 ships prebuilt libsecp256k1.so and libcrypto_bridge.so binaries aligned to 4 KB pages. This violates Android 15+'s 16 KB page-size requirement and causes Google Play warnings for every ABI.

We only use scrypt from this package — a single call site in user-storage-controller-init.ts. react-native-quick-crypto (which we already depend on) ships a native scrypt implementation since version 1.x via OpenSSL/Nitro Modules.

What changed:

  • Removed react-native-fast-crypto and its 3 yarn patches
  • Bumped react-native-quick-crypto from patched 0.7.151.1.5 (already ships -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON in its build.gradle)
  • Bumped react-native-quick-base64 from patched 2.2.03.0.0 (required peer dep of quick-crypto@1.x)
  • Bumped @craftzdog/react-native-buffer from ^6.1.0^6.1.2 — eliminates the nested quick-base64@2.x that was previously installed
  • Added a scrypt adapter at the single call site with maxmem: 256 MiB (profile-sync uses N=2^17, r=8 which requires ~134 MiB)
  • Restored x86_64 to reactNativeArchitectures — with libsecp256k1.so and libconceal.so (keychain v10) both gone, all four ABIs are now 16 KB-compliant
  • Added 6 unit tests: 3 RFC 7914 §12 known-vector tests + 3 parameter-passing tests

Changelog

CHANGELOG entry: Removed react-native-fast-crypto in favor of react-native-quick-crypto scrypt; reduces Android AAB size and improves Android 16 KB page-size compliance.

Related issues

Fixes: #30591

Manual testing steps

Feature: Profile sync key derivation

  Scenario: user syncs profile after the dependency swap
    Given the app is installed on an Android device
    And the user has an existing MetaMask account with profile sync enabled

    When the user opens the app
    Then profile sync initializes without errors
    And the user's synced data (contacts, settings) loads as expected

  Scenario: production AAB contains no 4 KB-aligned .so files
    Given a production AAB has been built with this branch
    When running: unzip -l app-prod-release.aab | grep -E 'libsecp256k1|libcrypto_bridge'
    Then no matching entries are returned for any ABI

Screenshots/Recordings

Before

N/A

After

N/A

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Made with Cursor

tommasini and others added 2 commits May 27, 2026 23:50
- CHANGELOG entry for fast-crypto removal
- Restore x86_64 in reactNativeArchitectures now that libsecp256k1.so and
  libconceal.so are no longer present in the AAB

Co-authored-by: Cursor <cursoragent@cursor.com>
@tommasini tommasini self-assigned this May 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@github-project-automation github-project-automation Bot moved this to Needs dev review in PR review queue May 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeIdentity, SmokeAccounts, SmokeWalletPlatform, SmokeSeedlessOnboarding, SmokeConfirmations, SmokeNetworkExpansion, SmokeSnaps, SmokeBrowser, SmokeMultiChainAPI, SmokeNetworkAbstractions, SmokeSwap, SmokeStake, SmokeMoney
  • Selected Performance tags: @PerformanceLogin, @PerformanceOnboarding
  • Risk Level: high
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
This PR replaces react-native-fast-crypto with react-native-quick-crypto (major version bump: 0.7.15 → 1.1.5) and upgrades react-native-quick-base64 (2.2.0 → 3.0.0). These are native crypto libraries used across critical wallet paths:

  1. SmokeIdentity: The scrypt function in user-storage-controller-init.ts is directly changed — it now uses react-native-quick-crypto for profile sync/user storage encryption. This is the primary change and must be validated.

  2. SmokeAccounts + SmokeWalletPlatform: Multi-SRP architecture and account management rely on the Encryptor which uses react-native-quick-crypto for PBKDF2 key derivation and AES encryption/decryption. Any regression here would break account access.

  3. SmokeSeedlessOnboarding: OAuthService/OAuthLoginHandlers directly imports react-native-quick-crypto for OAuth PKCE flows. A major version change could break social login.

  4. SmokeConfirmations: The Encryptor (using quick-crypto) is critical for wallet unlock and transaction signing. Confirmations require a working wallet.

  5. SmokeNetworkExpansion: Solana signing flows hit confirmations which require working crypto.

  6. SmokeSnaps: Snaps use crypto operations (BIP-32/BIP-44 key derivation, signing).

  7. SmokeBrowser: Browser/dApp connections require working wallet state.

  8. SmokeMultiChainAPI + SmokeNetworkAbstractions: Session management and chain permissions require working wallet.

  9. SmokeSwap + SmokeStake + SmokeMoney: These flows require transaction confirmations and wallet encryption to work.

The major version bump on react-native-quick-crypto (0.7.15 → 1.1.5) is particularly risky because:

  • The new version requires react-native-nitro-modules as a peer dependency (new architecture dependency)
  • The API may have subtle behavioral differences in crypto operations
  • The react-native-quick-base64 major bump (2.2.0 → 3.0.0) affects buffer operations used throughout the crypto stack
  • These are native modules that require correct linking in both iOS (Podfile.lock changed) and Android

Performance Test Selection:
The crypto library upgrade (react-native-quick-crypto 0.7.15 → 1.1.5) directly affects wallet unlock (PBKDF2 key derivation in Encryptor) and onboarding (scrypt for profile sync, OAuth PKCE). The new version uses react-native-nitro-modules which has different performance characteristics than the old patched version. Login performance could be impacted by changes in PBKDF2 derivation speed, and onboarding performance could be affected by the scrypt implementation change (now with 256 MiB maxmem). These are the two most directly impacted performance scenarios.

View GitHub Actions results

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​@​craftzdog/​react-native-buffer@​6.1.0 ⏵ 6.1.29910010087 +3100
Updatednpm/​react-native-quick-base64@​2.2.0 ⏵ 3.0.010010098 -288 +2100
Updatednpm/​react-native-quick-crypto@​0.7.15 ⏵ 1.1.598100100 +198 +1100

View full report

@socket-security

Copy link
Copy Markdown

Warning

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Warn Low
Potential code anomaly (AI signal): npm readable-stream is 100.0% likely to have a medium risk anomaly

Notes: No malicious behavior detected. This is a standard, legitimate stream utility implementing pipe semantics with a backward-compatibility shim. The only notable concern is the internal _events manipulation in the prependListener polyfill, which should be revisited for future-proofing, but it does not constitute an immediate security risk.

Confidence: 1.00

Severity: 0.60

From: ?npm/react-native-quick-crypto@1.1.5npm/readable-stream@4.7.0

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/readable-stream@4.7.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Needs dev review

Development

Successfully merging this pull request may close these issues.

tech-debt(android): replace react-native-fast-crypto with quick-crypto scrypt to drop libsecp256k1.so

1 participant