3

I have a long list of 1million+ permutations of a 12 word BIP39 seed. How can I try them all on a bitcoin address?

edit: I know the address and the 12 words but i don't know the order of the words

11
  • @JunaidShaikh I'm not asking if it is possible. I am asking for a specific tool to do it. And I only need to try 12 words not 1024 different words May 19, 2018 at 17:51
  • This isn't an exact duplicate - It's a lot more feasible to try all combinations of words if you know they are all in the seed (although this breaks down for 24+ words). May 19, 2018 at 17:52
  • @code511788465541441 Do you know the address you are looking for, and the derivation path which would lead to it? May 19, 2018 at 17:52
  • @RaghavSood yes i know the address and the words May 19, 2018 at 17:53

1 Answer 1

7

Doing this requires three things:

  1. Permutations of the seed words
  2. The address you're trying to locate
  3. The derivation path for that address.

In this specific case, the address is the one this puzzle on reddit leads to, so we will assume the derivation path is m/49'/0'/0'/0/0

This is a simple nodejs script using bitcoinjs-lib to read seeds from a file, validate them, and then try the first address against the one you are searching for. You can parallelize it by splitting the input file into pieces and running it once per file.

Do note that 12 words means roughly half a billion combinations. While this is doable with today's computing power, it is still going to take you a very long time. Some quick tests show it would take about 4 days on my laptop, although you may be able to speed it up by using a faster language, or parallelization.

var bip39 = require('bip39');
var bitcoin = require('bitcoinjs-lib')

var lineReader = require('readline').createInterface({
  input: require('fs').createReadStream('addresses.txt')
});
var ctr = 1;
lineReader.on('line', function (line) {
    if (ctr%100 == 0) {
        console.log("Processing #" + ctr);
    }
    if (bip39.validateMnemonic(line)) {
        var roothex = bip39.mnemonicToSeedHex(line);
        var rootnode = bitcoin.HDNode.fromSeedHex(roothex);
        var basechild = rootnode.deriveHardened(49)
                .deriveHardened(0)
                .deriveHardened(0)
                .derive(0);
        for (var i = 0; i < 3; i++) {
            var child = basechild.derive(i);
            var keyhash = bitcoin.crypto.hash160(child.getPublicKeyBuffer())
            var scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash)
            var addressBytes = bitcoin.crypto.hash160(scriptSig)
            var outputScript = bitcoin.script.scriptHash.output.encode(addressBytes)
            var address = bitcoin.address.fromOutputScript(outputScript)
            if (address == "3CcxyPhyvyc3S9UuPfu42GNZLvVVV11Uk8") {
                console.log("Found seed! " + line)
            }
        }
    }
    ctr++;
});

You will need to install nodejs, and bitcoinjs-lib for this.

5
  • Thanks, I'm trying that now. What's the for loop for? May 19, 2018 at 19:06
  • It'll check the first three addresses on every seed, just in case we're wrong about it being the first address. May 19, 2018 at 19:10
  • Any idea why validateMnemonic() returns false for this example 12 word seed string? proof know able order problem end just zero run air agree next May 19, 2018 at 19:22
  • 1
    Because it's an invalid mnemonic. The last word is a checksum. Not all combinations of BIP39 words are valid seeds. The valid mnemonic check will skip a seed if it is invalid, so you don't needlessly process it for addresses. May 19, 2018 at 19:26
  • Thanks a lot. It is a bit slow as you said so I am trying to write it to run in parallel. If I do find the key i'll get in touch :) May 19, 2018 at 19:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.