Fix overflow for DataWord calculations and add unit test for multiply
This commit is contained in:
parent
729e2822ce
commit
33b59c6583
|
@ -287,4 +287,36 @@ public class ByteUtil {
|
||||||
}
|
}
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to copy a byte array into a new byte array with given size.
|
||||||
|
* If the src length is smaller than the given size, the result will be left-padded
|
||||||
|
* with zeros.
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* @param size
|
||||||
|
* @return Byte array of given size with a copy of the </code>src</code>
|
||||||
|
*/
|
||||||
|
public static byte[] copyToArray(byte[] src, int size) {
|
||||||
|
byte[] dest = ByteBuffer.allocate(size).array();
|
||||||
|
return copyToArray(src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to copy a byte array into a given byte array.
|
||||||
|
* If the src length is smaller than the given size, the result will be left-padded
|
||||||
|
* with the original bytes.
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* @param dest
|
||||||
|
* @param size
|
||||||
|
* @return Destination byte array filled with a copy of the </code>src</code>
|
||||||
|
*/
|
||||||
|
public static byte[] copyToArray(byte[] src, byte[] dest) {
|
||||||
|
if (src.length > dest.length)
|
||||||
|
System.arraycopy(src, src.length-dest.length, dest, 0, dest.length-1);
|
||||||
|
else
|
||||||
|
System.arraycopy(src, 0, dest, dest.length - src.length, src.length);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -163,26 +163,16 @@ public class DataWord implements Comparable<DataWord> {
|
||||||
|
|
||||||
// old add-method with BigInteger quick hack
|
// old add-method with BigInteger quick hack
|
||||||
public void add2(DataWord word) {
|
public void add2(DataWord word) {
|
||||||
|
|
||||||
BigInteger result = value().add(word.value());
|
BigInteger result = value().add(word.value());
|
||||||
byte[] bytes = result.toByteArray();
|
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: mul can be done in more efficient way
|
// TODO: mul can be done in more efficient way
|
||||||
// TODO: with shift left shift right trick
|
// TODO: with shift left shift right trick
|
||||||
// TODO without BigInteger quick hack
|
// TODO without BigInteger quick hack
|
||||||
public void mul(DataWord word) {
|
public void mul(DataWord word) {
|
||||||
|
|
||||||
BigInteger result = value().multiply(word.value());
|
BigInteger result = value().multiply(word.value());
|
||||||
byte[] bytes = result.toByteArray();
|
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: improve with no BigInteger
|
// TODO: improve with no BigInteger
|
||||||
|
@ -194,11 +184,7 @@ public class DataWord implements Comparable<DataWord> {
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger result = value().divide(word.value());
|
BigInteger result = value().divide(word.value());
|
||||||
byte[] bytes = result.toByteArray();
|
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: improve with no BigInteger
|
// TODO: improve with no BigInteger
|
||||||
|
@ -210,37 +196,25 @@ public class DataWord implements Comparable<DataWord> {
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger result = sValue().divide(word.sValue());
|
BigInteger result = sValue().divide(word.sValue());
|
||||||
byte[] bytes = result.toByteArray();
|
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
ByteBuffer data = ByteBuffer.allocate(32);
|
||||||
if (result.compareTo(BigInteger.ZERO) == -1)
|
if (result.signum() == -1)
|
||||||
Arrays.fill(data.array(), (byte) 0xFF);
|
Arrays.fill(data.array(), (byte) 0xFF);
|
||||||
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
this.data = ByteUtil.copyToArray(result.toByteArray(), data.array());
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: improve with no BigInteger
|
// TODO: improve with no BigInteger
|
||||||
public void sub(DataWord word) {
|
public void sub(DataWord word) {
|
||||||
|
|
||||||
BigInteger result = value().subtract(word.value());
|
BigInteger result = value().subtract(word.value());
|
||||||
byte[] bytes = result.toByteArray();
|
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: improve with no BigInteger
|
// TODO: improve with no BigInteger
|
||||||
public void exp(DataWord word) {
|
public void exp(DataWord word) {
|
||||||
|
|
||||||
BigInteger result = value().pow(word.intValue());
|
BigInteger result = value().pow(word.intValue());
|
||||||
byte[] bytes = result.toByteArray();
|
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: improve with no BigInteger
|
// TODO: improve with no BigInteger
|
||||||
|
@ -252,11 +226,7 @@ public class DataWord implements Comparable<DataWord> {
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger result = value().mod(word.value());
|
BigInteger result = value().mod(word.value());
|
||||||
byte[] bytes = result.toByteArray();
|
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: improve with no BigInteger
|
// TODO: improve with no BigInteger
|
||||||
|
@ -268,14 +238,12 @@ public class DataWord implements Comparable<DataWord> {
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger result = sValue().mod( word.sValue());
|
BigInteger result = sValue().mod( word.sValue());
|
||||||
byte[] bytes = result.toByteArray();
|
|
||||||
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(32);
|
ByteBuffer data = ByteBuffer.allocate(32);
|
||||||
if (result.compareTo(BigInteger.ZERO) == -1)
|
if (result.signum() == -1)
|
||||||
Arrays.fill(data.array(), (byte) 0xFF);
|
Arrays.fill(data.array(), (byte) 0xFF);
|
||||||
|
|
||||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
this.data = ByteUtil.copyToArray(result.toByteArray(), data.array());
|
||||||
this.data = data.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -88,4 +88,37 @@ public class DataWordTest {
|
||||||
assertEquals(32, y.getData().length);
|
assertEquals(32, y.getData().length);
|
||||||
assertEquals(expected, Hex.toHexString(y.getData()));
|
assertEquals(expected, Hex.toHexString(y.getData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMul() {
|
||||||
|
byte[] one = new byte[32];
|
||||||
|
one[31] = 0x1; // 0x0000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
two[11] = 0x1; // 0x0000000000000000000000010000000000000000000000000000000000000000
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);// System.out.println(x.value());
|
||||||
|
DataWord y = new DataWord(two);// System.out.println(y.value());
|
||||||
|
x.mul(y);
|
||||||
|
assertEquals(32, y.getData().length);
|
||||||
|
assertEquals("0000000000000000000000010000000000000000000000000000000000000000", Hex.toHexString(y.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMulOverflow() {
|
||||||
|
|
||||||
|
byte[] one = new byte[32];
|
||||||
|
one[30] = 0x1; // 0x0000000000000000000000000000000000000000000000000000000000000100
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
two[0] = 0x1; // 0x1000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);// System.out.println(x.value());
|
||||||
|
DataWord y = new DataWord(two);// System.out.println(y.value());
|
||||||
|
x.mul(y);
|
||||||
|
assertEquals(32, y.getData().length);
|
||||||
|
assertEquals("0100000000000000000000000000000000000000000000000000000000000000", Hex.toHexString(y.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue