Implementing the method suggest that will provide us with a fresh new brainkey

This commit is contained in:
Nelson R. Perez 2016-11-23 12:20:24 -05:00
parent f5065b215b
commit 27c864ebd9
4 changed files with 93 additions and 26 deletions

View file

@ -1,27 +1,64 @@
package com.luminiasoft.bitshares; package com.luminiasoft.bitshares;
import org.bitcoinj.core.Base58; import com.luminiasoft.bitshares.crypto.AndroidRandomSource;
import org.bitcoinj.core.DumpedPrivateKey; import com.luminiasoft.bitshares.crypto.SecureRandomStrengthener;
import org.bitcoinj.core.ECKey; import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Base64;
/** /**
* Created by nelson on 11/19/16. * Class used to encapsulate all BrainKey-related operations.
*/ */
public class BrainKey { public class BrainKey {
// The size of the word dictionary
public static final int DICT_WORD_COUNT = 49744;
// The required number of words
public static final int BRAINKEY_WORD_COUNT = 12;
private ECKey mPrivateKey; private ECKey mPrivateKey;
/**
* Method that will generate a random brain key
* @param words The list of words from the graphene specification dictionary.
* @return A random sequence of words
*/
public static String suggest(String words){
String[] wordArray = words.split(",");
ArrayList<String> suggestedBrainKey = new ArrayList<String>();
assert(wordArray.length == DICT_WORD_COUNT);
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
randomStrengthener.addEntropySource(new AndroidRandomSource());
SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator();
int index;
for(int i = 0; i < BRAINKEY_WORD_COUNT; i++){
index = secureRandom.nextInt(DICT_WORD_COUNT - 1);
suggestedBrainKey.add(wordArray[index].toUpperCase());
}
String result = String.join(" ", suggestedBrainKey.toArray(new String[suggestedBrainKey.size()]));
System.out.println("result: '"+result+"'");
return result;
}
/**
* BrainKey constructor that takes as argument a specific brain key word sequence and generates the
* private key and address from that.
* @param words The brain key specifying the private key
* @param sequence Sequence number
*/
public BrainKey(String words, int sequence) { public BrainKey(String words, int sequence) {
String encoded = String.format("%s %d", words, sequence); String encoded = String.format("%s %d", words, sequence);
try { try {
MessageDigest sha512 = MessageDigest.getInstance("SHA-512"); MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] bytes = md.digest(encoded.getBytes("UTF-8"));
MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
mPrivateKey = ECKey.fromPrivate(sha256.digest(sha512.digest(encoded.getBytes("UTF-8")))); byte[] result = sha256.digest(bytes);
mPrivateKey = ECKey.fromPrivate(result);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgotithmException. Msg: " + e.getMessage()); System.out.println("NoSuchAlgotithmException. Msg: " + e.getMessage());
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
@ -29,7 +66,11 @@ public class BrainKey {
} }
} }
public String getPublicKey() {
return Base64.getEncoder().encodeToString(mPrivateKey.getPubKey());
}
public ECKey getPrivateKey(){ public ECKey getPrivateKey(){
return this.mPrivateKey; return mPrivateKey;
} }
} }

View file

@ -16,9 +16,10 @@ import org.spongycastle.crypto.Digest;
import org.spongycastle.crypto.digests.SHA512Digest; import org.spongycastle.crypto.digests.SHA512Digest;
import org.spongycastle.crypto.prng.DigestRandomGenerator; import org.spongycastle.crypto.prng.DigestRandomGenerator;
import java.io.IOException; import java.io.*;
import java.io.Serializable;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.net.URL;
import java.nio.file.Paths;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
@ -503,6 +504,14 @@ public class Test {
* into the WIF at Main.WIF * into the WIF at Main.WIF
*/ */
public void testBrainKeyOperations(){ public void testBrainKeyOperations(){
try {
String current = new java.io.File( "." ).getCanonicalPath();
File file = new File(current + "/src/main/java/com/luminiasoft/bitshares/brainkeydict.txt");
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
StringBuffer buffer = new StringBuffer();
String words = bufferedReader.readLine();
String suggestion = BrainKey.suggest(words);
BrainKey brainKey = new BrainKey(Main.BRAIN_KEY, 0); BrainKey brainKey = new BrainKey(Main.BRAIN_KEY, 0);
ECKey key = brainKey.getPrivateKey(); ECKey key = brainKey.getPrivateKey();
String wif = key.getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET)); String wif = key.getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
@ -520,6 +529,12 @@ public class Test {
byte[] pubKey3 = key.getPubKeyPoint().getEncoded(true); byte[] pubKey3 = key.getPubKeyPoint().getEncoded(true);
System.out.println("pub key compressed : "+Base58.encode(pubKey3)); System.out.println("pub key compressed : "+Base58.encode(pubKey3));
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException. Msg: "+e.getMessage());
} catch (IOException e) {
System.out.println("IOException. Msg: "+e.getMessage());
}
} }
} }

File diff suppressed because one or more lines are too long

View file

@ -38,9 +38,10 @@ import java.io.DataInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer;
public class AndroidRandomSource implements RandomSource { public class AndroidRandomSource implements RandomSource, EntropySource {
@Override @Override
public synchronized void nextBytes(byte[] bytes) { public synchronized void nextBytes(byte[] bytes) {
@ -58,4 +59,13 @@ public class AndroidRandomSource implements RandomSource {
throw new RuntimeException("Unable to generate random bytes on this Android device", e); throw new RuntimeException("Unable to generate random bytes on this Android device", e);
} }
} }
@Override
public ByteBuffer provideEntropy() {
byte[] buffer = new byte[ 256 / 8];
nextBytes(buffer);
ByteBuffer byteBuffer = ByteBuffer.allocate(buffer.length);
byteBuffer.put(buffer, 0, buffer.length);
return byteBuffer;
}
} }