Finally fixed address creation and private key import

This commit is contained in:
Christian Basler 2015-05-16 16:33:26 +02:00
parent cb1392e0f4
commit 07f185be35
7 changed files with 46 additions and 34 deletions

View File

@ -66,7 +66,7 @@ public class BitmessageAddress {
// but for the address and its checksum they need to be stripped // but for the address and its checksum they need to be stripped
int offset = Bytes.numberOfLeadingZeros(ripe); int offset = Bytes.numberOfLeadingZeros(ripe);
os.write(ripe, offset, ripe.length - offset); os.write(ripe, offset, ripe.length - offset);
checksum = Security.doubleSha512(os.toByteArray(), ripe); checksum = Security.doubleSha512(os.toByteArray());
os.write(checksum, 0, 4); os.write(checksum, 0, 4);
this.address = "BM-" + Base58.encode(os.toByteArray()); this.address = "BM-" + Base58.encode(os.toByteArray());
} catch (IOException e) { } catch (IOException e) {

View File

@ -16,8 +16,6 @@
package ch.dissem.bitmessage.entity.payload; package ch.dissem.bitmessage.entity.payload;
import ch.dissem.bitmessage.utils.Bytes;
import java.util.ArrayList; import java.util.ArrayList;
import static ch.dissem.bitmessage.utils.Security.ripemd160; import static ch.dissem.bitmessage.utils.Security.ripemd160;
@ -29,6 +27,10 @@ import static ch.dissem.bitmessage.utils.Security.sha512;
public abstract class Pubkey extends ObjectPayload { public abstract class Pubkey extends ObjectPayload {
public final static long LATEST_VERSION = 4; public final static long LATEST_VERSION = 4;
public static byte[] getRipe(byte[] publicSigningKey, byte[] publicEncryptionKey) {
return ripemd160(sha512(publicSigningKey, publicEncryptionKey));
}
public abstract long getVersion(); public abstract long getVersion();
public abstract byte[] getSigningKey(); public abstract byte[] getSigningKey();

View File

@ -35,9 +35,21 @@ public class PrivateKey implements Streamable {
private final Pubkey pubkey; private final Pubkey pubkey;
public PrivateKey(long stream, long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) { public PrivateKey(boolean shorter, long stream, long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
this.privateSigningKey = Security.randomBytes(64); byte[] privSK;
this.privateEncryptionKey = Security.randomBytes(64); byte[] pubSK;
byte[] privEK;
byte[] pubEK;
byte[] ripe;
do {
privSK = Security.randomBytes(64);
privEK = Security.randomBytes(64);
pubSK = Security.createPublicKey(privSK).getEncoded(false);
pubEK = Security.createPublicKey(privEK).getEncoded(false);
ripe = Pubkey.getRipe(pubSK, pubEK);
} while (ripe[0] != 0 || (shorter && ripe[1] != 0));
this.privateSigningKey = privSK;
this.privateEncryptionKey = privEK;
this.pubkey = Security.createPubkey(Pubkey.LATEST_VERSION, stream, privateSigningKey, privateEncryptionKey, this.pubkey = Security.createPubkey(Pubkey.LATEST_VERSION, stream, privateSigningKey, privateEncryptionKey,
nonceTrialsPerByte, extraBytes, features); nonceTrialsPerByte, extraBytes, features);
} }
@ -60,14 +72,6 @@ public class PrivateKey implements Streamable {
} }
} }
public byte[] getPrivateSigningKey() {
return privateSigningKey;
}
public byte[] getPrivateEncryptionKey() {
return privateEncryptionKey;
}
public static PrivateKey read(InputStream is) throws IOException { public static PrivateKey read(InputStream is) throws IOException {
int version = (int) Decode.varInt(is); int version = (int) Decode.varInt(is);
long stream = Decode.varInt(is); long stream = Decode.varInt(is);
@ -80,6 +84,14 @@ public class PrivateKey implements Streamable {
return new PrivateKey(signingKey, encryptionKey, pubkey); return new PrivateKey(signingKey, encryptionKey, pubkey);
} }
public byte[] getPrivateSigningKey() {
return privateSigningKey;
}
public byte[] getPrivateEncryptionKey() {
return privateEncryptionKey;
}
public Pubkey getPubkey() { public Pubkey getPubkey() {
return pubkey; return pubkey;
} }

View File

@ -96,8 +96,8 @@ public class Factory {
} }
} }
public static BitmessageAddress generatePrivateAddress(long stream, Pubkey.Feature... features) { public static BitmessageAddress generatePrivateAddress(boolean shorter, long stream, Pubkey.Feature... features) {
return new BitmessageAddress(new PrivateKey(stream, 1000, 1000, features)); return new BitmessageAddress(new PrivateKey(shorter, 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 {

View File

@ -36,7 +36,7 @@ public class EncryptionTest {
public void ensureDecryptedDataIsSameAsBeforeEncryption() throws IOException { public void ensureDecryptedDataIsSameAsBeforeEncryption() throws IOException {
GenericPayload before = new GenericPayload(1, Security.randomBytes(100)); GenericPayload before = new GenericPayload(1, Security.randomBytes(100));
PrivateKey privateKey = new PrivateKey(1, 1000, 1000); PrivateKey privateKey = new PrivateKey(false, 1, 1000, 1000);
CryptoBox cryptoBox = new CryptoBox(before, privateKey.getPubkey().getEncryptionKey()); CryptoBox cryptoBox = new CryptoBox(before, privateKey.getPubkey().getEncryptionKey());
GenericPayload after = GenericPayload.read(cryptoBox.decrypt(privateKey.getPrivateEncryptionKey()), 1, 100); GenericPayload after = GenericPayload.read(cryptoBox.decrypt(privateKey.getPrivateEncryptionKey()), 1, 100);

View File

@ -38,7 +38,7 @@ public class SignatureTest {
@Test @Test
public void ensureSigningWorks() throws IOException { public void ensureSigningWorks() throws IOException {
PrivateKey privateKey = new PrivateKey(1, 1000, 1000); PrivateKey privateKey = new PrivateKey(false, 1, 1000, 1000);
BitmessageAddress address = new BitmessageAddress(privateKey); BitmessageAddress address = new BitmessageAddress(privateKey);
ObjectMessage objectMessage = new ObjectMessage.Builder() ObjectMessage objectMessage = new ObjectMessage.Builder()

View File

@ -24,6 +24,7 @@ import ch.dissem.bitmessage.utils.*;
import org.junit.Test; import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import static ch.dissem.bitmessage.entity.payload.Pubkey.Feature.DOES_ACK; import static ch.dissem.bitmessage.entity.payload.Pubkey.Feature.DOES_ACK;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -54,7 +55,7 @@ public class BitmessageAddressTest {
@Test @Test
public void testCreateAddress() { public void testCreateAddress() {
BitmessageAddress address = new BitmessageAddress(new PrivateKey(1, 1000, 1000, DOES_ACK)); BitmessageAddress address = new BitmessageAddress(new PrivateKey(false, 1, 1000, 1000, DOES_ACK));
assertNotNull(address.getPubkey()); assertNotNull(address.getPubkey());
} }
@ -90,7 +91,7 @@ public class BitmessageAddressTest {
} }
@Test @Test
public void testV3Import() throws IOException { public void testV3AddressImport() throws IOException {
String address_string = "BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn"; String address_string = "BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn";
assertEquals(3, new BitmessageAddress(address_string).getVersion()); assertEquals(3, new BitmessageAddress(address_string).getVersion());
assertEquals(1, new BitmessageAddress(address_string).getStream()); assertEquals(1, new BitmessageAddress(address_string).getStream());
@ -107,7 +108,7 @@ public class BitmessageAddressTest {
@Test @Test
public void testGetSecret() throws IOException { public void testGetSecret() throws IOException {
assertHexEquals("040C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D", assertHexEquals("0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D",
getSecret("5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ")); getSecret("5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ"));
} }
@ -122,19 +123,16 @@ public class BitmessageAddressTest {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (hash[i] != bytes[33 + i]) throw new IOException("Hash check failed for secret " + walletImportFormat); if (hash[i] != bytes[33 + i]) throw new IOException("Hash check failed for secret " + walletImportFormat);
} }
byte[] result = new byte[33]; return Arrays.copyOfRange(bytes, 1, 33);
result[0] = 0x04;
System.arraycopy(bytes, 1, result, 1, 32);
return result;
} }
@Test @Test
public void testV4Import() { public void testV4AddressImport() throws IOException {
assertEquals(4, new BitmessageAddress("BM-2cV5f9EpzaYARxtoruSpa6pDoucSf9ZNke").getVersion()); assertEquals(4, new BitmessageAddress("BM-2cV5f9EpzaYARxtoruSpa6pDoucSf9ZNke").getVersion());
byte[] privsigningkey = Base58.decode("5KMWqfCyJZGFgW6QrnPJ6L9Gatz25B51y7ErgqNr1nXUVbtZbdU"); byte[] privsigningkey = getSecret("5KMWqfCyJZGFgW6QrnPJ6L9Gatz25B51y7ErgqNr1nXUVbtZbdU");
byte[] privencryptionkey = Base58.decode("5JXXWEuhHQEPk414SzEZk1PHDRi8kCuZd895J7EnKeQSahJPxGz"); byte[] privencryptionkey = getSecret("5JXXWEuhHQEPk414SzEZk1PHDRi8kCuZd895J7EnKeQSahJPxGz");
BitmessageAddress address = new BitmessageAddress(new PrivateKey(privsigningkey, privencryptionkey, BitmessageAddress address = new BitmessageAddress(new PrivateKey(privsigningkey, privencryptionkey,
Security.createPubkey(3, 1, privsigningkey, privencryptionkey, 320, 14000))); Security.createPubkey(4, 1, privsigningkey, privencryptionkey, 320, 14000)));
assertEquals("BM-2cV5f9EpzaYARxtoruSpa6pDoucSf9ZNke", address.getAddress()); assertEquals("BM-2cV5f9EpzaYARxtoruSpa6pDoucSf9ZNke", address.getAddress());
} }