Last active
March 7, 2019 04:57
-
-
Save shemnon/d1de679dcd7012d07fed70d6ba95dacd to your computer and use it in GitHub Desktop.
Utility to extract a Bip44 key phrase from any text document, talking the first 12 words in the document that are also bip44 seed words.
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
package tech.pegasys.benchmark; | |
import java.io.IOException; | |
import java.nio.file.Files; | |
import java.nio.file.Paths; | |
import java.util.Collections; | |
import java.util.List; | |
import java.util.TreeSet; | |
import java.util.stream.Collectors; | |
import java.util.stream.StreamSupport; | |
import com.google.common.base.Splitter; | |
import org.bitcoinj.crypto.MnemonicCode; | |
import org.bitcoinj.crypto.MnemonicException; | |
public class TextToBip44 { | |
/** | |
* Extracts the first Bip44 key from a document. | |
* | |
* @param args [0] - the BIP44 master list, [1] the document you want words from | |
*/ | |
public static void main(final String[] args) throws IOException, MnemonicException { | |
final List<String> wordList = Files.lines(Paths.get(args[0])).collect(Collectors.toList()); | |
final TreeSet<String> wordSet = new TreeSet<>(wordList); | |
final List<String> words = | |
Files.lines(Paths.get(args[1])) | |
.flatMap( | |
s -> | |
StreamSupport.stream( | |
Splitter.onPattern("[^a-zA-Z]+").split(s).spliterator(), false)) | |
.map(String::toLowerCase) | |
.filter(wordSet::contains) | |
.limit(12) | |
.collect(Collectors.toList()); | |
// This is MnenomicCode::toEntropy with the checksum check removed | |
final int concatLenBits = words.size() * 11; | |
final boolean[] concatBits = new boolean[concatLenBits]; | |
int wordindex = 0; | |
for (final String word : words) { | |
// Find the words index in the wordlist. | |
final int ndx = Collections.binarySearch(wordList, word); | |
if (ndx < 0) throw new MnemonicException.MnemonicWordException(word); | |
// Set the next 11 bits to the value of the index. | |
for (int ii = 0; ii < 11; ++ii) | |
concatBits[(wordindex * 11) + ii] = (ndx & (1 << (10 - ii))) != 0; | |
++wordindex; | |
} | |
final int checksumLengthBits = concatLenBits / 33; | |
final int entropyLengthBits = concatLenBits - checksumLengthBits; | |
final byte[] entropy = new byte[entropyLengthBits / 8]; | |
for (int ii = 0; ii < entropy.length; ++ii) | |
for (int jj = 0; jj < 8; ++jj) if (concatBits[(ii * 8) + jj]) entropy[ii] |= 1 << (7 - jj); | |
// end MnemonicCode::toEntropy | |
System.out.println(MnemonicCode.INSTANCE.toMnemonic(entropy)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment