Skip to content

Commit 4ac107c

Browse files
lu-pintothomas-quadratic
authored andcommitted
Fix issue with mulSub borrows
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
1 parent a6f0489 commit 4ac107c

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

evm/src/main/java/org/hyperledger/besu/evm/UInt256.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,8 +1407,11 @@ private UInt192 mulSub(final long v2, final long v1, final long v0, final long q
14071407
carry = p1 + ((Long.compareUnsigned(v1, res) < 0) ? 1 : 0);
14081408

14091409
// Propagate overflows (borrows)
1410-
long z2 = v2 - carry - borrow;
1411-
borrow = (Long.compareUnsigned(v2, z2) < 0) ? 1 : 0;
1410+
long t2 = v2 - carry;
1411+
long z2 = t2 - borrow;
1412+
borrow =
1413+
((Long.compareUnsigned(v2, t2) < 0) ? 1 : 0)
1414+
| ((Long.compareUnsigned(t2, z2) < 0) ? 1 : 0);
14121415

14131416
if (borrow != 0) return addBack(z2, z1, z0); // unlikely
14141417
return new UInt192(z2, z1, z0);
@@ -1620,14 +1623,21 @@ private UInt256 mulSub(
16201623

16211624
p0 = u2 * q;
16221625
p1 = Math.unsignedMultiplyHigh(u2, q);
1623-
res = v2 - p0 - borrow;
1626+
long t2 = v2 - p0;
1627+
res = t2 - borrow;
16241628
long z2 = res - carry;
16251629
borrow = (Long.compareUnsigned(res, z2) < 0) ? 1 : 0;
1626-
carry = p1 + ((Long.compareUnsigned(v2, res) < 0) ? 1 : 0);
1630+
carry =
1631+
p1
1632+
+ ((Long.compareUnsigned(v2, t2) < 0) ? 1 : 0)
1633+
+ ((Long.compareUnsigned(t2, res) < 0) ? 1 : 0);
16271634

16281635
// Propagate overflows (borrows)
1629-
long z3 = v3 - carry - borrow;
1630-
borrow = (Long.compareUnsigned(v3, z3) < 0) ? 1 : 0;
1636+
long t3 = v3 - carry;
1637+
long z3 = t3 - borrow;
1638+
borrow =
1639+
((Long.compareUnsigned(v3, t3) < 0) ? 1 : 0)
1640+
| ((Long.compareUnsigned(t3, z3) < 0) ? 1 : 0);
16311641

16321642
if (borrow != 0) return addBack(z3, z2, z1, z0);
16331643
return new UInt256(z3, z2, z1, z0);

evm/src/test/java/org/hyperledger/besu/evm/UInt256Test.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,25 @@ public void mulMod_Modulus256_mulSubOverflow() {
462462
assertThat(remainder).isEqualTo(expected);
463463
}
464464

465+
@Test
466+
public void mulMod_ExecutionSpecStateTest_104() {
467+
Bytes value0 =
468+
Bytes.fromHexString("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
469+
Bytes value1 =
470+
Bytes.fromHexString("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
471+
Bytes value2 =
472+
Bytes.fromHexString("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
473+
BigInteger aInt = new BigInteger(1, value0.toArrayUnsafe());
474+
BigInteger bInt = new BigInteger(1, value1.toArrayUnsafe());
475+
BigInteger cInt = new BigInteger(1, value2.toArrayUnsafe());
476+
UInt256 a = UInt256.fromBytesBE(value0.toArrayUnsafe());
477+
UInt256 b = UInt256.fromBytesBE(value1.toArrayUnsafe());
478+
UInt256 c = UInt256.fromBytesBE(value2.toArrayUnsafe());
479+
Bytes32 remainder = Bytes32.leftPad(Bytes.wrap(a.mulMod(b, c).toBytesBE()));
480+
Bytes32 expected = bigIntTo32B(aInt.multiply(bInt).mod(cInt));
481+
assertThat(remainder).isEqualTo(expected);
482+
}
483+
465484
@Test
466485
public void mulMod_ExecutionSpecStateTest_457() {
467486
Bytes value0 =

0 commit comments

Comments
 (0)