Experimentally changing the nonce type to BigInteger
This commit is contained in:
parent
33a330f44a
commit
fc91f7366c
3 changed files with 41 additions and 24 deletions
|
@ -11,6 +11,7 @@ import org.bitcoinj.core.ECKey;
|
||||||
import org.spongycastle.math.ec.ECPoint;
|
import org.spongycastle.math.ec.ECPoint;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -36,7 +37,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
|
|
||||||
private Address from;
|
private Address from;
|
||||||
private Address to;
|
private Address to;
|
||||||
private long nonce;
|
private BigInteger nonce;
|
||||||
private byte[] message;
|
private byte[] message;
|
||||||
private String plaintextMessage;
|
private String plaintextMessage;
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
* @param nonce: Nonce used in the encryption.
|
* @param nonce: Nonce used in the encryption.
|
||||||
* @param message: Message in ciphertext.
|
* @param message: Message in ciphertext.
|
||||||
*/
|
*/
|
||||||
public Memo(Address from, Address to, long nonce, byte[] message){
|
public Memo(Address from, Address to, BigInteger nonce, byte[] message){
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
this.nonce = nonce;
|
this.nonce = nonce;
|
||||||
|
@ -90,7 +91,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
return this.to;
|
return this.to;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNonce(){
|
public BigInteger getNonce(){
|
||||||
return this.nonce;
|
return this.nonce;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,15 +114,17 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
* @param message: Plaintext message.
|
* @param message: Plaintext message.
|
||||||
* @return: The encrypted version of the message.
|
* @return: The encrypted version of the message.
|
||||||
*/
|
*/
|
||||||
public static byte[] encryptMessage(ECKey privateKey, PublicKey publicKey, long nonce, String message){
|
public static byte[] encryptMessage(ECKey privateKey, PublicKey publicKey, BigInteger nonce, String message){
|
||||||
byte[] encrypted = null;
|
byte[] encrypted = null;
|
||||||
try {
|
try {
|
||||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||||
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
|
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
|
||||||
|
|
||||||
// Getting nonce bytes
|
// Getting nonce bytes
|
||||||
String stringNonce = String.format("%d", nonce);
|
byte[] paddedNonceBytes = new byte[8];
|
||||||
byte[] nonceBytes = Arrays.copyOfRange(Util.hexlify(stringNonce), 0, stringNonce.length());
|
byte[] originalNonceBytes = nonce.toByteArray();
|
||||||
|
System.arraycopy(originalNonceBytes, 0, paddedNonceBytes, 8 - originalNonceBytes.length, originalNonceBytes.length);
|
||||||
|
// byte[] nonceBytes = nonce.toByteArray();
|
||||||
|
|
||||||
// Getting shared secret
|
// Getting shared secret
|
||||||
byte[] secret = publicKey.getKey().getPubKeyPoint().multiply(privateKey.getPrivKey()).normalize().getXCoord().getEncoded();
|
byte[] secret = publicKey.getKey().getPubKeyPoint().multiply(privateKey.getPrivKey()).normalize().getXCoord().getEncoded();
|
||||||
|
@ -129,7 +132,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
// SHA-512 of shared secret
|
// SHA-512 of shared secret
|
||||||
byte[] ss = sha512.digest(secret);
|
byte[] ss = sha512.digest(secret);
|
||||||
|
|
||||||
byte[] seed = Bytes.concat(nonceBytes, Util.hexlify(Util.bytesToHex(ss)));
|
byte[] seed = Bytes.concat(paddedNonceBytes, Util.hexlify(Util.bytesToHex(ss)));
|
||||||
|
|
||||||
// Calculating checksum
|
// Calculating checksum
|
||||||
byte[] sha256Msg = sha256.digest(message.getBytes());
|
byte[] sha256Msg = sha256.digest(message.getBytes());
|
||||||
|
@ -154,7 +157,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
* @param message: Plaintext message.
|
* @param message: Plaintext message.
|
||||||
* @return: The encrypted version of the message.
|
* @return: The encrypted version of the message.
|
||||||
*/
|
*/
|
||||||
public static byte[] encryptMessage(ECKey privateKey, Address destinationAddress, long nonce, String message){
|
public static byte[] encryptMessage(ECKey privateKey, Address destinationAddress, BigInteger nonce, String message){
|
||||||
return encryptMessage(privateKey, destinationAddress.getPublicKey(), nonce, message);
|
return encryptMessage(privateKey, destinationAddress.getPublicKey(), nonce, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,15 +171,19 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
* @return: The plaintext version of the enrcrypted message.
|
* @return: The plaintext version of the enrcrypted message.
|
||||||
* @throws ChecksumException
|
* @throws ChecksumException
|
||||||
*/
|
*/
|
||||||
public static String decryptMessage(ECKey privateKey, PublicKey publicKey, long nonce, byte[] message) throws ChecksumException {
|
public static String decryptMessage(ECKey privateKey, PublicKey publicKey, BigInteger nonce, byte[] message) throws ChecksumException {
|
||||||
String plaintext = "";
|
String plaintext = "";
|
||||||
try {
|
try {
|
||||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||||
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
|
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
|
||||||
|
|
||||||
// Getting nonce bytes
|
// Getting nonce bytes
|
||||||
String stringNonce = String.format("%d", nonce);
|
byte[] paddedNonceBytes = new byte[8];
|
||||||
byte[] nonceBytes = Arrays.copyOfRange(Util.hexlify(stringNonce), 0, stringNonce.length());
|
byte[] originalNonceBytes = nonce.toByteArray();
|
||||||
|
System.arraycopy(originalNonceBytes, 0, paddedNonceBytes, 8 - originalNonceBytes.length, originalNonceBytes.length);
|
||||||
|
System.out.println("Nonce Bytes length......: "+originalNonceBytes.length);
|
||||||
|
System.out.println("Templated Bytes.........: "+Util.bytesToHex(originalNonceBytes));
|
||||||
|
System.out.println("Nonce bytes.............: "+Util.bytesToHex(paddedNonceBytes));
|
||||||
|
|
||||||
// Getting shared secret
|
// Getting shared secret
|
||||||
byte[] secret = publicKey.getKey().getPubKeyPoint().multiply(privateKey.getPrivKey()).normalize().getXCoord().getEncoded();
|
byte[] secret = publicKey.getKey().getPubKeyPoint().multiply(privateKey.getPrivKey()).normalize().getXCoord().getEncoded();
|
||||||
|
@ -184,7 +191,8 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
// SHA-512 of shared secret
|
// SHA-512 of shared secret
|
||||||
byte[] ss = sha512.digest(secret);
|
byte[] ss = sha512.digest(secret);
|
||||||
|
|
||||||
byte[] seed = Bytes.concat(nonceBytes, Util.hexlify(Util.bytesToHex(ss)));
|
byte[] seed = Bytes.concat(paddedNonceBytes, Util.hexlify(Util.bytesToHex(ss)));
|
||||||
|
System.out.println("seed: "+Util.bytesToHex(seed));
|
||||||
|
|
||||||
// Calculating checksum
|
// Calculating checksum
|
||||||
byte[] sha256Msg = sha256.digest(message);
|
byte[] sha256Msg = sha256.digest(message);
|
||||||
|
@ -215,7 +223,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
* @return: The plaintext version of the enrcrypted message.
|
* @return: The plaintext version of the enrcrypted message.
|
||||||
* @throws ChecksumException
|
* @throws ChecksumException
|
||||||
*/
|
*/
|
||||||
public static String decryptMessage(ECKey privateKey, Address sourceAddress, long nonce, byte[] message) throws ChecksumException {
|
public static String decryptMessage(ECKey privateKey, Address sourceAddress, BigInteger nonce, byte[] message) throws ChecksumException {
|
||||||
return decryptMessage(privateKey, sourceAddress.getPublicKey(), nonce, message);
|
return decryptMessage(privateKey, sourceAddress.getPublicKey(), nonce, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +244,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
new byte[]{(byte) this.message.length},
|
new byte[]{(byte) this.message.length},
|
||||||
this.message);
|
this.message);
|
||||||
} else {
|
} else {
|
||||||
byte[] nonceBytes = Util.revertLong(nonce);
|
byte[] nonceBytes = Util.revertBytes(nonce.toByteArray());
|
||||||
|
|
||||||
ECPoint senderPoint = ECKey.compressPoint(from.getPublicKey().getKey().getPubKeyPoint());
|
ECPoint senderPoint = ECKey.compressPoint(from.getPublicKey().getKey().getPubKeyPoint());
|
||||||
PublicKey senderPublicKey = new PublicKey(ECKey.fromPublicOnly(senderPoint));
|
PublicKey senderPublicKey = new PublicKey(ECKey.fromPublicOnly(senderPoint));
|
||||||
|
@ -288,7 +296,13 @@ public class Memo implements ByteSerializable, JsonSerializable {
|
||||||
JsonObject jsonObject = json.getAsJsonObject();
|
JsonObject jsonObject = json.getAsJsonObject();
|
||||||
String fromAddress = jsonObject.get(KEY_FROM).getAsString();
|
String fromAddress = jsonObject.get(KEY_FROM).getAsString();
|
||||||
String toAddress = jsonObject.get(KEY_TO).getAsString();
|
String toAddress = jsonObject.get(KEY_TO).getAsString();
|
||||||
long nonce = Long.parseLong(jsonObject.get(KEY_NONCE).getAsString(), 16);
|
BigInteger nonce;
|
||||||
|
System.out.println("Trying to deserialize memo with nonce: <"+jsonObject.get(KEY_NONCE).getAsString()+">");
|
||||||
|
try{
|
||||||
|
nonce = new BigInteger(jsonObject.get(KEY_NONCE).getAsString(), 10);
|
||||||
|
}catch(NumberFormatException e){
|
||||||
|
nonce = new BigInteger(jsonObject.get(KEY_NONCE).getAsString(), 16);
|
||||||
|
}
|
||||||
String msg = jsonObject.get(KEY_MESSAGE).getAsString();
|
String msg = jsonObject.get(KEY_MESSAGE).getAsString();
|
||||||
Memo memo = null;
|
Memo memo = null;
|
||||||
try{
|
try{
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -143,7 +144,7 @@ public class TransactionTest {
|
||||||
PublicKey to2 = new PublicKey(ECKey.fromPublicOnly(new BrainKey(BILTHON_16_BRAIN_KEY, 0).getPublicKey()));
|
PublicKey to2 = new PublicKey(ECKey.fromPublicOnly(new BrainKey(BILTHON_16_BRAIN_KEY, 0).getPublicKey()));
|
||||||
|
|
||||||
// Creating memo
|
// Creating memo
|
||||||
long nonce = 1;
|
BigInteger nonce = BigInteger.ONE;
|
||||||
byte[] encryptedMessage = Memo.encryptMessage(sourcePrivateKey, to1, nonce, "another message");
|
byte[] encryptedMessage = Memo.encryptMessage(sourcePrivateKey, to1, nonce, "another message");
|
||||||
Memo memo = new Memo(new Address(ECKey.fromPublicOnly(sourcePrivateKey.getPubKey())), new Address(to1.getKey()), nonce, encryptedMessage);
|
Memo memo = new Memo(new Address(ECKey.fromPublicOnly(sourcePrivateKey.getPubKey())), new Address(to1.getKey()), nonce, encryptedMessage);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import cy.agorise.graphenej.Address;
|
import cy.agorise.graphenej.Address;
|
||||||
import cy.agorise.graphenej.TestAccounts;
|
import cy.agorise.graphenej.TestAccounts;
|
||||||
import cy.agorise.graphenej.PublicKey;
|
import cy.agorise.graphenej.PublicKey;
|
||||||
|
@ -36,10 +38,10 @@ public class MemoTest {
|
||||||
private String longerMessage = "testing now longer string with some special charaters é ç o ú á í Í mMno!!";
|
private String longerMessage = "testing now longer string with some special charaters é ç o ú á í Í mMno!!";
|
||||||
|
|
||||||
private byte[] shortEncryptedMessage = Util.hexToBytes("93c398e05f2a36a535f82880032a062d");
|
private byte[] shortEncryptedMessage = Util.hexToBytes("93c398e05f2a36a535f82880032a062d");
|
||||||
private long shortEncryptedMessageNonce = 386471255144360L;
|
private BigInteger shortEncryptedMessageNonce = new BigInteger("386471255144360");
|
||||||
|
|
||||||
private byte[] longerEncryptedMessage = Util.hexToBytes("8ba8f5ed85ad9f7675bd30408a28d6f6ba138476d1e995dd61c01f0041ab25911e04d93fe4ce30e4f6c9a5134cceb67d653e140aa542da19ce2fc646bcde46e088da06a9327eaac79ffe8bc9d71d586195c04bb023995f18e66c9f9e5c6b0d7c");
|
private byte[] longerEncryptedMessage = Util.hexToBytes("8ba8f5ed85ad9f7675bd30408a28d6f6ba138476d1e995dd61c01f0041ab25911e04d93fe4ce30e4f6c9a5134cceb67d653e140aa542da19ce2fc646bcde46e088da06a9327eaac79ffe8bc9d71d586195c04bb023995f18e66c9f9e5c6b0d7c");
|
||||||
private long longEncryptedMessageNonce = 386469162162343L;
|
private BigInteger longEncryptedMessageNonce = new BigInteger("386469162162343");
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
@ -92,7 +94,7 @@ public class MemoTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldEncryptAndDecryptShortMessage(){
|
public void shouldEncryptAndDecryptShortMessage(){
|
||||||
try {
|
try {
|
||||||
long nonce = 1;
|
BigInteger nonce = BigInteger.ONE;
|
||||||
byte[] encrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, nonce, shortMessage);
|
byte[] encrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, nonce, shortMessage);
|
||||||
String decrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, encrypted);
|
String decrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, encrypted);
|
||||||
System.out.println("Short Decrypted Message: " + decrypted);
|
System.out.println("Short Decrypted Message: " + decrypted);
|
||||||
|
@ -105,7 +107,7 @@ public class MemoTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldEncryptAndDecryptLongerMessage(){
|
public void shouldEncryptAndDecryptLongerMessage(){
|
||||||
try{
|
try{
|
||||||
long nonce = 1;
|
BigInteger nonce = BigInteger.ONE;
|
||||||
byte[] longEncrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, nonce, longerMessage);
|
byte[] longEncrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, nonce, longerMessage);
|
||||||
String longDecrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, longEncrypted);
|
String longDecrypted = Memo.decryptMessage(destinationPrivate, sourceAddress, nonce, longEncrypted);
|
||||||
System.out.println("Long Decrypted Message: " + longDecrypted);
|
System.out.println("Long Decrypted Message: " + longDecrypted);
|
||||||
|
@ -138,20 +140,20 @@ public class MemoTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldBeByteSerializable(){
|
public void shouldBeByteSerializable(){
|
||||||
String byteReference = "01029392096400eafe5f5ce7e2ab74134c3422fc49e5853bdeb298fb096258e26f6303d1fb8c7421db64d46fba7e36f428854ca06eff65698b293f37c7ffaa54e2c2b20100000000000000104ccbca3750fd2e531441de02b23fe6c7";
|
String byteReference = "01029392096400eafe5f5ce7e2ab74134c3422fc49e5853bdeb298fb096258e26f6303d1fb8c7421db64d46fba7e36f428854ca06eff65698b293f37c7ffaa54e2c2b20100000000000000104ccbca3750fd2e531441de02b23fe6c7";
|
||||||
byte[] encrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, 1, shortMessage);
|
byte[] encrypted = Memo.encryptMessage(sourcePrivate, destinationAddress, BigInteger.ONE, shortMessage);
|
||||||
Memo memo = new Memo(sourceAddress, destinationAddress, 1, encrypted);
|
Memo memo = new Memo(sourceAddress, destinationAddress, BigInteger.ONE, encrypted);
|
||||||
byte[] memoBytes = memo.toBytes();
|
byte[] memoBytes = memo.toBytes();
|
||||||
assertEquals("Memo instance should generate a valid byte array", byteReference, Util.bytesToHex(memoBytes));
|
assertEquals("Memo instance should generate a valid byte array", byteReference, Util.bytesToHex(memoBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldDeserializeFromString(){
|
public void shouldDeserializeFromString(){
|
||||||
String jsonMemo = "{\"from\": \"BTS6nB7gw1EawYXRofLvuivLsboVmh2inXroQgSQqYfAc5Bamk4Vq\",\"to\": \"BTS4xAQGg2ePLeDGZvQFpsh9CjMhQvRnVkPp6jPoE6neVPotRfZX9\",\"nonce\": \"15f2d8ee4ec23\",\"message\": \"b9aeb7632f1f4281eedcf28a684828a42d02de71254fb88e13ddcb9a79adf51d9770c58d7e7efcdbb1515f1136c3be3e\"}";
|
String jsonMemo = "{\"from\": \"BTS6nB7gw1EawYXRofLvuivLsboVmh2inXroQgSQqYfAc5Bamk4Vq\",\"to\": \"BTS4xAQGg2ePLeDGZvQFpsh9CjMhQvRnVkPp6jPoE6neVPotRfZX9\",\"nonce\": \"8000000000000000\",\"message\": \"b9aeb7632f1f4281eedcf28a684828a42d02de71254fb88e13ddcb9a79adf51d9770c58d7e7efcdbb1515f1136c3be3e\"}";
|
||||||
GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(Memo.class, new Memo.MemoDeserializer());
|
GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(Memo.class, new Memo.MemoDeserializer());
|
||||||
Memo memo = gsonBuilder.create().fromJson(jsonMemo, Memo.class);
|
Memo memo = gsonBuilder.create().fromJson(jsonMemo, Memo.class);
|
||||||
Assert.assertEquals("Source address should match the serialized one", "BTS6nB7gw1EawYXRofLvuivLsboVmh2inXroQgSQqYfAc5Bamk4Vq", memo.getSource().toString());
|
Assert.assertEquals("Source address should match the serialized one", "BTS6nB7gw1EawYXRofLvuivLsboVmh2inXroQgSQqYfAc5Bamk4Vq", memo.getSource().toString());
|
||||||
Assert.assertEquals("Destination address should match the serialized one", "BTS4xAQGg2ePLeDGZvQFpsh9CjMhQvRnVkPp6jPoE6neVPotRfZX9", memo.getDestination().toString());
|
Assert.assertEquals("Destination address should match the serialized one", "BTS4xAQGg2ePLeDGZvQFpsh9CjMhQvRnVkPp6jPoE6neVPotRfZX9", memo.getDestination().toString());
|
||||||
Assert.assertEquals("Nonce should match serialized one", Long.parseLong("15f2d8ee4ec23", 16), memo.getNonce());
|
Assert.assertEquals("Nonce should match serialized one", new BigInteger("8000000000000000", 10), memo.getNonce());
|
||||||
Assert.assertArrayEquals(Util.hexToBytes("b9aeb7632f1f4281eedcf28a684828a42d02de71254fb88e13ddcb9a79adf51d9770c58d7e7efcdbb1515f1136c3be3e"), memo.getByteMessage());
|
Assert.assertArrayEquals(Util.hexToBytes("b9aeb7632f1f4281eedcf28a684828a42d02de71254fb88e13ddcb9a79adf51d9770c58d7e7efcdbb1515f1136c3be3e"), memo.getByteMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue