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, with bip32 allowing 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
IL as an integer;
- reject
IL == 0 or IL >= 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/coincurve from 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
bip32 or coincurve installed.
- 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.
Problem
On
reviewability-v1, the documented CLI install path is substantially hardened:bip32is pinned to a specific Git commit and hash, andcoincurve==21.0.0is 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→ libsecp256k1src/codex32/profiles/ms32.pyimportsbip32.BIP32, and_bip32_node()callsBIP32.from_seed(). The security model explicitly treats BIP32 and Coincurve as trusted cryptographic dependencies.There are two related concerns:
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.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:
Bitcoin seed;ILas an integer;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
bip32/coincurvefrom modules needed by backup/recovery operations.bip32orcoincurveinstalled.This would improve both reviewability and resistance to a maintainer/package-registry compromise without requiring codex32 to reimplement general secp256k1 arithmetic.