Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
351640a
ADD: UInt256 implementation of evm's op MOD
thomas-quadratic Sep 18, 2025
2c28b1f
FIX: MOD uses UInt256
thomas-quadratic Sep 19, 2025
8c5f036
FIX: underflow bug in uLimb - prod_low - borrow
thomas-quadratic Sep 22, 2025
b466c15
FIX: add back original test and left-pad inside toBytesBE()
thomas-quadratic Sep 23, 2025
c10375a
ADD: add back detailed benchmarks by sizes
thomas-quadratic Sep 23, 2025
9264ead
FIX: reincorporate zero modulus shortcut and random bench
thomas-quadratic Sep 25, 2025
c904842
ENH: AddMod operation accelerated with UInt256
thomas-quadratic Sep 25, 2025
7f3cf53
ADD: benchmarks for AddMod
thomas-quadratic Sep 26, 2025
9252761
ENH: MulMod Operation accelerated with UInt256
thomas-quadratic Sep 26, 2025
1b6cfc4
ADD: MulMod benchmarks + minor fixes
thomas-quadratic Sep 26, 2025
2786715
FIX: javadoc on UInt256
thomas-quadratic Sep 27, 2025
84f6bad
ADD: SMod operation with UInt256
thomas-quadratic Sep 30, 2025
c1085fe
FIX: spotless
thomas-quadratic Oct 1, 2025
49e0478
ADD: operations using BigInteger for comparaison
thomas-quadratic Oct 1, 2025
1df538f
ADD: benchmarking ByteBuffer
thomas-quadratic Oct 1, 2025
0b9d5b2
ENH: fixed-width allocation
thomas-quadratic Oct 2, 2025
a091237
FIX: ModOperations use UInt256
thomas-quadratic Oct 3, 2025
14774b9
FIX: sigmod tests bigintegers to 32Bytes
thomas-quadratic Oct 7, 2025
7fb232e
TEST: add fuzzing test case
thomas-quadratic Oct 8, 2025
5f51b50
Add UInt256 prop tests (failing)
moodmosaic Oct 2, 2025
13caf1f
Run ./gradlew :evm:spotlessApply
moodmosaic Oct 9, 2025
c675167
Pad signedMod property inputs to 32 bytes
moodmosaic Oct 9, 2025
98c67b0
FIX: prop test failing on shiftLeft
thomas-quadratic Oct 9, 2025
3667423
FIX: remove unused methods add, mul, shifts
thomas-quadratic Oct 10, 2025
7c5b000
ENH: reincrease the sample size in unit tests to 300
thomas-quadratic Oct 10, 2025
f2a7157
FIX: removing deadcode and some javadocs
thomas-quadratic Oct 13, 2025
2aa7779
Merge branch 'main' into feature/uint256-op-modulus
ahamlat Oct 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,149 @@
import org.hyperledger.besu.evm.operation.AddModOperation;
import org.hyperledger.besu.evm.operation.Operation;

import java.util.concurrent.ThreadLocalRandom;

import org.apache.tuweni.bytes.Bytes;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Setup;

public class AddModOperationBenchmark extends TernaryOperationBenchmark {

// Benches for (a + b) % c

// Define available scenarios
public enum Case {
ADDMOD_32_32_32(1, 1, 1),
ADDMOD_64_32_32(2, 1, 1),
ADDMOD_64_64_32(2, 2, 1),
ADDMOD_64_64_64(2, 2, 2),
ADDMOD_128_32_32(4, 1, 1),
ADDMOD_128_64_32(4, 2, 1),
ADDMOD_128_64_64(4, 2, 2),
ADDMOD_128_128_32(4, 4, 1),
ADDMOD_128_128_64(4, 4, 2),
ADDMOD_128_128_128(4, 4, 3),
ADDMOD_192_32_32(6, 1, 1),
ADDMOD_192_64_32(6, 2, 1),
ADDMOD_192_64_64(6, 2, 2),
ADDMOD_192_128_32(6, 4, 1),
ADDMOD_192_128_64(6, 4, 2),
ADDMOD_192_128_128(6, 4, 4),
ADDMOD_192_192_32(6, 6, 1),
ADDMOD_192_192_64(6, 6, 2),
ADDMOD_192_192_128(6, 6, 4),
ADDMOD_192_192_192(6, 6, 6),
ADDMOD_256_32_32(8, 1, 1),
ADDMOD_256_64_32(8, 2, 1),
ADDMOD_256_64_64(8, 2, 2),
ADDMOD_256_128_32(8, 4, 1),
ADDMOD_256_128_64(8, 4, 2),
ADDMOD_256_128_128(8, 4, 4),
ADDMOD_256_192_32(8, 6, 1),
ADDMOD_256_192_64(8, 6, 2),
ADDMOD_256_192_128(8, 6, 4),
ADDMOD_256_192_192(8, 6, 6),
ADDMOD_256_256_32(8, 8, 1),
ADDMOD_256_256_64(8, 8, 2),
ADDMOD_256_256_128(8, 8, 4),
ADDMOD_256_256_192(8, 8, 6),
ADDMOD_256_256_256(8, 8, 8),
LARGER_ADDMOD_64_64_128(2, 2, 4),
LARGER_ADDMOD_192_192_256(6, 6, 8),
ZERO_ADDMOD_128_256_0(4, 8, 0),
FULL_RANDOM(-1, -1, -1);

final int aSize;
final int bSize;
final int cSize;

Case(final int aSize, final int bSize, final int cSize) {
this.aSize = aSize;
this.bSize = bSize;
this.cSize = cSize;
}
}

@Param({
"ADDMOD_32_32_32",
"ADDMOD_64_32_32",
"ADDMOD_64_64_32",
"ADDMOD_64_64_64",
"ADDMOD_128_32_32",
"ADDMOD_128_64_32",
"ADDMOD_128_64_64",
"ADDMOD_128_128_32",
"ADDMOD_128_128_64",
"ADDMOD_128_128_128",
"ADDMOD_192_32_32",
"ADDMOD_192_64_32",
"ADDMOD_192_64_64",
"ADDMOD_192_128_32",
"ADDMOD_192_128_64",
"ADDMOD_192_128_128",
"ADDMOD_192_192_32",
"ADDMOD_192_192_64",
"ADDMOD_192_192_128",
"ADDMOD_192_192_192",
"ADDMOD_256_32_32",
"ADDMOD_256_64_32",
"ADDMOD_256_64_64",
"ADDMOD_256_128_32",
"ADDMOD_256_128_64",
"ADDMOD_256_128_128",
"ADDMOD_256_192_32",
"ADDMOD_256_192_64",
"ADDMOD_256_192_128",
"ADDMOD_256_192_192",
"ADDMOD_256_256_32",
"ADDMOD_256_256_64",
"ADDMOD_256_256_128",
"ADDMOD_256_256_192",
"ADDMOD_256_256_256",
"LARGER_ADDMOD_64_64_128",
"LARGER_ADDMOD_192_192_256",
"ZERO_ADDMOD_128_256_0",
"FULL_RANDOM"
})
private String caseName;

@Setup(Level.Iteration)
@Override
public void setUp() {
frame = BenchmarkHelper.createMessageCallFrame();

Case scenario = Case.valueOf(caseName);
aPool = new Bytes[SAMPLE_SIZE];
bPool = new Bytes[SAMPLE_SIZE];
cPool = new Bytes[SAMPLE_SIZE];

final ThreadLocalRandom random = ThreadLocalRandom.current();
int aSize;
int bSize;
int cSize;

for (int i = 0; i < SAMPLE_SIZE; i++) {
if (scenario.aSize < 0) aSize = random.nextInt(1, 33);
else aSize = scenario.aSize * 4;
if (scenario.bSize < 0) bSize = random.nextInt(1, 33);
else bSize = scenario.bSize * 4;
if (scenario.cSize < 0) cSize = random.nextInt(1, 33);
else cSize = scenario.cSize * 4;

final byte[] a = new byte[aSize];
final byte[] b = new byte[bSize];
final byte[] c = new byte[cSize];
random.nextBytes(a);
random.nextBytes(b);
random.nextBytes(c);
aPool[i] = Bytes.wrap(a);
bPool[i] = Bytes.wrap(b);
cPool[i] = Bytes.wrap(c);
}
index = 0;
}

@Override
protected Operation.OperationResult invoke(final MessageFrame frame) {
return AddModOperation.staticOperation(frame);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,113 @@
import org.hyperledger.besu.evm.operation.ModOperation;
import org.hyperledger.besu.evm.operation.Operation;

import java.math.BigInteger;
import java.util.concurrent.ThreadLocalRandom;

import org.apache.tuweni.bytes.Bytes;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Setup;

public class ModOperationBenchmark extends BinaryOperationBenchmark {
// Benches for a % b

// Define available scenarios
public enum Case {
MOD_32_32(1, 1),
MOD_64_32(2, 1),
MOD_64_64(2, 2),
MOD_128_32(4, 1),
MOD_128_64(4, 2),
MOD_128_128(4, 4),
MOD_192_32(6, 1),
MOD_192_64(6, 2),
MOD_192_128(6, 4),
MOD_192_192(6, 6),
MOD_256_32(8, 1),
MOD_256_64(8, 2),
MOD_256_128(8, 4),
MOD_256_192(8, 6),
MOD_256_256(8, 8),
LARGER_MOD_64_128(2, 4),
LARGER_MOD_192_256(6, 8),
ZERO_MOD_128_0(4, 0),
FULL_RANDOM(-1, -1);

final int divSize;
final int modSize;

Case(final int divSize, final int modSize) {
this.divSize = divSize;
this.modSize = modSize;
}
}

@Param({
"MOD_32_32",
"MOD_64_32",
"MOD_64_64",
"MOD_128_32",
"MOD_128_64",
"MOD_128_128",
"MOD_192_32",
"MOD_192_64",
"MOD_192_128",
"MOD_192_192",
"MOD_256_32",
"MOD_256_64",
"MOD_256_128",
"MOD_256_192",
"MOD_256_256",
"LARGER_MOD_64_128",
"LARGER_MOD_192_256",
"ZERO_MOD_128_0",
"FULL_RANDOM"
})
private String caseName;

@Setup(Level.Iteration)
@Override
public void setUp() {
frame = BenchmarkHelper.createMessageCallFrame();

Case scenario = Case.valueOf(caseName);
aPool = new Bytes[SAMPLE_SIZE];
bPool = new Bytes[SAMPLE_SIZE];

final ThreadLocalRandom random = ThreadLocalRandom.current();
int aSize;
int bSize;

for (int i = 0; i < SAMPLE_SIZE; i++) {
if (scenario.divSize < 0) aSize = random.nextInt(1, 33);
else aSize = scenario.divSize * 4;
if (scenario.modSize < 0) bSize = random.nextInt(1, 33);
else bSize = scenario.modSize * 4;

final byte[] a = new byte[aSize];
final byte[] b = new byte[bSize];
random.nextBytes(a);
random.nextBytes(b);

// Swap a and b if necessary
if ((scenario.divSize != scenario.modSize)) {
aPool[i] = Bytes.wrap(a);
bPool[i] = Bytes.wrap(b);
} else {
BigInteger aInt = new BigInteger(a);
BigInteger bInt = new BigInteger(b);
if ((aInt.compareTo(bInt) < 0)) {
aPool[i] = Bytes.wrap(b);
bPool[i] = Bytes.wrap(a);
} else {
aPool[i] = Bytes.wrap(a);
bPool[i] = Bytes.wrap(b);
}
}
}
index = 0;
}

@Override
protected Operation.OperationResult invoke(final MessageFrame frame) {
Expand Down
Loading