1import { s as secp256k1 } from './secp256k1-DAVU6K9A.js'; 2import { cp as concatBytes, cq as abytes, cr as hmac, cs as sha512, ct as createView, cn as createBase58check, co as sha256 } from './wallet-keystore-BVM_ybiA.js'; 3import { r as ripemd160 } from './legacy-BHpsF2A2.js'; 4 5/** 6 * BIP32 hierarchical deterministic (HD) wallets over secp256k1. 7 * @module 8 * @example 9 * ```js 10 * import { HDKey } from "@scure/bip32"; 11 * import { sha256 } from '@noble/hashes/sha2.js'; 12 * import { randomBytes } from '@noble/hashes/utils.js'; 13 * const seed = randomBytes(32); 14 * const root = HDKey.fromMasterSeed(seed); 15 * const base58key = root.privateExtendedKey; 16 * const restored = HDKey.fromExtendedKey(base58key); 17 * const fromJson = HDKey.fromJSON({ xpriv: base58key }); 18 * const child = fromJson.derive("m/0/2147483647'/1"); 19 * const msgHash = sha256(new TextEncoder().encode('hello scure-bip32')); 20 * 21 * // props 22 * [root.depth, root.index, root.chainCode]; 23 * [restored.privateKey, restored.publicKey]; 24 * const sig = child.sign(msgHash); 25 * child.verify(msgHash, sig); 26 * ``` 27 */ 28/*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */ 29const Point = /* @__PURE__ */ (() => secp256k1.Point)(); 30const Fn = /* @__PURE__ */ (() => Point.Fn)(); 31const base58check = /* @__PURE__ */ createBase58check(sha256); 32const MASTER_SECRET = /* @__PURE__ */ (() => { 33 return Uint8Array.from('Bitcoin seed'.split(''), (char) => char.charCodeAt(0)); 34})(); 35const BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e }; 36/** Hardened child index offset from BIP32. */ 37const HARDENED_OFFSET = 0x80000000; 38const hash160 = (data) => ripemd160(sha256(data)); 39const fromU32 = (data) => createView(data).getUint32(0, false); 40const toU32 = (n) => { 41 if (typeof n !== 'number') 42 throw new TypeError('invalid number, should be from 0 to 2**32-1, got ' + n); 43 if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) 44 throw new RangeError('invalid number, should be from 0 to 2**32-1, got ' + n); 45 const buf = new Uint8Array(4); 46 createView(buf).setUint32(0, n, false); 47 return buf; 48}; 49/** 50 * HDKey from BIP32 51 * @param opt - Node fields used to construct one HDKey instance. 52 * @example 53 * ```js 54 * import { HDKey } from '@scure/bip32'; 55 * import { randomBytes } from '@noble/hashes/utils.js'; 56 * 57 * const seed = randomBytes(32); 58 * const root = HDKey.fromMasterSeed(seed); 59 * const account0 = root.derive("m/0/1'"); 60 * account0.publicKey; 61 * ``` 62 */ 63class HDKey { 64 get fingerprint() { 65 if (!this.pubHash) { 66 throw new Error('No publicKey set!'); 67 } 68 return fromU32(this.pubHash); 69 } 70 get identifier() { 71 return this.pubHash; 72 } 73 get pubKeyHash() { 74 return this.pubHash; 75 } 76 // Returns the live private key buffer for this instance. 77 // Copy it first if you need an immutable snapshot. 78 get privateKey() { 79 return this._privateKey || null; 80 } 81 get publicKey() { 82 return this._publicKey || null; 83 } 84 get privateExtendedKey() { 85 const priv = this._privateKey; 86 if (!priv) { 87 throw new Error('No private key'); 88 } 89 return base58check.encode(this.serialize(this.versions.private, concatBytes(Uint8Array.of(0), priv))); 90 } 91 get publicExtendedKey() { 92 if (!this._publicKey) { 93 throw new Error('No public key'); 94 } 95 return base58check.encode(this.serialize(this.versions.public, this._publicKey)); 96 } 97 static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) { 98 abytes(seed); 99 if (8 * seed.length < 128 || 8 * seed.length > 512) { 100 throw new RangeError('HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got ' + 101 seed.length); 102 } 103 const I = hmac(sha512, MASTER_SECRET, seed); 104 const privateKey = I.slice(0, 32); 105 const chainCode = I.slice(32); 106 return new HDKey({ versions, chainCode, privateKey }); 107 } 108 static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) { 109 // => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
110 const keyBuffer = base58check.decode(base58key); 111 const keyView = createView(keyBuffer); 112 const version = keyView.getUint32(0, false); 113 const opt = { 114 versions, 115 depth: keyBuffer[4], 116 parentFingerprint: keyView.getUint32(5, false), 117 index: keyView.getUint32(9, false), 118 chainCode: keyBuffer.slice(13, 45), 119 }; 120 const key = keyBuffer.slice(45); 121 const isPriv = key[0] === 0; 122 if (version !== versions[isPriv ? 'private' : 'public']) { 123 throw new Error('Version mismatch'); 124 } 125 if (isPriv) { 126 return new HDKey({ ...opt, privateKey: key.slice(1) }); 127 } 128 else { 129 return new HDKey({ ...opt, publicKey: key }); 130 } 131 } 132 static fromJSON(json) { 133 return HDKey.fromExtendedKey(json.xpriv); 134 } 135 versions; 136 depth = 0; 137 index = 0; 138 chainCode = null; 139 parentFingerprint = 0; 140 _privateKey; 141 _publicKey; 142 pubHash; 143 constructor(opt) { 144 if (!opt || typeof opt !== 'object') { 145 throw new Error('HDKey.constructor must not be called directly'); 146 } 147 this.versions = opt.versions || BITCOIN_VERSIONS; 148 this.depth = opt.depth || 0; 149 this.chainCode = opt.chainCode ? Uint8Array.from(opt.chainCode) : null; 150 this.index = opt.index || 0; 151 this.parentFingerprint = opt.parentFingerprint || 0; 152 if (!this.depth) { 153 if (this.parentFingerprint || this.index) { 154 throw new Error('HDKey: zero depth with non-zero index/parent fingerprint'); 155 } 156 } 157 if (this.depth > 255) { 158 throw new Error('HDKey: depth exceeds the serializable value 255'); 159 } 160 if (opt.publicKey && opt.privateKey) { 161 throw new Error('HDKey: publicKey and privateKey at same time.'); 162 } 163 if (opt.privateKey) { 164 if (!secp256k1.utils.isValidSecretKey(opt.privateKey)) 165 throw new Error('Invalid private key'); 166 // Don't alias caller-owned secret buffers. 167 this._privateKey = Uint8Array.from(opt.privateKey); 168 this._publicKey = secp256k1.getPublicKey(this._privateKey, true); 169 } 170 else if (opt.publicKey) { 171 this._publicKey = Point.fromBytes(opt.publicKey).toBytes(true); // force compressed point 172 } 173 else { 174 throw new Error('HDKey: no public or private key provided'); 175 } 176 this.pubHash = hash160(this._publicKey); 177 } 178 derive(path) { 179 if (!/^[mM]'?/.test(path)) { 180 throw new Error('Path must start with "m" or "M"'); 181 } 182 if (/^[mM]'?$/.test(path)) { 183 return this; 184 } 185 const parts = path.replace(/^[mM]'?\//, '').split('/'); 186 // tslint:disable-next-line 187 let child = this; 188 for (const c of parts) { 189 const m = /^(\d+)('?)$/.exec(c); 190 const m1 = m && m[1]; 191 if (!m || m.length !== 3 || typeof m1 !== 'string') 192 throw new Error('invalid child index: ' + c); 193 let idx = +m1; 194 if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) { 195 throw new Error('Invalid index'); 196 } 197 // hardened key 198 if (m[2] === "'") { 199 idx += HARDENED_OFFSET; 200 } 201 child = child.deriveChild(idx); 202 } 203 return child; 204 } 205 /** 206 * @param _I - Test-only override for the 64-byte HMAC-SHA512 output; normal callers must omit it. 207 */ 208 deriveChild(index, _I) { 209 if (!this._publicKey || !this.chainCode) { 210 throw new Error('No publicKey or chainCode set'); 211 } 212 let data = toU32(index); 213 if (index >= HARDENED_OFFSET) { 214 // Hardened 215 const priv = this._privateKey; 216 if (!priv) { 217 throw new Error('Could not derive hardened child key'); 218 } 219 // Hardened child: 0x00 || ser256(kpar) || ser32(index) 220 data = concatBytes(Uint8Array.of(0), priv, data); 221 } 222 else { 223 // Normal child: serP(point(kpar)) || ser32(index) 224 data = concatBytes(this._publicKey, data); 225 } 226 const out = _I || hmac(sha512, this.chainCode, data); 227 abytes(out, 64); 228 const childTweak = out.slice(0, 32); 229 const chainCode = out.slice(32); 230 const opt = { 231 versions: this.versions, 232 chainCode, 233 depth: this.depth + 1, 234 parentFingerprint: this.fingerprint, 235 index, 236 }; 237 // Fail early instead of re-trying different index 238 if (opt.depth > 255) { 239 throw new Error('HDKey: depth exceeds the serializable value 255'); 240 } 241 try { 242 const ctweak = Fn.fromBytes(childTweak); 243 // BIP-32 private derivation retries only when parse256(I_L) >= n or k_i = 0. 244 // BIP-32 public derivation retries only when parse256(I_L) >= n or K_i is infinity. 245 // So I_L = 0 is valid here; Fn.fromBytes still rejects parse256(I_L) >= n. 246 if (this._privateKey) { 247 const added = Fn.create(Fn.fromBytes(this._privateKey) + ctweak); 248 if (!Fn.isValidNot0(added)) { 249 throw new Error('The tweak was out of range or the resulted private key is invali
249d'); 250 } 251 opt.privateKey = Fn.toBytes(added); 252 } 253 else { 254 const point = Point.fromBytes(this._publicKey); 255 const added = ctweak === 0n ? point : point.add(Point.BASE.multiply(ctweak)); 256 // Cryptographically impossible: hmac-sha512 preimage would need to be found 257 if (added.equals(Point.ZERO)) { 258 throw new Error('The tweak was equal to negative P, which made the result key invalid'); 259 } 260 opt.publicKey = added.toBytes(true); 261 } 262 return new HDKey(opt); 263 } 264 catch (err) { 265 return this.deriveChild(index + 1); 266 } 267 } 268 sign(hash) { 269 if (!this._privateKey) { 270 throw new Error('No privateKey set!'); 271 } 272 abytes(hash, 32); 273 return secp256k1.sign(hash, this._privateKey, { prehash: false }); 274 } 275 verify(hash, signature) { 276 abytes(hash, 32); 277 abytes(signature, 64); 278 if (!this._publicKey) { 279 throw new Error('No publicKey set!'); 280 } 281 return secp256k1.verify(signature, hash, this._publicKey, { prehash: false }); 282 } 283 wipePrivateData() { 284 if (this._privateKey) { 285 this._privateKey.fill(0); 286 this._privateKey = undefined; 287 } 288 return this; 289 } 290 toJSON() { 291 return { 292 xpriv: this.privateExtendedKey, 293 xpub: this.publicExtendedKey, 294 }; 295 } 296 serialize(version, key) { 297 if (!this.chainCode) { 298 throw new Error('No chainCode set'); 299 } 300 abytes(key, 33); 301 // version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33) 302 return concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key); 303 } 304} 305 306export { HARDENED_OFFSET, HDKey };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.