@scure/btc-signer 2.0.0 → 2.2.0

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.
package/utils.js CHANGED
@@ -1,27 +1,151 @@
1
1
  import { schnorr, secp256k1 as secp } from '@noble/curves/secp256k1.js';
2
- import { bytesToNumberBE, numberToBytesBE } from '@noble/curves/utils.js';
2
+ import { abytes, bytesToNumberBE, numberToBytesBE } from '@noble/curves/utils.js';
3
3
  import { ripemd160 } from '@noble/hashes/legacy.js';
4
- import { sha256 } from '@noble/hashes/sha2.js';
4
+ import { sha256 as nobleSha256 } from '@noble/hashes/sha2.js';
5
+ import {} from '@noble/hashes/utils.js';
5
6
  import { utils as packedUtils, U32LE } from 'micro-packed';
6
- const Point = secp.Point;
7
- const Fn = Point.Fn;
8
- const CURVE_ORDER = Point.Fn.ORDER;
7
+ export {} from '@noble/hashes/utils.js';
8
+ const Point = /* @__PURE__ */ (() => secp.Point)();
9
+ const Fn = /* @__PURE__ */ (() => Point.Fn)();
10
+ const CURVE_ORDER = /* @__PURE__ */ (() => Point.Fn.ORDER)();
11
+ /**
12
+ * Checks whether a curve y-coordinate is even.
13
+ * @param y - y-coordinate to inspect
14
+ * @returns `true` when the coordinate is even.
15
+ * @example
16
+ * Check whether a point coordinate has even parity.
17
+ * ```ts
18
+ * hasEven(2n);
19
+ * ```
20
+ */
9
21
  export const hasEven = (y) => y % 2n === 0n;
10
- const isBytes = packedUtils.isBytes;
11
- const concatBytes = packedUtils.concatBytes;
12
- const equalBytes = packedUtils.equalBytes;
13
- export { concatBytes, equalBytes, isBytes, sha256 };
22
+ /**
23
+ * Checks whether a value is a Uint8Array.
24
+ * @param a - value to inspect
25
+ * @returns `true` when the value is a Uint8Array.
26
+ * @example
27
+ * Check whether an unknown value is already bytes.
28
+ * ```ts
29
+ * isBytes(new Uint8Array([1]));
30
+ * ```
31
+ */
32
+ export const isBytes = /* @__PURE__ */ (() => packedUtils.isBytes)();
33
+ /**
34
+ * Concatenates byte arrays into a single Uint8Array.
35
+ * @param arrays - byte arrays to concatenate
36
+ * @returns Concatenated byte array.
37
+ * @example
38
+ * Join several byte chunks before hashing or signing them.
39
+ * ```ts
40
+ * concatBytes(new Uint8Array([1]), new Uint8Array([2]));
41
+ * ```
42
+ */
43
+ export const concatBytes =
44
+ /* @__PURE__ */ (() => packedUtils.concatBytes)();
45
+ /**
46
+ * Compares two byte arrays for equality.
47
+ * @param a - first byte array
48
+ * @param b - second byte array
49
+ * @returns `true` when both arrays contain the same bytes.
50
+ * @example
51
+ * Compare two serialized values without converting them first.
52
+ * ```ts
53
+ * equalBytes(new Uint8Array([1]), new Uint8Array([1]));
54
+ * ```
55
+ */
56
+ export const equalBytes =
57
+ /* @__PURE__ */ (() => packedUtils.equalBytes)();
58
+ /**
59
+ * SHA-256 hash function.
60
+ * @param msg - bytes to hash
61
+ * @returns SHA-256 digest.
62
+ * @example
63
+ * Hash a byte array with SHA-256.
64
+ * ```ts
65
+ * sha256(new Uint8Array([1, 2, 3]));
66
+ * ```
67
+ */
68
+ export const sha256 = /* @__PURE__ */ (() => nobleSha256)();
69
+ /**
70
+ * HASH160 helper used by classic Bitcoin addresses.
71
+ * @param msg - bytes to hash
72
+ * @returns RIPEMD160(SHA256(msg)).
73
+ * @example
74
+ * Derive the HASH160 used by legacy address formats.
75
+ * ```ts
76
+ * hash160(new Uint8Array([1, 2, 3]));
77
+ * ```
78
+ */
14
79
  export const hash160 = (msg) => ripemd160(sha256(msg));
80
+ /**
81
+ * Double-SHA256 helper used by Bitcoin transaction ids.
82
+ * @param msgs - message parts to concatenate and hash
83
+ * @returns SHA256(SHA256(concat(msgs))).
84
+ * @example
85
+ * Compute the double-SHA256 used by txids and sighashes.
86
+ * ```ts
87
+ * sha256x2(new Uint8Array([1]), new Uint8Array([2]));
88
+ * ```
89
+ */
15
90
  export const sha256x2 = (...msgs) => sha256(sha256(concatBytes(...msgs)));
16
- export const randomPrivateKeyBytes = schnorr.utils.randomSecretKey;
17
- export const pubSchnorr = schnorr.getPublicKey;
18
- export const pubECDSA = secp.getPublicKey;
91
+ /**
92
+ * Generates a random secp256k1 private key.
93
+ * @returns Random 32-byte private key.
94
+ * @example
95
+ * Generate a fresh secp256k1 private key for signing.
96
+ * ```ts
97
+ * const privKey = randomPrivateKeyBytes();
98
+ * ```
99
+ */
100
+ export const randomPrivateKeyBytes = () => schnorr.utils.randomSecretKey();
101
+ /**
102
+ * Derives a BIP340 Schnorr public key from a private key.
103
+ * @param priv - private key bytes
104
+ * @returns X-only public key bytes.
105
+ * @example
106
+ * Derive the x-only public key used by Schnorr and Taproot.
107
+ * ```ts
108
+ * import { pubSchnorr, randomPrivateKeyBytes } from '@scure/btc-signer/utils.js';
109
+ * pubSchnorr(randomPrivateKeyBytes());
110
+ * ```
111
+ */
112
+ export const pubSchnorr = (priv) => schnorr.getPublicKey(priv);
113
+ /**
114
+ * Derives a secp256k1 ECDSA public key from a private key.
115
+ * @param privateKey - private key bytes
116
+ * @param isCompressed - whether to return the compressed form
117
+ * @returns Serialized public key bytes.
118
+ * @example
119
+ * Derive the normal secp256k1 public key for legacy or SegWit scripts.
120
+ * ```ts
121
+ * import { pubECDSA, randomPrivateKeyBytes } from '@scure/btc-signer/utils.js';
122
+ * pubECDSA(randomPrivateKeyBytes());
123
+ * ```
124
+ */
125
+ export const pubECDSA = (privateKey, isCompressed) => secp.getPublicKey(privateKey, isCompressed);
19
126
  // low-r signature grinding. Used to reduce tx size by 1 byte.
20
127
  // noble/secp256k1 does not support the feature: it is not used outside of BTC.
21
128
  // We implement it manually, because in BTC it's common.
22
129
  // Not best way, but closest to bitcoin implementation (easier to check)
23
130
  const hasLowR = (sig) => sig.r < CURVE_ORDER / 2n;
131
+ /**
132
+ * Signs a 32-byte hash with ECDSA and returns DER encoding.
133
+ * @param hash - message hash to sign
134
+ * @param privateKey - signer private key
135
+ * @param lowR - whether to grind for low-R signatures
136
+ * @returns DER-encoded signature bytes.
137
+ * @throws If low-R grinding overflows or ECDSA signing fails validation. {@link Error}
138
+ * @example
139
+ * Hash a message first, then create the DER-encoded ECDSA signature.
140
+ * ```ts
141
+ * import { randomPrivateKeyBytes, sha256, signECDSA } from '@scure/btc-signer/utils.js';
142
+ * signECDSA(sha256(new Uint8Array([1, 2, 3])), randomPrivateKeyBytes());
143
+ * ```
144
+ */
24
145
  export function signECDSA(hash, privateKey, lowR = false) {
146
+ // signECDSA is the 32-byte sighash wrapper for BTC callers, so reject arbitrary-length
147
+ // messages here instead of silently signing them with prehash disabled.
148
+ abytes(hash, 32, 'hash');
25
149
  let sig = secp.Signature.fromBytes(secp.sign(hash, privateKey, { prehash: false }));
26
150
  if (lowR && !hasLowR(sig)) {
27
151
  const extraEntropy = new Uint8Array(32);
@@ -35,30 +159,89 @@ export function signECDSA(hash, privateKey, lowR = false) {
35
159
  }
36
160
  return sig.toBytes('der');
37
161
  }
38
- export const signSchnorr = schnorr.sign;
39
- export const tagSchnorr = schnorr.utils.taggedHash;
40
- export const PubT = {
162
+ /**
163
+ * BIP340 Schnorr signing function.
164
+ * @param message - 32-byte message digest
165
+ * @param secretKey - signer private key
166
+ * @param auxRand - optional auxiliary randomness
167
+ * @returns Schnorr signature bytes.
168
+ * @example
169
+ * Sign a 32-byte digest with the built-in BIP340 helper.
170
+ * ```ts
171
+ * import { randomPrivateKeyBytes, sha256, signSchnorr } from '@scure/btc-signer/utils.js';
172
+ * const msg = sha256(new Uint8Array([1, 2, 3]));
173
+ * signSchnorr(msg, randomPrivateKeyBytes());
174
+ * ```
175
+ */
176
+ export const signSchnorr = (message, secretKey, auxRand) => schnorr.sign(message, secretKey, auxRand);
177
+ /**
178
+ * Tagged-hash helper used by Schnorr and taproot constructions.
179
+ * @param tag - tagged-hash domain separator
180
+ * @param messages - message parts hashed under the tag
181
+ * @returns Tagged SHA-256 digest.
182
+ * @example
183
+ * Build the tagged hash used by Taproot leaves or tweaks.
184
+ * ```ts
185
+ * import { tagSchnorr } from '@scure/btc-signer/utils.js';
186
+ * tagSchnorr('TapLeaf', Uint8Array.of(0xc0), Uint8Array.of(0x51));
187
+ * ```
188
+ */
189
+ export const tagSchnorr = (tag, ...messages) => schnorr.utils.taggedHash(tag, ...messages);
190
+ /** Public key format tags used by validation helpers. */
191
+ export const PubT = /* @__PURE__ */ (() => Object.freeze({
41
192
  ecdsa: 0,
42
193
  schnorr: 1,
43
- };
194
+ }))();
195
+ /**
196
+ * Validates a public key against the expected Bitcoin key encoding.
197
+ * @param pub - public key bytes to validate
198
+ * @param type - expected public key format
199
+ * @returns The validated public key bytes.
200
+ * @throws On wrong argument types. {@link TypeError}
201
+ * @throws On wrong argument ranges or values. {@link RangeError}
202
+ * @example
203
+ * Reject keys that do not match the encoding required by the current script path.
204
+ * ```ts
205
+ * import {
206
+ * PubT,
207
+ * pubECDSA,
208
+ * randomPrivateKeyBytes,
209
+ * validatePubkey,
210
+ * } from '@scure/btc-signer/utils.js';
211
+ * validatePubkey(pubECDSA(randomPrivateKeyBytes()), PubT.ecdsa);
212
+ * ```
213
+ */
44
214
  export function validatePubkey(pub, type) {
45
215
  const len = pub.length;
46
216
  if (type === PubT.ecdsa) {
47
217
  if (len === 32)
48
- throw new Error('Expected non-Schnorr key');
218
+ throw new RangeError('Expected non-Schnorr key');
49
219
  Point.fromBytes(pub); // does assertValidity
50
220
  return pub;
51
221
  }
52
222
  else if (type === PubT.schnorr) {
53
223
  if (len !== 32)
54
- throw new Error('Expected 32-byte Schnorr key');
224
+ throw new RangeError('Expected 32-byte Schnorr key');
55
225
  schnorr.utils.lift_x(bytesToNumberBE(pub));
56
226
  return pub;
57
227
  }
58
228
  else {
59
- throw new Error('Unknown key type');
229
+ throw new TypeError('Unknown key type');
60
230
  }
61
231
  }
232
+ /**
233
+ * Computes the Taproot tweak scalar from an internal key and merkle root.
234
+ * @param a - internal key bytes
235
+ * @param b - optional merkle root bytes
236
+ * @returns Taproot tweak scalar.
237
+ * @throws If the tweak scalar is outside the curve order. {@link Error}
238
+ * @example
239
+ * Combine the internal key and Merkle root into the Taproot tweak scalar.
240
+ * ```ts
241
+ * import { pubSchnorr, randomPrivateKeyBytes, tapTweak } from '@scure/btc-signer/utils.js';
242
+ * tapTweak(pubSchnorr(randomPrivateKeyBytes()), new Uint8Array());
243
+ * ```
244
+ */
62
245
  export function tapTweak(a, b) {
63
246
  const u = schnorr.utils;
64
247
  const t = u.taggedHash('TapTweak', a, b);
@@ -67,8 +250,24 @@ export function tapTweak(a, b) {
67
250
  throw new Error('tweak higher than curve order');
68
251
  return tn;
69
252
  }
253
+ /**
254
+ * Tweaks a private key for Taproot key-path spending.
255
+ * @param privKey - internal private key bytes
256
+ * @param merkleRoot - optional taproot merkle root
257
+ * @returns Tweaked private key bytes.
258
+ * @throws If the Taproot tweak scalar is outside the curve order. {@link Error}
259
+ * @example
260
+ * Derive the tweaked Taproot key-path secret from the internal private key.
261
+ * ```ts
262
+ * import { randomPrivateKeyBytes, taprootTweakPrivKey } from '@scure/btc-signer/utils.js';
263
+ * taprootTweakPrivKey(randomPrivateKeyBytes());
264
+ * ```
265
+ */
70
266
  export function taprootTweakPrivKey(privKey, merkleRoot = Uint8Array.of()) {
71
267
  const u = schnorr.utils;
268
+ // BIP341 taproot_tweak_seckey starts with `seckey0 = int_from_bytes(seckey0)`, and
269
+ // BIP340 defines `int(x)` only for `x` as a 32-byte array, so reject other widths here.
270
+ abytes(privKey, 32, 'privKey');
72
271
  const seckey0 = bytesToNumberBE(privKey); // seckey0 = int_from_bytes(seckey0)
73
272
  const P = Point.BASE.multiply(seckey0); // P = point_mul(G, seckey0)
74
273
  // seckey = seckey0 if has_even_y(P) else SECP256K1_ORDER - seckey0
@@ -79,8 +278,28 @@ export function taprootTweakPrivKey(privKey, merkleRoot = Uint8Array.of()) {
79
278
  // bytes_from_int((seckey + t) % SECP256K1_ORDER)
80
279
  return numberToBytesBE(Fn.add(seckey, t), 32);
81
280
  }
281
+ /**
282
+ * Tweaks a Schnorr public key for Taproot key-path spending.
283
+ * @param pubKey - x-only internal public key
284
+ * @param h - taproot merkle root
285
+ * @returns Tweaked public key and output-key parity.
286
+ * @throws If the Taproot tweak scalar is outside the curve order. {@link Error}
287
+ * @example
288
+ * Derive the final Taproot output key from the internal key and Merkle root.
289
+ * ```ts
290
+ * import {
291
+ * pubSchnorr,
292
+ * randomPrivateKeyBytes,
293
+ * taprootTweakPubkey,
294
+ * } from '@scure/btc-signer/utils.js';
295
+ * taprootTweakPubkey(pubSchnorr(randomPrivateKeyBytes()), new Uint8Array());
296
+ * ```
297
+ */
82
298
  export function taprootTweakPubkey(pubKey, h) {
83
299
  const u = schnorr.utils;
300
+ // BIP341 taproot_tweak_pubkey feeds `pubkey` into `int_from_bytes(pubkey)`, and
301
+ // BIP340 defines `int(x)` only for `x` as a 32-byte array, so reject other widths here.
302
+ abytes(pubKey, 32, 'pubKey');
84
303
  const t = tapTweak(pubKey, h); // t = int_from_bytes(tagged_hash("TapTweak", pubkey + h))
85
304
  const P = u.lift_x(bytesToNumberBE(pubKey)); // P = lift_x(int_from_bytes(pubkey))
86
305
  const Q = P.add(Point.BASE.multiply(t)); // Q = point_add(P, point_mul(G, t))
@@ -89,27 +308,46 @@ export function taprootTweakPubkey(pubKey, h) {
89
308
  }
90
309
  // Another stupid decision, where lack of standard affects security.
91
310
  // Multisig needs to be generated with some key.
92
- // We are using approach from BIP 341/bitcoinjs-lib: SHA256(uncompressedDER(SECP256K1_GENERATOR_POINT))
311
+ // We are using the BIP 341/bitcoinjs-lib approach:
312
+ // SHA256(uncompressedDER(SECP256K1_GENERATOR_POINT))
93
313
  // It is possible to switch SECP256K1_GENERATOR_POINT with some random point;
94
314
  // but it's too complex to prove.
95
315
  // Also used by bitcoin-core and bitcoinjs-lib
96
- export const TAPROOT_UNSPENDABLE_KEY = sha256(Point.BASE.toBytes(false));
97
- export const NETWORK = {
316
+ // This is the fixed BIP 341 H example, not the privacy-preserving H + rG variant.
317
+ // Downstream helpers use exact-byte equality with it to recognize
318
+ // library-generated script-only outputs.
319
+ /** Standard unspendable internal key used for script-only Taproot outputs. */
320
+ export const TAPROOT_UNSPENDABLE_KEY = /* @__PURE__ */ (() => sha256(Point.BASE.toBytes(false)))();
321
+ /** Bitcoin mainnet network parameters. */
322
+ export const NETWORK = /* @__PURE__ */ Object.freeze({
98
323
  bech32: 'bc',
99
324
  pubKeyHash: 0x00,
100
325
  scriptHash: 0x05,
101
326
  wif: 0x80,
102
- };
103
- export const TEST_NETWORK = {
327
+ });
328
+ /** Bitcoin testnet network parameters. */
329
+ export const TEST_NETWORK = /* @__PURE__ */ Object.freeze({
104
330
  bech32: 'tb',
105
331
  pubKeyHash: 0x6f,
106
332
  scriptHash: 0xc4,
107
333
  wif: 0xef,
108
- };
334
+ });
109
335
  // Exported for tests, internal method
336
+ /**
337
+ * Lexicographically compares two byte arrays.
338
+ * @param a - first byte array
339
+ * @param b - second byte array
340
+ * @returns `-1`, `0`, or `1` depending on the ordering.
341
+ * @throws On wrong argument types. {@link TypeError}
342
+ * @example
343
+ * Compare two serialized keys using Bitcoin's byte ordering.
344
+ * ```ts
345
+ * compareBytes(new Uint8Array([1]), new Uint8Array([2]));
346
+ * ```
347
+ */
110
348
  export function compareBytes(a, b) {
111
349
  if (!isBytes(a) || !isBytes(b))
112
- throw new Error(`cmp: wrong type a=${typeof a} b=${typeof b}`);
350
+ throw new TypeError(`cmp: wrong type a=${typeof a} b=${typeof b}`);
113
351
  // -1 -> a<b, 0 -> a==b, 1 -> a>b
114
352
  const len = Math.min(a.length, b.length);
115
353
  for (let i = 0; i < len; i++)
@@ -118,8 +356,21 @@ export function compareBytes(a, b) {
118
356
  return Math.sign(a.length - b.length);
119
357
  }
120
358
  // Reverses key<->values
359
+ /**
360
+ * Reverses an object's keys and values.
361
+ * @param obj - object to reverse
362
+ * @returns Object with original values mapped back to keys.
363
+ * @throws If duplicate values would collide while reversing the object. {@link Error}
364
+ * @example
365
+ * Flip a lookup table so the values become keys.
366
+ * ```ts
367
+ * reverseObject({ a: 1, b: 2 });
368
+ * ```
369
+ */
121
370
  export function reverseObject(obj) {
122
- const res = {};
371
+ // Keep a raw dictionary shape so enum-like tables can reverse values like
372
+ // `toString` without colliding with inherited Object prototype properties.
373
+ const res = Object.create(null);
123
374
  for (const k in obj) {
124
375
  if (res[obj[k]] !== undefined)
125
376
  throw new Error('duplicate key');
package/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"}