3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-07 06:44:16 +00:00

Support for importing/exporting private keys in sipa format. Resolves issue 48.

This commit is contained in:
Mike Hearn 2011-08-18 11:49:42 +00:00
parent c89d2aa124
commit f91978cc28
4 changed files with 41 additions and 14 deletions

View File

@ -23,16 +23,12 @@ import java.math.BigInteger;
* bytes with a header byte and 4 checksum bytes at the end.
*/
public class DumpedPrivateKey extends VersionedChecksummedBytes {
/**
* Allows the output of a private key in versioned, checksummed form.
*
* @param params The network parameters of this key, needed for the version byte.
* @param keyBytes The 256-bit private key.
*/
public DumpedPrivateKey(NetworkParameters params, byte[] keyBytes) {
// Used by ECKey.getPrivateKeyEncoded()
DumpedPrivateKey(NetworkParameters params, byte[] keyBytes) {
super(params.dumpedPrivateKeyHeader, keyBytes);
if (keyBytes.length != 32) // 256 bit keys
throw new RuntimeException("Keys are 256 bits, so you must provide 32 bytes.");
throw new RuntimeException("Keys are 256 bits, so you must provide 32 bytes, got " +
keyBytes.length + " bytes");
}
/**

View File

@ -236,4 +236,24 @@ public class ECKey implements Serializable {
throw new RuntimeException(e); // Cannot happen, reading from memory stream.
}
}
/** 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.
byte[] bytes = new byte[32];
System.arraycopy(priv.toByteArray(), 1, bytes, 0, 32);
return bytes;
}
/**
* Exports the private key in the form used by the Satoshi client "dumpprivkey" and "importprivkey" commands. Use
* the {@link com.google.bitcoin.core.DumpedPrivateKey#toString()} method to get the string.
*
* @param params The network this key is intended for use on.
* @return Private key bytes as a {@link DumpedPrivateKey}.
*/
public DumpedPrivateKey getPrivateKeyEncoded(NetworkParameters params) {
return new DumpedPrivateKey(params, getPrivKeyBytes());
}
}

View File

@ -45,13 +45,13 @@ public class VersionedChecksummedBytes {
@Override
public String toString() {
// A stringified address is:
// 1 byte version + 20 bytes hash + 4 bytes check code (itself a truncated hash)
byte[] addressBytes = new byte[1 + 20 + 4];
// A stringified buffer is:
// 1 byte version + data bytes + 4 bytes check code (a truncated hash)
byte[] addressBytes = new byte[1 + bytes.length + 4];
addressBytes[0] = (byte)version;
System.arraycopy(bytes, 0, addressBytes, 1, 20);
byte[] check = Utils.doubleDigest(addressBytes, 0, 21);
System.arraycopy(check, 0, addressBytes, 21, 4);
System.arraycopy(bytes, 0, addressBytes, 1, bytes.length);
byte[] check = Utils.doubleDigest(addressBytes, 0, bytes.length + 1);
System.arraycopy(check, 0, addressBytes, bytes.length + 1, 4);
return Base58.encode(addressBytes);
}

View File

@ -20,8 +20,10 @@ import org.bouncycastle.util.encoders.Hex;
import org.junit.Test;
import java.math.BigInteger;
import java.security.PrivateKey;
import static com.google.bitcoin.core.Utils.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ECKeyTest {
@ -68,4 +70,13 @@ public class ECKeyTest {
assertTrue(roundtripKey.verify(message, decodedKey.sign(message)));
assertTrue(decodedKey.verify(message, roundtripKey.sign(message)));
}
@Test
public void base58Encoding() throws Exception {
String addr = "mqAJmaxMcG5pPHHc3H3NtyXzY7kGbJLuMF";
String privkey = "92shANodC6Y4evT5kFzjNFQAdjqTtHAnDTLzqBBq4BbKUPyx6CD";
ECKey key = new DumpedPrivateKey(NetworkParameters.testNet(), privkey).getKey();
assertEquals(privkey, key.getPrivateKeyEncoded(NetworkParameters.testNet()).toString());
assertEquals(addr, key.toAddress(NetworkParameters.testNet()).toString());
}
}