Benchmarking in evmtool (#5754)

Add a benchmarking command to EvmTool to benchmark performance of
selected benchmarks.

Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
pull/5765/head
Danno Ferrin 1 year ago committed by GitHub
parent 94f5e73239
commit 7019131d7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  3. 20
      crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256K1.java
  4. 95
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java
  5. 4
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java
  6. 183
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/AltBN128Benchmark.java
  7. 153
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java
  8. 466
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/ECRecoverBenchmark.java
  9. 164
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/ModExpBenchmark.java
  10. 72
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/Secp256k1Benchmark.java
  11. 25
      evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java
  12. 12
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java
  13. 24
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BigIntegerModularExponentiationPrecompiledContract.java
  14. 17
      evm/src/main/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContract.java
  15. 38
      evm/src/test/java/org/hyperledger/besu/evm/precompile/Benchmarks.java
  16. 66
      gradle/verification-metadata.xml

@ -7,6 +7,7 @@
- Add ABI-decoded revert reason to `eth_call` and `eth_estimateGas` responses [#5705](https://github.com/hyperledger/besu/issues/5705) - Add ABI-decoded revert reason to `eth_call` and `eth_estimateGas` responses [#5705](https://github.com/hyperledger/besu/issues/5705)
### Additions and Improvements ### Additions and Improvements
- Added `benchmark` subcommand to `evmtool` [#5754](https://github.com/hyperledger/besu/issues/5754)
### Bug Fixes ### Bug Fixes
- Make smart contract permissioning features work with london fork [#5727](https://github.com/hyperledger/besu/pull/5727) - Make smart contract permissioning features work with london fork [#5727](https://github.com/hyperledger/besu/pull/5727)

@ -1852,7 +1852,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
} }
if (unstableNativeLibraryOptions.getNativeModExp() if (unstableNativeLibraryOptions.getNativeModExp()
&& BigIntegerModularExponentiationPrecompiledContract.isNative()) { && BigIntegerModularExponentiationPrecompiledContract.maybeEnableNative()) {
logger.info("Using the native implementation of modexp"); logger.info("Using the native implementation of modexp");
} else { } else {
BigIntegerModularExponentiationPrecompiledContract.disableNative(); BigIntegerModularExponentiationPrecompiledContract.disableNative();

@ -59,10 +59,7 @@ public class SECP256K1 extends AbstractSECP256 {
super(CURVE_NAME, SecP256K1Curve.q); super(CURVE_NAME, SecP256K1Curve.q);
// use the native library implementation, if it is available // use the native library implementation, if it is available
useNative = LibSecp256k1.CONTEXT != null; maybeEnableNative();
if (!useNative) {
LOG.info("Native secp256k1 not available");
}
} }
@Override @Override
@ -70,6 +67,21 @@ public class SECP256K1 extends AbstractSECP256 {
useNative = false; useNative = false;
} }
/**
* Attempt to enable the native library for secp256k1
*
* @return true if the native library was enabled.
*/
public boolean maybeEnableNative() {
try {
useNative = LibSecp256k1.CONTEXT != null;
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
LOG.info("Native secp256k1 not available - {}", e.getMessage());
useNative = false;
}
return useNative;
}
@Override @Override
public boolean isNative() { public boolean isNative() {
return useNative; return useNative;

@ -0,0 +1,95 @@
/*
* Copyright contributors to Hyperledger Besu
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evmtool;
import static org.hyperledger.besu.evmtool.BenchmarkSubCommand.COMMAND_NAME;
import static picocli.CommandLine.ScopeType.INHERIT;
import org.hyperledger.besu.BesuInfo;
import org.hyperledger.besu.evm.EvmSpecVersion;
import org.hyperledger.besu.evmtool.benchmarks.AltBN128Benchmark;
import org.hyperledger.besu.evmtool.benchmarks.BenchmarkExecutor;
import org.hyperledger.besu.evmtool.benchmarks.ECRecoverBenchmark;
import org.hyperledger.besu.evmtool.benchmarks.ModExpBenchmark;
import org.hyperledger.besu.evmtool.benchmarks.Secp256k1Benchmark;
import java.io.PrintStream;
import java.util.EnumSet;
import picocli.CommandLine;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.ParentCommand;
@CommandLine.Command(
name = COMMAND_NAME,
description = "Execute an Ethereum State Test.",
mixinStandardHelpOptions = true,
versionProvider = VersionProvider.class)
public class BenchmarkSubCommand implements Runnable {
public static final String COMMAND_NAME = "benchmark";
private final PrintStream output;
enum Benchmark {
altBn128(new AltBN128Benchmark()),
// blake2f
EcRecover(new ECRecoverBenchmark()),
ModExp(new ModExpBenchmark()),
Secp256k1(new Secp256k1Benchmark());
final BenchmarkExecutor benchmarkExecutor;
Benchmark(final BenchmarkExecutor benchmarkExecutor) {
this.benchmarkExecutor = benchmarkExecutor;
}
}
@Option(
names = {"--native"},
description = "Use the native libraries.",
scope = INHERIT,
negatable = true)
Boolean nativeCode;
@Option(
names = {"--fork"},
paramLabel = "<String>",
description = "Fork to evaluate, when it impacts gas costing.")
String fork = EvmSpecVersion.defaultVersion().getName();
@Parameters(description = "One or more of ${COMPLETION-CANDIDATES}.")
EnumSet<Benchmark> benchmarks = EnumSet.noneOf(Benchmark.class);
@ParentCommand EvmToolCommand parentCommand;
public BenchmarkSubCommand() {
// PicoCLI requires this
this(System.out);
}
public BenchmarkSubCommand(final PrintStream output) {
this.output = output;
}
@Override
public void run() {
System.out.println(BesuInfo.version());
var benchmarksToRun = benchmarks.isEmpty() ? EnumSet.allOf(Benchmark.class) : benchmarks;
for (var benchmark : benchmarksToRun) {
System.out.println("Benchmarks for " + benchmark);
benchmark.benchmarkExecutor.runBenchmark(output, nativeCode, fork);
}
}
}

@ -85,6 +85,7 @@ import picocli.CommandLine.Option;
footerHeading = "%n", footerHeading = "%n",
footer = "Hyperledger Besu is licensed under the Apache License 2.0", footer = "Hyperledger Besu is licensed under the Apache License 2.0",
subcommands = { subcommands = {
BenchmarkSubCommand.class,
B11rSubCommand.class, B11rSubCommand.class,
CodeValidateSubCommand.class, CodeValidateSubCommand.class,
StateTestSubCommand.class, StateTestSubCommand.class,
@ -227,6 +228,9 @@ public class EvmToolCommand implements Runnable {
out = output; out = output;
in = input; in = input;
// don't require exact case to match enum values
commandLine.setCaseInsensitiveEnumValuesAllowed(true);
// add dagger-injected options // add dagger-injected options
commandLine.addMixin("Dagger Options", daggerOptions); commandLine.addMixin("Dagger Options", daggerOptions);

@ -0,0 +1,183 @@
/*
* Copyright contributors to Hyperledger Besu
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evmtool.benchmarks;
import org.hyperledger.besu.evm.EvmSpecVersion;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract;
import org.hyperledger.besu.evm.precompile.AltBN128AddPrecompiledContract;
import org.hyperledger.besu.evm.precompile.AltBN128MulPrecompiledContract;
import org.hyperledger.besu.evm.precompile.AltBN128PairingPrecompiledContract;
import java.io.PrintStream;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.tuweni.bytes.Bytes;
/** Benchmark AltBN128 add, mul, and pairings */
public class AltBN128Benchmark extends BenchmarkExecutor {
/** Benchmark AltBN128 add, mul, and pairings with default warmup and iterations */
public AltBN128Benchmark() {
super(MATH_WARMUP, MATH_ITERATIONS);
}
@Override
public void runBenchmark(
final PrintStream output, final Boolean attemptNative, final String fork) {
EvmSpecVersion forkVersion = EvmSpecVersion.fromName(fork);
if (attemptNative != null
&& (!attemptNative || !AbstractAltBnPrecompiledContract.maybeEnableNative())) {
AbstractAltBnPrecompiledContract.disableNative();
}
output.println(
AbstractAltBnPrecompiledContract.isNative() ? "Native AltBN128" : "Java AltBN128");
GasCalculator gasCalculator = gasCalculatorForFork(fork);
benchmarkAdd(output, gasCalculator, forkVersion);
benchmarkMul(output, gasCalculator, forkVersion);
benchmarkPairings(output, gasCalculator, forkVersion);
}
private void benchmarkAdd(
final PrintStream output,
final GasCalculator gasCalculator,
final EvmSpecVersion forkVersion) {
final Map<String, Bytes> addTestCases = new LinkedHashMap<>();
addTestCases.put(
"Add",
Bytes.fromHexString(
"17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"
+ "01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c"
+ "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"
+ "2e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb"));
AltBN128AddPrecompiledContract addContract =
EvmSpecVersion.ISTANBUL.compareTo(forkVersion) < 0
? AltBN128AddPrecompiledContract.byzantium(gasCalculator)
: AltBN128AddPrecompiledContract.istanbul(gasCalculator);
warmup = MATH_WARMUP / addTestCases.size();
iterations = MATH_ITERATIONS / addTestCases.size();
double execTime = Double.MIN_VALUE; // a way to dodge divide by zero
long gasCost = 0;
for (final Map.Entry<String, Bytes> testCase : addTestCases.entrySet()) {
execTime += runPrecompileBenchmark(testCase.getValue(), addContract);
gasCost += addContract.gasRequirement(testCase.getValue());
}
execTime /= addTestCases.size();
gasCost /= addTestCases.size();
output.printf(
"AltBN128 Add %,6d gas @%,7.1f µs /%,8.1f MGps%n",
gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
}
private void benchmarkMul(
final PrintStream output,
final GasCalculator gasCalculator,
final EvmSpecVersion forkVersion) {
final Map<String, Bytes> mulTestCases = new LinkedHashMap<>();
mulTestCases.put(
"mul",
Bytes.fromHexString(
"17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"
+ "01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c"
+ "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"
+ "2e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb"));
AltBN128MulPrecompiledContract mulContract =
EvmSpecVersion.ISTANBUL.compareTo(forkVersion) < 0
? AltBN128MulPrecompiledContract.byzantium(gasCalculator)
: AltBN128MulPrecompiledContract.istanbul(gasCalculator);
warmup = MATH_WARMUP / mulTestCases.size();
iterations = MATH_ITERATIONS / mulTestCases.size();
double execTime = Double.MIN_VALUE; // a way to dodge divide by zero
long gasCost = 0;
for (final Map.Entry<String, Bytes> testCase : mulTestCases.entrySet()) {
execTime += runPrecompileBenchmark(testCase.getValue(), mulContract);
gasCost += mulContract.gasRequirement(testCase.getValue());
}
execTime /= mulTestCases.size();
gasCost /= mulTestCases.size();
output.printf(
"AltBN128 Mul %,6d gas @%,7.1f µs /%,8.1f MGps%n",
gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
}
private void benchmarkPairings(
final PrintStream output,
final GasCalculator gasCalculator,
final EvmSpecVersion forkVersion) {
final Bytes[] pairings = {
Bytes.fromHexString(
"0x0fc6ebd1758207e311a99674dc77d28128643c057fb9ca2c92b4205b6bf57ed2"
+ "1e50042f97b7a1f2768fa15f6683eca9ee7fa8ee655d94246ab85fb1da3f0b90"
+ "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2"
+ "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed"
+ "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b"
+ "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"),
Bytes.fromHexString(
"0x2b101be01b2f064cba109e065dc0b5e5bf6b64ed4054b82af3a7e6e34c1e2005"
+ "1a4d9ceecf9115a98efd147c4abb2684102d3e925938989153b9ff330523cdb4"
+ "08d554bf59102bbb961ba81107ec71785ef9ce6638e5332b6c1a58b87447d181"
+ "01cf7cc93bfbf7b2c5f04a3bc9cb8b72bbcf2defcabdceb09860c493bdf1588d"
+ "02cb2a424885c9e412b94c40905b359e3043275cd29f5b557f008cd0a3e0c0dc"
+ "204e5d81d86c561f9344ad5f122a625f259996b065b80cbbe74a9ad97b6d7cc2"
+ "07402fdc3bc28a434909f24695adea3e9418d9857efc8c71f67a470a17f3cf12"
+ "255dbc3a8b5c2c1a7a3f8c59e2f5b6e04bc4d7b7bb82fcbe18b2294305c8473b"
+ "19156e854972d656d1020003e5781972d84081309cdf71baacf6c6e29272f5ff"
+ "2acded377df8902b7a75de6c0f53c161f3a2ff3f374470b78d5b3c4d826d84d5"
+ "1731ef3b84913296c30a649461b2ca35e3fcc2e3031ea2386d32f885ff096559"
+ "0919e7685f6ea605db14f311dede6e83f21937f05cfc53ac1dbe45891c47bf2a"),
Bytes.fromHexString(
"0x1a3fabea802788c8aa88741c6a68f271b221eb75838bb1079381f3f1ae414f40"
+ "126308d6cdb6b7efceb1ec0016b99cf7a1e5780f5a9a775d43bc7f2b6fd510e2"
+ "11b35cf2c85531eab64b96eb2eef487e0eb60fb9207fe4763e7f6e02dcead646"
+ "2cbea52f3417b398aed9e355ed16934a81b72d2646e3bf90dbc2dcba294b631d"
+ "2c6518cd26310e541a799357d1ae8bc477b162f2040407b965ecd777e26d31f7"
+ "125170b5860fb8f8da2c43e00ea4a83bcc1a974e47e59fcd657851d2b0dd1655"
+ "130a2183533392b5fd031857eb4c199a19382f39fcb666d6133b3a6e5784d6a5"
+ "2cca76f2bc625d2e61a41b5f382eadf1df1756dd392f639c3d9f3513099e63f9"
+ "07ecba8131b3fb354272c86d01577e228c5bd5fb6404bbaf106d7f4858dc2996"
+ "1c5d49a9ae291a2a2213da57a76653391fa1fc0fa7c534afa124ad71b7fdd719"
+ "10f1a73f94a8f077f478d069d7cf1c49444f64cd20ed75d4f6de3d8986147cf8"
+ "0d5816f2f116c5cc0be7dfc4c0b4c592204864acb70ad5f789013389a0092ce4"
+ "2650b89e5540eea1375b27dfd9081a0622e03352e5c6a7593df72e2113328e64"
+ "21991b3e5100845cd9b8f0fa16c7fe5f40152e702e61f4cdf0d98e7f213b1a47"
+ "10520008be7609bdb92145596ac6bf37da0269f7460e04e8e4701c3afbae0e52"
+ "0664e736b2af7bf9125f69fe5c3706cd893cd769b1dae8a6e3d639e2d76e66e2"
+ "1cacce8776f5ada6b35036f9343faab26c91b9aea83d3cb59cf5628ffe18ab1b"
+ "03b48ca7e6d84fca619aaf81745fbf9c30e5a78ed4766cc62b0f12aea5044f56")
};
final AltBN128PairingPrecompiledContract contract =
EvmSpecVersion.ISTANBUL.compareTo(forkVersion) < 0
? AltBN128PairingPrecompiledContract.byzantium(gasCalculator)
: AltBN128PairingPrecompiledContract.istanbul(gasCalculator);
warmup = MATH_WARMUP / 20;
iterations = MATH_ITERATIONS / 20;
for (int i = 0; i < pairings.length; i++) {
final double execTime = runPrecompileBenchmark(pairings[i], contract);
final long gasCost = contract.gasRequirement(pairings[i]);
output.printf(
"AltBN128 %d pairing %,6d gas @%,7.1f µs /%,8.1f MGps%n",
i * 2 + 2, gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
}
}
}

@ -0,0 +1,153 @@
/*
* Copyright contributors to Hyperledger Besu
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evmtool.benchmarks;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.EvmSpecVersion;
import org.hyperledger.besu.evm.code.CodeV0;
import org.hyperledger.besu.evm.fluent.SimpleBlockValues;
import org.hyperledger.besu.evm.fluent.SimpleWorld;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ByzantiumGasCalculator;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator;
import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator;
import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator;
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator;
import org.hyperledger.besu.evm.precompile.PrecompiledContract;
import java.io.PrintStream;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;
import org.apache.tuweni.bytes.Bytes;
/** Abstract class to support benchmarking of various client algorithms */
public abstract class BenchmarkExecutor {
static final int MATH_WARMUP = 10_000;
static final int MATH_ITERATIONS = 1_000;
int warmup;
int iterations;
static final MessageFrame fakeFrame =
MessageFrame.builder()
.type(MessageFrame.Type.CONTRACT_CREATION)
.contract(Address.ZERO)
.inputData(Bytes.EMPTY)
.sender(Address.ZERO)
.value(Wei.ZERO)
.apparentValue(Wei.ZERO)
.code(CodeV0.EMPTY_CODE)
.completer(__ -> {})
.address(Address.ZERO)
.blockHashLookup(n -> null)
.blockValues(new SimpleBlockValues())
.gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO)
.originator(Address.ZERO)
.initialGas(100_000L)
.worldUpdater(new SimpleWorld())
.build();
/**
* Run benchmarks with specified warmup and iterations
*
* @param warmup number of executions to run before timing
* @param iterations number of executions to time.
*/
protected BenchmarkExecutor(final int warmup, final int iterations) {
this.warmup = warmup;
this.iterations = iterations;
}
/** Run benchmarks with warmup and iterations set to MATH style benchmarks. */
protected BenchmarkExecutor() {
this(MATH_WARMUP, MATH_ITERATIONS);
}
/**
* Run the benchmark with the specific args. Execution will be done warmup + iterations times
*
* @param arg the bytes areguments to pass into the contract
* @param contract the precompiled contract to benchmark
* @return the mean number of seconds each timed iteration took.
*/
protected double runPrecompileBenchmark(final Bytes arg, final PrecompiledContract contract) {
if (contract.computePrecompile(arg, fakeFrame).getOutput() == null) {
throw new RuntimeException("Input is Invalid");
}
final Stopwatch timer = Stopwatch.createStarted();
for (int i = 0; i < warmup && timer.elapsed().getSeconds() < 1; i++) {
contract.computePrecompile(arg, fakeFrame);
}
timer.reset();
timer.start();
int executions = 0;
while (executions < iterations && timer.elapsed().getSeconds() < 1) {
contract.computePrecompile(arg, fakeFrame);
executions++;
}
timer.stop();
if (executions < 1) {
return Double.NaN;
}
final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D;
return elapsed / executions;
}
/**
* Return the gas calculator at a given fork. Some forks don't have a specific gas calculator and
* will return the prior one
*
* @param fork name of the fork
* @return a gas calculator
*/
public static GasCalculator gasCalculatorForFork(final String fork) {
return switch (EvmSpecVersion.valueOf(fork.toUpperCase())) {
case HOMESTEAD -> new HomesteadGasCalculator();
case FRONTIER -> new FrontierGasCalculator();
case BYZANTIUM -> new ByzantiumGasCalculator();
case CONSTANTINOPLE -> new ConstantinopleGasCalculator();
case PETERSBURG -> new PetersburgGasCalculator();
case ISTANBUL -> new IstanbulGasCalculator();
case BERLIN -> new BerlinGasCalculator();
case LONDON, PARIS -> new LondonGasCalculator();
case SHANGHAI -> new ShanghaiGasCalculator();
default -> new CancunGasCalculator();
};
}
/**
* Run the benchmarks
*
* @param output stream to print results to (typicall System.out)
* @param attemptNative Should the benchmark attempt to us native libraries? (null use the
* default, false disabled, true enabled)
* @param fork the fork name to run the benchmark against.
*/
public abstract void runBenchmark(
final PrintStream output, final Boolean attemptNative, final String fork);
}

@ -0,0 +1,466 @@
/*
* Copyright contributors to Hyperledger Besu
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evmtool.benchmarks;
import org.hyperledger.besu.crypto.SECP256K1;
import org.hyperledger.besu.evm.precompile.ECRECPrecompiledContract;
import java.io.PrintStream;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.tuweni.bytes.Bytes;
/** Benchmark ECRecover precompile (ECDSA key extraction + keccak hash) */
public class ECRecoverBenchmark extends BenchmarkExecutor {
/** Use default math based warmup and interations */
public ECRecoverBenchmark() {
super(MATH_WARMUP, MATH_ITERATIONS);
}
@Override
public void runBenchmark(
final PrintStream output, final Boolean attemptNative, final String fork) {
final Map<String, Bytes> testCases = new LinkedHashMap<>();
testCases.put(
"0x0c65a9d9ffc02c7c99e36e32ce0f950c7804ceda",
Bytes.fromHexString(
"0x0049872459827432342344987245982743234234498724598274323423429943000000000000000000000000000000000000000000000000000000000000001be8359c341771db7f9ea3a662a1741d27775ce277961470028e054ed3285aab8e31f63eaac35c4e6178abbc2a1073040ac9bbb0b67f2bc89a2e9593ba9abe8c53"));
testCases.put(
"0xc6e93f4c1920eaeaa1e699f76a7a8c18e3056074",
Bytes.fromHexString(
"0x82f3df49d3645876de6313df2bbe9fbce593f21341a7b03acdb9423bc171fcc9000000000000000000000000000000000000000000000000000000000000001cba13918f50da910f2d55a7ea64cf716ba31dad91856f45908dde900530377d8a112d60f36900d18eb8f9d3b4f85a697b545085614509e3520e4b762e35d0d6bd"));
testCases.put(
"0xfe26206ad0a5897a478dd046c56164553adaea20",
Bytes.fromHexString(
"0x0fcdd8f8c550589cbae6183bc40713beb8d11898a201d13d6d5e40bc9ebf221d000000000000000000000000000000000000000000000000000000000000001c3824317158d005cbe49614fa05798ea00f2ca9db302a5e92d55bcaecd33d33da3c7de48ebec95be7b5111a7812febed1421f839d4d480c98501b78666aefdcd3"));
testCases.put(
"0x39c0f4fbcd41581d5b440a7c9f964b903037e09e",
Bytes.fromHexString(
"0xeb9a6731fa269c24c2535aa00a4b31d7117a2791188120c71aacd97664d1cc16000000000000000000000000000000000000000000000000000000000000001c707c68dd904de055d735f9e5c4dfba46296ad38ff6ba8f0e5e3f4ae83243b84a5b1920d628abc74e4f3a09449011a9664ab9885f74fdc7628d417599207bde74"));
testCases.put(
"0x64849cfbf0353f2c80e2a1e558982f7c4738d9f1",
Bytes.fromHexString(
"0xf3ae1d9176371dd31accd73bb6bbaee561a041f5ac291a548880e1abe7b19e38000000000000000000000000000000000000000000000000000000000000001b116bd86d971b70ed540dc7c13756a99ff17644ed433781a3ffcc7359541d02fc4a2358ffc21682ece870e633cc8537f04be4ff75a142ecd35a951fc95fd1de57"));
testCases.put(
"0x5026d2655bc28bee480b2f31934f0970e8acc647",
Bytes.fromHexString(
"0x69567625d007e5c915eadb8b768f008227d57f4951f9d5711dfc72a8af13d35f000000000000000000000000000000000000000000000000000000000000001ba3ef328e9f95b4a28d9b8c20f3e9fc939bf94ad3611b4e1aaabb442f1c40545f6f83fe2c067d7a35f9bcb655894d15cd6d95d5e05c9fad33b2efa67592c0a4fe"));
testCases.put(
"0x24bf97810c294811aa8165c9a05717a7731342a0",
Bytes.fromHexString(
"0x5ecdd449eb48c111c596d6b41047547deb4bbb27eafa419d1d041d842f1d81cb000000000000000000000000000000000000000000000000000000000000001c7ee309958bcd2f7a8d0fa904f16358d7b1dd52dc653f62b0eba42eec74335a620bf25c9db104a22c77af694cdb56e115fe259eef0a5e7968698bad0a592f6a2d"));
testCases.put(
"0x9bdeac37b1bf31980c6e8cbc5bdfa38dacbc4c43",
Bytes.fromHexString(
"0x9a996c7083b19106163161ad5117a11703507ac61cad659c5bb164cd9d368672000000000000000000000000000000000000000000000000000000000000001bffc032f93b534eec6f76d194821f9fa70de06f0aac391e7f105401b23ab1a23071b55820c93857ed7e079e72f65798b2d5afad4f999048c1a987152bc5dbf78a"));
testCases.put(
"0x9ded673711119881765005a33ef7bb1961bfe98d",
Bytes.fromHexString(
"0xea3305a892449d8215a5c41c619a42aeef22f888ee1b2c370584a6eb9e16fa27000000000000000000000000000000000000000000000000000000000000001b8efcc5180b219820d57856f018a7de24b0c4c633dfae40a96a5110c4f94b947151f4320da2e79e2d5e5c0efaef659b60b7d3de1debb4e37853746395f9426f2b"));
testCases.put(
"0xd4bbacccff27e6e8534d14cd8fcd665d455dddf2",
Bytes.fromHexString(
"0xebb2b43c1070b6000aaa866071de173a24dbdec57443b9467c1aa11c0090d20c000000000000000000000000000000000000000000000000000000000000001bb52ebd3ee958d6487d7a6d68faa5df32e8f34a4703201feb6ea7687c1abf5b28439215bef624ef3799919da5980f3793f6aa14fd6dc43df3c5c652a4e2f6149b"));
testCases.put(
"0x5b73664bd5ef270f91775d27f47e436d960aa853",
Bytes.fromHexString(
"0xb28e4662bf41c1043e06400119c6c7804dcea81b1e4e8555c9db5be41380b1d3000000000000000000000000000000000000000000000000000000000000001ca010458d4c545fca2831e8ee9eb7857955d083feba0080c0b58a1b94233650572bfb5978a642da7b7f255562c47404ee3ad236d9f0319413f2e5a69cfafec2cb"));
testCases.put(
"0x200d8d10eab444331cb2a0802219771c11443205",
Bytes.fromHexString(
"0x694bace9fe95c0370ef0eb3c0c629186616e33469972ff6a7ecce90f3fe2ab2d000000000000000000000000000000000000000000000000000000000000001ca07e9497d29f7c9adae37b9a985c876b5b3ee6d21a9bc83cfcf27531cb5eb67879f317e2c145caaa798bb1b30fd96f32d843636559f195622f2fac69297f935a"));
testCases.put(
"0x4135437a672c7d48fefc4be43a26783fe030e9b7",
Bytes.fromHexString(
"0xc3964b44adfd407ce69ccae93c033b6418ab903c674e794681baadf3173e37c1000000000000000000000000000000000000000000000000000000000000001c28e8ff8b5d9e55740da1ab2f7cfb9b527509439b2a99117d40a2158501a5b4354cdda2112aa6a7e89019556011f50abec5c3ae48501a1594b831275a2f031999"));
testCases.put(
"0xff2726d26e39daf03ae70b7f4cce693329e3a027",
Bytes.fromHexString(
"0x0d56ee3eb6ecd6a949793c8afaa905550333dc9063bc58cdcace8a146f23b2af000000000000000000000000000000000000000000000000000000000000001cebdb65ebfd20803c364d393e4df95a3631d906d3ebeb7fae31bc5bdbf9297e6c5d4e7a93d40278c1c3ddd4659c58a0eeb01fa41a3ca78fdb184b4bf7b2e34af1"));
testCases.put(
"0x6c36670046a1f02fe217d95c5e78f5c84efd703e",
Bytes.fromHexString(
"0x23fa3e10e5b041840a8bd9055e9f6aca4c9764b6b21658bd6f126e6cf821e963000000000000000000000000000000000000000000000000000000000000001c19552a6e36c2c2c8fa97534c8e0a0575420364acd73f9399a6a375cb6ab8685d619a8afcdc09d88344dce929d90eed48f9caef102acb28c632340386d168cd14"));
testCases.put(
"0x52d2883c39100d09a6b8d793e0f693fd7f2bac51",
Bytes.fromHexString(
"0xe4e5120a2c41c1beac3a04fe7895fb93db7e53e33a4f279cf196ac8d12e4eccc000000000000000000000000000000000000000000000000000000000000001bc113be6e205a4851f4aa56b499aee3fe75389382fb7b4da2eb894537addf20980dac9e071a562749cce0ea9da2f4cac450509ec03ebcf23898c52b3375c29169"));
testCases.put(
"0xc65a2a9ef32f747865a119d1c044ad836a8f6d73",
Bytes.fromHexString(
"0x7b4ba1f9fd096f738c26df77a1a87a87153d5eb253a4622cc41ca1e57f678370000000000000000000000000000000000000000000000000000000000000001bbdb9a84a3eaea6f3a16bb084387c1dd1bf91c0be1300cc99ece1cf8d239d7e0d37f24155f143635a761427684207ffabfa00dda09d502056768a4e57e0f336c5"));
testCases.put(
"0x5cfe5b8bf54dee364ef6f411aac9bbb6eb051202",
Bytes.fromHexString(
"0x4c16d10f1bfbaa34814a39d017cdcc18590d08a52ee01be38b43742cf0f76ee9000000000000000000000000000000000000000000000000000000000000001c75d276f5646653753fdcec2ab92d27e58a59c614aab6cc3568834a4ef36819bd54bcaf3c605ed948a20e56cfe58c1595d727877b0bfa9b9b6553879ba0e08a2b"));
testCases.put(
"0xf34405682c4deb55da399822373b632cf5ca25c0",
Bytes.fromHexString(
"0x8e4ae0eb9cb54e2378b3d161eeedc36654269cd1bef02d68751cc1b0021b709f000000000000000000000000000000000000000000000000000000000000001c01f53df1ac64d831f7cb45bcf9037052162900e3d7fb4d62934112a8c4b257d50c0c36cc064d72ba8a3ba57b1d2eee88b0628907dfe2cf0088dbf69d89c2f1c7"));
testCases.put(
"0x617c0e2ac02fd3e876fd5bd8581e73937df53c5d",
Bytes.fromHexString(
"0xb755e67b6ba34376ac93bc8f81b072df191aed5c5e1bc7131cf1556731fad13e000000000000000000000000000000000000000000000000000000000000001b61b542768763d72e298e93cf8635ac430c2155835c079eb508e47d0cff5fb1fa62fb0cf03fd42a35bd6ade27fd10ba4e22975a61c259e1e71664892cb9f89f6c"));
testCases.put(
"0x2b43183e036afb83fed9ad70f1bfadda5497dbba",
Bytes.fromHexString(
"0x361a00e41d8e97cb935320dad3ba8b071f198e4c2424a2dbe110ab59a9a74511000000000000000000000000000000000000000000000000000000000000001c703cb0a9ee3a332e5b53664ee0495a757fbf1c168971a618f0010a894e8f00152d0fd7a61bbcfde075675e868593ff695298cb1dd7640ebdccd2864bd4f5fd71"));
testCases.put(
"0x81b6898913b2d49aec6e0bbcc8c192cff4d0eed8",
Bytes.fromHexString(
"0xff94a2c7dbfbb566784a5d0df05c461f050dbc826f622940ca96ea949f9e1a87000000000000000000000000000000000000000000000000000000000000001b66489a58f64e058f150ffdb7e22a0993f4299073fc2b0840b082850138990fb54fcaca68705d1108a555ed4733a959c8e302510098c80b5e3c9353b1a86a64de"));
testCases.put(
"0xb48bc9d6546fb5156954699062774443a7676986",
Bytes.fromHexString(
"0xf655a5caf4dba704f63f5e17e5a94535ea7d277f2b8f4d69951291319f5c2c1b000000000000000000000000000000000000000000000000000000000000001b66987335ff22966a6084e88a4dbdc96f2cfb126aba2f6a477c18bf0fb3c42f2a5f1ef94acf1184da542f3f7271032a931bfcf3afeb3a9dafca95d5aff68bdee5"));
testCases.put(
"0x13cb19ae4e86177abfcc9d44139dcebb993ebdc1",
Bytes.fromHexString(
"0x19e7a1205c185da64a45bb5e04f35c54cd092b70bb1a1527f8372f1ae67b4bb7000000000000000000000000000000000000000000000000000000000000001becde2323e521681126ea23af56953a18166158919d3fa445e93fcf957f60185a4738fce3d006827c432e5f6c1b8d7e3450fb434172b6ab4d619fe49a09ed4b68"));
testCases.put(
"0x6d78fd01abb065be75ffeef89a9df8f87926daf1",
Bytes.fromHexString(
"0x42d1878efb373fb18df168ce9687fae3cf8c1afa3063fb15b44f309adae25894000000000000000000000000000000000000000000000000000000000000001b15439bd45f426bdab38723290e9691371196e2105bee21c9dc36f77b3797fb6849f66ca42c6a4d5dde4b2996f68082c930fa6466e16077b074a63551d0a36bd4"));
testCases.put(
"0xd213383f34edd2a9d6e89dc6ed2bdedb2b875a3f",
Bytes.fromHexString(
"0x91f5c73a9e6b54b896940478ac0995d6d757feb38790cfeeaa0ca0c4c0c72db7000000000000000000000000000000000000000000000000000000000000001b5d26a45936c8b69117451625649c356a7a40627635f60e038313afd5a9e8082323aa5968522ea56d32beff94e628e36ebc0ceb68cf89f7141175b3dca19e2446"));
testCases.put(
"0x0bcfc1ef1f89de5d6bcd354d797faf3047ace632",
Bytes.fromHexString(
"0x654643af5d8045129adcbd4e2fe3a0270eae3072765e952ae1a8d239905f1848000000000000000000000000000000000000000000000000000000000000001cb3fdc5124a4193b35ba4eee7a3a764ea3ef14b0bacc61ce0a32e52258c64a31b2f66dc6529567230fc420f48e650a589146a409b85cb7b7d1d25cd7782198873"));
testCases.put(
"0xe2faafdf582764fa4b65004ef676466552f4bfe3",
Bytes.fromHexString(
"0xa3dcb3d6e954a0da9e57fef6322a489935535fb892eb60fc2aee0153207441f2000000000000000000000000000000000000000000000000000000000000001c58d31b5c643c2e2376e5420c250ab85ac58a730523449998d08c55ce7ef1a8871777e9f81e84fa66f656615e414b7f89e5800d429f618cf2fe88aa67631db651"));
testCases.put(
"0xa32c72d11ac3723ad0129c6f395c7d118db9e5db",
Bytes.fromHexString(
"0x98eec766a1da31be4aa5b56a3c1d388610a4a37f7b8ef17011c78c135c999783000000000000000000000000000000000000000000000000000000000000001c30a0d88c1733418d1248ffecf0b3585abde3999aa4c4b4496dce559a6a9cc1c81c1de713d501fef22da4bfd4afa7bbb65d0b2217ac03dbc3bc3c75156593a8f9"));
testCases.put(
"0x75cc7deb0bea00df88dc37a6a69038489b7a00da",
Bytes.fromHexString(
"0xd646626db60c8f37f0d67df1f7795860dc97f70fb26e85b7dd67fdd8865d70a1000000000000000000000000000000000000000000000000000000000000001c3f4c0a2e4c038aac868040990b4334a6c007e8394837ef2b467ac417075b502e2b67b91a1a52df65501d16645b7835849f70aa50a72d25ab9baeda90528003f4"));
testCases.put(
"0x8b38952f5858f58d8b448da2bfc7cd5f203d9874",
Bytes.fromHexString(
"0x4a3842955bc493c1478b8e5d091f5ea38b6e1fbfe29e2a76af6b642829a674d5000000000000000000000000000000000000000000000000000000000000001b9fdc9d14a459294ecdf918920dbc4f5bf957425563fcd2fcda6db19ef1ae37a144ec3663dbec38c0acb40623552b4062981c635842434e5529a6961eb468a815"));
testCases.put(
"0x01e86c2dc7888aaf69c067c3d81d3324b221ac4e",
Bytes.fromHexString(
"0x1fa23790ba1f754c40131e8ebd40ad95e8c3f9ed32308395907bd9b6f451286d000000000000000000000000000000000000000000000000000000000000001cb9eb00b69db8a908c0fb24cf9a54fecd06b568efac82ffa38df3c0a088825f6002e574107158e2a83da1227343a536966fd4e92b298e473893ccbaf20ca3b479"));
testCases.put(
"0xd7f38f4cdbf5cde5a68111970cb377003f971dd6",
Bytes.fromHexString(
"0x88f8b41d758a53d0065691f5c771b999c241508a26b6d49b0698f99675602372000000000000000000000000000000000000000000000000000000000000001b5f97bee8c1a2660617aa6d00b48cae9dc866e7dd92471a18e34f863841e4e7954a20c134006aa0a19fa7d1eecbdd3a7213029fc1b173157d2354a62e6add5a0a"));
testCases.put(
"0xb72b25e2dc98013d1e429180a95ce8d763b92ad3",
Bytes.fromHexString(
"0x85bced90e31303e32e094be2d0210d8ae7f4ff29a793bd3e5959fc86a79b2738000000000000000000000000000000000000000000000000000000000000001b04efc53658e9a47738a7078783dd6ef305b9912443fb6008451026e80a38a8f64d0abf58ef63bdf5ed576c6f0e99bdd3dc7f73f17549303222b144868bf17b58"));
testCases.put(
"0x270433b68a15b4979186f44c3594041e8f6fae80",
Bytes.fromHexString(
"0xb0df0e432f097fc53dfb8d14165a63a24313cff79254a7cbe554ab7eebd43bc6000000000000000000000000000000000000000000000000000000000000001bee9e7ad060f9c969b7d289c5006eb9b03cebb508af9e5647228d48030d1bf2c87d0d66c0cefaef9eb15617a891963d51bb1e19bc7cb33544e919c94bd2235ea6"));
testCases.put(
"0xa6182f0f4ceb72de969d20684f71660c2cd2ada0",
Bytes.fromHexString(
"0x70d6236cd7c57cb44dd1f99e20e785668b6cdead0b007458d0ed4e9655d7f990000000000000000000000000000000000000000000000000000000000000001bb262ec123fde934f67facf354ca12eb19b6b453a8bcd7beeb0566743fe4ed78607baec6194afcc4f66cb3c42518f0eda63e5f94df9121242e4e128133ede0024"));
testCases.put(
"0xecd91ebd69948e971744c52ceff54b5681c6d419",
Bytes.fromHexString(
"0xabcbaaca73cafb7fbf215909dd5750ec1ded7a3e151ff830df92590fad8cbf30000000000000000000000000000000000000000000000000000000000000001c0168786a30ab53bff4fac2f46c7f2cad22e96c0e80be8c6f96f1bf987b134c726caf9c6b4fafb3689506f8ed360cb61be6529c4de87e1d9bf553f7f3734beb6a"));
testCases.put(
"0x8cd8416864cc82c1061c00a2571e2b6ef1bc8f9f",
Bytes.fromHexString(
"0x4e166b5f7df865f51522a4ccc9616a4d8c9b83df29dbde6dc96dc94a13e4a7e4000000000000000000000000000000000000000000000000000000000000001ba43b80dd0721a715082425bf9252322c4b61671102e860b7371871abe5bd6a5e5c8abaf399cb7e6f39405a0583031f73b40ef41963b3827f3d20d5103ccd3517"));
testCases.put(
"0xa91aefd1bddca65485567c7014ebf4b48917e3de",
Bytes.fromHexString(
"0x515ac051195596523c6664ac8d8e48345ea5932cda58d22ac49339dc234127e1000000000000000000000000000000000000000000000000000000000000001ba780c9c0aea4501f09cf5a75d133e9c89386ffea400719dc82d9586975cfb6ab41adfa6195e155b7a2a7f598c32a754010d5ce98e967a2f812f77050e72d67cd"));
testCases.put(
"0xd5be345de0dd0d15d34899173b7c375d31140f24",
Bytes.fromHexString(
"0x3c5ad848eecf1a48d12f17ee1ef6a4ee45f3c1ae7cb5b843fbf70d0f9b7b4a13000000000000000000000000000000000000000000000000000000000000001c50cad8bc91ef3924d32ce6194c79a6104686de2e2f0e67c3353262489aa7f6451532f54f6b99e8f4ce54377a86a515088bfe440eebec374402122c69fb691f5f"));
testCases.put(
"0xfe4701547b7dbaba4c0702f226dc48a2663e18bc",
Bytes.fromHexString(
"0xfcde24b61bbd3ece34d2f7d99751e57e0d840cbcbd58fa1777a5e6be8f74bcd6000000000000000000000000000000000000000000000000000000000000001b378491f640df70d59dfba12f7135fec6e7b0ecd67bd07a29e3644f85071438ae0a737efc36831bd13576d2c517b2b4694181ee687f40732d428cc5478a8fa7f5"));
testCases.put(
"0x66036bc0f0fdcfbf8d814da7f3f16885132a43ec",
Bytes.fromHexString(
"0x83326209a1fc9e7f4e111a20ed12e2ce6d0639e8eeeb75fe403a9bb180288a47000000000000000000000000000000000000000000000000000000000000001cad837bf4ac65dc6741fd911ecc41ce1d137e135540bd1035a06cc732d23b3fe243b3d70317177dd578027952eeb6e701280beb3685cb44a9cbc6685cd3149aa7"));
testCases.put(
"0xa4e7416ef65b74c3b61a1eee53a33eb1d2b51a63",
Bytes.fromHexString(
"0x4ab6fb0952a3e801814a72bdeb8630aeb9edce54f0b08c8284bc7efa0d737ff0000000000000000000000000000000000000000000000000000000000000001cc8fc37b1724ce16d169b4856fe2113ff305290859070a3cb5cfbb93f90a248e3382c9ca18fa7f926e914cf781999c2c8de6ea1fa4e8536030699005b45efce86"));
testCases.put(
"0xabb83304268fec4160d80e3e45d1376c0b458636",
Bytes.fromHexString(
"0x80d7c38d08128721cb1d6b78f26b2f53b7bdcb2448a6d87668f4fe4e19cf5dcb000000000000000000000000000000000000000000000000000000000000001be5dc7cddccc9c61eac363691c6305420bc393a4ca17f1e10bc5192ff63b5d03f02536812a3fd90cc50208fc3b886efca921c520b4a66ef00d3228cf02fbad675"));
testCases.put(
"0x78bbe6f432b755a9bc0bf9798ea82e2574d01930",
Bytes.fromHexString(
"0x1e4c87808973dd4b705d20186d4daf911f7002006aeca1ae1a476ec23a3eb67b000000000000000000000000000000000000000000000000000000000000001b942c0416506f34ae4a5aff5bde5fbe4e093f4fca798e4d8be460a84c5cbe8a1a0fdc6113fa280b9c4e736147ccd5bf8d383353556692f27405e77344b7c9b253"));
testCases.put(
"0xd309698bda9fbc6ba8f56ec71cd0fe50374ab147",
Bytes.fromHexString(
"0x5a174e433de66595c112432074d5d6fd07239edb8f3e1bc6b78814d4ce41cf22000000000000000000000000000000000000000000000000000000000000001c964fc2baba65aef4a47358132fd87ac92dbdf08e7fab49605293e43f47a76fac320d603d6e841fea09a4dd7b7bddb8b9c6bbb30b81893ee655bb8a16e3939d51"));
testCases.put(
"0xf658c09eaa7cdf744e34b676a92de4cdbef19306",
Bytes.fromHexString(
"0x390fe5599dcc23aabd594ae17f08b27a3f686f5a12d3ebd2624811738976e21a000000000000000000000000000000000000000000000000000000000000001c4d32732c7278ba4060cd00c4bbef14189604470147910f6f254cfe04bff7638346a2c66f0acc61b8a612d05ceddda4f2dd9ce79a7f36597bc74797d3d28d6cc7"));
testCases.put(
"0x4566e04fe531b85ad7103ac1d234e36fcc4c80c7",
Bytes.fromHexString(
"0xe0a1f6a2b34ed7cabe5829e4a0fb68989c8b520cb69376f4e6b754181cd02c4a000000000000000000000000000000000000000000000000000000000000001bcb22c52a26b97580036849796289293ff7e7016c13e948d99f2dfb5176d7ec01441aad675e9119fb30019f6c73adcdc4bcecb077c9164026230b5bf71cbbcbb2"));
testCases.put(
"0xe22dc594d5a836902a398fef392e4acae4eb64d8",
Bytes.fromHexString(
"0x925023d3dde43d2691bacaa0202dad390a73acd5c67dbc3b73c8667696103cb2000000000000000000000000000000000000000000000000000000000000001c61cb8f8271a58b25ac3fe24e2b1a91b613a5e0da5fea8a27c4c4f38c46c7d74901be5ad35bbf74b5f23bcd03f5cb06dca74054738411e86fad9d985ee43d6003"));
testCases.put(
"0x6825015903052024e1c39b5ec4686d8f17650623",
Bytes.fromHexString(
"0x809e822931959c627d36bf34ebc22415614f20c1b98839665187154233ab35c6000000000000000000000000000000000000000000000000000000000000001baa4df42f677f348f44151cfd059b3fc0e43468301acc0e32c68fe1175428308129eb46f79704e3169f336f7a269a026f43a316b7318198b9880fe25c069c4628"));
testCases.put(
"0xc19cb83c80aca377fe7d32114f0391c64fe5a043",
Bytes.fromHexString(
"0x3e84e7a38dd4802b3469a55ffeba8e3b09cd6f2d50c446b217ca943ed09c7143000000000000000000000000000000000000000000000000000000000000001bd10fcd30c21a2f7eae829e5445a7e8ac1f4d64ebb5e007c087b64e369e502a25101bbc6e6e3c2b8a0a7b0cc936be004570de3c58e6dcfa460507861aac2d7675"));
testCases.put(
"0x5f8e0630b06762a24670bd407f79bceee4ec0841",
Bytes.fromHexString(
"0x4c6dcfab6ae4a6f8b9f812d361d7064ca6802a6d391a5e936c7e80b53723f172000000000000000000000000000000000000000000000000000000000000001ce680d9f9b0fbb6a7edba040c9e03415530b7d954910790ecda3892ab881a7a8a2ffa92fcb1824d6098f4ab4704630fac4f0f34dcc36795af6984f9302551fcfd"));
testCases.put(
"0x4caad3e55d7c8e67c3a9c0397d743b8cf207ce2f",
Bytes.fromHexString(
"0x0c77a6a08a98cc812e7a5275421336d78cd6063747a3fa90385391df9f17d32f000000000000000000000000000000000000000000000000000000000000001bfa375b6bd93d3a73787ded81e2d470f511db2e127f950d63308d23a34d2eafc5594a8c4cb868f796a37b2a1c55eaea2d9fe6aa77d41c9f9b01a0ce240d605c1c"));
testCases.put(
"0x763f039273833269c26cfd79fe4713da5d74a45b",
Bytes.fromHexString(
"0x131d7ad7d9ef2b50c379b4cc5d84df851d652d6012cbc612e600a7f99455b241000000000000000000000000000000000000000000000000000000000000001c90e090540445c5533d4391e7bf4e5b11d6985105bdb7944abdcee09753a4b3e0697d19c3b03c7433672132d175a991111be1ecae5ea0d236eb751355e628beeb"));
testCases.put(
"0x014f31c9e429c69c270f4ccff594508abd520420",
Bytes.fromHexString(
"0x8370b9d2e6dd2d7ab1a0adf391a4f8380229de45fb017f812091b4226d7ebefc000000000000000000000000000000000000000000000000000000000000001ca7184b28a17f1fcb25953de968f5bf5c4b67ca115155f00cb4ee7c7a838d82cd44b55aa67acfd3fc8939b607eec5fe256f8098ab65db1c3db04c0efffff4c34c"));
testCases.put(
"0x6bafa3e7d355788ade4f5c3ce4ab865a490118da",
Bytes.fromHexString(
"0xc9d7002487ee5026fadffeed13893e827378acfca9171b89817c53dee584d289000000000000000000000000000000000000000000000000000000000000001bb5a3c506e8c38cd916bf20c237906befc29ae91d5474700c66ed47263222a487116fc65be6ad78140feb2df974d4568cc5aade5bf78ce14ec0df274b0983aafa"));
testCases.put(
"0xc7d1544579c6a0002966ca562923c5cfcb5e21d0",
Bytes.fromHexString(
"0x8dac2bb0d2e8ba5923577b2b12a0b9eb6b1af5c35ac6ec381ecf8ace2de84172000000000000000000000000000000000000000000000000000000000000001c549c2c7d6f644a5a9df73dfb88cbf1902fb6ad2ce7de27b18560f58d11c1de6658ba07f35e5676c33e71c6fbabfa30c7654f997394a8c713f7eedd2da78b25d1"));
testCases.put(
"0xf18c3dbf2aca83afc71b520e8ac3d4d016fa9ec1",
Bytes.fromHexString(
"0xfd7bdacc8bf6f0901fbb76d18dd3a9580b88cbbe8c5c667feb497ab2ec1aaf60000000000000000000000000000000000000000000000000000000000000001b01fb675ce7c18d34abf4d21993a36bd3b213fbd29f5077d178a84f6f5dbf7c4422f1d63423dc3bb682eed2f3c96c9ecbde516f1e26364556ad9950e431217240"));
testCases.put(
"0x22a09a6e7578d42f9af290f6417d2bc04ce3380f",
Bytes.fromHexString(
"0xe24beed8117992ce468610a4c7ea3b8bbce67831d5459993ad80ef75ff74399f000000000000000000000000000000000000000000000000000000000000001c65d5763121e91655fa84d7ae74b422d61db272cc6584622673e9993af10f5d7f5181a54f089809da91d008fca5fb6d7af9bb41d064b839f7643881a70c124bae"));
testCases.put(
"0x0431be799b7f179e4431ae1cb629c17edabdf917",
Bytes.fromHexString(
"0xd0490e2210e00722e024000245b28c5cb699c1597881a6e0dff13adfd7f00b7b000000000000000000000000000000000000000000000000000000000000001bc95aa8a187ed486f3f4a2c4fbc58b4f1e8fac5f6aad373ebce0d5e91d8e8bea67008db4c559da979b5b07a60890fd4cbe8db164d0102e395de7ea27aa5224fab"));
testCases.put(
"0x1ef26cd19e0b83e4f56c88b68293c1cd9444c684",
Bytes.fromHexString(
"0x96a49e2d7833c3dee1b5ba8da56088b3fc900ba28b80e1120341796271bbc8c7000000000000000000000000000000000000000000000000000000000000001b488f5bf61a104009d5b1c2102454199afb712742c4d563ce3dc6a1aaf5e177d7605652e31020e876ce65c1fd3f75ddbb163cb636065639b1f03e7b90c256e2f9"));
testCases.put(
"0xe04d0368b19ef078d6040abc1eac64869a510e8d",
Bytes.fromHexString(
"0x5f764e0f288b12167977651452f233de59ed6163eb6b17796195c96c603e4313000000000000000000000000000000000000000000000000000000000000001b5bb97625154686b77f4c3480fa06e314798503d157c5db85a15218f076d19239052a96f028d44331020106277591db48c0b07e7c501c181a842ccdd20b3089a6"));
testCases.put(
"0x730594bd0a7389acc19aad47741533abd0f19e81",
Bytes.fromHexString(
"0x5d811d11af03c52f95907d5f8fe1cf9ca6d25e44031588a08673ee39fc720c29000000000000000000000000000000000000000000000000000000000000001c963a39edda9392c83b390b7540b6b901bf1bf0f678c59603c0b8ec02f41633945ce49973a3e15591eebe3ff1b677696c1609509e547ba84ad711e13aa229c5e3"));
testCases.put(
"0x150e6c28a10d4b01ef1c5c733a2e5831fd75f684",
Bytes.fromHexString(
"0xed6b74c00def739b829b1d11f44190c075804414bcf78c30b6ea781d5f842b5d000000000000000000000000000000000000000000000000000000000000001c115e46eac1f6abaa48f4ed42713e8a10eb748d638331e83ab1f5b1aa672c3faa7f5892be39cfa345c785a369dd147d5c8bd79e37d4fc392782495231d52752aa"));
testCases.put(
"0xffb0f15492e9bb8dc8a8b3caf74cf30fbff51add",
Bytes.fromHexString(
"0xbc80fc2f142d3c139a6bdddccfb8d793be4bfff086904e4016ef5fdf4f552186000000000000000000000000000000000000000000000000000000000000001b8b5fc96d3cd453c51bf480ca1f564c6a88e3310bd938993acd6f4d2e1fa30857640660bb208f15a9cbc3bb2c1de892dea23628040c84cd48bf035cf1440e6ff2"));
testCases.put(
"0x5cba0a3e82a42466cbdd0cef06165f3936be541f",
Bytes.fromHexString(
"0xd14c00d0637bd1f80b8a29695375c4c4fbc25abeb0215190b937ac5d77138389000000000000000000000000000000000000000000000000000000000000001ceb7236075f80b65a43318e377fce6b4403a9fdf37e9d5e4563942625cba9603a67e8aae700ac3a877381cdcc71ddda0fbbf16a807e9f89ada558fef5b89c5eb5"));
testCases.put(
"0xfc7eaab26c1dfbb2a112d34794e0ec67ce76d471",
Bytes.fromHexString(
"0x964f1ec157e2214d09985d8d96997cedf59d6c75c1e01f9b6038d841f9a02f41000000000000000000000000000000000000000000000000000000000000001b61154b748a60ab1171413ad6d8cf8bf3d21c5c8da5c5025385565cc685519ff45358e7cb911a227fc36ce4d14bb11144735e90ad80d074f59b453bf2d8273b6e"));
testCases.put(
"0xe157b225a52436ac28043a4940a300bca589d0d9",
Bytes.fromHexString(
"0xd98b755dd654a52b968830f43c01f7b312c87b210c614bb13b27f3a1c3be430a000000000000000000000000000000000000000000000000000000000000001b8d0eb91bf9a3e3c7dd67e1703acf6f7d558e8e4407b30bc8db31b8b3c29ef907188c479e1285d9d5e74ca4e863114e70de6cd66f381e0adb1b387829aca1191d"));
testCases.put(
"0x726871df1a80253abcdc39b8efbb019485f0aa92",
Bytes.fromHexString(
"0xae7c9444d3777ab5966ce98a996cc590bd0560e5b7b4cf7c603c294e5f83ef64000000000000000000000000000000000000000000000000000000000000001b4462a10e115f9beb9a1ae7e1f9bc135ba18c3cb47d4562b63f34a2ffc3f0e104454e9de9b8f86ef018f185f6131cea90967c13377be39162fd70326cba74e088"));
testCases.put(
"0xb70a82e0b8d80c113f31797bef325f9894e33d53",
Bytes.fromHexString(
"0x59d4a98ff7238c392d366f4e1b59c0e0f062b8069d6aa7217d4271e6e06ea1b7000000000000000000000000000000000000000000000000000000000000001c180b92c72691caa41d149d3c8c4b02d8e637d447fbf702f80353e1c89aade51b27d59ae0d0bad8148134e17744de8a1ed126a381b2ba0039336b815b093e8178"));
testCases.put(
"0x6f8763efc3d08828982d41e37a9be12d795d81db",
Bytes.fromHexString(
"0x1d651cc72be8cafc2f831a5030188dc23bce6648be7045ff9eb3dad7f0d0458b000000000000000000000000000000000000000000000000000000000000001c15b9fcdba84fb454a47cbf830705a7fbb03bb8547cde5695338bab38213048505363b8bf99f730d497983ab0eb3986f9bb7750a98e2db08fc24f8e094c23f8e1"));
testCases.put(
"0x85f54483bb76aaf73fa1ee8313de109f309aaf33",
Bytes.fromHexString(
"0xeb3558fc388e8d245f892684fe0bd166bf5e1ec061f778436c36f7ba27fb5e88000000000000000000000000000000000000000000000000000000000000001cda01d3af46bfeb57e495ff722d0612132b66a3e2f7358e2d6a210ffa36a91c4671a5a1eeeb5f03f9b97fbd4076266a3aec7c2c64c13cf533298ea440e54aac04"));
testCases.put(
"0xf1383ccac546c49072c73fb3a0a4da4ca54d4b30",
Bytes.fromHexString(
"0x85543dcd0a1c590cfe63cc1c6e732a124b2138d4ebc7aa257ce4ff5ab7838a67000000000000000000000000000000000000000000000000000000000000001b737c920964ae5e15f3be8548774dd965f5b5af522f3e811cad247bda80c13e753bc58cb3f973fb67b3856a3a6f5aca1847ed06711ed722f11f8124c025adac1e"));
testCases.put(
"0xeaef2c85d19516bb3434a8bc364ecd270fba994c",
Bytes.fromHexString(
"0x334ea2be8566052b9c0f52fac3005b8fa96950dc17a2998f4ccc8a68b6f483a9000000000000000000000000000000000000000000000000000000000000001b5bb08f9a15c2deb532774b0e29d9782f7be619f57d15467d4282148eacf114d943c430c811c5979351ce3e77d1843e7677a1eeca350e3952958323ee5c5406e8"));
testCases.put(
"0x7a3177965811818903f69d2202464de03d43b6c7",
Bytes.fromHexString(
"0x9797b28b78d1a41f655e4670e797c4b4054b7aefa4c0b7cfabecfdedba772ab5000000000000000000000000000000000000000000000000000000000000001b8c69b0dc1f4fa557d658d9f2a2ae2a87abba4dc30a918c2249cc0df2cd520aed3f5012f755ad6320af14746a7531a70503200e5818a243e7d9d7389dcd47db08"));
testCases.put(
"0xc07d2a4f05c1617f3314e29e3dd98c083b9cc55c",
Bytes.fromHexString(
"0x185faa83fbab6980289744d05f6fbac7a9eea9078ed82af38b2f542922a57355000000000000000000000000000000000000000000000000000000000000001b345a728c2c87c11adc137d19d1c7a3acc2195b7591fb7449b3fd9ef476b32a005df1738096a09ec334cbbc43bfbc42be19777d6583f82ea499f59f8ac652a879"));
testCases.put(
"0x6722fa2ba638738b50b9cb45f4f7722ff8264b62",
Bytes.fromHexString(
"0xc281aefd2405635d3229c7bd155abf3ae22abd2a6b60b9f6358aa3b349fe76de000000000000000000000000000000000000000000000000000000000000001b5bc6959194476096e223df55cefc3ca991e5886fe80751a5ad40b1ad9999d6045426b00332eceed4152c733e8dbeb04987718a458e4369bfc6c30e538a95641f"));
testCases.put(
"0x2c3bc458c2aa4e62ba5c4300cfcbc344da9ee93e",
Bytes.fromHexString(
"0x53fdbd4b17fa328ed653476b7ce5beaa9f6b99affe3e64cf6fd99dc440379878000000000000000000000000000000000000000000000000000000000000001b0960d87cebc136087ed15f005349b20dcef74ea4f234d1ce9e10fb9e5fb0e4ee28d0755d8a6c66eb49eddb6b3ea8061a4265b83052d5e4ef9c7b6a3cccbd0441"));
testCases.put(
"0xff6e669dee405c6dc021a7e1ba2f5feb96c97adf",
Bytes.fromHexString(
"0x6edc1c049d2a86ca8fe892bf24a48dd3c5b630b03adb2a3b2855c1f7935264b9000000000000000000000000000000000000000000000000000000000000001b9a2f685a2089728baaf03c379703097d412504fd3399c2f79a18e1d13c07ee945c5da9bc00581bf2b1977dd5809683ec4e06a9a4a7a32561ec7aabbd54b04dbc"));
testCases.put(
"0xba0093215db426d68708d1e95156ef0aaf90b588",
Bytes.fromHexString(
"0x65f6ec58597df636a59d070d48b29db68fc229801db026a4dce11e59ca6d23b1000000000000000000000000000000000000000000000000000000000000001b5bee25353248c9d12df421c3db9eb3141918e2a69f766d7f11edc1ba66852d205ca06336f49919bb3f45e81a463d96b0dd5071bf7edb7663e20e3fbc505e232c"));
testCases.put(
"0x130dc34dc7b806a3e7aa2a2b2db8cd9dec66fd89",
Bytes.fromHexString(
"0x3546335f92dbc0883248693660061db1cb8283d2dd1969f0260915983d7ce30b000000000000000000000000000000000000000000000000000000000000001c27b51e23abfab6a82bf3bf83c23b222a01ecfdadda3587b58d965eebfab7dc5a7b3006e95e02b19c2fdfcb85794bad59cd2708b43cf658e4696b292c95cb6fc8"));
testCases.put(
"0xd50240c7d2ae4a7c30ebd3948460581f72385732",
Bytes.fromHexString(
"0x237d94f90f917d6eaf1987353f5907950ed6c8136112f029494e0f769ccddbcf000000000000000000000000000000000000000000000000000000000000001b14919b0374173a158b04213c718d74573c438891cca416f9e198704d56320daf7ab172688fdf770b1553fd7ec4e27a9bb57a84374562734904b8ade0f31fdb41"));
testCases.put(
"0x674fadf0fcf26febc6a21a70d27dbf2219d374dd",
Bytes.fromHexString(
"0xf2c26852616ca8ca4fbefad89111e5326f2c78158e609488461ab8fe3bc6573c000000000000000000000000000000000000000000000000000000000000001c0ed26622b205d658331ccea6286cf5d623687047e61b81c7cccae5181eb1c4b827312bb9af5c55c23f75cc72b20ff10a301ac3023f5823757c0fc9c4b9f827a2"));
testCases.put(
"0x8e76a1cd7db91aff5c8ed95f17148f9a8d4c81f6",
Bytes.fromHexString(
"0xd238468a4cf3eb5939950c0dfd1ed56f13f61784ea1dcc4ec472470370f8e4fd000000000000000000000000000000000000000000000000000000000000001b059cc3c246d17f6b044b3b15ee1f3bffc59865701703c2b6e9a9e282d65e3771788c55359b3f9879245ede61f801a4bcaa18bd6a90216b952e06815a407bc7ef"));
testCases.put(
"0xeb10e6f82e42a18ad05f623ed291f7bba26c1166",
Bytes.fromHexString(
"0x5dafec9564fbff6371b45399a361407b8e0f11ae8b62b784e121974957db9ef9000000000000000000000000000000000000000000000000000000000000001c2a71af5be39a199bb3b668994f28be40de1c0f5d59fa7b193cb72d4d357073f42e21a423a8b3bc8443ec9a05af6f2bf709f23c98c2c6c3a4d728873000d0b3c3"));
testCases.put(
"0x6ed176182fdb30cc2d9f553179603ba45fadbc4f",
Bytes.fromHexString(
"0x8eef9ad23caf2ddfb868faa610cee0de186722d20c8d8bd15d8258fd278f4b81000000000000000000000000000000000000000000000000000000000000001b890ae7c25d8c93d9b232d664f46357bfc21b529b427d9f3c84fe1e24cb5eabe515146ea64479f18acfebad6f556437d826833650fab32f940f5eeeeff0865aea"));
testCases.put(
"0x45505cf5182b9bfaee12c1b5b3e3d09377567b5c",
Bytes.fromHexString(
"0x7e38048ef47052bc73329abe12d51de302b690ec6e5c612a6dc545a16e578bdc000000000000000000000000000000000000000000000000000000000000001c1879fbfaeec45b117adfd62abc9fdc3ad575f1d7f09b388f02a2ad5ec37287504761f9cee67e6b6d75c6b53ddc966939df3f5f605083e8c93c06a64812b08ab7"));
testCases.put(
"0xcb69ddd0bf6c51348567444a93d8a3f9d995f363",
Bytes.fromHexString(
"0x9981e530d595012980ad4f1cd860f6d524a2f34f6aa132932796cd4be96d6e5d000000000000000000000000000000000000000000000000000000000000001ce08be9670177846e05696271da3960eb617869935456a14f634c3f604543dff36f1b05d985d111ae7cdaf679f75e9151030e09f0c8148c6ce3e02c1847415002"));
testCases.put(
"0xc97af81301f96ad50d9b7c64e322ef1527702278",
Bytes.fromHexString(
"0xcb7f1bf45f76e3dca564764290cbdaa64a7622fac589799a70199845682566b2000000000000000000000000000000000000000000000000000000000000001be6c9c8dc4b408518b89e5a048d36ad1426b3ace96b8518a5a9e88f286103758e0cd9a5ddac0f848eefb204dd403bffb063a718c8e1fca4c4ec94155269370b77"));
testCases.put(
"0xf00f8df597663bf073bcbf43f75d0e5b6caae7cb",
Bytes.fromHexString(
"0x21e69437899f6a37302b239fc0261c7ffabb970e8a48096475e998d2871f5bd2000000000000000000000000000000000000000000000000000000000000001b89501dd1567e56253ba097ffc663718fac90818e56ca6b393b69e9925162ce5a7262088cff050243662adfb2aac50143bf5aff60f904f2279d6f6cce5adbebdb"));
testCases.put(
"0x532f5d1695f4305a7193eecf7f17c4ae7fbd5c1c",
Bytes.fromHexString(
"0xf524d92f0d374b4d104786fb521265f6034cb6e2e6370d9d83464aaf8c87b0a6000000000000000000000000000000000000000000000000000000000000001b94332385b44da4cb31cc83c8d1caa85c99a85b58a812f9d3b8ab62e32c9dfc7e17f2b4d58e52bccb42bc069e8e6445a87deed25e094fe1cdce663623493c21c8"));
testCases.put(
"0x0b67296d0486d16d83f4f3ddb8e07a0a57c36631",
Bytes.fromHexString(
"0x739c5a643ca04c7bf21ea78cc89270a2d66662f1441879f6f0246a3b71416996000000000000000000000000000000000000000000000000000000000000001ba6f422a6fec65ac04fe923c8e7e92cd65a26b914f06124276dfdfb7ad396eb9b7613f03ab9c71d48af2c93d430a805cb9600991d92e76b504b63d55d7dd187a3"));
testCases.put(
"0xe5c7698dc89c75475d5d067e124696b81a0d53f5",
Bytes.fromHexString(
"0x33693f2a0c99ea981b5b11acd2c6bfbd58e43170c5a31f79b5a8eb3321858e71000000000000000000000000000000000000000000000000000000000000001b5b33ddf363736a3abd5a356eb610d2f9fd09ef6125fdcd4ff4c7775b39e87349225b33e5afebde52fe30eb987d72318e9cf095d892e7fbdcd9e5892786f49d1c"));
testCases.put(
"0x988cfd3652a9bacc3debc441f02a8bac7913e048",
Bytes.fromHexString(
"0xdb9ffb31945e1cbe86910f30bf7129e276f0ed9d7cd623f7b74a245324ce9c82000000000000000000000000000000000000000000000000000000000000001c8b9f853439623cc3af1f15ba21c639bfb3d8ba8302fa9d1603587a537b32fcd1308adf297dde649d208fc0b323f3c36e9404ba6dc8a74510d4082c867fbe1205"));
testCases.put(
"0xfcbbfb74050fee34c54f3b18a50d61a679f5f320",
Bytes.fromHexString(
"0x3930cff06ebe66193b61bd2d099c001a4f1c8597276b6324ced78b401746ed82000000000000000000000000000000000000000000000000000000000000001be2f6e9aa05b5af82987c65c31c131c152e4fa58f6b52a140519b11654c3cc8970472559ab09821cfb51b6d0c96ca9e5421f78f98af0d4aa601c49a6ceb9d4a78"));
testCases.put(
"0xe21d622e34869e656a1e28f278a6b8226082d153",
Bytes.fromHexString(
"0xadf263dddf4ad5f323822773b76e64abc06230aec4bde5d8b7be5ea1193f2b6d000000000000000000000000000000000000000000000000000000000000001c8caf0f4834f493ade134f733cd97752b4b1f0a5c8ffee47b6ec05f46857557bf20de09970e1c57404cf7ca7efbcaa95c47d99a2eba76aa72bd1b44bb0486e368"));
testCases.put(
"0x7bbba2e9fca9f2ade01d6c9c0f63a12307e3fcfd",
Bytes.fromHexString(
"0x9b3ef1d284641e6c3be8dddfcf29844b393729155edb1d146dd6023dd336dc46000000000000000000000000000000000000000000000000000000000000001ba08e0795bbf5850b36b4326bb104aa14a49d44eb18e31b034b1694c5bbbcfd9732580cd88ea1277b202c6d3a575e45fbb6b2e0a489b74343035bdeef5c32863a"));
testCases.put(
"0x6df661c685e9433e2f85961d15c1a1c3f2121417",
Bytes.fromHexString(
"0x7eed0e79c71b7baf9b2598a7a53bcdbaffb985ec48e1560bf963aa631d5d8c92000000000000000000000000000000000000000000000000000000000000001b21a8126ccf776ed394576e3c50e10e489951886b7e8b1a9d640b5ab4c63253737f76e9955dc860d49295a3782130cabe694eb2ee34ef0dc3367b07b3efe9f3ac"));
testCases.put(
"0xbf14cdbb0f88457c9e6225c0b87b0b0b3d38e953",
Bytes.fromHexString(
"0xead4ef63f6bd001593e8088cdd8ab3c0c35ba808bebb091f43240ecbd81db3b9000000000000000000000000000000000000000000000000000000000000001b30d5d51ab3a1987baf4fb41ad5a2467b4a4a1000c909d51caf389e191441634135d94ea50996b6db1b1182a2c28162058ae53c3ef52695e5cc6b17018039d90e"));
testCases.put(
"0xcd6eb47247a12aea535d6fd96cad1f4c7bcb409c",
Bytes.fromHexString(
"0x0c24abcfa29ff1f068a19f2f1db51b6da6ab042ac0ea3d74c87465b2075377ff000000000000000000000000000000000000000000000000000000000000001b18e975c578187caeda96b6029a7ec7aa037757cfd182b5f8d71f872233c2264a6adbb4465a68fbf4a574071cc4973f5fd5e7b721c86cb7e0f47f595222e37289"));
testCases.put(
"0x9765c8a57ade562c30166b7e18aef179a22da185",
Bytes.fromHexString(
"0xda13687f911cf8ede5e0a4317d8b9bf691b56bc2f3f4e463c8c2eb1f61a54469000000000000000000000000000000000000000000000000000000000000001bf6e5df315197d9fe994fae7e05e33be4bd090f9533f36c6285b80478cd21c38533928bb06d48795a86c12f5ccb95758e891d8b1b2d62106e85ae36cb8414d56b"));
final SECP256K1 signatureAlgorithm = new SECP256K1();
if (attemptNative != null && (!attemptNative || !signatureAlgorithm.maybeEnableNative())) {
signatureAlgorithm.disableNative();
}
output.println(signatureAlgorithm.isNative() ? "Native secp256k1" : "Java secp256k1");
final ECRECPrecompiledContract contract =
new ECRECPrecompiledContract(gasCalculatorForFork(fork), signatureAlgorithm);
warmup = warmup / testCases.size();
iterations = iterations / testCases.size();
double execTime = Double.MIN_VALUE; // a way to dodge divide by zero
long gasCost = 0;
for (final Map.Entry<String, Bytes> testCase : testCases.entrySet()) {
execTime += runPrecompileBenchmark(testCase.getValue(), contract);
gasCost += contract.gasRequirement(testCase.getValue());
}
execTime /= testCases.size();
gasCost /= testCases.size();
output.printf(
"ecrecover %,6d gas @%,7.1f µs /%,8.1f MGps%n",
gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
}
}

@ -0,0 +1,164 @@
/*
* Copyright contributors to Hyperledger Besu
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evmtool.benchmarks;
import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract;
import java.io.PrintStream;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.tuweni.bytes.Bytes;
/** Benchmark Modular Exponentiation */
public class ModExpBenchmark extends BenchmarkExecutor {
/** Benchmark with default math warmups and iterations */
public ModExpBenchmark() {
super(MATH_WARMUP, MATH_ITERATIONS);
}
@Override
public void runBenchmark(
final PrintStream output, final Boolean attemptNative, final String fork) {
final Map<String, Bytes> testcases = new LinkedHashMap<>();
testcases.put(
"eip_example1",
Bytes.fromHexString(
"0000000000000000000000000000000000000000000000000000000000000001"
+ "0000000000000000000000000000000000000000000000000000000000000020"
+ "0000000000000000000000000000000000000000000000000000000000000020"
+ "03"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"));
testcases.put(
"eip_example2",
Bytes.fromHexString(
"0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000020"
+ "0000000000000000000000000000000000000000000000000000000000000020"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"));
testcases.put(
"even-modulus-1",
Bytes.fromHexString(
"0000000000000000000000000000000000000000000000000000000000000003"
+ "0000000000000000000000000000000000000000000000000000000000000001"
+ "00000000000000000000000000000000000000000000000000000000000003c2"
+ "040160"
+ "02"
+ "4518968061546464452029984405379963244433254832348165045983839181603600983245188119082741180552472823434126339186042653363989253518144015007104659260895861906540664936284389736130979465984263224400655133820675791338815252163142936101184074977707018635613728563507946963514079867296353079585444179075183175315953500862929638853495671020263166123912364061541662955981749424030252416330220564030645929402440479045589943839631409636357644094127401186503107365632233122371688639562179885062893961510897259834525401728081797411184820573804096446362924176080926052008070342876591822173915634645231182811305568049542955744148010693635112077769594038286419007643605441221736768092092706367136248982357930831050114862462054469804238839007660797444001134145988063087013657265067255538916788266246587774231646489345179567885975873995767749906187041937713976494258573504873269320274358396975658022816526738914029788471066595929777423497242252763504644221066495966982158816143636722736200299105017320500139589998102103536908651755056175006587609525845133254470473698921229697550145309121304642224273213418856615560961843245211567388930209839462064588566503446549415643465733541976019955544090933949692508519895293721888001835024288589127818157262958206047538648802179821901844091151603223229973835165715768557428338775055435040494382003663260090655173262271219880999454966135210800173588881197223814096778846598765822161982688788574265773201009190341430440400154076998270731076034021917712825351270109621323258567738829791704547404897555410847468529100600344699859551947494210268509149049419749744679372826553895949980386864014015247047775654329663958663391477680679444996526407026021137970100258833584773507489900747148344826790699325870056679710341571267983857125765234149331990149745571500943300684008078036054281629105618499442731182983775330888524074001975745730722737461725166625564316976464879780901853271273641654911641084141502464"));
testcases.put(
"even-modulus-2",
Bytes.fromHexString(
"0000000000000000000000000000000000000000000000000000000000000010"
+ "00000000000000000000000000000000000000000000000000000000000000d8"
+ "0000000000000000000000000000000000000000000000000000000000000010"
+ "e0060000a921212121212121ff000021"
+ "2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf82828282828200ff"
+ "ff28ff2b218282000000000000000000"));
testcases.put(
"even-modulus-3",
Bytes.fromHexString(
"0000000000000000000000000000000000000000000000000000000000000002"
+ "0000000000000000000000000000000000000000000000000000000000000001"
+ "000000000000000000000000000000000000000000000000000000000000031f"
+ "9ce0"
+ "02"
+ "4BC7569FD25D6FDAC9A0AB948FA20EE025AC8E9465351384E619B417B0A9E88ECDE2503875E7F9E06D9E3167E5763CDAE0938BF63F2E026AED3494BA85D03A215C9B804779632B6DFC08585FA39C2491B7A63DD819E9F0E8D818CA0DA4C5DDF34AF225FC90F0047B88F39A708AE2529DE01B2AFEE12B5F7D9420CB6ACFAC048BCF7E99411E1D7ECDDA8625278FEFC2765D3E2EFD5255554E2C381FFAA3D9BF01A9941CBEFAF96EBA1B40C9C8A3CCFAA181DED264214233AA7B71D1D1DEDCE61F7C96FB056BAEE8D0481E0F95E14583AEB53D36D4FC70AE26E0578018F5E73C8A85A8F0047050C70D2BE3FEB6DEA8A63F47051286E1151430B0EC410081D0A223313DF2D2C6BF5CE28C32DEA4F3EF79F0BE51460DC6E4733265E122BB074CE6578D906D77D8C7BBAA4EAEB1EDD1D52805284E310A493B865739A30C33E5366B3AF1F6A27E3001499EEA600B4FA22A2E6E15FCED013D1717A3E2FCB06C971B2CAFECA7D85A7D98921F49730364A7703AF47F3894346D683070F38B1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
testcases.put(
"nagydani-1-square",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb502fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b"));
testcases.put(
"nagydani-1-qube",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb503fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b"));
testcases.put(
"nagydani-1-pow0x10001",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5010001fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b"));
testcases.put(
"nagydani-2-square",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf5102e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087"));
testcases.put(
"nagydani-2-qube",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf5103e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087"));
testcases.put(
"nagydani-2-pow0x10001",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51010001e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087"));
testcases.put(
"nagydani-3-square",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb02d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d"));
testcases.put(
"nagydani-3-qube",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb03d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d"));
testcases.put(
"nagydani-3-pow0x10001",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb010001d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d"));
testcases.put(
"nagydani-4-square",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b8102df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f"));
testcases.put(
"nagydani-4-qube",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b8103df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f"));
testcases.put(
"nagydani-4-pow0x10001",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81010001df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f"));
testcases.put(
"nagydani-5-square",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf02e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad"));
testcases.put(
"nagydani-5-qube",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf03e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad"));
testcases.put(
"nagydani-5-pow0x10001",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf010001e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad"));
final BigIntegerModularExponentiationPrecompiledContract contract =
new BigIntegerModularExponentiationPrecompiledContract(gasCalculatorForFork(fork));
if (attemptNative != null
&& (!attemptNative
|| !BigIntegerModularExponentiationPrecompiledContract.maybeEnableNative())) {
BigIntegerModularExponentiationPrecompiledContract.disableNative();
}
output.println(
BigIntegerModularExponentiationPrecompiledContract.isNative()
? "Native ModExp"
: "Java modExp");
for (final Map.Entry<String, Bytes> testCase : testcases.entrySet()) {
final double execTime = runPrecompileBenchmark(testCase.getValue(), contract);
long gasCost = contract.gasRequirement(testCase.getValue());
output.printf(
"ModEXP %-22s %,6d gas @%,7.1f µs /%,8.1f MGps%n",
testCase.getKey(), gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000);
}
}
}

@ -0,0 +1,72 @@
/*
* Copyright contributors to Hyperledger Besu
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evmtool.benchmarks;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hyperledger.besu.crypto.Hash.keccak256;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SECP256K1;
import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SECPSignature;
import java.io.PrintStream;
import java.math.BigInteger;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
/** Benchmark secp256k1 public key extraction */
public class Secp256k1Benchmark extends BenchmarkExecutor {
/** secp256k1 benchmark using default math warmup and iterations */
public Secp256k1Benchmark() {
super(MATH_WARMUP, MATH_ITERATIONS);
}
@Override
public void runBenchmark(
final PrintStream output, final Boolean attemptNative, final String fork) {
final SECP256K1 signatureAlgorithm = new SECP256K1();
if (attemptNative != null && (!attemptNative || !signatureAlgorithm.maybeEnableNative())) {
signatureAlgorithm.disableNative();
}
output.println(signatureAlgorithm.isNative() ? "Native secp256k1" : "Java secp256k1");
final SECPPrivateKey privateKey =
signatureAlgorithm.createPrivateKey(
new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16));
final KeyPair keyPair = signatureAlgorithm.createKeyPair(privateKey);
final Bytes data = Bytes.wrap("This is an example of a signed message.".getBytes(UTF_8));
final Bytes32 dataHash = keccak256(data);
final SECPSignature signature = signatureAlgorithm.sign(dataHash, keyPair);
for (int i = 0; i < warmup; i++) {
signatureAlgorithm.recoverPublicKeyFromSignature(dataHash, signature);
}
final Stopwatch timer = Stopwatch.createStarted();
for (int i = 0; i < iterations; i++) {
signatureAlgorithm.recoverPublicKeyFromSignature(dataHash, signature);
}
timer.stop();
final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D;
final double perCall = elapsed / MATH_ITERATIONS;
output.printf("secp256k1 signature recovery for %,.1f µs%n", perCall * 1_000_000);
}
}

@ -79,6 +79,16 @@ public enum EvmSpecVersion {
this.description = description; this.description = description;
} }
/**
* What is the "default" version of EVM that should be made. Newer versions of Besu will adjust
* this to reflect mainnet fork development.
*
* @return the current mainnet for as of the release of this version of Besu
*/
public static EvmSpecVersion defaultVersion() {
return SHANGHAI;
}
/** /**
* Gets max eof version. * Gets max eof version.
* *
@ -120,4 +130,19 @@ public enum EvmSpecVersion {
} }
versionWarned = true; versionWarned = true;
} }
/**
* Calculate a spec version from a text fork name.
*
* @param name The name of the fork, such as "shahghai" or "berlin"
* @return the EVM spec version for that fork, or null if no fork matched.
*/
public static EvmSpecVersion fromName(final String name) {
for (var version : EvmSpecVersion.values()) {
if (version.name().equalsIgnoreCase(name)) {
return version;
}
}
return null;
}
} }

@ -40,12 +40,22 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil
static boolean useNative; static boolean useNative;
static { static {
maybeEnableNative();
}
/**
* Attempt to enable the native library for AltBn contracts
*
* @return true if the native library was enabled.
*/
public static boolean maybeEnableNative() {
try { try {
useNative = LibEthPairings.ENABLED; useNative = LibEthPairings.ENABLED;
} catch (UnsatisfiedLinkError ule) { } catch (UnsatisfiedLinkError | NoClassDefFoundError ule) {
LOG.info("altbn128 native precompile not available: {}", ule.getMessage()); LOG.info("altbn128 native precompile not available: {}", ule.getMessage());
useNative = false; useNative = false;
} }
return useNative;
} }
/** Disable native. */ /** Disable native. */

@ -44,15 +44,6 @@ public class BigIntegerModularExponentiationPrecompiledContract
/** Use native Arithmetic libraries. */ /** Use native Arithmetic libraries. */
static boolean useNative; static boolean useNative;
static {
try {
useNative = LibArithmetic.ENABLED;
} catch (UnsatisfiedLinkError | NoClassDefFoundError ule) {
LOG.info("modexp native precompile not available: {}", ule.getMessage());
useNative = false;
}
}
/** The constant BASE_OFFSET. */ /** The constant BASE_OFFSET. */
public static final int BASE_OFFSET = 96; public static final int BASE_OFFSET = 96;
@ -75,6 +66,21 @@ public class BigIntegerModularExponentiationPrecompiledContract
useNative = false; useNative = false;
} }
/**
* Attempt to enable the native library for ModExp
*
* @return true if the native library was enabled.
*/
public static boolean maybeEnableNative() {
try {
useNative = LibArithmetic.ENABLED;
} catch (UnsatisfiedLinkError | NoClassDefFoundError ule) {
LOG.info("modexp native precompile not available: {}", ule.getMessage());
useNative = false;
}
return useNative;
}
/** /**
* Check if native Arithmetic libraries are enabled. * Check if native Arithmetic libraries are enabled.
* *

@ -35,14 +35,26 @@ import org.apache.tuweni.bytes.MutableBytes32;
public class ECRECPrecompiledContract extends AbstractPrecompiledContract { public class ECRECPrecompiledContract extends AbstractPrecompiledContract {
private static final int V_BASE = 27; private static final int V_BASE = 27;
final SignatureAlgorithm signatureAlgorithm;
/** /**
* Instantiates a new ECREC precompiled contract. * Instantiates a new ECREC precompiled contract with the default signature algorithm.
* *
* @param gasCalculator the gas calculator * @param gasCalculator the gas calculator
*/ */
public ECRECPrecompiledContract(final GasCalculator gasCalculator) { public ECRECPrecompiledContract(final GasCalculator gasCalculator) {
this(gasCalculator, SignatureAlgorithmFactory.getInstance());
}
/**
* Configure a new ECRecover precompile with a specific signature algorith and gas.
*
* @param gasCalculator the gas calculator
* @param signatureAlgorithm the algoritm (such as secp256k1 or secp256r1)
*/
public ECRECPrecompiledContract(
final GasCalculator gasCalculator, final SignatureAlgorithm signatureAlgorithm) {
super("ECREC", gasCalculator); super("ECREC", gasCalculator);
this.signatureAlgorithm = signatureAlgorithm;
} }
@Override @Override
@ -68,7 +80,6 @@ public class ECRECPrecompiledContract extends AbstractPrecompiledContract {
final int recId = d.get(63) - V_BASE; final int recId = d.get(63) - V_BASE;
final BigInteger r = d.slice(64, 32).toUnsignedBigInteger(); final BigInteger r = d.slice(64, 32).toUnsignedBigInteger();
final BigInteger s = d.slice(96, 32).toUnsignedBigInteger(); final BigInteger s = d.slice(96, 32).toUnsignedBigInteger();
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
final SECPSignature signature; final SECPSignature signature;
try { try {

@ -18,7 +18,6 @@ package org.hyperledger.besu.evm.precompile;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hyperledger.besu.crypto.Hash.keccak256; import static org.hyperledger.besu.crypto.Hash.keccak256;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.crypto.Hash; import org.hyperledger.besu.crypto.Hash;
import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.KeyPair;
@ -29,11 +28,11 @@ import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.code.CodeV0;
import org.hyperledger.besu.evm.frame.BlockValues; import org.hyperledger.besu.evm.fluent.SimpleBlockValues;
import org.hyperledger.besu.evm.fluent.SimpleWorld;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator; import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator;
import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Map; import java.util.Map;
@ -45,6 +44,7 @@ import com.google.common.collect.ImmutableMap;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.bytes.Bytes32;
@SuppressWarnings("UnusedMethod")
public class Benchmarks { public class Benchmarks {
static final Random random = new Random(); static final Random random = new Random();
@ -68,12 +68,12 @@ public class Benchmarks {
.completer(__ -> {}) .completer(__ -> {})
.address(Address.ZERO) .address(Address.ZERO)
.blockHashLookup(n -> null) .blockHashLookup(n -> null)
.blockValues(mock(BlockValues.class)) .blockValues(new SimpleBlockValues())
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)
.originator(Address.ZERO) .originator(Address.ZERO)
.initialGas(100_000L) .initialGas(100_000L)
.worldUpdater(mock(WorldUpdater.class)) .worldUpdater(new SimpleWorld())
.build(); .build();
private static void benchSecp256k1Recover() { private static void benchSecp256k1Recover() {
@ -109,7 +109,7 @@ public class Benchmarks {
final byte[] warmupData = new byte[240]; final byte[] warmupData = new byte[240];
final Bytes warmupBytes = Bytes.wrap(warmupData); final Bytes warmupBytes = Bytes.wrap(warmupData);
for (int i = 0; i < HASH_WARMUP; i++) { for (int i = 0; i < HASH_WARMUP; i++) {
contract.compute(warmupBytes, fakeFrame); contract.computePrecompile(warmupBytes, fakeFrame);
} }
for (int len = 0; len <= 256; len += 8) { for (int len = 0; len <= 256; len += 8) {
final byte[] data = new byte[len]; final byte[] data = new byte[len];
@ -117,7 +117,7 @@ public class Benchmarks {
final Bytes bytes = Bytes.wrap(data); final Bytes bytes = Bytes.wrap(data);
final Stopwatch timer = Stopwatch.createStarted(); final Stopwatch timer = Stopwatch.createStarted();
for (int i = 0; i < HASH_ITERATIONS; i++) { for (int i = 0; i < HASH_ITERATIONS; i++) {
contract.compute(bytes, fakeFrame); contract.computePrecompile(bytes, fakeFrame);
} }
timer.stop(); timer.stop();
@ -165,7 +165,7 @@ public class Benchmarks {
final byte[] warmupData = new byte[240]; final byte[] warmupData = new byte[240];
final Bytes warmupBytes = Bytes.wrap(warmupData); final Bytes warmupBytes = Bytes.wrap(warmupData);
for (int i = 0; i < HASH_WARMUP; i++) { for (int i = 0; i < HASH_WARMUP; i++) {
contract.compute(warmupBytes, fakeFrame); contract.computePrecompile(warmupBytes, fakeFrame);
} }
for (int len = 0; len <= 256; len += 8) { for (int len = 0; len <= 256; len += 8) {
final byte[] data = new byte[len]; final byte[] data = new byte[len];
@ -173,7 +173,7 @@ public class Benchmarks {
final Bytes bytes = Bytes.wrap(data); final Bytes bytes = Bytes.wrap(data);
final Stopwatch timer = Stopwatch.createStarted(); final Stopwatch timer = Stopwatch.createStarted();
for (int i = 0; i < HASH_ITERATIONS; i++) { for (int i = 0; i < HASH_ITERATIONS; i++) {
contract.compute(bytes, fakeFrame); contract.computePrecompile(bytes, fakeFrame);
} }
timer.stop(); timer.stop();
@ -207,6 +207,14 @@ public class Benchmarks {
+ "0000000000000000000000000000000000000000000000000000000000000020" + "0000000000000000000000000000000000000000000000000000000000000020"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f")) + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"))
.put(
"even-modulus-1",
Bytes.fromHexString(
"0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003c2040160024518968061546464452029984405379963244433254832348165045983839181603600983245188119082741180552472823434126339186042653363989253518144015007104659260895861906540664936284389736130979465984263224400655133820675791338815252163142936101184074977707018635613728563507946963514079867296353079585444179075183175315953500862929638853495671020263166123912364061541662955981749424030252416330220564030645929402440479045589943839631409636357644094127401186503107365632233122371688639562179885062893961510897259834525401728081797411184820573804096446362924176080926052008070342876591822173915634645231182811305568049542955744148010693635112077769594038286419007643605441221736768092092706367136248982357930831050114862462054469804238839007660797444001134145988063087013657265067255538916788266246587774231646489345179567885975873995767749906187041937713976494258573504873269320274358396975658022816526738914029788471066595929777423497242252763504644221066495966982158816143636722736200299105017320500139589998102103536908651755056175006587609525845133254470473698921229697550145309121304642224273213418856615560961843245211567388930209839462064588566503446549415643465733541976019955544090933949692508519895293721888001835024288589127818157262958206047538648802179821901844091151603223229973835165715768557428338775055435040494382003663260090655173262271219880999454966135210800173588881197223814096778846598765822161982688788574265773201009190341430440400154076998270731076034021917712825351270109621323258567738829791704547404897555410847468529100600344699859551947494210268509149049419749744679372826553895949980386864014015247047775654329663958663391477680679444996526407026021137970100258833584773507489900747148344826790699325870056679710341571267983857125765234149331990149745571500943300684008078036054281629105618499442731182983775330888524074001975745730722737461725166625564316976464879780901853271273641654911641084141502464"))
.put(
"even-modulus-2",
Bytes.fromHexString(
"000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d80000000000000000000000000000000000000000000000000000000000000010e0060000a921212121212121ff0000212b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf82828282828200ffff28ff2b218282000000000000000000"))
.put( .put(
"nagydani-1-square", "nagydani-1-square",
Bytes.fromHexString( Bytes.fromHexString(
@ -274,10 +282,16 @@ public class Benchmarks {
for (final Map.Entry<String, Bytes> testCase : testcases.entrySet()) { for (final Map.Entry<String, Bytes> testCase : testcases.entrySet()) {
final double gasSpent = runBenchmark(testCase.getValue(), contract); final double gasSpent = runBenchmark(testCase.getValue(), contract);
long gasCost = contract.gasRequirement(testCase.getValue());
System.out.printf( System.out.printf(
"ModEXP %s for \t%,d gas. Charging %,d gas.%n", "ModEXP %s for \t%,d gas. Charging %,d gas. \t@ %,.3f MGps%n",
testCase.getKey(), (int) gasSpent, contract.gasRequirement(testCase.getValue())); testCase.getKey(),
(int) gasSpent,
gasCost,
gasCost / gasSpent * GAS_PER_SECOND_STANDARD / 1_000_000);
} }
System.getProperties().forEach((k, v) -> System.out.println(k + " = " + v));
} }
private static void benchBNADD() { private static void benchBNADD() {
@ -403,7 +417,7 @@ public class Benchmarks {
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
final BLS12G1MulPrecompiledContract contract = new BLS12G1MulPrecompiledContract(); final BLS12G1MulPrecompiledContract contract = new BLS12G1MulPrecompiledContract();
contract.compute(arg, fakeFrame); contract.computePrecompile(arg, fakeFrame);
final double gasSpent = runBenchmark(arg, contract); final double gasSpent = runBenchmark(arg, contract);

@ -4625,17 +4625,6 @@
<sha256 value="125ed16e300f225a36c5b64c5d24b6d01d7dd607a16ba906aac563d9f1584183" origin="Generated by Gradle"/> <sha256 value="125ed16e300f225a36c5b64c5d24b6d01d7dd607a16ba906aac563d9f1584183" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </component>
<component group="org.hyperledger.besu" name="arithmetic" version="0.8.0">
<artifact name="arithmetic-0.8.0.jar">
<sha256 value="d212ae934d5b4bb9566cccc3be3975f6b761f20be39b678dc62d4d3c7d4630bb" origin="Generated by Gradle"/>
</artifact>
<artifact name="arithmetic-0.8.0.module">
<sha256 value="60e1a6dd82c4dd9850af1085dcbb16b0fad7f90652cc87506942056152b154f8" origin="Generated by Gradle"/>
</artifact>
<artifact name="arithmetic-0.8.0.pom">
<sha256 value="458a641eab685b596068c2ff6eed09cd63f7fca3c7d12691ad9572e4febb11b2" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="arithmetic" version="0.8.1"> <component group="org.hyperledger.besu" name="arithmetic" version="0.8.1">
<artifact name="arithmetic-0.8.1.jar"> <artifact name="arithmetic-0.8.1.jar">
<sha256 value="17ab44a742073928b1afb57ccd288a729a4406c75d9fe4bbf1d28a988f647322" origin="Generated by Gradle"/> <sha256 value="17ab44a742073928b1afb57ccd288a729a4406c75d9fe4bbf1d28a988f647322" origin="Generated by Gradle"/>
@ -4658,17 +4647,6 @@
<sha256 value="58d501993a559e26cfab9151abcd52636386bd26029c84541c7f5f52e063f580" origin="Generated by Gradle"/> <sha256 value="58d501993a559e26cfab9151abcd52636386bd26029c84541c7f5f52e063f580" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </component>
<component group="org.hyperledger.besu" name="blake2bf" version="0.8.0">
<artifact name="blake2bf-0.8.0.jar">
<sha256 value="baea77d08ea00eeec9ee282f63c8adc8a4d1813f96ea67cddd223e3fe4254473" origin="Generated by Gradle"/>
</artifact>
<artifact name="blake2bf-0.8.0.module">
<sha256 value="1e4a409998592799ccced76c6e51019f09f8d38b62319ab4c6911ad04a7c066a" origin="Generated by Gradle"/>
</artifact>
<artifact name="blake2bf-0.8.0.pom">
<sha256 value="cd5f9eda36b9304b88ecb2148eb2cf433463892606da24a9770f735e6aed31c4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="blake2bf" version="0.8.1"> <component group="org.hyperledger.besu" name="blake2bf" version="0.8.1">
<artifact name="blake2bf-0.8.1.jar"> <artifact name="blake2bf-0.8.1.jar">
<sha256 value="a604d6aa5e5b8195702bd37021bcc75ca71bb82fc5f9d6b62e728470d00eaa1f" origin="Generated by Gradle"/> <sha256 value="a604d6aa5e5b8195702bd37021bcc75ca71bb82fc5f9d6b62e728470d00eaa1f" origin="Generated by Gradle"/>
@ -4691,17 +4669,6 @@
<sha256 value="eb939df4f6ad29183c8f216e193a8aa83690b3e6314ed9f5627c9f9e8b9dd762" origin="Generated by Gradle"/> <sha256 value="eb939df4f6ad29183c8f216e193a8aa83690b3e6314ed9f5627c9f9e8b9dd762" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </component>
<component group="org.hyperledger.besu" name="bls12-381" version="0.8.0">
<artifact name="bls12-381-0.8.0.jar">
<sha256 value="88a876cdb8e82ae18a4a2d638b5bf5ff405073cd0f80381e3ec5cca1897ca096" origin="Generated by Gradle"/>
</artifact>
<artifact name="bls12-381-0.8.0.module">
<sha256 value="a83e64d317b5fd7b92d99330f86b5b63ca956c8553af6ebdfbe84f47bccae69a" origin="Generated by Gradle"/>
</artifact>
<artifact name="bls12-381-0.8.0.pom">
<sha256 value="8b4c36761f333101c0b8bb3c81cb1a243c6ab3ef7376bf5b57e3e98ae046a56a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="bls12-381" version="0.8.1"> <component group="org.hyperledger.besu" name="bls12-381" version="0.8.1">
<artifact name="bls12-381-0.8.1.jar"> <artifact name="bls12-381-0.8.1.jar">
<sha256 value="271008a549cb5d881139dd750d7d0258a8ff31618ea36cb3f9a5b4a3df5f9a99" origin="Generated by Gradle"/> <sha256 value="271008a549cb5d881139dd750d7d0258a8ff31618ea36cb3f9a5b4a3df5f9a99" origin="Generated by Gradle"/>
@ -4724,17 +4691,6 @@
<sha256 value="736c81314a55fa16e856885c8357ff6cbee003b529142b6dd8aa6c4555332146" origin="Generated by Gradle"/> <sha256 value="736c81314a55fa16e856885c8357ff6cbee003b529142b6dd8aa6c4555332146" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </component>
<component group="org.hyperledger.besu" name="ipa-multipoint" version="0.8.0">
<artifact name="ipa-multipoint-0.8.0.jar">
<sha256 value="d782dac28b58ca3dc5ecc465693f73987120928ce26e9b4a2a88541b074c5fbf" origin="Generated by Gradle"/>
</artifact>
<artifact name="ipa-multipoint-0.8.0.module">
<sha256 value="d8d6120d3be96ffde850a3bd389dcc5d9533adcc261ba9e1912213c57e99cd67" origin="Generated by Gradle"/>
</artifact>
<artifact name="ipa-multipoint-0.8.0.pom">
<sha256 value="044105580bf327bed6e79179abaac211f4052578feb1fa0f41bbd657e23cc1db" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="ipa-multipoint" version="0.8.1"> <component group="org.hyperledger.besu" name="ipa-multipoint" version="0.8.1">
<artifact name="ipa-multipoint-0.8.1.jar"> <artifact name="ipa-multipoint-0.8.1.jar">
<sha256 value="ade17354e57645288634f6242e68fc1299afa7732773b3d5ef7c98157567c8aa" origin="Generated by Gradle"/> <sha256 value="ade17354e57645288634f6242e68fc1299afa7732773b3d5ef7c98157567c8aa" origin="Generated by Gradle"/>
@ -4757,17 +4713,6 @@
<sha256 value="f1685ec3024a025df9a87c36936fc607915f2178586aa8e5cea2f572920836c1" origin="Generated by Gradle"/> <sha256 value="f1685ec3024a025df9a87c36936fc607915f2178586aa8e5cea2f572920836c1" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </component>
<component group="org.hyperledger.besu" name="secp256k1" version="0.8.0">
<artifact name="secp256k1-0.8.0.jar">
<sha256 value="b6316569037dff6f03afb03eaa1a98a46abcf2780daff56087f4341f68e03744" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256k1-0.8.0.module">
<sha256 value="e3cd691714950f8d538129d145776aeda72a37aed19fda03ea097c8fd62eb1e5" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256k1-0.8.0.pom">
<sha256 value="80d37682bde537b12714937f297b51078bd109e1c3f1aa72df2eeea582d60503" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="secp256k1" version="0.8.1"> <component group="org.hyperledger.besu" name="secp256k1" version="0.8.1">
<artifact name="secp256k1-0.8.1.jar"> <artifact name="secp256k1-0.8.1.jar">
<sha256 value="95331608c36d19ad455f48df123f6aa2a20d865dad25a6d0a7b10b83d381c71b" origin="Generated by Gradle"/> <sha256 value="95331608c36d19ad455f48df123f6aa2a20d865dad25a6d0a7b10b83d381c71b" origin="Generated by Gradle"/>
@ -4790,17 +4735,6 @@
<sha256 value="b1bd15999f2f6d8a9ed8ac269d625b463055e7c60f6c6dbe5456d950a63c0a2a" origin="Generated by Gradle"/> <sha256 value="b1bd15999f2f6d8a9ed8ac269d625b463055e7c60f6c6dbe5456d950a63c0a2a" origin="Generated by Gradle"/>
</artifact> </artifact>
</component> </component>
<component group="org.hyperledger.besu" name="secp256r1" version="0.8.0">
<artifact name="secp256r1-0.8.0.jar">
<sha256 value="f2d0e156b7275d1fd52d6888eda612284cb87825ad131741c4ce6af9cba419da" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256r1-0.8.0.module">
<sha256 value="35fa61a6a7396108e8e019ec1a022ffdebc1a6adb38fc3a75a57e2581c927250" origin="Generated by Gradle"/>
</artifact>
<artifact name="secp256r1-0.8.0.pom">
<sha256 value="fbed51dbc4bba2d8f8ade4c9fb777faba7bc12cabc451b55d44b9b025eea26ca" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.hyperledger.besu" name="secp256r1" version="0.8.1"> <component group="org.hyperledger.besu" name="secp256r1" version="0.8.1">
<artifact name="secp256r1-0.8.1.jar"> <artifact name="secp256r1-0.8.1.jar">
<sha256 value="9b7b8f3f557ad9216ed36a2f8ef8427fba78090d4d8bcb413d117993b4f9473e" origin="Generated by Gradle"/> <sha256 value="9b7b8f3f557ad9216ed36a2f8ef8427fba78090d4d8bcb413d117993b4f9473e" origin="Generated by Gradle"/>

Loading…
Cancel
Save