Post
Topic
Board Bitcoin Technical Support
Merits 1 from 1 user
Re: My private key doesn't link to my corresponding bitcoin adddress - please help!
by
PowerGlove
on 14/11/2024, 02:44:43 UTC
⭐ Merited by Cricktor (1)
There's a chance here that Blockchain messed-up the WIF private key's encoding where it should be without the compressed byte flag.
Nice catch!

For the next time this comes up, here's a little standard-library-only Python script that converts a compressed WIF into an uncompressed one:

Code:
#!/usr/bin/env python3

# uncompress_wif.py v2024.11.14 (https://bitcointalk.org/index.php?action=profile;u=3486361)

import sys

from hashlib import sha256

from functools import reduce

def main(args):

    alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

    if len(args) != 1 or not all(char in alphabet for char in args[0]) or len(args[0]) != 52 or args[0][0] not in {'K', 'L'}:

        sys.exit('Huh? Gimme a compressed WIF.')

    unbased = reduce(lambda a, b: a * 58 + b, (alphabet.index(char) for char in args[0]))

    if unbased & 2**32-1 != int.from_bytes(sha256(sha256((unbased >> 32).to_bytes(34, 'big')).digest()).digest()[:4], 'big'):

        sys.exit('Bad checksum. Maybe you mistyped your WIF?')

    scalar = unbased >> 40 & 2**256-1

    versioned = 0x80 << 256 | scalar

    checksum = int.from_bytes(sha256(sha256(versioned.to_bytes(33, 'big')).digest()).digest()[:4], 'big')

    combined = versioned << 32 | checksum

    output = ''.join(alphabet[scale % 58] for scale in (combined // 58**index for index in range(51)))[::-1]

    print(f'Uncompressed WIF: {output}')

if __name__ == '__main__':

    main(sys.argv[1:])

That Ian Coleman page/tool that you pointed to works well, but, for this particular problem, it's both massive (~2 megs of code to check/audit) and it's just too tempting for newbies to use while still online...

Really, all the OP needed was a concise, offline-only tool to correct Blockchain.com's (stupid) mistake. So, what they could have done is booted into Tails (making sure at the welcome screen to select "Disable all networking" under "Additional Settings -> Offline Mode"), and then used the above script (copied into /home/amnesia from a second USB stick) to get the correct WIF, like this:

Code:
$ python3 uncompress_wif.py L2Wbv5pGcwhaThC8ZAmcUbQqMGzwJMgMideQVhKtnrDDVeCx16ZJ
Uncompressed WIF: 5K1pLH3Z5yM4xSRGkzVgkrwLZgsjfNT8sDP4xtjLtd58N3rx2na

@OP: I'm glad that you managed to successfully sweep your funds! Remember, if you're ever holding a large bag, it's worth looking into hardware wallets or (my preference) looking into how to use something like Electrum in such a way that you can create a transaction using an online machine (without exposing your private key to it), and then sign that transaction using a different, encrypted, strictly-offline machine (and then broadcast the now-signed transaction using the first, Internet-connected machine; I know that that all sounds like a huge PITA, and it kind of is, but nothing beats basically knowing that your offline-generated private keys have never, ever been exposed to the Internet).