Merging differences
This commit is contained in:
commit
95f19b7b74
4 changed files with 179 additions and 36 deletions
|
@ -2,9 +2,12 @@ package com.luminiasoft.bitshares;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
import org.bitcoinj.core.Base58;
|
||||||
import org.bitcoinj.core.ECKey;
|
import org.bitcoinj.core.ECKey;
|
||||||
import org.bitcoinj.crypto.HDKeyDerivation;
|
import org.bitcoinj.crypto.HDKeyDerivation;
|
||||||
import org.bitcoinj.crypto.MnemonicCode;
|
import org.bitcoinj.crypto.MnemonicCode;
|
||||||
|
import org.spongycastle.crypto.digests.RIPEMD160Digest;
|
||||||
|
import org.spongycastle.crypto.digests.SHA512Digest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -12,7 +15,7 @@ import org.bitcoinj.crypto.MnemonicCode;
|
||||||
*/
|
*/
|
||||||
public class BIP39 {
|
public class BIP39 {
|
||||||
|
|
||||||
private ECKey mPrivateKey;
|
private final ECKey mPrivateKey;
|
||||||
|
|
||||||
public BIP39(String words, String passphrase) {
|
public BIP39(String words, String passphrase) {
|
||||||
|
|
||||||
|
@ -21,8 +24,56 @@ public class BIP39 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPublicKey() {
|
public String getUncompressedAddress() {
|
||||||
return Base64.getEncoder().encodeToString(mPrivateKey.getPubKey());
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
|
SHA512Digest sha512Digest = new SHA512Digest();
|
||||||
|
sha512Digest.update(mPrivateKey.decompress().getPubKey(), 0, mPrivateKey.decompress().getPubKey().length);
|
||||||
|
byte[] intermediate = new byte[512 / 8];
|
||||||
|
sha512Digest.doFinal(intermediate, 0);
|
||||||
|
ripemd160Digest.update(intermediate, 0, intermediate.length);
|
||||||
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
String encoded = Base58.encode(output);
|
||||||
|
byte[] checksum = new byte[(160 / 8) + 4];
|
||||||
|
System.arraycopy(calculateChecksum(output), 0, checksum, checksum.length - 4, 4);
|
||||||
|
System.arraycopy(output, 0, checksum, 0, output.length);
|
||||||
|
|
||||||
|
return ("BTS" + Base58.encode(checksum));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
|
SHA512Digest sha512Digest = new SHA512Digest();
|
||||||
|
sha512Digest.update(mPrivateKey.getPubKey(), 0, mPrivateKey.getPubKey().length);
|
||||||
|
byte[] intermediate = new byte[512 / 8];
|
||||||
|
sha512Digest.doFinal(intermediate, 0);
|
||||||
|
ripemd160Digest.update(intermediate, 0, intermediate.length);
|
||||||
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
String encoded = Base58.encode(output);
|
||||||
|
byte[] checksum = new byte[(160 / 8) + 4];
|
||||||
|
System.arraycopy(calculateChecksum(output), 0, checksum, checksum.length - 4, 4);
|
||||||
|
System.arraycopy(output, 0, checksum, 0, output.length);
|
||||||
|
|
||||||
|
return ("BTS" + Base58.encode(checksum));
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] calculateChecksum(byte[] input) {
|
||||||
|
byte[] answer = new byte[4];
|
||||||
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
|
ripemd160Digest.update(input, 0, input.length);
|
||||||
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
System.arraycopy(output, 0, answer, 0, 4);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getPublicKey() {
|
||||||
|
return mPrivateKey.getPubKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ECKey getPrivateKey() {
|
||||||
|
return mPrivateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,24 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to encapsulate all BrainKey-related operations.
|
* Class used to encapsulate all BrainKey-related operations.
|
||||||
*/
|
*/
|
||||||
public class BrainKey {
|
public class BrainKey {
|
||||||
|
|
||||||
// The size of the word dictionary
|
// The size of the word dictionary
|
||||||
public static final int DICT_WORD_COUNT = 49744;
|
public static final int DICT_WORD_COUNT = 49744;
|
||||||
|
|
||||||
|
@ -25,29 +38,32 @@ public class BrainKey {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that will generate a random brain key
|
* Method that will generate a random brain key
|
||||||
* @param words The list of words from the graphene specification dictionary.
|
*
|
||||||
|
* @param words The list of words from the graphene specification
|
||||||
|
* dictionary.
|
||||||
* @return A random sequence of words
|
* @return A random sequence of words
|
||||||
*/
|
*/
|
||||||
public static String suggest(String words){
|
public static String suggest(String words) {
|
||||||
String[] wordArray = words.split(",");
|
String[] wordArray = words.split(",");
|
||||||
ArrayList<String> suggestedBrainKey = new ArrayList<String>();
|
ArrayList<String> suggestedBrainKey = new ArrayList<String>();
|
||||||
assert(wordArray.length == DICT_WORD_COUNT);
|
assert (wordArray.length == DICT_WORD_COUNT);
|
||||||
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
|
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
|
||||||
randomStrengthener.addEntropySource(new AndroidRandomSource());
|
randomStrengthener.addEntropySource(new AndroidRandomSource());
|
||||||
SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator();
|
SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator();
|
||||||
int index;
|
int index;
|
||||||
for(int i = 0; i < BRAINKEY_WORD_COUNT; i++){
|
for (int i = 0; i < BRAINKEY_WORD_COUNT; i++) {
|
||||||
index = secureRandom.nextInt(DICT_WORD_COUNT - 1);
|
index = secureRandom.nextInt(DICT_WORD_COUNT - 1);
|
||||||
suggestedBrainKey.add(wordArray[index].toUpperCase());
|
suggestedBrainKey.add(wordArray[index].toUpperCase());
|
||||||
}
|
}
|
||||||
String result = String.join(" ", suggestedBrainKey.toArray(new String[suggestedBrainKey.size()]));
|
String result = String.join(" ", suggestedBrainKey.toArray(new String[suggestedBrainKey.size()]));
|
||||||
System.out.println("result: '"+result+"'");
|
System.out.println("result: '" + result + "'");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BrainKey constructor that takes as argument a specific brain key word sequence and generates the
|
* BrainKey constructor that takes as argument a specific brain key word
|
||||||
* private key and address from that.
|
* sequence and generates the private key and address from that.
|
||||||
|
*
|
||||||
* @param words The brain key specifying the private key
|
* @param words The brain key specifying the private key
|
||||||
* @param sequence Sequence number
|
* @param sequence Sequence number
|
||||||
*/
|
*/
|
||||||
|
@ -59,6 +75,7 @@ public class BrainKey {
|
||||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||||
byte[] result = sha256.digest(bytes);
|
byte[] result = sha256.digest(bytes);
|
||||||
mPrivateKey = ECKey.fromPrivate(result);
|
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) {
|
||||||
|
@ -66,11 +83,55 @@ public class BrainKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPublicKey() {
|
public String getUncompressedAddress() {
|
||||||
return Base64.getEncoder().encodeToString(mPrivateKey.getPubKey());
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
|
SHA512Digest sha512Digest = new SHA512Digest();
|
||||||
|
sha512Digest.update(mPrivateKey.decompress().getPubKey(), 0, mPrivateKey.decompress().getPubKey().length);
|
||||||
|
byte[] intermediate = new byte[512 / 8];
|
||||||
|
sha512Digest.doFinal(intermediate, 0);
|
||||||
|
ripemd160Digest.update(intermediate, 0, intermediate.length);
|
||||||
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
String encoded = Base58.encode(output);
|
||||||
|
byte[] checksum = new byte[(160 / 8) + 4];
|
||||||
|
System.arraycopy(calculateChecksum(output), 0, checksum, checksum.length - 4, 4);
|
||||||
|
System.arraycopy(output, 0, checksum, 0, output.length);
|
||||||
|
|
||||||
|
return ("BTS" + Base58.encode(checksum));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ECKey getPrivateKey(){
|
public String getAddress() {
|
||||||
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
|
SHA512Digest sha512Digest = new SHA512Digest();
|
||||||
|
sha512Digest.update(mPrivateKey.getPubKey(), 0, mPrivateKey.getPubKey().length);
|
||||||
|
byte[] intermediate = new byte[512 / 8];
|
||||||
|
sha512Digest.doFinal(intermediate, 0);
|
||||||
|
ripemd160Digest.update(intermediate, 0, intermediate.length);
|
||||||
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
String encoded = Base58.encode(output);
|
||||||
|
byte[] checksum = new byte[(160 / 8) + 4];
|
||||||
|
System.arraycopy(calculateChecksum(output), 0, checksum, checksum.length - 4, 4);
|
||||||
|
System.arraycopy(output, 0, checksum, 0, output.length);
|
||||||
|
|
||||||
|
return ("BTS" + Base58.encode(checksum));
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] calculateChecksum(byte[] input) {
|
||||||
|
byte[] answer = new byte[4];
|
||||||
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
|
ripemd160Digest.update(input, 0, input.length);
|
||||||
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
System.arraycopy(output, 0, answer, 0, 4);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getPublicKey() {
|
||||||
|
return mPrivateKey.getPubKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ECKey getPrivateKey() {
|
||||||
return mPrivateKey;
|
return mPrivateKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.io.IOException;
|
||||||
public class Main {
|
public class Main {
|
||||||
// Brain key from Nelson's app referencing the bilthon-83 account
|
// Brain key from Nelson's app referencing the bilthon-83 account
|
||||||
public static final String BRAIN_KEY = "PUMPER ISOTOME SERE STAINER CLINGER MOONLIT CHAETA UPBRIM AEDILIC BERTHER NIT SHAP SAID SHADING JUNCOUS CHOUGH";
|
public static final String BRAIN_KEY = "PUMPER ISOTOME SERE STAINER CLINGER MOONLIT CHAETA UPBRIM AEDILIC BERTHER NIT SHAP SAID SHADING JUNCOUS CHOUGH";
|
||||||
|
//public static final String BRAIN_KEY = "TWIXT SERMO TRILLI AUDIO PARDED PLUMET BIWA REHUNG MAUDLE VALVULA OUTBURN FEWNESS ALIENER UNTRACE PRICH TROKER";
|
||||||
|
|
||||||
public static final String BIP39_KEY = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
public static final String BIP39_KEY = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.luminiasoft.bitshares;
|
package com.luminiasoft.bitshares;
|
||||||
|
|
||||||
import com.google.common.primitives.Bytes;
|
|
||||||
import com.google.common.primitives.UnsignedLong;
|
import com.google.common.primitives.UnsignedLong;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
@ -509,11 +508,11 @@ public class Test {
|
||||||
* The final purpose of this test is to convert the plain brainkey at
|
* The final purpose of this test is to convert the plain brainkey at
|
||||||
* Main.BRAIN_KEY into the WIF at Main.WIF
|
* Main.BRAIN_KEY into the WIF at Main.WIF
|
||||||
*/
|
*/
|
||||||
public void testBrainKeyOperations(boolean random){
|
public void testBrainKeyOperations(boolean random) {
|
||||||
try {
|
try {
|
||||||
BrainKey brainKey;
|
BrainKey brainKey;
|
||||||
if(random){
|
if (random) {
|
||||||
String current = new java.io.File( "." ).getCanonicalPath();
|
String current = new java.io.File(".").getCanonicalPath();
|
||||||
File file = new File(current + "/src/main/java/com/luminiasoft/bitshares/brainkeydict.txt");
|
File file = new File(current + "/src/main/java/com/luminiasoft/bitshares/brainkeydict.txt");
|
||||||
|
|
||||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
|
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
|
||||||
|
@ -521,41 +520,72 @@ public class Test {
|
||||||
String words = bufferedReader.readLine();
|
String words = bufferedReader.readLine();
|
||||||
String suggestion = BrainKey.suggest(words);
|
String suggestion = BrainKey.suggest(words);
|
||||||
brainKey = new BrainKey(suggestion, 0);
|
brainKey = new BrainKey(suggestion, 0);
|
||||||
}else{
|
} else {
|
||||||
brainKey = new BrainKey(Main.BRAIN_KEY, 0);
|
brainKey = new BrainKey(Main.BRAIN_KEY, 0);
|
||||||
}
|
}
|
||||||
ECKey key = brainKey.getPrivateKey();
|
ECKey key = brainKey.getPrivateKey();
|
||||||
System.out.println("Private key :"+Util.bytesToHex(key.getSecretBytes()));
|
System.out.println("Private key");
|
||||||
|
System.out.println(Util.bytesToHex(key.getSecretBytes()));
|
||||||
String wif = key.getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
String wif = key.getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
||||||
System.out.println("wif compressed : "+wif);
|
System.out.println("wif compressed: " + wif);
|
||||||
String wif2 = key.decompress().getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
String wif2 = key.decompress().getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
||||||
System.out.println("wif decompressed : "+wif2);
|
System.out.println("wif decompressed: " + wif2);
|
||||||
|
|
||||||
byte[] pubKey1 = key.decompress().getPubKey();
|
byte[] pubKey1 = key.decompress().getPubKey();
|
||||||
System.out.println("decompressed public key: "+Base58.encode(pubKey1));
|
System.out.println("decompressed public key: " + Base58.encode(pubKey1));
|
||||||
byte[] pubKey2 = key.getPubKey();
|
byte[] pubKey2 = key.getPubKey();
|
||||||
System.out.println("compressed public key : "+Base58.encode(pubKey2));
|
System.out.println("compressed public key: " + Base58.encode(pubKey2));
|
||||||
|
|
||||||
System.out.println("pub key decompressed : "+Util.bytesToHex(pubKey1));
|
System.out.println("pub key compressed : " + Util.bytesToHex(pubKey1));
|
||||||
System.out.println("pub key compressed : "+Util.bytesToHex(pubKey2));
|
System.out.println("pub key uncompressed : " + Util.bytesToHex(pubKey2));
|
||||||
|
|
||||||
// Generating address
|
byte[] pubKey3 = key.getPubKeyPoint().getEncoded(true);
|
||||||
byte[] checksum = new byte[160 / 8];
|
System.out.println("pub key compressed : " + Base58.encode(pubKey3));
|
||||||
|
|
||||||
|
// Address generation test
|
||||||
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
ripemd160Digest.reset();
|
SHA512Digest sha512Digest = new SHA512Digest();
|
||||||
ripemd160Digest.update(pubKey2, 0, pubKey2.length);
|
sha512Digest.update(pubKey2, 0, pubKey2.length);
|
||||||
ripemd160Digest.doFinal(checksum, 0);
|
byte[] intermediate = new byte[512 / 8];
|
||||||
byte[] pubKeyChecksummed = Bytes.concat(pubKey2, Arrays.copyOfRange(checksum, 0, 4));
|
sha512Digest.doFinal(intermediate, 0);
|
||||||
String address = "BTS" + Base58.encode(pubKeyChecksummed);
|
ripemd160Digest.update(intermediate, 0, intermediate.length);
|
||||||
System.out.println("Address : "+address);
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
System.out.println("output after : " + Util.bytesToHex(output));
|
||||||
|
String encoded = Base58.encode(output);
|
||||||
|
System.out.println("base 58: " + encoded);
|
||||||
|
|
||||||
|
byte[] checksum = new byte[(160 / 8) + 4];
|
||||||
|
|
||||||
|
System.arraycopy(calculateChecksum(output), 0, checksum, checksum.length - 4, 4);
|
||||||
|
|
||||||
|
System.arraycopy(output, 0, checksum, 0, output.length);
|
||||||
|
|
||||||
|
System.out.println("BTS" + Base58.encode(checksum));
|
||||||
|
|
||||||
|
System.out.println("Compress Adress : " + brainKey.getAddress());
|
||||||
|
System.out.println("Uncompress Adress : " + brainKey.getUncompressedAddress());
|
||||||
|
|
||||||
|
Address address = new Address(key);
|
||||||
|
System.out.println("Block explorer's address: "+address);
|
||||||
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
System.out.println("FileNotFoundException. Msg: "+e.getMessage());
|
System.out.println("FileNotFoundException. Msg: " + e.getMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("IOException. Msg: "+e.getMessage());
|
System.out.println("IOException. Msg: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] calculateChecksum(byte[] input) {
|
||||||
|
byte[] answer = new byte[4];
|
||||||
|
RIPEMD160Digest ripemd160Digest = new RIPEMD160Digest();
|
||||||
|
ripemd160Digest.update(input, 0, input.length);
|
||||||
|
byte[] output = new byte[160 / 8];
|
||||||
|
ripemd160Digest.doFinal(output, 0);
|
||||||
|
System.arraycopy(output, 0, answer, 0, 4);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
public void testBip39Opertion() {
|
public void testBip39Opertion() {
|
||||||
BIP39 bip39 = new BIP39(Main.BIP39_KEY, "");
|
BIP39 bip39 = new BIP39(Main.BIP39_KEY, "");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue