diff --git a/examples/example_22.conf b/examples/example_22.conf new file mode 100644 index 0000000..fb09d31 --- /dev/null +++ b/examples/example_22.conf @@ -0,0 +1,13 @@ +PERMUTATION_CHECK +bc1q9fdjavqhzdttar9kjchpw3rerkzfs3zvgrwg9e +9 +lady +oblige +cable +hidden +surface +marriage +grit +priority +forget +m/84'/0'/0'/0/0 \ No newline at end of file diff --git a/pom.xml b/pom.xml index ead4a63..d3e32eb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.pawelgorny lostword - 0.13.3 + 0.14.0 jar @@ -23,17 +23,17 @@ com.google.guava guava - 30.0-jre + 31.0.1-jre org.slf4j slf4j-log4j12 - 1.7.26 + 1.7.32 com.google.code.gson gson - 2.8.6 + 2.8.8 @@ -50,21 +50,21 @@ org.apache.maven.plugins maven-jar-plugin - 2.3.2 - - lostWord - + 3.2.0 org.apache.maven.plugins maven-compiler-plugin + 3.8.1 1.8 1.8 + org.apache.maven.plugins maven-assembly-plugin + 3.3.0 @@ -74,7 +74,6 @@ jar-with-dependencies - lostWord diff --git a/src/main/java/com/pawelgorny/lostword/WorkerPermutationCheck.java b/src/main/java/com/pawelgorny/lostword/WorkerPermutationCheck.java index 42415e3..df6e4dd 100644 --- a/src/main/java/com/pawelgorny/lostword/WorkerPermutationCheck.java +++ b/src/main/java/com/pawelgorny/lostword/WorkerPermutationCheck.java @@ -2,11 +2,16 @@ import org.bitcoinj.core.Utils; import org.bitcoinj.crypto.MnemonicException; +import org.bouncycastle.crypto.macs.HMac; import java.security.MessageDigest; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class WorkerPermutationCheck extends Worker{ @@ -28,15 +33,67 @@ public void run() throws InterruptedException, MnemonicException { String[] words = new String[0]; words = configuration.getWORDS().toArray(words); start = System.currentTimeMillis(); - printAllRecursive(configuration.getSIZE(), words); + THREADS = Math.min(THREADS, configuration.getSIZE()); + List> workPerThread = new ArrayList<>(THREADS); + int tIx=0; + for(String w:words){ + if (workPerThread.size()==tIx){ + workPerThread.add(new ArrayList<>(1)); + } + workPerThread.get(tIx).add(w); + tIx=(++tIx%THREADS); + } + final List SHA_256_DIGESTS= new ArrayList<>(THREADS); + final List SHA_512_DIGESTS= new ArrayList<>(THREADS); + + final CountDownLatch latch = new CountDownLatch(THREADS); + final ExecutorService executorService = Executors.newFixedThreadPool(THREADS); + + for(tIx=0; tIx WORDS_TO_WORK = workPerThread.get(tIx); + executorService.submit(() -> { + final HMac LOCAL_SHA_512_DIGEST = SHA_512_DIGESTS.get(T_NUMBER); + final MessageDigest LOCAL_SHA_256_DIGEST = SHA_256_DIGESTS.get(T_NUMBER); + if (REPORTER) { + start = System.currentTimeMillis(); + } + for (String PREFIX : WORDS_TO_WORK) { + if (RESULT != null) { + break; + } + List seedToProcess = new ArrayList<>(configuration.getWORDS()); + for (int i = 0; i < configuration.getSIZE(); i++) { + if (seedToProcess.get(i).equals(PREFIX)) { + seedToProcess.remove(i); + break; + } + } + String[] target = new String[configuration.getSIZE()]; + String[] toProcess = new String[configuration.getSIZE() - 1]; + toProcess = seedToProcess.toArray(toProcess); + target[0] = PREFIX; + checkAllRecursive(configuration.getSIZE() - 1, toProcess, target, LOCAL_SHA_512_DIGEST, LOCAL_SHA_256_DIGEST, REPORTER); + } + latch.countDown(); + }); + } + latch.await(); + executorService.shutdown(); } - private boolean printAllRecursive(int n, String[] elements) { + private boolean checkAllRecursive(int n, String[] elements, final String[] target, HMac LOCAL_SHA_512_DIGEST, MessageDigest LOCAL_SHA_256_DIGEST, Boolean REPORTER) { if(n == 1) { - return checkElements(elements); + return checkElements(target, elements, LOCAL_SHA_512_DIGEST, LOCAL_SHA_256_DIGEST, REPORTER); } else { for(int i = 0; i < n-1; i++) { - if (printAllRecursive(n - 1, elements)){ + if (checkAllRecursive(n - 1, elements, target, LOCAL_SHA_512_DIGEST, LOCAL_SHA_256_DIGEST, REPORTER)){ return true; } if(n % 2 == 0) { @@ -45,24 +102,25 @@ private boolean printAllRecursive(int n, String[] elements) { swap(elements, 0, n - 1); } } - if (printAllRecursive(n - 1, elements)){ + if (checkAllRecursive(n - 1, elements, target, LOCAL_SHA_512_DIGEST, LOCAL_SHA_256_DIGEST, REPORTER)){ return true; } } return RESULT!=null; } - private boolean checkElements(String[] input) { - List mnemonic = Arrays.asList(input); + private boolean checkElements(String[] target, String[] input, HMac LOCAL_SHA_512_DIGEST, MessageDigest LOCAL_SHA_256_DIGEST, Boolean REPORTER) { + System.arraycopy(input,0, target, 1, input.length); + List mnemonic = Arrays.asList(target); try { - boolean result = check(mnemonic, null, SHA_256_DIGEST); + boolean result = check(mnemonic, LOCAL_SHA_512_DIGEST, LOCAL_SHA_256_DIGEST); if (result){ RESULT = new Result(mnemonic); } }catch (MnemonicException e){ System.out.println(e.getLocalizedMessage()); } - if (System.currentTimeMillis()-start > STATUS_PERIOD){ + if (REPORTER && (System.currentTimeMillis()-start > STATUS_PERIOD)){ System.out.println(SDTF.format(new Date())+ " Alive!"); start = System.currentTimeMillis(); }