3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-12 18:25:51 +00:00

DumpedPrivateKey: Fix toBase58() for the case where the key is compressed.

This commit is contained in:
Nicola Atzei 2017-11-03 15:31:00 +01:00 committed by Andreas Schildbach
parent 6208f06d75
commit 3cc652858c
2 changed files with 52 additions and 14 deletions

View File

@ -30,7 +30,6 @@ import javax.annotation.Nullable;
* the last byte is a discriminator value for the compressed pubkey.
*/
public class DumpedPrivateKey extends VersionedChecksummedBytes {
private boolean compressed;
/**
* Construct a private key from its Base58 representation.
@ -50,7 +49,6 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
// Used by ECKey.getPrivateKeyEncoded()
DumpedPrivateKey(NetworkParameters params, byte[] keyBytes, boolean compressed) {
super(params.getDumpedPrivateKeyHeader(), encode(keyBytes, compressed));
this.compressed = compressed;
}
private static byte[] encode(byte[] keyBytes, boolean compressed) {
@ -72,12 +70,7 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
super(encoded);
if (params != null && version != params.getDumpedPrivateKeyHeader())
throw new WrongNetworkException(version, new int[]{ params.getDumpedPrivateKeyHeader() });
if (bytes.length == 33 && bytes[32] == 1) {
compressed = true;
bytes = Arrays.copyOf(bytes, 32); // Chop off the additional marker byte.
} else if (bytes.length == 32) {
compressed = false;
} else {
if (bytes.length != 32 && bytes.length != 33) {
throw new AddressFormatException("Wrong number of bytes for a private key, not 32 or 33");
}
}
@ -86,8 +79,14 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
* Returns an ECKey created from this encoded private key.
*/
public ECKey getKey() {
final ECKey key = ECKey.fromPrivate(bytes);
return compressed ? key : key.decompress();
return ECKey.fromPrivate(Arrays.copyOf(bytes, 32), isPubKeyCompressed());
}
/**
* Returns true if the public key corresponding to this private key is compressed.
*/
public boolean isPubKeyCompressed() {
return bytes.length == 33 && bytes[32] == 1;
}
@Override
@ -95,11 +94,11 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DumpedPrivateKey other = (DumpedPrivateKey) o;
return version == other.version && compressed == other.compressed && Arrays.equals(bytes, other.bytes);
return version == other.version && Arrays.equals(bytes, other.bytes);
}
@Override
public int hashCode() {
return Objects.hashCode(version, compressed, Arrays.hashCode(bytes));
return Objects.hashCode(version, Arrays.hashCode(bytes));
}
}

View File

@ -17,12 +17,15 @@
package org.bitcoinj.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import org.junit.Test;
import org.bitcoinj.params.MainNetParams;
@ -66,7 +69,43 @@ public class DumpedPrivateKeyTest {
@Test
public void roundtripBase58() throws Exception {
String base58 = "5HtUCLMFWNueqN9unpgX2DzjMg6SDNZyKRb8s3LJgpFg5ubuMrk";
assertEquals(base58, DumpedPrivateKey.fromBase58(null, base58).toBase58());
String base58 = "5HtUCLMFWNueqN9unpgX2DzjMg6SDNZyKRb8s3LJgpFg5ubuMrk"; // 32-bytes key
DumpedPrivateKey dumpedPrivateKey = DumpedPrivateKey.fromBase58(null, base58);
assertFalse(dumpedPrivateKey.isPubKeyCompressed());
assertEquals(base58, dumpedPrivateKey.toBase58());
}
@Test
public void roundtripBase58_compressed() throws Exception {
String base58 = "cSthBXr8YQAexpKeh22LB9PdextVE1UJeahmyns5LzcmMDSy59L4"; // 33-bytes, compressed == true
DumpedPrivateKey dumpedPrivateKey = DumpedPrivateKey.fromBase58(null, base58);
assertTrue(dumpedPrivateKey.isPubKeyCompressed());
assertEquals(base58, dumpedPrivateKey.toBase58());
}
@Test(expected = AddressFormatException.class)
public void roundtripBase58_invalidCompressed() {
String base58 = "5Kg5shEQWrf1TojaHTdc2kLuz5Mfh4uvp3cYu8uJHaHgfTGUbTD"; // 32-bytes key
byte[] bytes = Base58.decodeChecked(base58);
bytes = Arrays.copyOf(bytes, bytes.length + 1); // append a "compress" byte
bytes[bytes.length - 1] = 0; // set it to false
base58 = Base58.encode(bytes); // 33-bytes key, compressed == false
DumpedPrivateKey.fromBase58(null, base58); // fail
}
@Test
public void roundtripBase58_getKey() throws Exception {
ECKey k = new ECKey().decompress();
assertFalse(k.isCompressed());
assertEquals(k.getPrivKey(),
DumpedPrivateKey.fromBase58(null, k.getPrivateKeyAsWiF(MAINNET)).getKey().getPrivKey());
}
@Test
public void roundtripBase58_compressed_getKey() throws Exception {
ECKey k = new ECKey();
assertTrue(k.isCompressed());
assertEquals(k.getPrivKey(),
DumpedPrivateKey.fromBase58(null, k.getPrivateKeyAsWiF(MAINNET)).getKey().getPrivKey());
}
}