Last active
May 8, 2017 04:10
-
-
Save gabmontes/1e432d16ce11d2bf99e3e8a7834a8c0d to your computer and use it in GitHub Desktop.
Brute force approach to find desired bitcoin network params
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict' | |
| const bitcore = require('bitcore-lib') | |
| const ROUNDS = 15 | |
| const targetStrings = { | |
| networkMagic: 'mYnT', | |
| pubkeyhash: 'G', | |
| scripthash: '2', | |
| privatekey: 'M', | |
| xprivkey: 'Gprv', | |
| xpubkey: 'Gpub' | |
| } | |
| const maxCount = (list) => Object.keys(list).reduce( | |
| (max, hex) => list[hex] > list[max] ? hex : max | |
| ) | |
| const strToHex = str => '0x' + Number.parseInt(str).toString(16) | |
| function checkAll256Values(createNet, checkString, rounds) { | |
| const list = {} | |
| for (let hex = 0; hex < 256; hex++) { | |
| const network = bitcore.Networks.add(createNet(hex)) | |
| for (let j = 0; j < rounds; j++) { | |
| if (checkString(network)) { | |
| list[hex] = (list[hex] || 0) + 1 | |
| } | |
| } | |
| bitcore.Networks.remove(network) | |
| } | |
| return list | |
| } | |
| function status(msg) { | |
| process.stdout.write(msg + '\r') | |
| } | |
| function mergeLists(shift, prefixes) { | |
| const merged = {} | |
| prefixes.forEach(function (prefix) { | |
| Object.keys(prefix.matches).forEach(function (match) { | |
| merged[prefix.value * (1 << shift) + Number.parseInt(match)] = prefix.matches[match] | |
| }) | |
| }) | |
| return merged | |
| } | |
| // Network magic | |
| const networkMagic = Buffer.from(targetStrings.networkMagic).toString('hex') | |
| console.log('Network magic: 0x' + networkMagic) | |
| // Pubkey hash | |
| const pubkeyhashList = checkAll256Values( | |
| hex => ({ name: 'pkh_' + hex, pubkeyhash: hex }), | |
| network => bitcore.PrivateKey.fromRandom(network).toAddress().toString()[0] === targetStrings.pubkeyhash, | |
| ROUNDS | |
| ) | |
| const pubkeyhash = maxCount(pubkeyhashList) | |
| console.log('Pubkey hash: ' + strToHex(pubkeyhash)) | |
| // Script hash | |
| const scripthashList = checkAll256Values( | |
| hex => ({ name: 'sh_' + hex, scripthash: hex }), | |
| network => bitcore.Address([ | |
| bitcore.PrivateKey.fromRandom(network).toPublicKey() | |
| ], 1).toString()[0] === targetStrings.scripthash, | |
| ROUNDS | |
| ) | |
| const scripthash = maxCount(scripthashList) | |
| console.log('Script hash: ' + strToHex(scripthash)) | |
| // Private key (WIF) | |
| const privatekeyList = checkAll256Values( | |
| hex => ({ name: 'pk_' + hex, privatekey: hex }), | |
| network => bitcore.PrivateKey.fromRandom(network).toWIF()[0] === targetStrings.privatekey, | |
| ROUNDS | |
| ) | |
| const privatekey = maxCount(privatekeyList) | |
| console.log('Compressed private key: ' + strToHex(privatekey)) | |
| // HD private key | |
| const xprivL0List = checkAll256Values( | |
| hex => ({ | |
| name: 'xprivL0_' + hex, | |
| xprivkey: hex * (1 << 24) | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xprivkey) + '...') | |
| return bitcore.HDPrivateKey(network).toString().substr(0, 1) === targetStrings.xprivkey.substr(0, 1) | |
| }, | |
| 1 | |
| ) | |
| const xprivL0Candidates = Object.keys(xprivL0List) | |
| const xprivL1List = mergeLists(8, xprivL0Candidates.map( | |
| xprivL0 => ({ | |
| value: Number.parseInt(xprivL0), | |
| matches: checkAll256Values( | |
| hex => ({ | |
| name: 'xprivL1_' + hex, | |
| xprivkey: xprivL0 * (1 << 24) + hex * (1 << 16) | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xprivkey) + '...') | |
| return bitcore.HDPrivateKey(network).toString().substr(0, 2) === targetStrings.xprivkey.substr(0, 2) | |
| }, | |
| 1 | |
| ) | |
| }) | |
| )) | |
| const xprivL1Candidates = Object.keys(xprivL1List) | |
| const xprivL2List = mergeLists(8, xprivL1Candidates.map( | |
| xprivL1 => ({ | |
| value: Number.parseInt(xprivL1), | |
| matches: checkAll256Values( | |
| hex => ({ | |
| name: 'xprivL2_' + hex, | |
| xprivkey: xprivL1 * (1 << 16) + hex * (1 << 8) | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xprivkey) + '...') | |
| return bitcore.HDPrivateKey(network).toString().substr(0, 3) === targetStrings.xprivkey.substr(0, 3) | |
| }, | |
| 1 | |
| ) | |
| }) | |
| )) | |
| const xprivL2Candidates = Object.keys(xprivL2List) | |
| const xprivL3List = mergeLists(8, xprivL2Candidates.map( | |
| xprivL2 => ({ | |
| value: Number.parseInt(xprivL2), | |
| matches: checkAll256Values( | |
| hex => ({ | |
| name: 'xprivL3_' + hex, | |
| xprivkey: xprivL2 * (1 << 8) + hex | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xprivkey) + '...') | |
| return bitcore.HDPrivateKey(network).toString().substr(0, 4) === targetStrings.xprivkey.substr(0, 4) | |
| }, | |
| 1 | |
| ) | |
| }) | |
| )) | |
| const xprivkeys = Object.keys(xprivL3List) | |
| const xprivkey = xprivkeys.shift() | |
| console.log('HD Private key: ' + strToHex(xprivkey) + ' (to ' + strToHex(xprivkeys.pop()) + ')') | |
| // HD public key | |
| const xpubL0List = checkAll256Values( | |
| hex => ({ | |
| name: 'xpubL0_' + hex, | |
| xprivkey: Number.parseInt(xprivkey), | |
| xpubkey: hex * (1 << 24) | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xpubkey) + '...') | |
| return bitcore.HDPrivateKey(network).hdPublicKey.toString().substr(0, 1) === targetStrings.xpubkey.substr(0, 1) | |
| }, | |
| 1 | |
| ) | |
| const xpubL0Candidates = Object.keys(xpubL0List) | |
| const xpubL1List = mergeLists(8, xpubL0Candidates.map( | |
| xpubL0 => ({ | |
| value: Number.parseInt(xpubL0), | |
| matches: checkAll256Values( | |
| hex => ({ | |
| name: 'xpubL1_' + hex, | |
| xprivkey: Number.parseInt(xprivkey), | |
| xpubkey: xpubL0 * (1 << 24) + hex * (1 << 16) | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xpubkey) + '...') | |
| return bitcore.HDPrivateKey(network).hdPublicKey.toString().substr(0, 2) === targetStrings.xpubkey.substr(0, 2) | |
| }, | |
| 1 | |
| ) | |
| }) | |
| )) | |
| const xpubL1Candidates = Object.keys(xpubL1List) | |
| const xpubL2List = mergeLists(8, xpubL1Candidates.map( | |
| xpubL1 => ({ | |
| value: Number.parseInt(xpubL1), | |
| matches: checkAll256Values( | |
| hex => ({ | |
| name: 'xpubL2_' + hex, | |
| xprivkey: Number.parseInt(xprivkey), | |
| xpubkey: xpubL1 * (1 << 16) + hex * (1 << 8) | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xpubkey) + '...') | |
| return bitcore.HDPrivateKey(network).hdPublicKey.toString().substr(0, 3) === targetStrings.xpubkey.substr(0, 3) | |
| }, | |
| 1 | |
| ) | |
| }) | |
| )) | |
| const xpubL2Candidates = Object.keys(xpubL2List) | |
| const xpubL3List = mergeLists(8, xpubL2Candidates.map( | |
| xpubL2 => ({ | |
| value: Number.parseInt(xpubL2), | |
| matches: checkAll256Values( | |
| hex => ({ | |
| name: 'xpubL3_' + hex, | |
| xprivkey: Number.parseInt(xprivkey), | |
| xpubkey: xpubL2 * (1 << 8) + hex | |
| }), | |
| network => { | |
| status('testing ' + strToHex(network.xpubkey) + '...') | |
| return bitcore.HDPrivateKey(network).hdPublicKey.toString().substr(0, 4) === targetStrings.xpubkey.substr(0, 4) | |
| }, | |
| 1 | |
| ) | |
| }) | |
| )) | |
| const xpubkeys = Object.keys(xpubL3List) | |
| const xpubkey = xpubkeys.shift() | |
| console.log('HD Public key: ' + strToHex(xpubkey) + ' (to ' + strToHex(xpubkeys.pop()) + ')') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment