Some work on addresses, unfortunately it doesn't work yet.
This commit is contained in:
parent
00bd6a08b7
commit
08c46b3a97
@ -12,5 +12,5 @@ dependencies {
|
|||||||
compile project(':networking')
|
compile project(':networking')
|
||||||
compile project(':inventory')
|
compile project(':inventory')
|
||||||
compile 'org.slf4j:slf4j-simple:1.7.12'
|
compile 'org.slf4j:slf4j-simple:1.7.12'
|
||||||
testCompile group: 'junit', name: 'junit', version: '4.11'
|
testCompile 'junit:junit:4.11'
|
||||||
}
|
}
|
@ -35,25 +35,25 @@ public class PrivateKey implements Streamable {
|
|||||||
|
|
||||||
private final Pubkey pubkey;
|
private final Pubkey pubkey;
|
||||||
|
|
||||||
public PrivateKey(long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
public PrivateKey(long stream, long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
||||||
this.privateSigningKey = Security.randomBytes(64);
|
this.privateSigningKey = Security.randomBytes(64);
|
||||||
this.privateEncryptionKey = Security.randomBytes(64);
|
this.privateEncryptionKey = Security.randomBytes(64);
|
||||||
this.pubkey = Security.createPubkey(Pubkey.LATEST_VERSION, privateSigningKey, privateEncryptionKey,
|
this.pubkey = Security.createPubkey(Pubkey.LATEST_VERSION, stream, privateSigningKey, privateEncryptionKey,
|
||||||
nonceTrialsPerByte, extraBytes, features);
|
nonceTrialsPerByte, extraBytes, features);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PrivateKey(byte[] privateSigningKey, byte[] privateEncryptionKey, Pubkey pubkey) {
|
public PrivateKey(byte[] privateSigningKey, byte[] privateEncryptionKey, Pubkey pubkey) {
|
||||||
this.privateSigningKey = privateSigningKey;
|
this.privateSigningKey = privateSigningKey;
|
||||||
this.privateEncryptionKey = privateEncryptionKey;
|
this.privateEncryptionKey = privateEncryptionKey;
|
||||||
this.pubkey = pubkey;
|
this.pubkey = pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrivateKey(long version, String passphrase, long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
public PrivateKey(long version, long stream, String passphrase, long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
||||||
try {
|
try {
|
||||||
// FIXME: this is most definitely wrong
|
// FIXME: this is most definitely wrong
|
||||||
this.privateSigningKey = Bytes.truncate(Security.sha512(passphrase.getBytes("UTF-8"), new byte[]{0}), 32);
|
this.privateSigningKey = Bytes.truncate(Security.sha512(passphrase.getBytes("UTF-8"), new byte[]{0}), 32);
|
||||||
this.privateEncryptionKey = Bytes.truncate(Security.sha512(passphrase.getBytes("UTF-8"), new byte[]{1}), 32);
|
this.privateEncryptionKey = Bytes.truncate(Security.sha512(passphrase.getBytes("UTF-8"), new byte[]{1}), 32);
|
||||||
this.pubkey = Security.createPubkey(version, privateSigningKey, privateEncryptionKey,
|
this.pubkey = Security.createPubkey(version, stream, privateSigningKey, privateEncryptionKey,
|
||||||
nonceTrialsPerByte, extraBytes, features);
|
nonceTrialsPerByte, extraBytes, features);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
@ -54,7 +54,7 @@ public class Factory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pubkey createPubkey(long version, byte[] publicSigningKey, byte[] publicEncryptionKey,
|
public static Pubkey createPubkey(long version, long stream, byte[] publicSigningKey, byte[] publicEncryptionKey,
|
||||||
long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
||||||
if (publicSigningKey.length != 64)
|
if (publicSigningKey.length != 64)
|
||||||
throw new IllegalArgumentException("64 bytes signing key expected, but it was "
|
throw new IllegalArgumentException("64 bytes signing key expected, but it was "
|
||||||
@ -66,12 +66,14 @@ public class Factory {
|
|||||||
switch ((int) version) {
|
switch ((int) version) {
|
||||||
case 2:
|
case 2:
|
||||||
return new V2Pubkey.Builder()
|
return new V2Pubkey.Builder()
|
||||||
|
.stream(stream)
|
||||||
.publicSigningKey(publicSigningKey)
|
.publicSigningKey(publicSigningKey)
|
||||||
.publicEncryptionKey(publicEncryptionKey)
|
.publicEncryptionKey(publicEncryptionKey)
|
||||||
.behaviorBitfield(Pubkey.Feature.bitfield(features))
|
.behaviorBitfield(Pubkey.Feature.bitfield(features))
|
||||||
.build();
|
.build();
|
||||||
case 3:
|
case 3:
|
||||||
return new V3Pubkey.Builder()
|
return new V3Pubkey.Builder()
|
||||||
|
.stream(stream)
|
||||||
.publicSigningKey(publicSigningKey)
|
.publicSigningKey(publicSigningKey)
|
||||||
.publicEncryptionKey(publicEncryptionKey)
|
.publicEncryptionKey(publicEncryptionKey)
|
||||||
.behaviorBitfield(Pubkey.Feature.bitfield(features))
|
.behaviorBitfield(Pubkey.Feature.bitfield(features))
|
||||||
@ -81,6 +83,7 @@ public class Factory {
|
|||||||
case 4:
|
case 4:
|
||||||
return new V4Pubkey(
|
return new V4Pubkey(
|
||||||
new V3Pubkey.Builder()
|
new V3Pubkey.Builder()
|
||||||
|
.stream(stream)
|
||||||
.publicSigningKey(publicSigningKey)
|
.publicSigningKey(publicSigningKey)
|
||||||
.publicEncryptionKey(publicEncryptionKey)
|
.publicEncryptionKey(publicEncryptionKey)
|
||||||
.behaviorBitfield(Pubkey.Feature.bitfield(features))
|
.behaviorBitfield(Pubkey.Feature.bitfield(features))
|
||||||
@ -93,8 +96,8 @@ public class Factory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BitmessageAddress generatePrivateAddress(Pubkey.Feature... features) {
|
public static BitmessageAddress generatePrivateAddress(long stream, Pubkey.Feature... features) {
|
||||||
return new BitmessageAddress(new PrivateKey(1000, 1000, features));
|
return new BitmessageAddress(new PrivateKey(stream, 1000, 1000, features));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ObjectPayload getObjectPayload(long objectType, long version, long streamNumber, InputStream stream, int length) throws IOException {
|
static ObjectPayload getObjectPayload(long objectType, long version, long streamNumber, InputStream stream, int length) throws IOException {
|
||||||
|
@ -99,4 +99,27 @@ public class Bytes {
|
|||||||
System.arraycopy(bytes, 0, result, 1, bytes.length);
|
System.arraycopy(bytes, 0, result, 1, bytes.length);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] fromHex(String hex) {
|
||||||
|
if (hex.length() % 2 != 0) throw new IllegalArgumentException("expected even number of characters");
|
||||||
|
byte[] result = new byte[hex.length() / 2];
|
||||||
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
result[i] = (byte) (hexValue(hex.charAt(i * 2)) * 16);
|
||||||
|
result[i] += hexValue(hex.charAt(i * 2 + 1));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int hexValue(char c) {
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
return c - '0';
|
||||||
|
}
|
||||||
|
if (c >= 'a' && c <= 'f') {
|
||||||
|
return 10 + c - 'a';
|
||||||
|
}
|
||||||
|
if (c >= 'A' && c <= 'F') {
|
||||||
|
return 10 + c - 'A';
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("'" + c + "' is not a valid hex value");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,15 +129,17 @@ public class Security {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pubkey createPubkey(long version, byte[] privateSigningKey, byte[] privateEncryptionKey,
|
public static Pubkey createPubkey(long version, long stream, byte[] privateSigningKey, byte[] privateEncryptionKey,
|
||||||
long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
|
||||||
byte[] publicSigningKey = EC_PARAMETERS.getG().multiply(keyToBigInt(privateSigningKey)).getEncoded(false);
|
byte[] publicSigningKey = EC_PARAMETERS.getG().multiply(keyToBigInt(privateSigningKey)).getEncoded(false);
|
||||||
byte[] publicEncryptionKey = EC_PARAMETERS.getG().multiply(keyToBigInt(privateEncryptionKey)).getEncoded(false);
|
byte[] publicEncryptionKey = EC_PARAMETERS.getG().multiply(keyToBigInt(privateEncryptionKey)).getEncoded(false);
|
||||||
return Factory.createPubkey(version, Bytes.subArray(publicSigningKey, 1, 64), Bytes.subArray(publicEncryptionKey, 1, 64),
|
return Factory.createPubkey(version, stream, // publicSigningKey, publicEncryptionKey,
|
||||||
|
Bytes.subArray(publicSigningKey, 1, publicSigningKey.length - 1),
|
||||||
|
Bytes.subArray(publicEncryptionKey, 1, publicEncryptionKey.length - 1),
|
||||||
nonceTrialsPerByte, extraBytes, features);
|
nonceTrialsPerByte, extraBytes, features);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BigInteger keyToBigInt(byte[] key) {
|
private static BigInteger keyToBigInt(byte[] key) {
|
||||||
return new BigInteger(Bytes.concatenate((byte) 0x00, key));
|
return new BigInteger(1, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
package ch.dissem.bitmessage.entity;
|
package ch.dissem.bitmessage.entity;
|
||||||
|
|
||||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
||||||
|
import ch.dissem.bitmessage.utils.Base58;
|
||||||
|
import ch.dissem.bitmessage.utils.Bytes;
|
||||||
|
import ch.dissem.bitmessage.utils.Security;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@ -42,7 +45,37 @@ public class BitmessageAddressTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAddress() {
|
public void testCreateAddress() {
|
||||||
BitmessageAddress address = new BitmessageAddress(new PrivateKey(0, 0));
|
BitmessageAddress address = new BitmessageAddress(new PrivateKey(0, 0, 0));
|
||||||
assertNotNull(address.getPubkey());
|
assertNotNull(address.getPubkey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testV3Import() {
|
||||||
|
assertEquals(3, new BitmessageAddress("BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn").getVersion());
|
||||||
|
assertEquals(1, new BitmessageAddress("BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn").getStream());
|
||||||
|
|
||||||
|
byte[] privsigningkey = Base58.decode("5KU2gbe9u4rKJ8PHYb1rvwMnZnAJj4gtV5GLwoYckeYzygWUzB9");
|
||||||
|
byte[] privencryptionkey = Base58.decode("5KHd4c6cavd8xv4kzo3PwnVaYuBgEfg7voPQ5V97aZKgpYBXGck");
|
||||||
|
assertEquals((byte) 0x80, privsigningkey[0]);
|
||||||
|
assertEquals((byte) 0x80, privencryptionkey[0]);
|
||||||
|
privsigningkey = Bytes.subArray(privsigningkey, 1, privsigningkey.length - 5);
|
||||||
|
privencryptionkey = Bytes.subArray(privencryptionkey, 1, privencryptionkey.length - 5);
|
||||||
|
|
||||||
|
privsigningkey = Bytes.expand(privsigningkey, 32);
|
||||||
|
privencryptionkey = Bytes.expand(privencryptionkey, 32);
|
||||||
|
|
||||||
|
BitmessageAddress address = new BitmessageAddress(new PrivateKey(privsigningkey, privencryptionkey,
|
||||||
|
Security.createPubkey(3, 1, privsigningkey, privencryptionkey, 320, 14000)));
|
||||||
|
assertEquals("BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn", address.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testV4Import() {
|
||||||
|
assertEquals(4, new BitmessageAddress("BM-2cV5f9EpzaYARxtoruSpa6pDoucSf9ZNke").getVersion());
|
||||||
|
byte[] privsigningkey = Base58.decode("5KMWqfCyJZGFgW6QrnPJ6L9Gatz25B51y7ErgqNr1nXUVbtZbdU");
|
||||||
|
byte[] privencryptionkey = Base58.decode("5JXXWEuhHQEPk414SzEZk1PHDRi8kCuZd895J7EnKeQSahJPxGz");
|
||||||
|
BitmessageAddress address = new BitmessageAddress(new PrivateKey(privsigningkey, privencryptionkey,
|
||||||
|
Security.createPubkey(3, 1, privsigningkey, privencryptionkey, 320, 14000)));
|
||||||
|
assertEquals("BM-2cV5f9EpzaYARxtoruSpa6pDoucSf9ZNke", address.getAddress());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user