const { B32, SECP, deriveChildPubkey, ripemd160, hash160, toBech32, deriveAddresses } = require('/tmp/cripto/crypto.js'); const hex = a => Array.from(a).map(b=>b.toString(16).padStart(2,'0')).join(''); let pass=0, fail=0; const check=(n,g,w)=>{ const ok=g===w; console.log(` ${ok?'✓':'✗'} ${n}`); if(!ok){console.log(` obtenido: ${g}`);console.log(` esperado: ${w}`);fail++;}else pass++; }; (async () => { // ── BIP32, vectores oficiales del estándar ── // Vector 1: seed 000102...0e0f // m/0/1 derivado SOLO con clave pública (derivación no endurecida) console.log("=== 4. BIP32 — vector 1 oficial, derivación pública ==="); // xpub de m (raíz) del vector 1 const M = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"; const raw = B32.decodeBase58(M); const chain = raw.slice(13,45), pub = raw.slice(45,78); check("clave pública de m", hex(pub), "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"); check("chain code de m", hex(chain), "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"); // m/0 → xpub esperado del estándar const m0 = await deriveChildPubkey(pub, chain, 0); // del vector oficial: xpub de m/0'/1 ... usamos m/0 no endurecido del vector 2 console.log("\n=== 5. BIP32 — vector 2 oficial (m/0, no endurecida) ==="); const M2 = "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"; const r2 = B32.decodeBase58(M2); const c2 = r2.slice(13,45), p2 = r2.slice(45,78); const d2 = await deriveChildPubkey(p2, c2, 0); check("m/0 clave pública", hex(d2.pub), "02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea"); check("m/0 chain code", hex(d2.chain), "f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"); // m/0/2147483647 no se puede (endurecida). Probamos m/0/1 del vector 2: const d3 = await deriveChildPubkey(d2.pub, d2.chain, 1); console.log("\n=== 6. bech32 — vectores oficiales BIP173 ==="); // P2WPKH conocido: pubkey 0279be66... → bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4 const pk = Uint8Array.from(Buffer.from("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","hex")); const h = await hash160(pk); check("hash160 de G", hex(h), "751e76e8199196d454941c45d1b3a323f1433bd6"); check("dirección P2WPKH", toBech32("bc", Array.from(h)), "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"); check("misma en testnet", toBech32("tb", Array.from(h)), "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"); console.log(`\nRESULTADO: ${pass} correctas, ${fail} incorrectas`); })();