Repository navigation
Reduce secp256k1 supply-chain trust in backup/recovery path #3
Description
Problem
On reviewability-v1, the documented CLI install path is substantially hardened: bip32 is pinned to a specific Git commit and hash, and coincurve==21.0.0 is installed with --require-hashes. That protects users who follow the reviewed installation procedure from silently receiving a later malicious upstream release.
However, the runtime/package architecture still has a concentrated trust point:
codex32 → bip32 → coincurve → libsecp256k1
src/codex32/profiles/ms32.py imports bip32.BIP32, and _bip32_node() calls BIP32.from_seed(). The security model explicitly treats BIP32 and Coincurve as trusted cryptographic dependencies.
There are two related concerns:
- A normal package installation resolves the declared metadata ranges (
bip32>=5,<6, withbip32allowing a Coincurve range) rather than the repository's hash-pinned lockfiles. A malicious future version inside those ranges could therefore enter an environment without any change to codex32 source. - Coincurve is native code loaded into the same Python process that handles master seeds. A malicious native dependency is not limited to returning incorrect EC results; it can inspect process memory or otherwise violate the process boundary.
The hash-pinned install procedure mitigates the first concern for the prescribed CLI installation, but it does not remove the architectural trust chokepoint.
Proposed direction
Make the codex32 backup/recovery core independent of secp256k1-native dependencies, and move wallet derivation / descriptor functionality behind an explicit wallet-integration boundary.
In particular, BIP32 root validity does not require public-key point multiplication. Root validation can be implemented using stdlib primitives:
- HMAC-SHA512 with key
Bitcoin seed; - parse
ILas an integer; - reject
IL == 0orIL >= n.
That would allow creation, parsing, sharing, recovery, correction, and validation of master-seed backups without importing Coincurve at all.
Wallet-specific operations that need fingerprints, xpubs, or descriptors could continue to use a secp256k1 implementation, but only when the user explicitly invokes that functionality.
Desired security property
A user should be able to create, verify, split, recover, and correct a codex32 master-seed backup without loading third-party native cryptographic code into the secret-handling process.
The remaining secp256k1 trust boundary should be limited to wallet interoperability/derivation, where it is actually required.
Possible implementation shape
- Replace the current BIP32 dependency in master-seed validity checks with a small internal stdlib-only root validator.
- Avoid importing
bip32/coincurvefrom modules needed by backup/recovery operations. - Move BIP32/xpub/fingerprint/descriptor code into the wallet integration layer or an optional dependency path.
- Add a test asserting that core backup/recovery operations work in an environment with no
bip32orcoincurveinstalled. - Keep the existing hash-pinned installation path for wallet-enabled CLI use.
This would improve both reviewability and resistance to a maintainer/package-registry compromise without requiring codex32 to reimplement general secp256k1 arithmetic.
Activity
Remove Python wallet test dependencies
Tests: verify Core fingerprints centrally
Tests: separate wallet fingerprints from BIP93 vectors
Tests: keep wallet fingerprints seed-sensitive
BenWestgate commentedon Sep 27, 2026
Current release-gate status: the production backup/recovery path on
reviewability-v1no longer depends on Pythonbip32/Coincurve for root validity or hardened derivation; stdlib code validates/serializes the root and Bitcoin Core v32 performs the wallet-side hardened derivation/public-key work. PR #7 is the remaining test/CI cleanup that removes the Python wallet oracle and secp256k1 dependency from the documented.[dev]contributor path; #51 independently checks its frozen fingerprints against real pinned Core. #7 is not ready to close this issue today: #36 has moved its head to8338c72, which is currently non-mergeable againstreviewability-v1and has no fresh workflow run. Refresh/revalidate #7 first, then #3/#6 can close with it.docs: Define trusted computer boundary
Remove Python wallet test dependencies
Remove Python wallet test dependencies
docs: Define trusted computer boundary