mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-19 05:33:44 +01:00
Fix Utils.decodeMPI and add a Utils.encodeMPI
This commit is contained in:
parent
61ed962e63
commit
e5c88cda8b
@ -612,6 +612,7 @@ public class Script {
|
||||
|
||||
/**
|
||||
* Writes out the given byte buffer to the output stream with the correct opcode prefix
|
||||
* To write an integer call writeBytes(out, Utils.reverseBytes(Utils.encodeMPI(val, false)));
|
||||
*/
|
||||
static void writeBytes(OutputStream os, byte[] buf) throws IOException {
|
||||
if (buf.length < OP_PUSHDATA1) {
|
||||
|
@ -323,13 +323,64 @@ public class Utils {
|
||||
/**
|
||||
* MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function. They consist of
|
||||
* a 4 byte big endian length field, followed by the stated number of bytes representing
|
||||
* the number in big endian format.
|
||||
* the number in big endian format (with a sign bit).
|
||||
* @param hasLength can be set to false if the given array is missing the 4 byte length field
|
||||
*/
|
||||
static BigInteger decodeMPI(byte[] mpi) {
|
||||
static BigInteger decodeMPI(byte[] mpi, boolean hasLength) {
|
||||
byte[] buf;
|
||||
if (hasLength) {
|
||||
int length = (int) readUint32BE(mpi, 0);
|
||||
byte[] buf = new byte[length];
|
||||
buf = new byte[length];
|
||||
System.arraycopy(mpi, 4, buf, 0, length);
|
||||
return new BigInteger(buf);
|
||||
} else
|
||||
buf = mpi;
|
||||
if (buf.length == 0)
|
||||
return BigInteger.ZERO;
|
||||
boolean isNegative = (buf[0] & 0x80) == 0x80;
|
||||
if (isNegative)
|
||||
buf[0] &= 0x7f;
|
||||
BigInteger result = new BigInteger(buf);
|
||||
return isNegative ? result.negate() : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function. They consist of
|
||||
* a 4 byte big endian length field, followed by the stated number of bytes representing
|
||||
* the number in big endian format (with a sign bit).
|
||||
* @param hasLength indicates whether the 4 byte length field should be included
|
||||
*/
|
||||
static byte[] encodeMPI(BigInteger value, boolean includeLength) {
|
||||
if (value.equals(BigInteger.ZERO)) {
|
||||
if (!includeLength)
|
||||
return new byte[] {};
|
||||
else
|
||||
return new byte[] {0x00, 0x00, 0x00, 0x00};
|
||||
}
|
||||
boolean isNegative = value.compareTo(BigInteger.ZERO) < 0;
|
||||
if (isNegative)
|
||||
value = value.negate();
|
||||
byte[] array = value.toByteArray();
|
||||
int length = array.length;
|
||||
if ((array[0] & 0x80) == 0x80)
|
||||
length++;
|
||||
if (includeLength) {
|
||||
byte[] result = new byte[length + 4];
|
||||
System.arraycopy(array, 0, result, length - array.length + 3, array.length);
|
||||
uint32ToByteArrayBE(length, result, 0);
|
||||
if (isNegative)
|
||||
result[4] |= 0x80;
|
||||
return result;
|
||||
} else {
|
||||
byte[] result;
|
||||
if (length != array.length) {
|
||||
result = new byte[length];
|
||||
System.arraycopy(array, 0, result, 1, array.length);
|
||||
}else
|
||||
result = array;
|
||||
if (isNegative)
|
||||
result[0] |= 0x80;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// The representation of nBits uses another home-brew encoding, as a way to represent a large
|
||||
@ -341,7 +392,7 @@ public class Utils {
|
||||
if (size >= 1) bytes[4] = (byte) ((compact >> 16) & 0xFF);
|
||||
if (size >= 2) bytes[5] = (byte) ((compact >> 8) & 0xFF);
|
||||
if (size >= 3) bytes[6] = (byte) ((compact >> 0) & 0xFF);
|
||||
return decodeMPI(bytes);
|
||||
return decodeMPI(bytes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user