@btc-vision/bitcoin 7.0.0-beta.0 → 7.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +112 -13
  2. package/benchmark-compare/BENCHMARK.md +74 -59
  3. package/benchmark-compare/compare.bench.ts +249 -96
  4. package/benchmark-compare/harness.ts +23 -25
  5. package/benchmark-compare/package.json +1 -0
  6. package/browser/address.d.ts +4 -4
  7. package/browser/address.d.ts.map +1 -1
  8. package/browser/chunks/{psbt-parallel-B-dfm5GZ.js → psbt-parallel-jZ6QcCnM.js} +3128 -2731
  9. package/browser/index.d.ts +1 -1
  10. package/browser/index.d.ts.map +1 -1
  11. package/browser/index.js +603 -585
  12. package/browser/io/base58check.d.ts +1 -25
  13. package/browser/io/base58check.d.ts.map +1 -1
  14. package/browser/io/base64.d.ts.map +1 -1
  15. package/browser/networks.d.ts +1 -0
  16. package/browser/networks.d.ts.map +1 -1
  17. package/browser/payments/bip341.d.ts +17 -0
  18. package/browser/payments/bip341.d.ts.map +1 -1
  19. package/browser/payments/index.d.ts +3 -2
  20. package/browser/payments/index.d.ts.map +1 -1
  21. package/browser/payments/p2mr.d.ts +169 -0
  22. package/browser/payments/p2mr.d.ts.map +1 -0
  23. package/browser/payments/types.d.ts +11 -1
  24. package/browser/payments/types.d.ts.map +1 -1
  25. package/browser/psbt/bip371.d.ts +30 -0
  26. package/browser/psbt/bip371.d.ts.map +1 -1
  27. package/browser/psbt/psbtutils.d.ts +1 -0
  28. package/browser/psbt/psbtutils.d.ts.map +1 -1
  29. package/browser/psbt.d.ts.map +1 -1
  30. package/browser/workers/index.js +9 -9
  31. package/build/address.d.ts +4 -4
  32. package/build/address.d.ts.map +1 -1
  33. package/build/address.js +11 -1
  34. package/build/address.js.map +1 -1
  35. package/build/index.d.ts +1 -1
  36. package/build/index.d.ts.map +1 -1
  37. package/build/index.js.map +1 -1
  38. package/build/io/base58check.d.ts +1 -25
  39. package/build/io/base58check.d.ts.map +1 -1
  40. package/build/io/base58check.js +1 -31
  41. package/build/io/base58check.js.map +1 -1
  42. package/build/io/base64.d.ts.map +1 -1
  43. package/build/io/base64.js +3 -0
  44. package/build/io/base64.js.map +1 -1
  45. package/build/networks.d.ts +1 -0
  46. package/build/networks.d.ts.map +1 -1
  47. package/build/networks.js +12 -0
  48. package/build/networks.js.map +1 -1
  49. package/build/payments/bip341.d.ts +17 -0
  50. package/build/payments/bip341.d.ts.map +1 -1
  51. package/build/payments/bip341.js +32 -1
  52. package/build/payments/bip341.js.map +1 -1
  53. package/build/payments/index.d.ts +3 -2
  54. package/build/payments/index.d.ts.map +1 -1
  55. package/build/payments/index.js +2 -1
  56. package/build/payments/index.js.map +1 -1
  57. package/build/payments/p2mr.d.ts +178 -0
  58. package/build/payments/p2mr.d.ts.map +1 -0
  59. package/build/payments/p2mr.js +555 -0
  60. package/build/payments/p2mr.js.map +1 -0
  61. package/build/payments/types.d.ts +11 -1
  62. package/build/payments/types.d.ts.map +1 -1
  63. package/build/payments/types.js +1 -0
  64. package/build/payments/types.js.map +1 -1
  65. package/build/psbt/bip371.d.ts +30 -0
  66. package/build/psbt/bip371.d.ts.map +1 -1
  67. package/build/psbt/bip371.js +80 -15
  68. package/build/psbt/bip371.js.map +1 -1
  69. package/build/psbt/psbtutils.d.ts +1 -0
  70. package/build/psbt/psbtutils.d.ts.map +1 -1
  71. package/build/psbt/psbtutils.js +2 -0
  72. package/build/psbt/psbtutils.js.map +1 -1
  73. package/build/psbt.d.ts.map +1 -1
  74. package/build/psbt.js +3 -2
  75. package/build/psbt.js.map +1 -1
  76. package/build/pubkey.js +1 -1
  77. package/build/pubkey.js.map +1 -1
  78. package/build/tsconfig.build.tsbuildinfo +1 -1
  79. package/documentation/README.md +122 -0
  80. package/documentation/address.md +820 -0
  81. package/documentation/block.md +679 -0
  82. package/documentation/crypto.md +461 -0
  83. package/documentation/ecc.md +584 -0
  84. package/documentation/errors.md +656 -0
  85. package/documentation/io.md +942 -0
  86. package/documentation/networks.md +625 -0
  87. package/documentation/p2mr.md +380 -0
  88. package/documentation/payments.md +1485 -0
  89. package/documentation/psbt.md +1400 -0
  90. package/documentation/script.md +730 -0
  91. package/documentation/taproot.md +670 -0
  92. package/documentation/transaction.md +943 -0
  93. package/documentation/types.md +587 -0
  94. package/documentation/workers.md +1007 -0
  95. package/eslint.config.js +3 -0
  96. package/package.json +17 -14
  97. package/src/address.ts +22 -10
  98. package/src/index.ts +1 -0
  99. package/src/io/base58check.ts +1 -35
  100. package/src/io/base64.ts +5 -0
  101. package/src/networks.ts +13 -0
  102. package/src/payments/bip341.ts +36 -1
  103. package/src/payments/index.ts +4 -0
  104. package/src/payments/p2mr.ts +660 -0
  105. package/src/payments/types.ts +12 -0
  106. package/src/psbt/bip371.ts +84 -13
  107. package/src/psbt/psbtutils.ts +2 -0
  108. package/src/psbt.ts +4 -2
  109. package/src/pubkey.ts +1 -1
  110. package/test/bitcoin.core.spec.ts +1 -1
  111. package/test/fixtures/p2mr.json +270 -0
  112. package/test/integration/taproot.spec.ts +7 -3
  113. package/test/opnetTestnet.spec.ts +302 -0
  114. package/test/payments.spec.ts +3 -1
  115. package/test/psbt.spec.ts +297 -2
  116. package/test/tsconfig.json +2 -2
@@ -0,0 +1,461 @@
1
+ # Cryptographic Hash Functions
2
+
3
+ This module provides all cryptographic hashing primitives used throughout the Bitcoin protocol. It exposes single-pass hashes (`sha256`, `sha1`, `ripemd160`), composite hashes (`hash160`, `hash256`), and BIP340 tagged hashes (`taggedHash`) used by Taproot.
4
+
5
+ ## Overview
6
+
7
+ | Function | Algorithm | Output Size | Primary Bitcoin Use |
8
+ |----------|-----------|-------------|---------------------|
9
+ | `sha256` | SHA-256 | 32 bytes (`Bytes32`) | SegWit v1 sighash components, witness commitments |
10
+ | `sha1` | SHA-1 | 20 bytes (`Bytes20`) | `OP_SHA1` script opcode |
11
+ | `ripemd160` | RIPEMD-160 | 20 bytes (`Bytes20`) | `OP_RIPEMD160` script opcode |
12
+ | `hash160` | RIPEMD-160(SHA-256(x)) | 20 bytes (`Bytes20`) | P2PKH addresses, P2SH addresses, P2WPKH witness programs |
13
+ | `hash256` | SHA-256(SHA-256(x)) | 32 bytes (`Bytes32`) | Block headers, transaction IDs (txid), legacy sighash |
14
+ | `taggedHash` | SHA-256(tag_prefix \|\| data) | 32 bytes (`Bytes32`) | Taproot (BIP340/341): key tweaking, leaf/branch hashing, Schnorr signatures |
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```typescript
21
+ import {
22
+ sha256,
23
+ sha1,
24
+ ripemd160,
25
+ hash160,
26
+ hash256,
27
+ taggedHash,
28
+ TAGS,
29
+ TAGGED_HASH_PREFIXES,
30
+ } from '@btc-vision/bitcoin';
31
+
32
+ // Or via the crypto namespace
33
+ import { crypto } from '@btc-vision/bitcoin';
34
+ crypto.sha256(data);
35
+ ```
36
+
37
+ ---
38
+
39
+ ## sha256
40
+
41
+ Computes the SHA-256 hash of the input data.
42
+
43
+ ```typescript
44
+ function sha256(data: Uint8Array): Bytes32
45
+ ```
46
+
47
+ | Parameter | Type | Description |
48
+ |-----------|------|-------------|
49
+ | `data` | `Uint8Array` | Arbitrary input bytes |
50
+ | **Returns** | `Bytes32` | 32-byte SHA-256 digest |
51
+
52
+ SHA-256 is the foundational hash in Bitcoin. While it is rarely used as a single pass for addresses or block identification (those use `hash256` or `hash160`), it is used directly in SegWit v1 (BIP 143 / BIP 341) sighash computation to hash individual transaction components (prevouts, sequences, amounts, outputs, script pubkeys) before they are assembled into the final sighash message.
53
+
54
+ ### Example
55
+
56
+ ```typescript
57
+ import { sha256 } from '@btc-vision/bitcoin';
58
+
59
+ const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // "Hello"
60
+ const digest = sha256(data);
61
+ // digest is a 32-byte Uint8Array (Bytes32)
62
+ console.log(digest.length); // 32
63
+ ```
64
+
65
+ ---
66
+
67
+ ## sha1
68
+
69
+ Computes the SHA-1 hash of the input data.
70
+
71
+ ```typescript
72
+ function sha1(data: Uint8Array): Bytes20
73
+ ```
74
+
75
+ | Parameter | Type | Description |
76
+ |-----------|------|-------------|
77
+ | `data` | `Uint8Array` | Arbitrary input bytes |
78
+ | **Returns** | `Bytes20` | 20-byte SHA-1 digest |
79
+
80
+ SHA-1 is available in Bitcoin Script via the `OP_SHA1` opcode. It is not used in standard transaction workflows but is required for certain specialized scripts.
81
+
82
+ ### Example
83
+
84
+ ```typescript
85
+ import { sha1 } from '@btc-vision/bitcoin';
86
+
87
+ const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
88
+ const digest = sha1(data);
89
+ console.log(digest.length); // 20
90
+ ```
91
+
92
+ ---
93
+
94
+ ## ripemd160
95
+
96
+ Computes the RIPEMD-160 hash of the input data.
97
+
98
+ ```typescript
99
+ function ripemd160(data: Uint8Array): Bytes20
100
+ ```
101
+
102
+ | Parameter | Type | Description |
103
+ |-----------|------|-------------|
104
+ | `data` | `Uint8Array` | Arbitrary input bytes |
105
+ | **Returns** | `Bytes20` | 20-byte RIPEMD-160 digest |
106
+
107
+ RIPEMD-160 is available in Bitcoin Script via the `OP_RIPEMD160` opcode. On its own it is not commonly used in standard Bitcoin payments, but it is a core component of the `hash160` composite hash (see below).
108
+
109
+ ### Example
110
+
111
+ ```typescript
112
+ import { ripemd160 } from '@btc-vision/bitcoin';
113
+
114
+ const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
115
+ const digest = ripemd160(data);
116
+ console.log(digest.length); // 20
117
+ ```
118
+
119
+ ---
120
+
121
+ ## hash160
122
+
123
+ Computes RIPEMD-160(SHA-256(data)), the standard 20-byte address hash used throughout Bitcoin.
124
+
125
+ ```typescript
126
+ function hash160(data: Uint8Array): Bytes20
127
+ ```
128
+
129
+ | Parameter | Type | Description |
130
+ |-----------|------|-------------|
131
+ | `data` | `Uint8Array` | Arbitrary input bytes (typically a public key or redeem script) |
132
+ | **Returns** | `Bytes20` | 20-byte composite digest |
133
+
134
+ `hash160` is the most widely used address-derivation hash in Bitcoin:
135
+
136
+ - **P2PKH** (Pay-to-Public-Key-Hash): The output script contains `hash160(compressed_pubkey)`. This is what produces classic `1...` Bitcoin addresses.
137
+ - **P2SH** (Pay-to-Script-Hash): The output script contains `hash160(redeem_script)`. This produces `3...` addresses.
138
+ - **P2WPKH** (Pay-to-Witness-Public-Key-Hash): The witness program is `hash160(compressed_pubkey)`. This produces `bc1q...` bech32 addresses.
139
+
140
+ The `OP_HASH160` opcode in Bitcoin Script performs exactly this operation.
141
+
142
+ ### Example
143
+
144
+ ```typescript
145
+ import { hash160 } from '@btc-vision/bitcoin';
146
+
147
+ // Hash a compressed public key to derive a P2PKH address hash
148
+ const compressedPubkey = new Uint8Array(33); // 33-byte compressed public key
149
+ const pubkeyHash = hash160(compressedPubkey);
150
+ console.log(pubkeyHash.length); // 20
151
+
152
+ // This 20-byte hash is what goes into a P2PKH output script:
153
+ // OP_DUP OP_HASH160 <pubkeyHash> OP_EQUALVERIFY OP_CHECKSIG
154
+ ```
155
+
156
+ ### Usage in P2PKH Address Derivation
157
+
158
+ ```typescript
159
+ import { payments } from '@btc-vision/bitcoin';
160
+ import type { PublicKey } from '@btc-vision/bitcoin';
161
+
162
+ // P2PKH internally calls hash160(pubkey) to derive the address
163
+ const payment = payments.P2PKH.fromPubkey(compressedPubkey as PublicKey);
164
+ console.log(payment.hash); // 20-byte hash160 of the public key (Bytes20 | undefined)
165
+ console.log(payment.address); // Base58Check-encoded address (string | undefined)
166
+ ```
167
+
168
+ ### Usage in P2SH
169
+
170
+ ```typescript
171
+ import { payments } from '@btc-vision/bitcoin';
172
+
173
+ // P2SH internally calls hash160(redeemScript) for the script hash
174
+ const payment = payments.P2SH.fromRedeem({ output: redeemScript });
175
+ console.log(payment.hash); // 20-byte hash160 of the redeem script (Bytes20 | undefined)
176
+ console.log(payment.address); // Base58Check-encoded address (string | undefined)
177
+ ```
178
+
179
+ ---
180
+
181
+ ## hash256
182
+
183
+ Computes SHA-256(SHA-256(data)), the double-SHA-256 hash used for block headers and transaction identifiers.
184
+
185
+ ```typescript
186
+ function hash256(data: Uint8Array): Bytes32
187
+ ```
188
+
189
+ | Parameter | Type | Description |
190
+ |-----------|------|-------------|
191
+ | `data` | `Uint8Array` | Arbitrary input bytes (typically a serialized block header or transaction) |
192
+ | **Returns** | `Bytes32` | 32-byte double-SHA-256 digest |
193
+
194
+ `hash256` (double SHA-256) is the backbone of Bitcoin's proof-of-work and transaction identification:
195
+
196
+ - **Block header hashing**: The 80-byte block header is double-SHA-256 hashed to produce the block hash. Miners must find a nonce such that this hash is below the target threshold.
197
+ - **Transaction IDs (txid)**: Every transaction is identified by the double-SHA-256 of its serialized form (excluding witness data).
198
+ - **Merkle tree construction**: The transaction merkle root in each block is built by pairwise double-SHA-256 hashing of transaction IDs.
199
+ - **Legacy sighash**: Pre-SegWit signature hashes use `hash256` over the sighash preimage.
200
+ - **BIP 143 sighash (SegWit v0)**: The intermediate components (hashPrevouts, hashSequence, hashOutputs) and the final sighash digest are computed with `hash256`.
201
+
202
+ ### Example
203
+
204
+ ```typescript
205
+ import { hash256 } from '@btc-vision/bitcoin';
206
+
207
+ // Double-SHA-256 of arbitrary data
208
+ const data = new Uint8Array([0x01, 0x00, 0x00, 0x00]);
209
+ const digest = hash256(data);
210
+ console.log(digest.length); // 32
211
+ ```
212
+
213
+ ### Block Header Hashing
214
+
215
+ ```typescript
216
+ import { Block } from '@btc-vision/bitcoin';
217
+
218
+ const block = Block.fromHex(blockHex);
219
+
220
+ // Block.getHash() internally calls hash256(serialized_80_byte_header)
221
+ const blockHash = block.getHash();
222
+ console.log(blockHash.length); // 32
223
+
224
+ // The block ID is the hash in reversed byte order (display convention)
225
+ console.log(block.getId()); // hex string as shown in block explorers
226
+ ```
227
+
228
+ ### Transaction ID Computation
229
+
230
+ ```typescript
231
+ import { Transaction } from '@btc-vision/bitcoin';
232
+
233
+ const tx = Transaction.fromHex(txHex);
234
+
235
+ // tx.getHash() internally calls hash256(serialized_tx_without_witness)
236
+ const txid = tx.getHash();
237
+ console.log(txid.length); // 32
238
+ ```
239
+
240
+ ### Merkle Tree
241
+
242
+ ```typescript
243
+ import { Block } from '@btc-vision/bitcoin';
244
+
245
+ // Block.calculateMerkleRoot uses hash256 for pairwise merkle node hashing
246
+ const merkleRoot = Block.calculateMerkleRoot(transactions);
247
+ ```
248
+
249
+ ---
250
+
251
+ ## taggedHash
252
+
253
+ Computes a BIP340-style tagged hash: `SHA-256(SHA-256(tag) || SHA-256(tag) || data)`.
254
+
255
+ ```typescript
256
+ function taggedHash(prefix: TaggedHashPrefix, data: Uint8Array): Bytes32
257
+ ```
258
+
259
+ | Parameter | Type | Description |
260
+ |-----------|------|-------------|
261
+ | `prefix` | `TaggedHashPrefix` | One of the predefined tag names (see TAGS below) |
262
+ | `data` | `Uint8Array` | Input data to hash |
263
+ | **Returns** | `Bytes32` | 32-byte tagged hash digest |
264
+
265
+ Tagged hashing was introduced by BIP340 (Schnorr signatures) and BIP341 (Taproot) to provide domain separation. Each tag produces a different hash function, ensuring that a hash computed in one context cannot collide with a hash in another context. The tag prefix (`SHA-256(tag) || SHA-256(tag)`) is prepended to the data before the final SHA-256, making it impossible for two different tags to produce the same output for the same input.
266
+
267
+ The library precomputes the 64-byte tag prefixes in `TAGGED_HASH_PREFIXES` for performance, avoiding redundant SHA-256 computations of the tag string on every call.
268
+
269
+ ### Example
270
+
271
+ ```typescript
272
+ import { taggedHash } from '@btc-vision/bitcoin';
273
+
274
+ // Compute a TapTweak tagged hash (used when tweaking an internal public key)
275
+ const tweakData = new Uint8Array(64); // e.g., internal_pubkey || merkle_root
276
+ const tweakHash = taggedHash('TapTweak', tweakData);
277
+ console.log(tweakHash.length); // 32
278
+ ```
279
+
280
+ ### Taproot Leaf Hashing
281
+
282
+ ```typescript
283
+ import { tapleafHash, LEAF_VERSION_TAPSCRIPT } from '@btc-vision/bitcoin';
284
+
285
+ // tapleafHash internally calls taggedHash('TapLeaf', version || script_length || script)
286
+ const leafHash = tapleafHash({
287
+ output: leafScript,
288
+ version: LEAF_VERSION_TAPSCRIPT,
289
+ });
290
+ ```
291
+
292
+ ### Taproot Branch Hashing
293
+
294
+ ```typescript
295
+ import { tapBranchHash } from '@btc-vision/bitcoin';
296
+
297
+ // tapBranchHash internally calls taggedHash('TapBranch', left || right)
298
+ const branchHash = tapBranchHash(leftHash, rightHash);
299
+ ```
300
+
301
+ ### Taproot Sighash
302
+
303
+ ```typescript
304
+ // The BIP341 sighash for SegWit v1 transactions uses taggedHash('TapSighash', ...)
305
+ // This is handled internally by Transaction.hashForWitnessV1()
306
+ const sighash = tx.hashForWitnessV1(inputIndex, prevOutScripts, values, hashType);
307
+ ```
308
+
309
+ ---
310
+
311
+ ## TAGS
312
+
313
+ A readonly tuple of all recognized BIP340/BIP341/MuSig2 tag names.
314
+
315
+ ```typescript
316
+ const TAGS = [
317
+ 'BIP0340/challenge',
318
+ 'BIP0340/aux',
319
+ 'BIP0340/nonce',
320
+ 'TapLeaf',
321
+ 'TapBranch',
322
+ 'TapSighash',
323
+ 'TapTweak',
324
+ 'KeyAgg list',
325
+ 'KeyAgg coefficient',
326
+ ] as const;
327
+ ```
328
+
329
+ | Tag | BIP | Purpose |
330
+ |-----|-----|---------|
331
+ | `BIP0340/challenge` | BIP 340 | Schnorr signature challenge hash `e = H(R \|\| P \|\| m)` |
332
+ | `BIP0340/aux` | BIP 340 | Auxiliary randomness in nonce generation |
333
+ | `BIP0340/nonce` | BIP 340 | Deterministic nonce derivation |
334
+ | `TapLeaf` | BIP 341 | Hashing individual tapscript leaves |
335
+ | `TapBranch` | BIP 341 | Hashing pairs of child nodes in the Taproot Merkle tree |
336
+ | `TapSighash` | BIP 341 | Computing the sighash for SegWit v1 (Taproot) inputs |
337
+ | `TapTweak` | BIP 341 | Tweaking the internal public key with the Merkle root |
338
+ | `KeyAgg list` | BIP 327 (MuSig2) | Key aggregation list commitment |
339
+ | `KeyAgg coefficient` | BIP 327 (MuSig2) | Key aggregation coefficient derivation |
340
+
341
+ ---
342
+
343
+ ## TaggedHashPrefix
344
+
345
+ A union type of all valid tag strings. Only these strings are accepted by `taggedHash()`.
346
+
347
+ ```typescript
348
+ type TaggedHashPrefix = (typeof TAGS)[number];
349
+ // Equivalent to:
350
+ // 'BIP0340/challenge' | 'BIP0340/aux' | 'BIP0340/nonce' |
351
+ // 'TapLeaf' | 'TapBranch' | 'TapSighash' | 'TapTweak' |
352
+ // 'KeyAgg list' | 'KeyAgg coefficient'
353
+ ```
354
+
355
+ ---
356
+
357
+ ## TAGGED_HASH_PREFIXES
358
+
359
+ A precomputed map from each `TaggedHashPrefix` to its 64-byte prefix (`SHA-256(tag) || SHA-256(tag)`). These are computed once and reused on every call to `taggedHash()`, avoiding the overhead of hashing the tag string each time.
360
+
361
+ ```typescript
362
+ const TAGGED_HASH_PREFIXES: { [key in TaggedHashPrefix]: Uint8Array }
363
+ ```
364
+
365
+ Each entry is exactly 64 bytes: the first 32 bytes are `SHA-256(tag)` and the second 32 bytes are an identical copy. When `taggedHash(prefix, data)` is called, it computes:
366
+
367
+ ```
368
+ SHA-256( TAGGED_HASH_PREFIXES[prefix] || data )
369
+ ```
370
+
371
+ This follows the BIP340 specification:
372
+
373
+ ```
374
+ tagged_hash(tag, msg) = SHA-256(SHA-256(tag) || SHA-256(tag) || msg)
375
+ ```
376
+
377
+ ### Example: Verifying a Prefix
378
+
379
+ ```typescript
380
+ import { sha256, TAGGED_HASH_PREFIXES } from '@btc-vision/bitcoin';
381
+
382
+ // The prefix for 'TapTweak' should be SHA-256("TapTweak") repeated twice
383
+ const tagBytes = new TextEncoder().encode('TapTweak');
384
+ const tagHash = sha256(tagBytes);
385
+
386
+ const prefix = TAGGED_HASH_PREFIXES['TapTweak'];
387
+ console.log(prefix.length); // 64
388
+
389
+ // First 32 bytes === SHA-256("TapTweak")
390
+ console.log(prefix.subarray(0, 32)); // equals tagHash
391
+ // Second 32 bytes === SHA-256("TapTweak")
392
+ console.log(prefix.subarray(32, 64)); // equals tagHash
393
+ ```
394
+
395
+ ---
396
+
397
+ ## Return Types
398
+
399
+ The crypto module uses branded `Uint8Array` subtypes for type safety:
400
+
401
+ | Type | Length | Used By |
402
+ |------|--------|---------|
403
+ | `Bytes32` | 32 bytes | `sha256`, `hash256`, `taggedHash` |
404
+ | `Bytes20` | 20 bytes | `sha1`, `ripemd160`, `hash160` |
405
+
406
+ These types help catch misuse at compile time. A `Bytes32` cannot be accidentally passed where a `Bytes20` is expected, and vice versa.
407
+
408
+ ```typescript
409
+ import { isBytes32, isBytes20, toBytes32, toBytes20 } from '@btc-vision/bitcoin';
410
+
411
+ // Runtime validation
412
+ if (isBytes32(value)) {
413
+ // value is Bytes32
414
+ }
415
+
416
+ // Runtime conversion (throws if length is wrong)
417
+ const b32 = toBytes32(someUint8Array); // asserts 32 bytes
418
+ const b20 = toBytes20(someUint8Array); // asserts 20 bytes
419
+ ```
420
+
421
+ ---
422
+
423
+ ## Underlying Implementation
424
+
425
+ The raw hash functions are provided by the `@noble/hashes` library:
426
+
427
+ ```typescript
428
+ // src/crypto-hashes.ts
429
+ import { ripemd160, sha1 } from '@noble/hashes/legacy.js';
430
+ import { sha256 } from '@noble/hashes/sha2.js';
431
+ ```
432
+
433
+ The `crypto.ts` module wraps these with proper return types (`Bytes20`, `Bytes32`) and builds the composite functions (`hash160`, `hash256`, `taggedHash`) on top of them.
434
+
435
+ ---
436
+
437
+ ## Hash Function Usage Summary by Bitcoin Feature
438
+
439
+ | Bitcoin Feature | Hash Function | Details |
440
+ |-----------------|---------------|---------|
441
+ | P2PKH addresses (`1...`) | `hash160` | `RIPEMD-160(SHA-256(pubkey))` produces the 20-byte pubkey hash |
442
+ | P2SH addresses (`3...`) | `hash160` | `RIPEMD-160(SHA-256(redeemScript))` produces the 20-byte script hash |
443
+ | P2WPKH addresses (`bc1q...`) | `hash160` | 20-byte witness program is `hash160(pubkey)` |
444
+ | P2WSH addresses (`bc1q...`) | `sha256` | 32-byte witness program is `SHA-256(witnessScript)` |
445
+ | Block header hash | `hash256` | Double-SHA-256 of the 80-byte header; basis for proof-of-work |
446
+ | Transaction ID (txid) | `hash256` | Double-SHA-256 of the serialized transaction (no witness) |
447
+ | Merkle root (block) | `hash256` | Pairwise double-SHA-256 of txids |
448
+ | Legacy sighash (pre-SegWit) | `hash256` | Double-SHA-256 of the sighash preimage |
449
+ | SegWit v0 sighash (BIP 143) | `hash256` | Double-SHA-256 for intermediate components and final digest |
450
+ | SegWit v1 sighash (BIP 341) | `sha256` + `taggedHash` | Single SHA-256 for intermediate components; `taggedHash('TapSighash', ...)` for the final digest |
451
+ | Taproot key tweaking | `taggedHash` | `taggedHash('TapTweak', pubkey \|\| merkleRoot)` |
452
+ | Tapscript leaf hash | `taggedHash` | `taggedHash('TapLeaf', version \|\| scriptLen \|\| script)` |
453
+ | Tapscript branch hash | `taggedHash` | `taggedHash('TapBranch', left \|\| right)` |
454
+ | Schnorr signature challenge | `taggedHash` | `taggedHash('BIP0340/challenge', R \|\| P \|\| m)` |
455
+ | Schnorr nonce generation | `taggedHash` | `taggedHash('BIP0340/nonce', ...)` and `taggedHash('BIP0340/aux', ...)` |
456
+ | MuSig2 key aggregation | `taggedHash` | `taggedHash('KeyAgg list', ...)` and `taggedHash('KeyAgg coefficient', ...)` |
457
+ | `OP_SHA1` script opcode | `sha1` | Rarely used; available for specialized scripts |
458
+ | `OP_RIPEMD160` script opcode | `ripemd160` | Rarely used directly; component of `hash160` |
459
+ | `OP_SHA256` script opcode | `sha256` | Single SHA-256 in script evaluation |
460
+ | `OP_HASH160` script opcode | `hash160` | RIPEMD-160(SHA-256(x)) in script evaluation |
461
+ | `OP_HASH256` script opcode | `hash256` | SHA-256(SHA-256(x)) in script evaluation |