Crypto-View

bitcoinjs/bitcoinjs-lib

Cryptographic posture

167 cryptographic locations: 145 quantum-vulnerable, 12 reduced-margin, 5 undetermined, 5 quantum-safe

1 imported cryptographic library is listed separately. 188 files analysed.

Quantum-vulnerable 145 Reduced margin 12 Could not be determined 5 Quantum-safe 5
To address99
Key establishment0
Inventory only1
Total findings168
What was analysed
Branch master
Commit ab9fad5978bc1f4fb6542d1cde903d4427c3344e Merge pull request #2313 from jasonandjay/fix/changelog-v7
Committed 2026-02-17 01:08 UTC
Scanned 2026-09-21 10:59 UTC 9 hours ago
Coverage 188 files, 147 javascript

List of cryptographic assets

secp256k1256-bitsecg/secp256k1 Quantum-vulnerable Renamed import 98 places See details

Cryptocurrency key derivation

A BIP-32 derivation or a secp256k1 operation. Wallet keys are secp256k1, and on a public ledger the public key is usually already visible, so an attacker with a quantum computer does not have to wait to observe a signature.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer. Bitcoin-family keys are additionally exposed because public keys are published on-chain, so the attacker does not have to wait for a signature.

What to do. No standardised replacement exists for consensus-level signatures. Follow the protocol's own migration plan; an application cannot make this change alone.

  1. src/cjs/ecc_lib.cjs:124 const r = ecc.xOnlyPointAddTweak(h(t.pubkey), h(t.tweak));
  2. src/cjs/psbt.cjs:1077 if (tools.compare(root.derivePath(d.path).publicKey, d.pubkey))
  3. src/cjs/psbt.cjs:1586 const node = hdKeyPair.derivePath(bipDv.path);
  4. src/esm/ecc_lib.js:76 const r = ecc.xOnlyPointAddTweak(h(t.pubkey), h(t.tweak));
  5. src/esm/psbt.js:1012 if (tools.compare(root.derivePath(d.path).publicKey, d.pubkey))
  6. src/esm/psbt.js:1508 const node = hdKeyPair.derivePath(bipDv.path);
  7. test/integration/addresses.spec.ts:20 test path const keyPair = ECPair.makeRandom({ rng });
  8. test/integration/addresses.spec.ts:39 test path const keyPair = ECPair.fromWIF(
  9. test/integration/addresses.spec.ts:61 test path const keyPair = ECPair.fromWIF(
  10. test/integration/addresses.spec.ts:70 test path const keyPair = ECPair.fromWIF(
  11. test/integration/addresses.spec.ts:113 test path const keyPair = ECPair.makeRandom({ network: TESTNET, rng });
  12. test/integration/addresses.spec.ts:140 test path const keyPair = ECPair.makeRandom({ network: LITECOIN, rng });
  13. test/integration/bip32.spec.ts:18 test path const node = bip32.fromBase58(xpriv, bitcoin.networks.testnet);
  14. test/integration/bip32.spec.ts:29 test path const seed = bip39.mnemonicToSeedSync(mnemonic);
  15. test/integration/bip32.spec.ts:30 test path const node = bip32.fromSeed(seed);
  16. test/integration/bip32.spec.ts:32 test path const restored = bip32.fromBase58(strng);
  17. test/integration/bip32.spec.ts:41 test path const seed = bip39.mnemonicToSeedSync(mnemonic);
  18. test/integration/bip32.spec.ts:42 test path const node = bip32.fromSeed(seed);
  19. test/integration/bip32.spec.ts:53 test path const root = bip32.fromSeed(
  20. test/integration/bip32.spec.ts:60 test path const child1 = root.derivePath(path);
  21. test/integration/bip32.spec.ts:76 test path const root = bip32.fromSeed(
  22. test/integration/bip32.spec.ts:83 test path const child1 = root.derivePath("m/44'/0'/0'/0/0");
  23. test/integration/bip32.spec.ts:106 test path const seed = bip39.mnemonicToSeedSync(mnemonic);
  24. test/integration/bip32.spec.ts:107 test path const root = bip32.fromSeed(seed);
  25. test/integration/bip32.spec.ts:110 test path const child = root.derivePath(path);
  26. test/integration/bip32.spec.ts:128 test path const seed = bip39.mnemonicToSeedSync(mnemonic);
  27. test/integration/bip32.spec.ts:129 test path const root = bip32.fromSeed(seed);
  28. test/integration/bip32.spec.ts:133 test path getAddress(root.derivePath("m/0'/0/0")),
  29. test/integration/bip32.spec.ts:137 test path getAddress(root.derivePath("m/0'/0/1")),
  30. test/integration/bip32.spec.ts:143 test path getAddress(root.derivePath("m/0'/1/0")),
  31. test/integration/bip32.spec.ts:147 test path getAddress(root.derivePath("m/0'/1/1")),
  32. test/integration/cltv.spec.ts:22 test path const alice = ECPair.fromWIF(
  33. test/integration/cltv.spec.ts:26 test path const bob = ECPair.fromWIF(
  34. test/integration/csv.spec.ts:24 test path const alice = ECPair.fromWIF(
  35. test/integration/csv.spec.ts:28 test path const bob = ECPair.fromWIF(
  36. test/integration/csv.spec.ts:32 test path const charles = ECPair.fromWIF(
  37. test/integration/csv.spec.ts:36 test path const dave = ECPair.fromWIF(
  38. test/integration/payments.spec.ts:37 test path ECPair.makeRandom({ network: NETWORK, rng }),
  39. test/integration/payments.spec.ts:38 test path ECPair.makeRandom({ network: NETWORK, rng }),
  40. test/integration/taproot.spec.ts:45 test path const seed = await bip39.mnemonicToSeed(mnemonic);
  41. test/integration/taproot.spec.ts:46 test path const rootKey = bip32.fromSeed(seed);
  42. test/integration/taproot.spec.ts:48 test path const childNode = rootKey.derivePath(path);
  43. test/integration/taproot.spec.ts:103 test path const internalKey = bip32.fromSeed(rng(64), regtest);
  44. test/integration/taproot.spec.ts:104 test path const p2pkhKey = bip32.fromSeed(rng(64), regtest);
  45. test/integration/taproot.spec.ts:143 test path const sendInternalKey = bip32.fromSeed(rng(64), regtest);
  46. test/integration/taproot.spec.ts:178 test path const internalKey = bip32.fromSeed(rng(64), regtest);
  47. test/integration/taproot.spec.ts:179 test path const leafKey = bip32.fromSeed(rng(64), regtest);
  48. test/integration/taproot.spec.ts:240 test path const internalKey = bip32.fromSeed(rng(64), regtest);
  49. test/integration/taproot.spec.ts:241 test path const leafKey = bip32.fromSeed(rng(64), regtest);
  50. test/integration/taproot.spec.ts:331 test path const sendInternalKey = bip32.fromSeed(rng(64), regtest);
  51. test/integration/taproot.spec.ts:362 test path const internalKey = bip32.fromSeed(rng(64), regtest);
  52. test/integration/taproot.spec.ts:363 test path const leafKey = bip32.fromSeed(rng(64), regtest);
  53. test/integration/taproot.spec.ts:425 test path const sendInternalKey = bip32.fromSeed(rng(64), regtest);
  54. test/integration/taproot.spec.ts:469 test path const internalKey = bip32.fromSeed(rng(64), regtest);
  55. test/integration/taproot.spec.ts:474 test path const leafKey = bip32.fromSeed(rng(64), regtest);
  56. test/integration/taproot.spec.ts:563 test path const leafKey = bip32.fromSeed(rng(64), regtest);
  57. test/integration/taproot.spec.ts:644 test path const internalKey = bip32.fromSeed(rng(64), regtest);
  58. test/integration/transactions.spec.ts:21 test path ): boolean => ECPair.fromPublicKey(pubkey).verify(msghash, signature);
  59. test/integration/transactions.spec.ts:27 test path const alice = ECPair.fromWIF(
  60. test/integration/transactions.spec.ts:460 test path keys.push(ECPair.makeRandom({ network: regtest, rng }));
  61. test/integration/transactions.spec.ts:608 test path const myKey = ECPair.makeRandom({ network: regtest, rng });
  62. test/integration/transactions.spec.ts:611 test path ECPair.fromPrivateKey(myKey.privateKey!, { network: regtest }),
  63. test/integration/transactions.spec.ts:635 test path const hdRoot = bip32.fromSeed(rng(64));
  64. test/integration/transactions.spec.ts:638 test path const childNode = hdRoot.derivePath(path);
  65. test/integration/transactions.spec.ts:712 test path keys.push(ECPair.makeRandom({ network, rng }));
  66. test/integration/transactions.spec.ts:716 test path if (!myKeys) keys.push(ECPair.makeRandom({ network, rng }));
  67. test/psbt.spec.ts:35 test path ): boolean => ECPair.fromPublicKey(pubkey).verify(msghash, signature);
  68. test/psbt.spec.ts:139 test path const keyPair = ECPair.makeRandom({ rng });
  69. test/psbt.spec.ts:191 test path const keyPair = ECPair.fromWIF(WIF, NETWORKS.testnet);
  70. test/psbt.spec.ts:277 test path ECPair.fromWIF(f.shouldSign.WIF),
  71. test/psbt.spec.ts:292 test path failedAsyncSigner(ECPair.fromWIF(f.shouldSign.WIF).publicKey),
  72. test/psbt.spec.ts:303 test path ECPair.fromWIF(f.shouldThrow.WIF),
  73. test/psbt.spec.ts:310 test path toAsyncSigner(ECPair.fromWIF(f.shouldThrow.WIF)),
  74. test/psbt.spec.ts:333 test path ECPair.fromWIF(f.shouldSign.WIF),
  75. test/psbt.spec.ts:344 test path ECPair.fromWIF(f.shouldThrow.WIF),
  76. test/psbt.spec.ts:365 test path ECPair.fromWIF(f.shouldSign.WIF),
  77. test/psbt.spec.ts:375 test path ECPair.fromWIF(f.shouldThrow.WIF),
  78. test/psbt.spec.ts:396 test path ECPair.fromWIF(f.shouldSign.WIF),
  79. test/psbt.spec.ts:406 test path ECPair.fromWIF(f.shouldThrow.WIF),
  80. test/psbt.spec.ts:426 test path bip32.fromBase58(f.shouldSign.xprv),
  81. test/psbt.spec.ts:437 test path bip32.fromBase58(f.shouldThrow.xprv),
  82. test/psbt.spec.ts:459 test path bip32.fromBase58(f.shouldSign.xprv),
  83. test/psbt.spec.ts:470 test path bip32.fromBase58(f.shouldThrow.xprv),
  84. test/psbt.spec.ts:491 test path bip32.fromBase58(f.shouldSign.xprv),
  85. test/psbt.spec.ts:501 test path bip32.fromBase58(f.shouldThrow.xprv),
  86. test/psbt.spec.ts:520 test path bip32.fromBase58(f.shouldSign.xprv),
  87. test/psbt.spec.ts:530 test path bip32.fromBase58(f.shouldThrow.xprv),
  88. test/psbt.spec.ts:725 test path const key = ECPair.makeRandom({ rng });
  89. test/psbt.spec.ts:825 test path const root = bip32.fromSeed(crypto.randomBytes(32));
  90. test/psbt.spec.ts:826 test path const root2 = bip32.fromSeed(crypto.randomBytes(32));
  91. test/psbt.spec.ts:836 test path pubkey: root.derivePath(path).publicKey,
  92. test/psbt.spec.ts:917 test path const root = bip32.fromSeed(crypto.randomBytes(32));
  93. test/psbt.spec.ts:918 test path const root2 = bip32.fromSeed(crypto.randomBytes(32));
  94. test/psbt.spec.ts:936 test path pubkey: root.derivePath(path).publicKey,
  95. test/psbt.spec.ts:1216 test path const alice = ECPair.fromWIF(
  96. ts_src/ecc_lib.ts:86 const r = ecc.xOnlyPointAddTweak(h(t.pubkey), h(t.tweak));
  97. ts_src/psbt.ts:1355 if (tools.compare(root.derivePath(d.path).publicKey, d.pubkey))
  98. ts_src/psbt.ts:2005 const node = hdKeyPair.derivePath(bipDv!.path);
js.wallet.keys · CWE-327
ECDSA Quantum-vulnerable Renamed import 1 place See details

Noble cryptography library in use

A `@noble/curves`, `@noble/secp256k1` or `@noble/ed25519` import. These are the modern audited JavaScript curve implementations, and every curve they offer is broken by Shor. `@noble/hashes` is inventoried separately and is not quantum-vulnerable.

A quantum computer of sufficient size breaks this completely. It has to be replaced, not tuned. Broken by Shor's algorithm on a cryptographically relevant quantum computer.

What to do. `@noble/post-quantum` provides ML-KEM and ML-DSA from the same authors.

  1. test/integration/taproot.spec.ts:1069 test path return ecc.sign(hash, this.privateKey);
js.noble · CWE-327
unknown Could not be determined 1 place See details

Cryptographic library in the dependency manifest

A dependency known to implement classical asymmetric cryptography. Its presence is inventory, not a finding about this codebase: the library may never be called with a quantum-vulnerable algorithm.

The project depends on a cryptography library. Listed so the inventory is complete; it is not by itself a problem.

What to do. Check the version. Several of these libraries have shipped ML-KEM and ML-DSA support since 2024, so the migration may need an upgrade rather than a replacement.

  1. package.json:107 "tiny-secp256k1": "^2.2.0",
dep.crypto-library
CSPRNG Quantum-safe Renamed import 5 places See details

Random number generation

`crypto.randomBytes()`, `randomUUID()` or `getRandomValues()`. A platform CSPRNG is not a quantum exposure; it is recorded because an inventory that omits the randomness source is incomplete. `Math.random()` is a separate, present-day defect.

This is where the software gets its random numbers. Quantum computers do not weaken it.

What to do. No action.

  1. test/integration/addresses.spec.ts:13 test path const rng = (size: number) => randomBytes(size);
  2. test/integration/payments.spec.ts:13 test path const rng = (size: number) => randomBytes(size);
  3. test/integration/taproot.spec.ts:27 test path const rng = (size: number) => randomBytes(size);
  4. test/integration/transactions.spec.ts:13 test path const rng = (size: number) => randomBytes(size);
  5. test/psbt.spec.ts:15 test path const rng = (size: number) => crypto.randomBytes(size);
js.rng

Cryptographic assets

Algorithm Assessment What it means Occurrences
secp256k1 Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. Bitcoin-family keys are additionally exposed because public keys are published on-chain, so the attacker does not have to wait for a signature. 144
SHA-256 Reduced margin Pre-image resistance falls to about 128 bits of quantum work. Adequate for most uses; SHA-384 restores the full margin where a signature must last decades. 12
CSPRNG Quantum-safe A cryptographically secure random number generator provided by the platform. Not weakened by a quantum computer. 5
unknown Could not be determined The algorithm could not be established from the source - chosen at runtime, or decided somewhere this scan does not reach. 5
ECDSA Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 1

Imported cryptographic libraries

Library Files
tiny-secp256k1 secp256k1 signatures 24
@noble/hashes hash functions 12
crypto the Node crypto module 5