diff --git a/src/main/java/de/bitsharesmunich/graphenej/Main.java b/src/main/java/de/bitsharesmunich/graphenej/Main.java index 53a78e7..a3833ac 100644 --- a/src/main/java/de/bitsharesmunich/graphenej/Main.java +++ b/src/main/java/de/bitsharesmunich/graphenej/Main.java @@ -56,8 +56,8 @@ public class Main { // test.testAccountUpdateOperationBroadcast(); // test.testCreateBinFile(); // test.testImportBinFile(); - test.testLookupAccounts(); +// test.testLookupAccounts(); // test.testLookupAccounts(); -// test.testDecodeMemo(); + test.testDecodeMemo(); } } diff --git a/src/main/java/de/bitsharesmunich/graphenej/PublicKey.java b/src/main/java/de/bitsharesmunich/graphenej/PublicKey.java index 163ec3b..ea6bb9f 100644 --- a/src/main/java/de/bitsharesmunich/graphenej/PublicKey.java +++ b/src/main/java/de/bitsharesmunich/graphenej/PublicKey.java @@ -2,6 +2,7 @@ package de.bitsharesmunich.graphenej; import de.bitsharesmunich.graphenej.interfaces.ByteSerializable; import org.bitcoinj.core.ECKey; +import org.spongycastle.math.ec.ECPoint; /** * Created by nelson on 11/30/16. @@ -10,6 +11,9 @@ public class PublicKey implements ByteSerializable { private ECKey publicKey; public PublicKey(ECKey key) { + if(key.hasPrivKey()){ + throw new IllegalStateException("Passing a private key to PublicKey constructor"); + } this.publicKey = key; } @@ -19,10 +23,20 @@ public class PublicKey implements ByteSerializable { @Override public byte[] toBytes() { - return publicKey.getPubKey(); + if(publicKey.isCompressed()) { + return publicKey.getPubKey(); + }else{ + publicKey = ECKey.fromPublicOnly(ECKey.compressPoint(publicKey.getPubKeyPoint())); + return publicKey.getPubKey(); + } } - + public String getAddress(){ - return new Address(publicKey).toString(); + ECKey pk = ECKey.fromPublicOnly(publicKey.getPubKey()); + if(!pk.isCompressed()){ + ECPoint point = ECKey.compressPoint(pk.getPubKeyPoint()); + pk = ECKey.fromPublicOnly(point); + } + return new Address(pk).toString(); } -} +} \ No newline at end of file diff --git a/src/main/java/de/bitsharesmunich/graphenej/Test.java b/src/main/java/de/bitsharesmunich/graphenej/Test.java index 2de438b..95464d6 100644 --- a/src/main/java/de/bitsharesmunich/graphenej/Test.java +++ b/src/main/java/de/bitsharesmunich/graphenej/Test.java @@ -299,7 +299,7 @@ public class Test { try { // Creating memo - PublicKey from = new PublicKey(new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey()); + ECKey from = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey(); PublicKey to = new PublicKey(ECKey.fromPublicOnly(new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0).getPublicKey())); Memo memo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("sample message").build(); @@ -377,15 +377,44 @@ public class Test { } public void testGetAccountByName() { + + WitnessResponseListener accountByNameListener = new WitnessResponseListener() { + @Override + public void onSuccess(WitnessResponse response) { + System.out.println("onSuccess"); + WitnessResponse accountProperties = response; + System.out.println("account id: "+accountProperties.result.id); + Authority authority = accountProperties.result.active; + System.out.println("number of keys: "+authority.getKeyAuths().size()); + for(PublicKey publicKey : authority.getKeyAuths()){ + System.out.println("public key: "+publicKey.getAddress()); + } + } + + @Override + public void onError(BaseResponse.Error error) { + System.out.println("onError. Msg: "+error.message); + } + }; + try { - WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(5000); - WebSocket mWebSocket = factory.createSocket(WITNESS_URL); - mWebSocket.addListener(new GetAccountByName("bilthon-83", mListener)); + SSLContext context = null; + context = NaiveSSLContext.getInstance("TLS"); + WebSocketFactory factory = new WebSocketFactory(); + + // Set the custom SSL context. + factory.setSSLContext(context); + + WebSocket mWebSocket = factory.createSocket(BLOCK_PAY_DE); + + mWebSocket.addListener(new GetAccountByName("bilthon-83", accountByNameListener)); mWebSocket.connect(); } catch (IOException e) { System.out.println("IOException. Msg: " + e.getMessage()); } catch (WebSocketException e) { System.out.println("WebSocketException. Msg: " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage()); } } @@ -434,7 +463,7 @@ public class Test { } else { System.out.println("Using brain key: " + Main.BILTHON_5_BRAIN_KEY); // brainKey = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0); - brainKey = new BrainKey("CYNEBOT LUFBERY DAUNTER TOO SALOOP HOPOFF DIAULOS REV AES TORPOR RECTRIX DEVILRY", 0); + brainKey = new BrainKey("CONCOCT BALOW JINJILI UNOILED MESOBAR REEST BREATH OOCYST MOUSLE HOGWARD STOLLEN ASH", 0); } ECKey key = brainKey.getPrivateKey(); System.out.println("Private key..................: " + Util.bytesToHex(key.getSecretBytes())); @@ -707,13 +736,13 @@ public class Test { public void testDecodeMemo() { - PublicKey from = new PublicKey((new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey())); - PublicKey to = new PublicKey(new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0).getPrivateKey()); + ECKey from = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey(); + PublicKey to = new PublicKey(ECKey.fromPublicOnly(new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0).getPublicKey())); Memo sendMemo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("test message").build(); JsonElement memoJson = sendMemo.toJsonObject(); System.out.println("generated Json : " + memoJson.toString()); - System.out.println("Decode Memo : " + Memo.decodeMessage(from, to, memoJson.getAsJsonObject().get("message").getAsString(), memoJson.getAsJsonObject().get("nonce").getAsString())); +// System.out.println("Decode Memo : " + Memo.decodeMessage(from, to, memoJson.getAsJsonObject().get("message").getAsString(), memoJson.getAsJsonObject().get("nonce").getAsString())); } } diff --git a/src/main/java/de/bitsharesmunich/graphenej/objects/Memo.java b/src/main/java/de/bitsharesmunich/graphenej/objects/Memo.java index 7cb9c08..e055091 100644 --- a/src/main/java/de/bitsharesmunich/graphenej/objects/Memo.java +++ b/src/main/java/de/bitsharesmunich/graphenej/objects/Memo.java @@ -8,6 +8,8 @@ import de.bitsharesmunich.graphenej.Util; import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener; import de.bitsharesmunich.graphenej.interfaces.ByteSerializable; import de.bitsharesmunich.graphenej.interfaces.JsonSerializable; +import org.bitcoinj.core.ECKey; + import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -17,13 +19,13 @@ import java.security.SecureRandom; * Created by nelson on 11/9/16. */ public class Memo implements ByteSerializable, JsonSerializable { - + public final static String TAG = "Memo"; public static final String KEY_FROM = "from"; public static final String KEY_TO = "to"; public static final String KEY_NONCE = "nonce"; public static final String KEY_MESSAGE = "message"; - private PublicKey from; + private ECKey from; private PublicKey to; private final byte[] nonce = new byte[8]; private byte[] message; @@ -36,7 +38,7 @@ public class Memo implements ByteSerializable, JsonSerializable { this.to = null; this.message = null; } - + /** * Implement metod, serialized this Object * @return the byte array of this object serialized @@ -50,7 +52,10 @@ public class Memo implements ByteSerializable, JsonSerializable { for (int i = 0; i < nonceformat.length; i++) { nonceformat[i] = nonce[nonce.length - i - 1]; } - return Bytes.concat(new byte[]{1}, this.from.toBytes(), this.to.toBytes(), nonceformat, new byte[]{(byte) this.message.length}, this.message); + org.spongycastle.math.ec.ECPoint point = ECKey.compressPoint(from.getPubKeyPoint()); + PublicKey senderPublicKey = new PublicKey(ECKey.fromPublicOnly(point)); + + return Bytes.concat(new byte[]{1}, senderPublicKey.toBytes(), this.to.toBytes(), nonceformat, new byte[]{(byte) this.message.length}, this.message); } } @@ -61,20 +66,20 @@ public class Memo implements ByteSerializable, JsonSerializable { * @param msg The message in bytes * @return a Memo corresponding with the message encoding */ - public static Memo encodeMessage(PublicKey fromKey, PublicKey toKey, byte[] msg) { + public static Memo encodeMessage(ECKey fromKey, PublicKey toKey, byte[] msg) { return encodeMessage(fromKey, toKey, msg, 0); } /** * Encode a message a return a memo with that message encoded - * + * * @param fromKey The source destination, need to have a private key accesss * @param toKey The destination, needs only the public key access * @param msg The message in bytes * @param custom_nonce the custom nonce to be use or 0 to create a new one * @return a Memo corresponding with the message encoding */ - public static Memo encodeMessage(PublicKey fromKey, PublicKey toKey, byte[] msg, long custom_nonce) { + public static Memo encodeMessage(ECKey fromKey, PublicKey toKey, byte[] msg, long custom_nonce) { Memo memo = new Memo(); try { MessageDigest md = MessageDigest.getInstance("SHA-256"); @@ -84,7 +89,7 @@ public class Memo implements ByteSerializable, JsonSerializable { if (custom_nonce == 0) { SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance(); - //randomStrengthener.addEntropySource(new AndroidRandomSource()); +// randomStrengthener.addEntropySource(new AndroidRandomSource()); SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator(); secureRandom.nextBytes(memo.nonce); @@ -100,8 +105,7 @@ public class Memo implements ByteSerializable, JsonSerializable { custom_nonce = custom_nonce / 0x100; } } - - byte[] secret = toKey.getKey().getPubKeyPoint().multiply(fromKey.getKey().getPrivKey()).normalize().getXCoord().getEncoded(); + byte[] secret = toKey.getKey().getPubKeyPoint().multiply(fromKey.getPrivKey()).normalize().getXCoord().getEncoded(); byte[] finalKey = new byte[secret.length + memo.nonce.length]; System.arraycopy(secret, 0, finalKey, 0, secret.length); System.arraycopy(memo.nonce, 0, finalKey, secret.length, memo.nonce.length); @@ -120,16 +124,16 @@ public class Memo implements ByteSerializable, JsonSerializable { /** * returns the string coreesponding a encode memo - * + * * @param fromKey The soruce key, need to have public key only * @param toKey The destination key, need to have private key access * @param msg The message to be decoded * @param nonce The nonce used in the decoded message * @return The message */ - public static String decodeMessage(PublicKey fromKey, PublicKey toKey, byte[] msg, byte[] nonce) { + public static String decodeMessage(PublicKey fromKey, ECKey toKey, byte[] msg, byte[] nonce) { - byte[] secret = fromKey.getKey().getPubKeyPoint().multiply(toKey.getKey().getPrivKey()).normalize().getXCoord().getEncoded(); + byte[] secret = fromKey.getKey().getPubKeyPoint().multiply(toKey.getPrivKey()).normalize().getXCoord().getEncoded(); byte[] finalKey = new byte[secret.length + nonce.length]; System.arraycopy(secret, 0, finalKey, 0, secret.length); System.arraycopy(nonce, 0, finalKey, secret.length, nonce.length); @@ -142,15 +146,15 @@ public class Memo implements ByteSerializable, JsonSerializable { } /** - * returns the string coreesponding a encode memo - * - * @param fromKey The soruce key, need to have public key only + * returns the string corresponding a encode memo + * + * @param fromKey The source key, need to have public key only * @param toKey The destination key, need to have private key access * @param message The message to be decoded * @param nonce The nonce used in the decoded message * @return The message */ - public static String decodeMessage(PublicKey fromKey, PublicKey toKey, String message, String nonce) { + public static String decodeMessage(PublicKey fromKey, ECKey toKey, String message, String nonce) { byte[] msg = new BigInteger(message, 16).toByteArray(); if (msg[0] == 0) { byte[] temp = new byte[msg.length - 1]; @@ -173,12 +177,14 @@ public class Memo implements ByteSerializable, JsonSerializable { if ((this.from == null) || (this.to == null) || (this.nonce == null) || (this.message == null)) { return null; } + org.spongycastle.math.ec.ECPoint point = ECKey.compressPoint(from.getPubKeyPoint()); + PublicKey publicKey = new PublicKey(ECKey.fromPublicOnly(point)); + JsonObject memoObject = new JsonObject(); - memoObject.addProperty(KEY_FROM, this.from.getAddress()); + memoObject.addProperty(KEY_FROM, publicKey.getAddress()); memoObject.addProperty(KEY_TO, this.to.getAddress()); memoObject.addProperty(KEY_NONCE, new BigInteger(1, this.nonce).toString(10)); memoObject.addProperty(KEY_MESSAGE, new BigInteger(1, this.message).toString(16)); return memoObject; } - } diff --git a/src/main/java/de/bitsharesmunich/graphenej/objects/MemoBuilder.java b/src/main/java/de/bitsharesmunich/graphenej/objects/MemoBuilder.java index ab8426b..31d816c 100644 --- a/src/main/java/de/bitsharesmunich/graphenej/objects/MemoBuilder.java +++ b/src/main/java/de/bitsharesmunich/graphenej/objects/MemoBuilder.java @@ -1,6 +1,7 @@ package de.bitsharesmunich.graphenej.objects; import de.bitsharesmunich.graphenej.PublicKey; +import org.bitcoinj.core.ECKey; /** * Class to build a Memo Object @@ -8,7 +9,7 @@ import de.bitsharesmunich.graphenej.PublicKey; */ public class MemoBuilder { - private PublicKey fromKey; + private ECKey fromKey; private PublicKey toKey; private String message; private long nonce = 0; @@ -24,7 +25,7 @@ public class MemoBuilder { * @param fromKey The Public Key of the sender * @return The MemoBuilder */ - public MemoBuilder setFromKey(PublicKey fromKey) { + public MemoBuilder setFromKey(ECKey fromKey) { this.fromKey = fromKey; return this; } @@ -70,5 +71,4 @@ public class MemoBuilder { } return Memo.encodeMessage(fromKey, toKey, message.getBytes(), nonce); } - -} +} \ No newline at end of file