Understanding fingerprint generation in xpub

7 replies 392 views
bear100Member
Posts: 11 · Reputation: 90
#1May 30, 2025, 07:43 PM
So, I've got this XPUB: [5183a8d8/86'/1'/0']tpubDDtdVYn7LWnWNUXADgoLGu48aLH4dZ17hYfRfV9rjB7QQK3BrphnrSV6pGAeyfyiAM7DmXPJgRz GoBdwWvRoFdJoMVpWfmM9FCk8ojVhbMS/* I'm curious about the 5183a8d8 part in the xpub. Is this what they call the fingerprint?
5 Reply Quote Share
gr3g.0rbitHero Member
Posts: 1025 · Reputation: 2646
#2May 30, 2025, 09:54 PM
Just get the HASH160 of the compressed public key pair of ECDSA Private key part (without the 'Chain Code') of the "Master Private Key". Given that your example has an "Extended Public Key" instead, you wont be able to compute the master fingerprint from it. I'll provide you a valid example: Descriptor (Master Fingerprint: de651e9f): Descriptor with Master Private Key (private version of the above): Now to compute the Master Fingerprint: Decode the base58 tprv above and get the private key (teal colored):04358394 00 00000000 00000000 f8f8553de856d4e29504423da00dad4067296c782213919c64bb98f41752c66f 00 56a85c89f1df3bd53d00723768357bcb02930b366c13e97170133c12c4344b1f f9f0b48eCompute its Compressed Public key pair: 02cd9776ca76833f399a5c0fa7af51edca0b1edaa24a09accc3f7568964fdbb0fc Compute the HASH160 of the above; RIPEMD160[SHA256(PubKey)]: de651e9fb4c50f68fe4be1ca9d6bb563a78307ce Get the first four Bytes of the above (check if it's the same as the Master Fingerprint): de651e9f
4 Reply Quote Share
bear100Member
Posts: 11 · Reputation: 90
#3Jun 1, 2025, 09:18 AM
const bitcoin = require('bitcoinjs-lib'); const bip39 = require('bip39'); const bitcoinMessage = require('bitcoinjs-message'); const ecc = require('tiny-secp256k1') const { BIP32Factory } = require('bip32') const bip32 = BIP32Factory(ecc) function computeFingerprintFromXPriv() {   const mnemonic = "top ritual venue glad soon alcohol annual base tornado invest speak lpke";   const seed = bip39.mnemonicToSeedSync(mnemonic);   const network = bitcoin.networks.testnet;   const root = bip32.fromSeed(seed, network);   const path = "m/86'/1'/0'";   const account = root.derivePath(path);   const xpriv = account.toBase58()   const extendedPublicKey = account.neutered().toBase58();   console.log(extendedPublicKey)   const node = bip32.fromBase58(xpriv,network);   const compressedPublicKey = node.publicKey;   const hash160 = bitcoin.crypto.hash160(compressedPublicKey);   console.log(`Master fingerprint: ${hash160.toString('hex')}`);     return hash160.toString('hex').substring(0, ; } I successfully reproduced it using bitcoinjs of node, but the final result of hash160 does not correspond to the correct result. I don't know why [133a3b35/86h/1h/0h]tpubDCynnv7orn7ymby6QpWMgw9DwJahdDzzgxARwSd4ipdJ9rv5na4ppub8Pv6346pWtigrNMFrnau uCgcsx1SrtaWqNuELKFGTeZYvAVhX3ES/<0;1;9;10> The correct result is 133a3b35, but the final output is de404428. I have confirmed that the extended public key is consistent with the extended public key result above, but the fingerprint is different. I don't know why
4 Reply Quote Share
gr3g.0rbitHero Member
Posts: 1025 · Reputation: 2646
#4Jun 2, 2025, 07:34 PM
The problem is: your code is using the "Extended Private Key" at m/86'/1'/0' derivation path. Which has the fingerprint de404428.prvKey: 072439bb6c3508a0b583c781a1fb787d173ea7619866d86a1d32d10be0310fa4 pubKey: 0330104bf9b299b41c775842dc22f26b420ce36e0787104bbc6ce2472f3447f88b SHA256: 459c1f0d9f68e849dc245a8910763a0752358f2eb9fc3b797032ddc3917e1502 RIPEMD160: de4044283b4e32a35e1adfe6001a24eaf3fa8f76 Fingerprint: de404428It has to be the "Master Private Key" which is the "m" in the derivation path.
4 Reply Quote Share
bear100Member
Posts: 11 · Reputation: 90
#5Jun 4, 2025, 02:59 PM
But the final value submitted is [133a3b35/86h/1h/0h]tpubDCynnv7orn7ymby6QpWMgw9DwJahdDzzgxARwSd4ipdJ9rv5na4ppub8Pv6346pWtigrNMFrnau uCgcsx1SrtaWqNuELKFGTeZYvAVhX3ES/ The extended public key is correct, but the fingerprint is incorrect
4 Reply Quote Share
bear100Member
Posts: 11 · Reputation: 90
#6Jun 4, 2025, 06:42 PM
Are there other different private keys?
2 Reply Quote Share
bear100Member
Posts: 11 · Reputation: 90
#7Jun 4, 2025, 09:33 PM
Thank you for your help. After testing, I successfully tested 133a3b3
0 Reply Quote Share
gr3g.0rbitHero Member
Posts: 1025 · Reputation: 2646
#8Jun 5, 2025, 03:17 AM
In case this still isn't clear: The other private keys at the lower hierarchy of the derivation path other than "m" (Master Private Key) are its children private keys, And if that children private key is used to derive its own children, it's called "Extended Private Key". e.g.: If we put those terms on the xprv key in your derivation path, it's: m/86'/1'/0' = master_prvKey/extended_prvKey/extended_prvKey/extended_prvKey In that sample descriptor: The Master Fingerprint represents the Master Private Key and not the private pair (Extended Private Key) of the displayed Extended Public key. (notice that it's positioned where the "m" should be in the derivation path) Glad that you figured it out.
1 Reply Quote Share

Related topics