diff --git a/src/com/google/bitcoin/core/ECKey.java b/src/com/google/bitcoin/core/ECKey.java index e44ad758..394c5f43 100644 --- a/src/com/google/bitcoin/core/ECKey.java +++ b/src/com/google/bitcoin/core/ECKey.java @@ -239,10 +239,15 @@ public class ECKey implements Serializable { /** Returns a 32 byte array containing the private key. */ public byte[] getPrivKeyBytes() { - // Getting the bytes out of a BigInteger gives us an extra null byte on the end (for signedness), so snip - // it off here. + // Getting the bytes out of a BigInteger gives us an extra zero byte on the end (for signedness) + // or less than 32 bytes (leading zeros). Coerce to 32 bytes in all cases. byte[] bytes = new byte[32]; - System.arraycopy(priv.toByteArray(), 1, bytes, 0, 32); + + byte[] privArray = priv.toByteArray(); + int privStart = (privArray.length == 33) ? 1 : 0; + int privLength = Math.min(privArray.length, 32); + System.arraycopy(privArray, privStart, bytes, 32 - privLength, privLength); + return bytes; } diff --git a/tests/com/google/bitcoin/core/ECKeyTest.java b/tests/com/google/bitcoin/core/ECKeyTest.java index acd75876..05686312 100644 --- a/tests/com/google/bitcoin/core/ECKeyTest.java +++ b/tests/com/google/bitcoin/core/ECKeyTest.java @@ -79,4 +79,24 @@ public class ECKeyTest { assertEquals(privkey, key.getPrivateKeyEncoded(NetworkParameters.testNet()).toString()); assertEquals(addr, key.toAddress(NetworkParameters.testNet()).toString()); } + + @Test + public void base58Encoding_leadingZero() throws Exception { + String privkey = "91axuYLa8xK796DnBXXsMbjuc8pDYxYgJyQMvFzrZ6UfXaGYuqL"; + ECKey key = new DumpedPrivateKey(NetworkParameters.testNet(), privkey).getKey(); + assertEquals(privkey, key.getPrivateKeyEncoded(NetworkParameters.testNet()).toString()); + assertEquals(0, key.getPrivKeyBytes()[0]); + } + + @Test + public void base58Encoding_stress() throws Exception { + // Replace the loop bound with 1000 to get some keys with leading zero byte + for (int i = 0 ; i < 20 ; i++) { + ECKey key = new ECKey(); + ECKey key1 = new DumpedPrivateKey(NetworkParameters.testNet(), + key.getPrivateKeyEncoded(NetworkParameters.testNet()).toString()).getKey(); + assertEquals(Utils.bytesToHexString(key.getPrivKeyBytes()), + Utils.bytesToHexString(key1.getPrivKeyBytes())); + } + } }