2016-11-23 14:26:25 +00:00
|
|
|
package com.luminiasoft.bitshares;
|
|
|
|
|
2016-11-23 17:20:24 +00:00
|
|
|
import com.luminiasoft.bitshares.crypto.AndroidRandomSource;
|
|
|
|
import com.luminiasoft.bitshares.crypto.SecureRandomStrengthener;
|
2016-11-23 14:26:25 +00:00
|
|
|
import org.bitcoinj.core.ECKey;
|
|
|
|
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
|
import java.security.MessageDigest;
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
2016-11-23 17:20:24 +00:00
|
|
|
import java.security.SecureRandom;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Base64;
|
2016-11-23 19:50:21 +00:00
|
|
|
import org.bitcoinj.core.Base58;
|
|
|
|
import org.bitcoinj.core.BitcoinSerializer;
|
|
|
|
import org.bitcoinj.core.Block;
|
|
|
|
import org.bitcoinj.core.Coin;
|
|
|
|
import org.bitcoinj.core.NetworkParameters;
|
|
|
|
import org.bitcoinj.core.StoredBlock;
|
|
|
|
import org.bitcoinj.core.VerificationException;
|
|
|
|
import org.bitcoinj.store.BlockStore;
|
|
|
|
import org.bitcoinj.store.BlockStoreException;
|
|
|
|
import org.bitcoinj.utils.MonetaryFormat;
|
|
|
|
import org.spongycastle.crypto.digests.RIPEMD160Digest;
|
|
|
|
import org.spongycastle.crypto.digests.SHA512Digest;
|
2016-11-23 14:26:25 +00:00
|
|
|
|
|
|
|
/**
|
2016-11-23 17:20:24 +00:00
|
|
|
* Class used to encapsulate all BrainKey-related operations.
|
2016-11-23 14:26:25 +00:00
|
|
|
*/
|
|
|
|
public class BrainKey {
|
2016-11-23 19:50:21 +00:00
|
|
|
|
2016-11-23 17:20:24 +00:00
|
|
|
// 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;
|
2016-11-23 14:26:25 +00:00
|
|
|
|
|
|
|
private ECKey mPrivateKey;
|
|
|
|
|
2016-11-23 17:20:24 +00:00
|
|
|
/**
|
|
|
|
* Method that will generate a random brain key
|
2016-11-23 19:50:21 +00:00
|
|
|
*
|
|
|
|
* @param words The list of words from the graphene specification
|
|
|
|
* dictionary.
|
2016-11-23 17:20:24 +00:00
|
|
|
* @return A random sequence of words
|
|
|
|
*/
|
2016-11-23 19:50:21 +00:00
|
|
|
public static String suggest(String words) {
|
2016-11-23 17:20:24 +00:00
|
|
|
String[] wordArray = words.split(",");
|
|
|
|
ArrayList<String> suggestedBrainKey = new ArrayList<String>();
|
2016-11-23 19:50:21 +00:00
|
|
|
assert (wordArray.length == DICT_WORD_COUNT);
|
2016-11-23 17:20:24 +00:00
|
|
|
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
|
|
|
|
randomStrengthener.addEntropySource(new AndroidRandomSource());
|
|
|
|
SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator();
|
|
|
|
int index;
|
2016-11-23 19:50:21 +00:00
|
|
|
for (int i = 0; i < BRAINKEY_WORD_COUNT; i++) {
|
2016-11-23 17:20:24 +00:00
|
|
|
index = secureRandom.nextInt(DICT_WORD_COUNT - 1);
|
|
|
|
suggestedBrainKey.add(wordArray[index].toUpperCase());
|
|
|
|
}
|
|
|
|
String result = String.join(" ", suggestedBrainKey.toArray(new String[suggestedBrainKey.size()]));
|
2016-11-23 19:50:21 +00:00
|
|
|
System.out.println("result: '" + result + "'");
|
2016-11-23 17:20:24 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-11-23 19:50:21 +00:00
|
|
|
* BrainKey constructor that takes as argument a specific brain key word
|
|
|
|
* sequence and generates the private key and address from that.
|
|
|
|
*
|
2016-11-23 17:20:24 +00:00
|
|
|
* @param words The brain key specifying the private key
|
|
|
|
* @param sequence Sequence number
|
|
|
|
*/
|
2016-11-23 14:26:25 +00:00
|
|
|
public BrainKey(String words, int sequence) {
|
|
|
|
String encoded = String.format("%s %d", words, sequence);
|
|
|
|
try {
|
2016-11-23 17:20:24 +00:00
|
|
|
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
|
|
|
byte[] bytes = md.digest(encoded.getBytes("UTF-8"));
|
2016-11-23 14:26:25 +00:00
|
|
|
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
2016-11-23 17:20:24 +00:00
|
|
|
byte[] result = sha256.digest(bytes);
|
|
|
|
mPrivateKey = ECKey.fromPrivate(result);
|
2016-11-23 19:50:21 +00:00
|
|
|
|
2016-11-23 14:26:25 +00:00
|
|
|
} catch (NoSuchAlgorithmException e) {
|
|
|
|
System.out.println("NoSuchAlgotithmException. Msg: " + e.getMessage());
|
|
|
|
} catch (UnsupportedEncodingException e) {
|
|
|
|
System.out.println("UnsupportedEncodingException. Msg: " + e.getMessage());
|
|
|
|
}
|
|
|
|
}
|
2016-11-23 19:50:21 +00:00
|
|
|
public byte[] getPublicKey() {
|
|
|
|
return mPrivateKey.getPubKey();
|
2016-11-23 17:20:24 +00:00
|
|
|
}
|
|
|
|
|
2016-11-23 19:50:21 +00:00
|
|
|
public ECKey getPrivateKey() {
|
2016-11-23 17:20:24 +00:00
|
|
|
return mPrivateKey;
|
2016-11-23 14:26:25 +00:00
|
|
|
}
|
2016-11-23 19:50:21 +00:00
|
|
|
}
|