`gestdescriptorinfo` ignores hardened paths in origin info for computing the checksum (therefore returns invalid checksums) #24317

issue darosior opened this issue on February 11, 2022
  1. darosior commented at 2:56 PM on February 11, 2022: member

    Let's say i have two xpubs, derived at m/1'/2'/3'/0 from a master xpub. I'd like to create a descriptor describing a multisig between those 2 keys.

    I create a descriptor wallet

    $ bcreg1 -named createwallet wallet_name=repro disable_private_keys=true descriptors=true
    {
      "name": "repro",
      "warning": ""
    }
    

    Since i won't compute the checksum by hand i use the hack of getting it from getdescriptorinfo

    $ bcreg1 getdescriptorinfo "wsh(multi(2,[0a0a0a0a/1'/2'/3'/0]tpubD6NzVbkrYhZ4WkU5UCcpShsnkYoYPSH9Lor6Kg7J6ytgCjcrpZKtpLPT4NtWLoVirjiWPhgupH1V1UkKaTJoFCRPbcZwMN6kxepTUzKg6mM/*,[bbbbbbbb/1'/2'/3'/0]tpubD6NzVbkrYhZ4Xm62aaUb6DiTMqnnbQNKQsBddsiHwx2Q2KaqYApSCizhyZcEaCRSvr5QSZKuF53pJ6ZQcRzFFDJ6HaKAkpdJAfZt8h1ZzDz/*))"
    {
      "descriptor": "wsh(multi(2,[0a0a0a0a/1'/2'/3'/0]tpubD6NzVbkrYhZ4WkU5UCcpShsnkYoYPSH9Lor6Kg7J6ytgCjcrpZKtpLPT4NtWLoVirjiWPhgupH1V1UkKaTJoFCRPbcZwMN6kxepTUzKg6mM/*,[bbbbbbbb/1'/2'/3'/0]tpubD6NzVbkrYhZ4Xm62aaUb6DiTMqnnbQNKQsBddsiHwx2Q2KaqYApSCizhyZcEaCRSvr5QSZKuF53pJ6ZQcRzFFDJ6HaKAkpdJAfZt8h1ZzDz/*))#hs0kuwwv",
      "checksum": "hs0kuwwv",
      "isrange": true,
      "issolvable": true,
      "hasprivatekeys": false
    }
    

    Now i use the output of getdescriptorinfo to import the descriptor and...

    $ bcreg1 -rpcwallet=repro importdescriptors '[{"desc":"wsh(multi(2,[0a0a0a0a/1'/2'/3'/0]tpubD6NzVbkrYhZ4WkU5UCcpShsnkYoYPSH9Lor6Kg7J6ytgCjcrpZKtpLPT4NtWLoVirjiWPhgupH1V1UkKaTJoFCRPbcZwMN6kxepTUzKg6mM/*,[bbbbbbbb/1'/2'/3'/0]tpubD6NzVbkrYhZ4Xm62aaUb6DiTMqnnbQNKQsBddsiHwx2Q2KaqYApSCizhyZcEaCRSvr5QSZKuF53pJ6ZQcRzFFDJ6HaKAkpdJAfZt8h1ZzDz/*))#hs0kuwwv","timestamp":"now"}]'
    [
      {
        "success": false,
        "error": {
          "code": -5,
          "message": "Provided checksum 'hs0kuwwv' does not match computed checksum 'rgsu3znf'"
        }
      }
    ]
    

    Hmm. Turns out the checksum getdescriptorinfo gave me is invalid (both in the "descriptor" and "checksum" fields). I remember some discussions around canonicalization and the h vs ' notation for hardened paths, so i try by using h instead.

    $ bcreg1 getdescriptorinfo "wsh(multi(2,[0a0a0a0a/1h/2h/3h/0]tpubD6NzVbkrYhZ4WkU5UCcpShsnkYoYPSH9Lor6Kg7J6ytgCjcrpZKtpLPT4NtWLoVirjiWPhgupH1V1UkKaTJoFCRPbcZwMN6kxepTUzKg6mM/*,[bbbbbbbb/1h/2h/3h/0]tpubD6NzVbkrYhZ4Xm62aaUb6DiTMqnnbQNKQsBddsiHwx2Q2KaqYApSCizhyZcEaCRSvr5QSZKuF53pJ6ZQcRzFFDJ6HaKAkpdJAfZt8h1ZzDz/*))"
    {
      "descriptor": "wsh(multi(2,[0a0a0a0a/1'/2'/3'/0]tpubD6NzVbkrYhZ4WkU5UCcpShsnkYoYPSH9Lor6Kg7J6ytgCjcrpZKtpLPT4NtWLoVirjiWPhgupH1V1UkKaTJoFCRPbcZwMN6kxepTUzKg6mM/*,[bbbbbbbb/1'/2'/3'/0]tpubD6NzVbkrYhZ4Xm62aaUb6DiTMqnnbQNKQsBddsiHwx2Q2KaqYApSCizhyZcEaCRSvr5QSZKuF53pJ6ZQcRzFFDJ6HaKAkpdJAfZt8h1ZzDz/*))#hs0kuwwv",
      "checksum": "6nuh6ujc",
      "isrange": true,
      "issolvable": true,
      "hasprivatekeys": false
    }
    

    It outputs the same invalid descriptor in the "descriptor" field. Fortunately the checksum in "checksum" is actually valid, so i can use that in importdescriptors.

    Maybe worth mentioning, before trying on latest master i had an additional issue with 22.0 where getdescriptorinfo would literally remove the hardened paths from the origin info:

    $ bc getdescriptorinfo 'wsh(sortedmulti(2,[f4d84203/48'/0'/0']xpub6BqGLdDLrAeSfoaxcU4VPLrLjWnVAdTcE1jFaocxupbqpyU6tdUA6nZoU17RrYQaGxpjWh7eLempM6W8d6C4p5siF8rWvgvwnASKyzKn14S/0/*,[ff620a62/48'/0'/0']xpub6C7cPJJsmrM6hQuqX2DEdqn38VF2csDeC5BmQbSzpga4EP64V211hYSCSStkFKnELchieG2WKMckrKRdHrUjeaCbRszHJJ7nP4E68rPViPE/0/*))'        
    {                                                                                                                                                                                                                                                                                                                                                                          
      "descriptor": "wsh(sortedmulti(2,[f4d84203/48/0/0]xpub6BqGLdDLrAeSfoaxcU4VPLrLjWnVAdTcE1jFaocxupbqpyU6tdUA6nZoU17RrYQaGxpjWh7eLempM6W8d6C4p5siF8rWvgvwnASKyzKn14S/0/*,[ff620a62/48/0/0]xpub6C7cPJJsmrM6hQuqX2DEdqn38VF2csDeC5BmQbSzpga4EP64V211hYSCSStkFKnELchieG2WKMckrKRdHrUjeaCbRszHJJ7nP4E68rPViPE/0/*))#kvvtf4uz",                                                  
      "checksum": "kvvtf4uz",                                                                                                                                                                                                                                                                                                                                                  
      "isrange": true,                                                                                                                                                                                                                                                                                                                                                         
      "issolvable": true,                                                                                                                                                                                                                                                                                                                                                      
      "hasprivatekeys": false                                                                                                                                                                                                                                                                                                                                                  
    }
    

    So maybe the bad checksum above was the checksum without the hardened paths?

    $ bcreg1 getdescriptorinfo "wsh(multi(2,[0a0a0a0a/1/2/3/0]tpubD6NzVbkrYhZ4WkU5UCcpShsnkYoYPSH9Lor6Kg7J6ytgCjcrpZKtpLPT4NtWLoVirjiWPhgupH1V1UkKaTJoFCRPbcZwMN6kxepTUzKg6mM/*,[bbbbbbbb/1/2/3/0]tpubD6NzVbkrYhZ4Xm62aaUb6DiTMqnnbQNKQsBddsiHwx2Q2KaqYApSCizhyZcEaCRSvr5QSZKuF53pJ6ZQcRzFFDJ6HaKAkpdJAfZt8h1ZzDz/*))"                     
    
    {
      "descriptor": "wsh(multi(2,[0a0a0a0a/1/2/3/0]tpubD6NzVbkrYhZ4WkU5UCcpShsnkYoYPSH9Lor6Kg7J6ytgCjcrpZKtpLPT4NtWLoVirjiWPhgupH1V1UkKaTJoFCRPbcZwMN6kxepTUzKg6mM/*,[bbbbbbbb/1/2/3/0]tpubD6NzVbkrYhZ4Xm62aaUb6DiTMqnnbQNKQsBddsiHwx2Q2KaqYApSCizhyZcEaCRSvr5QSZKuF53pJ6ZQcRzFFDJ6HaKAkpdJAfZt8h1ZzDz/*))#rgsu3znf",
      "checksum": "rgsu3znf",
      "isrange": true,
      "issolvable": true,
      "hasprivatekeys": false
    }
    

    Bingo!

  2. darosior added the label Bug on Feb 11, 2022
  3. darosior renamed this:
    `gestdescriptorinfo` gives bad checksums for hardened paths in origin info
    `gestdescriptorinfo` ignores hardened paths in origin info for computing the checksum (therefore returns invalid checksums)
    on Feb 11, 2022
  4. achow101 commented at 11:35 PM on February 21, 2022: member

    Does this happen with all descriptors that have hardened steps in the origin or just some descriptors?

    Are you sure this happens on master? I tried the example failing import, and it works fine.

  5. fanquake commented at 3:20 PM on August 15, 2022: member

    @darosior are you able to follow up to the questions posted here?

  6. darosior commented at 4:46 PM on August 16, 2022: member

    Yes, i plan to come back to this soon.

  7. darosior commented at 4:49 PM on September 16, 2022: member

    Indeed it's fixed on master. Closing this.

  8. darosior closed this on Sep 16, 2022

  9. bitcoin locked this on Sep 16, 2023
Labels

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-02 09:14 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me