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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
public void add2(DataWord word) {
|
||||
|
||||
BigInteger result = value().add(word.value());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||
}
|
||||
|
||||
// TODO: mul can be done in more efficient way
|
||||
// TODO: with shift left shift right trick
|
||||
// TODO without BigInteger quick hack
|
||||
public void mul(DataWord word) {
|
||||
|
||||
BigInteger result = value().multiply(word.value());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||
}
|
||||
|
||||
// TODO: improve with no BigInteger
|
||||
|
@ -194,11 +184,7 @@ public class DataWord implements Comparable<DataWord> {
|
|||
}
|
||||
|
||||
BigInteger result = value().divide(word.value());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||
}
|
||||
|
||||
// TODO: improve with no BigInteger
|
||||
|
@ -210,37 +196,25 @@ public class DataWord implements Comparable<DataWord> {
|
|||
}
|
||||
|
||||
BigInteger result = sValue().divide(word.sValue());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
if (result.compareTo(BigInteger.ZERO) == -1)
|
||||
if (result.signum() == -1)
|
||||
Arrays.fill(data.array(), (byte) 0xFF);
|
||||
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), data.array());
|
||||
}
|
||||
|
||||
|
||||
// TODO: improve with no BigInteger
|
||||
public void sub(DataWord word) {
|
||||
|
||||
BigInteger result = value().subtract(word.value());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||
}
|
||||
|
||||
// TODO: improve with no BigInteger
|
||||
public void exp(DataWord word) {
|
||||
|
||||
BigInteger result = value().pow(word.intValue());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||
}
|
||||
|
||||
// TODO: improve with no BigInteger
|
||||
|
@ -252,11 +226,7 @@ public class DataWord implements Comparable<DataWord> {
|
|||
}
|
||||
|
||||
BigInteger result = value().mod(word.value());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), 32);
|
||||
}
|
||||
|
||||
// TODO: improve with no BigInteger
|
||||
|
@ -268,14 +238,12 @@ public class DataWord implements Comparable<DataWord> {
|
|||
}
|
||||
|
||||
BigInteger result = sValue().mod( word.sValue());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
if (result.compareTo(BigInteger.ZERO) == -1)
|
||||
if (result.signum() == -1)
|
||||
Arrays.fill(data.array(), (byte) 0xFF);
|
||||
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
this.data = ByteUtil.copyToArray(result.toByteArray(), data.array());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
|
|
@ -88,4 +88,37 @@ public class DataWordTest {
|
|||
assertEquals(32, y.getData().length);
|
||||
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