package org.ripple.power.txns.btc;
import java.math.BigInteger;
import java.util.Arrays;
import org.ripple.power.Helper;
/**
* The DumpedPrivateKey represents a private key in printable format as created
* by the Bitcoin reference client. It can be imported into another wallet to
* recreate the private key, public key and address.
*/
public class DumpedPrivateKey {
/** Private key bytes (32 bytes) */
private byte[] privKeyBytes;
/** Compressed public key */
private boolean isCompressed;
/**
* Creates a DumpedPrivateKey from an existing private key
*
* @param privKey Private key
* @param compressed TRUE if the public key should be compressed
*/
public DumpedPrivateKey(BigInteger privKey, boolean compressed) {
privKeyBytes = Helper.bigIntegerToBytes(privKey, 32);
isCompressed = compressed;
}
/**
* Creates a DumpedPrivateKey from an encoded string
*
* @param string Encoded private key
* @throws AddressFormatException Encoded private key is not valid
*/
public DumpedPrivateKey(String string) throws AddressFormatException {
//
// Decode the private key
//
byte[] decodedKey = Base58.decodeChecked(string);
int version = (int)decodedKey[0]&0xff;
if (version != NetParams.DUMPED_PRIVATE_KEY_VERSION)
throw new AddressFormatException(String.format("Version %d is not correct", version));
//
// The private key length is 33 for a compressed public key, otherwise it is 32
//
if (decodedKey.length == 33+1 && decodedKey[33] == (byte)1) {
isCompressed = true;
privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length-1);
} else if (decodedKey.length == 32+1) {
isCompressed = false;
privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length);
} else {
throw new AddressFormatException("Private key length is incorrect");
}
}
/**
* Returns an ECKey for this private key
*
* @return ECKey
*/
public ECKey getKey() {
return new ECKey(new BigInteger(1, privKeyBytes), isCompressed);
}
/**
* Returns the Base58-encoded string with a 1-byte version and a 4-byte
* checksum.
*
* @return Base58-encoded string
*/
@Override
public String toString() {
//
// The encoded private key has an extra byte appended if the public key is compressed
//
byte[] keyBytes;
if (isCompressed) {
keyBytes = new byte[1+32+1+4];
keyBytes[1+32] = (byte)1;
} else {
keyBytes = new byte[1+32+4];
}
keyBytes[0] = (byte)NetParams.DUMPED_PRIVATE_KEY_VERSION;
System.arraycopy(privKeyBytes, 0, keyBytes, 1, 32);
byte[] digest = Helper.doubleDigest(keyBytes, 0, keyBytes.length-4);
System.arraycopy(digest, 0, keyBytes, keyBytes.length-4, 4);
return Base58.encode(keyBytes);
}
}