mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 15:37:54 -05:00
Speedup modexp (#4780)
Increate the speed of ModExp gas calculations by using primitive types. Use a native lib for modexp precompile. Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com> * Native modexp
This commit is contained in:
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,11 +1,13 @@
|
||||
# Changelog
|
||||
## 22.10.3
|
||||
|
||||
### Additions and Improvements
|
||||
- Implement Eth/68 sub-protocol [#4715](https://github.com/hyperledger/besu/issues/4715)
|
||||
|
||||
### Breaking Changes
|
||||
- Added `--rpc-max-logs-range` CLI option to allow limiting the number of blocks queried by `eth_getLogs` RPC API. Default value: 1000 [#4597](https://github.com/hyperledger/besu/pull/4597)
|
||||
- The `graalvm` docker variant no longer meets the performance requirements for Ethereum Mainnet. The `openjdk-11` and `openjdk-latest` variants are recommended in its place.
|
||||
|
||||
### Additions and Improvements
|
||||
- Implement Eth/68 sub-protocol [#4715](https://github.com/hyperledger/besu/issues/4715)
|
||||
- Increase the speed of modexp gas execution and execution. [#4780](https://github.com/hyperledger/besu/pull/4780)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -18,8 +20,8 @@ This is a hotfix release to resolve a race condition that results in segfaults,
|
||||
- bugfix for async operations on Snashot worldstates [#4767](https://github.com/hyperledger/besu/pull/4767)
|
||||
|
||||
### Download Links
|
||||
https://hyperledger.jfrog.io/hyperledger/besu-binaries/besu/22.10.2/besu-22.10.2.tar.gz / sha256: TBA
|
||||
https://hyperledger.jfrog.io/hyperledger/besu-binaries/besu/22.10.2/besu-22.10.2.zip / sha256: TBA
|
||||
https://hyperledger.jfrog.io/hyperledger/besu-binaries/besu/22.10.2/besu-22.10.2.tar.gz / sha256: cdb36141e3cba6379d35016e0a2de2edba579d4786124b5f7257b1e4a68867a2
|
||||
https://hyperledger.jfrog.io/hyperledger/besu-binaries/besu/22.10.2/besu-22.10.2.zip / sha256: 4c9208f684762670cb4f2c6ebfb6930e05e339a7c3c586fe8caa9f26462830aa
|
||||
|
||||
|
||||
## 22.10.1
|
||||
|
||||
@@ -146,6 +146,7 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorage;
|
||||
import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract;
|
||||
import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
|
||||
import org.hyperledger.besu.metrics.MetricsProtocol;
|
||||
@@ -1740,6 +1741,14 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
logger.info("Using the Java implementation of alt bn128");
|
||||
}
|
||||
|
||||
if (unstableNativeLibraryOptions.getNativeModExp()
|
||||
&& BigIntegerModularExponentiationPrecompiledContract.isNative()) {
|
||||
logger.info("Using the native implementation of modexp");
|
||||
} else {
|
||||
BigIntegerModularExponentiationPrecompiledContract.disableNative();
|
||||
logger.info("Using the Java implementation of modexp");
|
||||
}
|
||||
|
||||
if (unstableNativeLibraryOptions.getNativeSecp()
|
||||
&& SignatureAlgorithmFactory.getInstance().isNative()) {
|
||||
logger.info("Using the native implementation of the signature algorithm");
|
||||
|
||||
@@ -45,6 +45,15 @@ public class NativeLibraryOptions {
|
||||
arity = "1")
|
||||
private final Boolean nativeBlake2bf = Boolean.TRUE;
|
||||
|
||||
@CommandLine.Option(
|
||||
hidden = true,
|
||||
names = {"--Xmodexp-native-enabled"},
|
||||
description =
|
||||
"Per default a native library is used for modexp. "
|
||||
+ "If the Java implementation should be used instead, this option must be set to false",
|
||||
arity = "1")
|
||||
private final Boolean nativeModExp = Boolean.TRUE;
|
||||
|
||||
public static NativeLibraryOptions create() {
|
||||
return new NativeLibraryOptions();
|
||||
}
|
||||
@@ -60,4 +69,8 @@ public class NativeLibraryOptions {
|
||||
public Boolean getNativeBlake2bf() {
|
||||
return nativeBlake2bf;
|
||||
}
|
||||
|
||||
public Boolean getNativeModExp() {
|
||||
return nativeModExp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,16 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
|
||||
private long rounds; // unsigned integer represented as long
|
||||
|
||||
private final long[] v;
|
||||
private static boolean useNative = LibBlake2bf.ENABLED;
|
||||
private static boolean useNative;
|
||||
|
||||
static {
|
||||
try {
|
||||
useNative = LibBlake2bf.ENABLED;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
LOG.info("blake2bf native precompile not available: {}", ule.getMessage());
|
||||
useNative = false;
|
||||
}
|
||||
}
|
||||
|
||||
Blake2bfDigest() {
|
||||
if (!useNative) {
|
||||
|
||||
@@ -16,6 +16,7 @@ package org.hyperledger.besu.crypto;
|
||||
|
||||
import org.hyperledger.besu.nativelib.secp256r1.LibSECP256R1;
|
||||
import org.hyperledger.besu.nativelib.secp256r1.Signature;
|
||||
import org.hyperledger.besu.nativelib.secp256r1.besuNativeEC.BesuNativeEC;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Optional;
|
||||
@@ -25,15 +26,25 @@ import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.bouncycastle.crypto.signers.DSAKCalculator;
|
||||
import org.bouncycastle.crypto.signers.RandomDSAKCalculator;
|
||||
import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SECP256R1 extends AbstractSECP256 {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SECP256R1.class);
|
||||
|
||||
public static final String CURVE_NAME = "secp256r1";
|
||||
private boolean useNative = true;
|
||||
private boolean useNative;
|
||||
private final LibSECP256R1 libSECP256R1 = new LibSECP256R1();
|
||||
|
||||
public SECP256R1() {
|
||||
super(CURVE_NAME, SecP256R1Curve.q);
|
||||
try {
|
||||
useNative = BesuNativeEC.INSTANCE != null;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
LOG.info("secp256r1 native precompile not available: {}", ule.getMessage());
|
||||
useNative = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
FROM ghcr.io/graalvm/graalvm-ce:ol7-java11
|
||||
FROM ghcr.io/graalvm/graalvm-ce:ol8-java11
|
||||
ARG VERSION="dev"
|
||||
|
||||
RUN adduser --home /opt/besu besu && \
|
||||
|
||||
@@ -100,7 +100,7 @@ public class StateTestVersionedTransaction {
|
||||
@JsonDeserialize(using = StateTestAccessListDeserializer.class) @JsonProperty("accessLists")
|
||||
final List<List<AccessListEntry>> maybeAccessLists) {
|
||||
|
||||
this.nonce = Long.decode(nonce);
|
||||
this.nonce = Bytes.fromHexStringLenient(nonce).toLong();
|
||||
this.gasPrice = Optional.ofNullable(gasPrice).map(Wei::fromHexString).orElse(null);
|
||||
this.maxFeePerGas = Optional.ofNullable(maxFeePerGas).map(Wei::fromHexString).orElse(null);
|
||||
this.maxPriorityFeePerGas =
|
||||
|
||||
@@ -41,6 +41,7 @@ dependencies {
|
||||
compileOnly 'com.fasterxml.jackson.core:jackson-databind'
|
||||
|
||||
implementation 'org.apache.tuweni:tuweni-bytes'
|
||||
implementation 'org.hyperledger.besu:arithmetic'
|
||||
implementation 'org.hyperledger.besu:bls12-381'
|
||||
implementation 'net.java.dev.jna:jna'
|
||||
implementation 'com.github.ben-manes.caffeine:caffeine'
|
||||
|
||||
@@ -16,11 +16,14 @@ package org.hyperledger.besu.evm.gascalculator;
|
||||
|
||||
import static org.hyperledger.besu.datatypes.Address.BLAKE2B_F_COMPRESSION;
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedAdd;
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedMultiply;
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedToInt;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.internal.Words;
|
||||
import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -218,38 +221,29 @@ public class BerlinGasCalculator extends IstanbulGasCalculator {
|
||||
|
||||
@Override
|
||||
public long modExpGasCost(final Bytes input) {
|
||||
final BigInteger baseLength =
|
||||
BigIntegerModularExponentiationPrecompiledContract.baseLength(input);
|
||||
final BigInteger exponentLength =
|
||||
final long baseLength = BigIntegerModularExponentiationPrecompiledContract.baseLength(input);
|
||||
final long exponentLength =
|
||||
BigIntegerModularExponentiationPrecompiledContract.exponentLength(input);
|
||||
final BigInteger modulusLength =
|
||||
final long modulusLength =
|
||||
BigIntegerModularExponentiationPrecompiledContract.modulusLength(input);
|
||||
final BigInteger exponentOffset =
|
||||
BigIntegerModularExponentiationPrecompiledContract.BASE_OFFSET.add(baseLength);
|
||||
final int firstExponentBytesCap =
|
||||
exponentLength.min(ByzantiumGasCalculator.MAX_FIRST_EXPONENT_BYTES).intValue();
|
||||
final long exponentOffset =
|
||||
clampedAdd(BigIntegerModularExponentiationPrecompiledContract.BASE_OFFSET, baseLength);
|
||||
final long firstExponentBytesCap =
|
||||
Math.min(exponentLength, ByzantiumGasCalculator.MAX_FIRST_EXPONENT_BYTES);
|
||||
final BigInteger firstExpBytes =
|
||||
BigIntegerModularExponentiationPrecompiledContract.extractParameter(
|
||||
input, exponentOffset, firstExponentBytesCap);
|
||||
final BigInteger adjustedExponentLength = adjustedExponentLength(exponentLength, firstExpBytes);
|
||||
final BigInteger multiplicationComplexity =
|
||||
modulusLength
|
||||
.max(baseLength)
|
||||
.add(BigInteger.valueOf(7))
|
||||
.divide(BigInteger.valueOf(8))
|
||||
.pow(2);
|
||||
input, clampedToInt(exponentOffset), clampedToInt(firstExponentBytesCap));
|
||||
final long adjustedExponentLength = adjustedExponentLength(exponentLength, firstExpBytes);
|
||||
long multiplicationComplexity = (Math.max(modulusLength, baseLength) + 7L) / 8L;
|
||||
multiplicationComplexity =
|
||||
Words.clampedMultiply(multiplicationComplexity, multiplicationComplexity);
|
||||
|
||||
final BigInteger gasRequirement =
|
||||
multiplicationComplexity
|
||||
.multiply(adjustedExponentLength.max(BigInteger.ONE))
|
||||
.divide(BigInteger.valueOf(3));
|
||||
|
||||
// Gas price is so large it will not fit in a Gas type, so a
|
||||
// very very very unlikely high gas price is used instead.
|
||||
if (gasRequirement.bitLength() > ByzantiumGasCalculator.MAX_GAS_BITS) {
|
||||
return Long.MAX_VALUE;
|
||||
} else {
|
||||
return Math.max(gasRequirement.longValueExact(), 200L);
|
||||
long gasRequirement =
|
||||
clampedMultiply(multiplicationComplexity, Math.max(adjustedExponentLength, 1L));
|
||||
if (gasRequirement != Long.MAX_VALUE) {
|
||||
gasRequirement /= 3;
|
||||
}
|
||||
|
||||
return Math.max(gasRequirement, 200L);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package org.hyperledger.besu.evm.gascalculator;
|
||||
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedAdd;
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedMultiply;
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedToInt;
|
||||
|
||||
import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -22,58 +26,44 @@ import java.math.BigInteger;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class ByzantiumGasCalculator extends SpuriousDragonGasCalculator {
|
||||
private static final BigInteger GQUADDIVISOR = BigInteger.valueOf(20);
|
||||
private static final BigInteger WORD_SIZE = BigInteger.valueOf(32);
|
||||
private static final BigInteger BITS_IN_BYTE = BigInteger.valueOf(8);
|
||||
private static final int GQUADDIVISOR = 20;
|
||||
private static final int WORD_SIZE = 32;
|
||||
private static final int BITS_IN_BYTE = 8;
|
||||
|
||||
public static final BigInteger MAX_FIRST_EXPONENT_BYTES = BigInteger.valueOf(32);
|
||||
public static final int MAX_GAS_BITS = 63;
|
||||
public static final int MAX_FIRST_EXPONENT_BYTES = 32;
|
||||
|
||||
@Override
|
||||
public long modExpGasCost(final Bytes input) {
|
||||
final BigInteger baseLength =
|
||||
BigIntegerModularExponentiationPrecompiledContract.baseLength(input);
|
||||
final BigInteger exponentLength =
|
||||
final long baseLength = BigIntegerModularExponentiationPrecompiledContract.baseLength(input);
|
||||
final long exponentLength =
|
||||
BigIntegerModularExponentiationPrecompiledContract.exponentLength(input);
|
||||
final BigInteger modulusLength =
|
||||
final long modulusLength =
|
||||
BigIntegerModularExponentiationPrecompiledContract.modulusLength(input);
|
||||
final BigInteger exponentOffset =
|
||||
BigIntegerModularExponentiationPrecompiledContract.BASE_OFFSET.add(baseLength);
|
||||
final int firstExponentBytesCap = exponentLength.min(MAX_FIRST_EXPONENT_BYTES).intValue();
|
||||
final long exponentOffset =
|
||||
clampedAdd(BigIntegerModularExponentiationPrecompiledContract.BASE_OFFSET, baseLength);
|
||||
final long firstExponentBytesCap = Math.min(exponentLength, MAX_FIRST_EXPONENT_BYTES);
|
||||
final BigInteger firstExpBytes =
|
||||
BigIntegerModularExponentiationPrecompiledContract.extractParameter(
|
||||
input, exponentOffset, firstExponentBytesCap);
|
||||
final BigInteger adjustedExponentLength = adjustedExponentLength(exponentLength, firstExpBytes);
|
||||
final BigInteger multiplicationComplexity =
|
||||
input, clampedToInt(exponentOffset), clampedToInt(firstExponentBytesCap));
|
||||
final long adjustedExponentLength = adjustedExponentLength(exponentLength, firstExpBytes);
|
||||
final long multiplicationComplexity =
|
||||
BigIntegerModularExponentiationPrecompiledContract.multiplicationComplexity(
|
||||
baseLength.max(modulusLength));
|
||||
final BigInteger gasRequirement =
|
||||
multiplicationComplexity
|
||||
.multiply(adjustedExponentLength.max(BigInteger.ONE))
|
||||
.divide(GQUADDIVISOR);
|
||||
|
||||
// Gas price is so large it will not fit in a Gas type, so a
|
||||
// very very very unlikely high gas price is used instead.
|
||||
if (gasRequirement.bitLength() > MAX_GAS_BITS) {
|
||||
return Long.MAX_VALUE;
|
||||
} else {
|
||||
return gasRequirement.longValueExact();
|
||||
}
|
||||
Math.max(baseLength, modulusLength));
|
||||
long numerator = clampedMultiply(multiplicationComplexity, Math.max(adjustedExponentLength, 1));
|
||||
return (numerator == Long.MAX_VALUE) ? Long.MAX_VALUE : numerator / GQUADDIVISOR;
|
||||
}
|
||||
|
||||
public static BigInteger adjustedExponentLength(
|
||||
final BigInteger exponentLength, final BigInteger firstExpBytes) {
|
||||
final BigInteger bitLength = bitLength(firstExpBytes);
|
||||
if (exponentLength.compareTo(WORD_SIZE) <= 0) {
|
||||
public static long adjustedExponentLength(
|
||||
final long exponentLength, final BigInteger firstExpBytes) {
|
||||
final int bitLength = bitLength(firstExpBytes);
|
||||
if (exponentLength < WORD_SIZE) {
|
||||
return bitLength;
|
||||
} else {
|
||||
return BITS_IN_BYTE.multiply(exponentLength.subtract(WORD_SIZE)).add(bitLength);
|
||||
return clampedAdd(clampedMultiply(BITS_IN_BYTE, (exponentLength - WORD_SIZE)), bitLength);
|
||||
}
|
||||
}
|
||||
|
||||
private static BigInteger bitLength(final BigInteger n) {
|
||||
return n.compareTo(BigInteger.ZERO) == 0
|
||||
? BigInteger.ZERO
|
||||
: BigInteger.valueOf(n.bitLength() - 1L);
|
||||
private static int bitLength(final BigInteger n) {
|
||||
return n.compareTo(BigInteger.ZERO) == 0 ? 0 : (n.bitLength() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ import org.apache.tuweni.bytes.MutableBytes;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
/** Static utility methods to work with VM words (that is, {@link Bytes32} values). */
|
||||
public abstract class Words {
|
||||
private Words() {}
|
||||
|
||||
public interface Words {
|
||||
/**
|
||||
* Creates a new word containing the provided address.
|
||||
*
|
||||
@@ -32,7 +30,7 @@ public abstract class Words {
|
||||
* @return A VM word containing {@code address} (left-padded as according to the VM specification
|
||||
* (Appendix H. of the Yellow paper)).
|
||||
*/
|
||||
public static UInt256 fromAddress(final Address address) {
|
||||
static UInt256 fromAddress(final Address address) {
|
||||
return UInt256.fromBytes(Bytes32.leftPad(address));
|
||||
}
|
||||
|
||||
@@ -43,18 +41,7 @@ public abstract class Words {
|
||||
* @return An address build from the right-most 160-bits of the {@code bytes} (as according to the
|
||||
* VM specification (Appendix H. of the Yellow paper)).
|
||||
*/
|
||||
public static Address toAddress(final Bytes32 bytes) {
|
||||
return Address.wrap(bytes.slice(bytes.size() - Address.SIZE, Address.SIZE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract an address from the provided address.
|
||||
*
|
||||
* @param bytes The word to extract the address from.
|
||||
* @return An address build from the right-most 160-bits of the {@code bytes} (as according to the
|
||||
* VM specification (Appendix H. of the Yellow paper)).
|
||||
*/
|
||||
public static Address toAddress(final Bytes bytes) {
|
||||
static Address toAddress(final Bytes bytes) {
|
||||
final int size = bytes.size();
|
||||
if (size < 20) {
|
||||
final MutableBytes result = MutableBytes.create(20);
|
||||
@@ -77,7 +64,7 @@ public abstract class Words {
|
||||
* @param input the input to check.
|
||||
* @return the number of (32 bytes) words that {@code input} spans.
|
||||
*/
|
||||
public static int numWords(final Bytes input) {
|
||||
static int numWords(final Bytes input) {
|
||||
// m/n round up == (m + n - 1)/n: http://www.cs.nott.ac.uk/~psarb2/G51MPC/slides/NumberLogic.pdf
|
||||
return (input.size() + Bytes32.SIZE - 1) / Bytes32.SIZE;
|
||||
}
|
||||
@@ -89,7 +76,7 @@ public abstract class Words {
|
||||
* @param uint the unsigned integer
|
||||
* @return the least of the integer value or Long.MAX_VALUE
|
||||
*/
|
||||
public static long clampedToLong(final Bytes uint) {
|
||||
static long clampedToLong(final Bytes uint) {
|
||||
if (uint.size() <= 8) {
|
||||
final long result = uint.toLong();
|
||||
return result < 0 ? Long.MAX_VALUE : result;
|
||||
@@ -105,6 +92,23 @@ public abstract class Words {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the long as though it was representing an unsigned integer, however if the value
|
||||
* is out of range it will return the number at the end of the range.
|
||||
*
|
||||
* @param l the signed integer
|
||||
* @return The int value, or Integer.MAX_VALUE if too large or Integer.MIN_VALUE if to small.
|
||||
*/
|
||||
static int clampedToInt(final long l) {
|
||||
if (l > Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else if (l < Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
} else {
|
||||
return (int) l;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a and b, but if an underflow/overflow occurs return the Long max/min value
|
||||
*
|
||||
@@ -112,7 +116,7 @@ public abstract class Words {
|
||||
* @param b second value
|
||||
* @return value of a plus b if no over/underflows or Long.MAX_VALUE/Long.MIN_VALUE otherwise
|
||||
*/
|
||||
public static long clampedAdd(final long a, final long b) {
|
||||
static long clampedAdd(final long a, final long b) {
|
||||
try {
|
||||
return Math.addExact(a, b);
|
||||
} catch (final ArithmeticException ae) {
|
||||
@@ -127,7 +131,7 @@ public abstract class Words {
|
||||
* @param b second value
|
||||
* @return value of a times b if no over/underflows or Long.MAX_VALUE/Long.MIN_VALUE otherwise
|
||||
*/
|
||||
public static long clampedMultiply(final long a, final long b) {
|
||||
static long clampedMultiply(final long a, final long b) {
|
||||
try {
|
||||
return Math.multiplyExact(a, b);
|
||||
} catch (final ArithmeticException ae) {
|
||||
@@ -135,6 +139,22 @@ public abstract class Words {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a and b, but if an underflow/overflow occurs return the Integer max/min value
|
||||
*
|
||||
* @param a first value
|
||||
* @param b second value
|
||||
* @return value of a times b if no over/underflows or Integer.MAX_VALUE/Integer.MIN_VALUE
|
||||
* otherwise
|
||||
*/
|
||||
static int clampedMultiply(final int a, final int b) {
|
||||
try {
|
||||
return Math.multiplyExact(a, b);
|
||||
} catch (final ArithmeticException ae) {
|
||||
return ((a ^ b) < 0) ? Integer.MIN_VALUE : Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lesser of the two values, when compared as an unsigned value
|
||||
*
|
||||
@@ -142,7 +162,7 @@ public abstract class Words {
|
||||
* @param b second value
|
||||
* @return a if, as an unsigned integer, a is less than b; otherwise b.
|
||||
*/
|
||||
public static long unsignedMin(final long a, final long b) {
|
||||
static long unsignedMin(final long a, final long b) {
|
||||
return Long.compareUnsigned(a, b) < 0 ? a : b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,16 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractAltBnPrecompiledContract.class);
|
||||
|
||||
// use the native library implementation, if it is available
|
||||
static boolean useNative = LibEthPairings.ENABLED;
|
||||
static boolean useNative;
|
||||
|
||||
static {
|
||||
try {
|
||||
useNative = LibEthPairings.ENABLED;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
LOG.info("altbn128 native precompile not available: {}", ule.getMessage());
|
||||
useNative = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void disableNative() {
|
||||
useNative = false;
|
||||
|
||||
@@ -14,39 +14,62 @@
|
||||
*/
|
||||
package org.hyperledger.besu.evm.precompile;
|
||||
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedMultiply;
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedToInt;
|
||||
import static org.hyperledger.besu.evm.internal.Words.clampedToLong;
|
||||
|
||||
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.nativelib.arithmetic.LibArithmetic;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.MutableBytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
// The big integer modular exponentiation precompiled contract defined in EIP-198.
|
||||
public class BigIntegerModularExponentiationPrecompiledContract
|
||||
extends AbstractPrecompiledContract {
|
||||
|
||||
public static final BigInteger BASE_OFFSET = BigInteger.valueOf(96);
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(BigIntegerModularExponentiationPrecompiledContract.class);
|
||||
|
||||
static boolean useNative;
|
||||
|
||||
static {
|
||||
try {
|
||||
useNative = LibArithmetic.ENABLED;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
LOG.info("modexp native precompile not available: {}", ule.getMessage());
|
||||
useNative = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int BASE_OFFSET = 96;
|
||||
private static final int PARAMETER_LENGTH = 32;
|
||||
private static final int BASE_LENGTH_OFFSET = 0;
|
||||
private static final int EXPONENT_LENGTH_OFFSET = 32;
|
||||
private static final int MODULUS_LENGTH_OFFSET = 64;
|
||||
|
||||
private static final BigInteger BIGINT_4 = BigInteger.valueOf(4);
|
||||
private static final BigInteger BIGINT_16 = BigInteger.valueOf(16);
|
||||
private static final BigInteger BIGINT_64 = BigInteger.valueOf(64);
|
||||
private static final BigInteger BIGINT_96 = BigInteger.valueOf(96);
|
||||
private static final BigInteger BIGINT_480 = BigInteger.valueOf(480);
|
||||
private static final BigInteger BIGINT_1024 = BigInteger.valueOf(1_024L);
|
||||
private static final BigInteger BIGINT_3072 = BigInteger.valueOf(3_072L);
|
||||
private static final BigInteger BIGINT_199680 = BigInteger.valueOf(199_680L);
|
||||
|
||||
public BigIntegerModularExponentiationPrecompiledContract(final GasCalculator gasCalculator) {
|
||||
super("BigIntModExp", gasCalculator);
|
||||
}
|
||||
|
||||
public static void disableNative() {
|
||||
useNative = false;
|
||||
}
|
||||
|
||||
public static boolean isNative() {
|
||||
return useNative;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long gasRequirement(final Bytes input) {
|
||||
return gasCalculator().modExpGasCost(input);
|
||||
@@ -56,24 +79,33 @@ public class BigIntegerModularExponentiationPrecompiledContract
|
||||
@Override
|
||||
public PrecompileContractResult computePrecompile(
|
||||
final Bytes input, @Nonnull final MessageFrame messageFrame) {
|
||||
final BigInteger baseLength = baseLength(input);
|
||||
final BigInteger exponentLength = exponentLength(input);
|
||||
final BigInteger modulusLength = modulusLength(input);
|
||||
if (useNative) {
|
||||
return computeNative(input);
|
||||
} else {
|
||||
return computeDefault(input);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public PrecompileContractResult computeDefault(final Bytes input) {
|
||||
final int baseLength = clampedToInt(baseLength(input));
|
||||
final int exponentLength = clampedToInt(exponentLength(input));
|
||||
final int modulusLength = clampedToInt(modulusLength(input));
|
||||
// If baseLength and modulusLength are zero
|
||||
// we could have a massively overflowing exp because it wouldn't have been filtered out at the
|
||||
// gas cost phase
|
||||
if (baseLength.equals(BigInteger.ZERO) && modulusLength.equals(BigInteger.ZERO)) {
|
||||
if ((baseLength == 0) && (modulusLength == 0)) {
|
||||
return PrecompileContractResult.success(Bytes.EMPTY);
|
||||
}
|
||||
final BigInteger exponentOffset = BASE_OFFSET.add(baseLength);
|
||||
final BigInteger modulusOffset = exponentOffset.add(exponentLength);
|
||||
final BigInteger base = extractParameter(input, BASE_OFFSET, baseLength.intValue());
|
||||
final BigInteger exp = extractParameter(input, exponentOffset, exponentLength.intValue());
|
||||
final BigInteger mod = extractParameter(input, modulusOffset, modulusLength.intValue());
|
||||
final int exponentOffset = BASE_OFFSET + baseLength;
|
||||
final int modulusOffset = exponentOffset + exponentLength;
|
||||
final BigInteger base = extractParameter(input, BASE_OFFSET, baseLength);
|
||||
final BigInteger exp = extractParameter(input, exponentOffset, exponentLength);
|
||||
final BigInteger mod = extractParameter(input, modulusOffset, modulusLength);
|
||||
|
||||
final Bytes modExp;
|
||||
// Result must be the length of the modulus.
|
||||
final MutableBytes result = MutableBytes.create(modulusLength.intValue());
|
||||
final MutableBytes result = MutableBytes.create(modulusLength);
|
||||
if (mod.compareTo(BigInteger.ZERO) == 0) {
|
||||
modExp = MutableBytes.EMPTY;
|
||||
} else {
|
||||
@@ -87,30 +119,29 @@ public class BigIntegerModularExponentiationPrecompiledContract
|
||||
}
|
||||
|
||||
// Equation to estimate the multiplication complexity.
|
||||
public static BigInteger multiplicationComplexity(final BigInteger x) {
|
||||
if (x.compareTo(BIGINT_64) <= 0) {
|
||||
public static long multiplicationComplexity(final long x) {
|
||||
if (x <= 64) {
|
||||
return square(x);
|
||||
} else if (x.compareTo(BIGINT_1024) <= 0) {
|
||||
return square(x).divide(BIGINT_4).add(BIGINT_96.multiply(x)).subtract(BIGINT_3072);
|
||||
} else if (x <= 1024) {
|
||||
return (square(x) / 4) + (x * 96) - 3072;
|
||||
} else {
|
||||
return square(x).divide(BIGINT_16).add(BIGINT_480.multiply(x)).subtract(BIGINT_199680);
|
||||
return (square(x) / 16) + (480 * x) - 199680;
|
||||
}
|
||||
}
|
||||
|
||||
public static BigInteger baseLength(final Bytes input) {
|
||||
return extractParameter(input, BASE_LENGTH_OFFSET, PARAMETER_LENGTH);
|
||||
public static long baseLength(final Bytes input) {
|
||||
return extractParameterLong(input, BASE_LENGTH_OFFSET, PARAMETER_LENGTH);
|
||||
}
|
||||
|
||||
public static BigInteger exponentLength(final Bytes input) {
|
||||
return extractParameter(input, EXPONENT_LENGTH_OFFSET, PARAMETER_LENGTH);
|
||||
public static long exponentLength(final Bytes input) {
|
||||
return extractParameterLong(input, EXPONENT_LENGTH_OFFSET, PARAMETER_LENGTH);
|
||||
}
|
||||
|
||||
public static BigInteger modulusLength(final Bytes input) {
|
||||
return extractParameter(input, MODULUS_LENGTH_OFFSET, PARAMETER_LENGTH);
|
||||
public static long modulusLength(final Bytes input) {
|
||||
return extractParameterLong(input, MODULUS_LENGTH_OFFSET, PARAMETER_LENGTH);
|
||||
}
|
||||
|
||||
private static BigInteger extractParameter(
|
||||
final Bytes input, final int offset, final int length) {
|
||||
public static BigInteger extractParameter(final Bytes input, final int offset, final int length) {
|
||||
if (offset > input.size() || length == 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
@@ -118,15 +149,41 @@ public class BigIntegerModularExponentiationPrecompiledContract
|
||||
return new BigInteger(1, raw);
|
||||
}
|
||||
|
||||
public static BigInteger extractParameter(
|
||||
final Bytes input, final BigInteger offset, final int length) {
|
||||
if (BigInteger.valueOf(input.size()).compareTo(offset) <= 0) {
|
||||
return BigInteger.ZERO;
|
||||
public static long extractParameterLong(final Bytes input, final int offset, final int length) {
|
||||
if (offset >= input.size() || length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return extractParameter(input, offset.intValue(), length);
|
||||
Bytes num;
|
||||
if (offset + length <= input.size()) {
|
||||
num = input.slice(offset, length).trimLeadingZeros();
|
||||
} else {
|
||||
// Ethereum's memory is always infinitely full of zeros, but we don't store those zeros, just
|
||||
// what we write. If we are asked for a range that is outside the written memory create a
|
||||
// result of the correct size (defaults to zeros) and copy the memory we do have into there.
|
||||
MutableBytes mut = MutableBytes.create(length);
|
||||
input.slice(offset).copyTo(mut, 0);
|
||||
num = mut.trimLeadingZeros();
|
||||
}
|
||||
return clampedToLong(num);
|
||||
}
|
||||
|
||||
private static BigInteger square(final BigInteger n) {
|
||||
return n.multiply(n);
|
||||
private static long square(final long n) {
|
||||
return clampedMultiply(n, n);
|
||||
}
|
||||
|
||||
public PrecompileContractResult computeNative(final @Nonnull Bytes input) {
|
||||
final int modulusLength = clampedToInt(modulusLength(input));
|
||||
final IntByReference o_len = new IntByReference(modulusLength);
|
||||
|
||||
final byte[] result = new byte[modulusLength];
|
||||
final int errorNo =
|
||||
LibArithmetic.modexp_precompiled(input.toArrayUnsafe(), input.size(), result, o_len);
|
||||
if (errorNo == 0) {
|
||||
return PrecompileContractResult.success(Bytes.wrap(result, 0, o_len.getValue()));
|
||||
} else {
|
||||
LOG.trace("Error executing precompiled contract {}: {}", getName(), errorNo);
|
||||
return PrecompileContractResult.halt(
|
||||
null, Optional.of(ExceptionalHaltReason.PRECOMPILE_ERROR));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package org.hyperledger.besu.evm.precompile;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assumptions.assumeThat;
|
||||
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator;
|
||||
@@ -143,6 +144,36 @@ public class MODEXPPrecompiledContractTest {
|
||||
"5a0eb2bdf0ac1cae8e586689fa16cd4b07dfdedaec8a110ea1fdb059dd5253231b6132987598dfc6e11f86780428982d50cf68f67ae452622c3b336b537ef3298ca645e8f89ee39a26758206a5a3f6409afc709582f95274b57b71fae5c6b74619ae6f089a5393c5b79235d9caf699d23d88fb873f78379690ad8405e34c19f5257d596580c7a6a7206a3712825afe630c76b31cdb4a23e7f0632e10f14f4e282c81a66451a26f8df2a352b5b9f607a7198449d1b926e27036810368e691a74b91c61afa73d9d3b99453e7c8b50fd4f09c039a2f2feb5c419206694c31b92df1d9586140cb3417b38d0c503c7b508cc2ed12e813a1c795e9829eb39ee78eeaf360a169b491a1d4e419574e712402de9d48d54c1ae5e03739b7156615e8267e1fb0a897f067afd11fb33f6e24182d7aaaaa18fe5bc1982f20d6b871e5a398f0f6f718181d31ec225cfa9a0a70124ed9a70031bdf0c1c7829f708b6e17d50419ef361cf77d99c85f44607186c8d683106b8bd38a49b5d0fb503b397a83388c5678dcfcc737499d84512690701ed621a6f0172aecf037184ddf0f2453e4053024018e5ab2e30d6d5363b56e8b41509317c99042f517247474ab3abc848e00a07f69c254f46f2a05cf6ed84e5cc906a518fdcfdf2c61ce731f24c5264f1a25fc04934dc28aec112134dd523f70115074ca34e3807aa4cb925147f3a0ce152d323bd8c675ace446d0fd1ae30c4b57f0eb2c23884bc18f0964c0114796c5b6d080c3d89175665fbf63a6381a6a9da39ad070b645c8bb1779506da14439a9f5b5d481954764ea114fac688930bc68534d403cff4210673b6a6ff7ae416b7cd41404c3d3f282fcd193b86d0f54d0006c2a503b40d5c3930da980565b8f9630e9493a79d1c03e74e5f93ac8e4dc1a901ec5e3b3e57049124c7b72ea345aa359e782285d9e6a5c144a378111dd02c40855ff9c2be9b48425cb0b2fd62dc8678fd151121cf26a65e917d65d8e0dacfae108eb5508b601fb8ffa370be1f9a8b749a2d12eeab81f41079de87e2d777994fa4d28188c579ad327f9957fb7bdecec5c680844dd43cb57cf87aeb763c003e65011f73f8c63442df39a92b946a6bd968a1c1e4d5fa7d88476a68bd8e20e5b70a99259c7d3f85fb1b65cd2e93972e6264e74ebf289b8b6979b9b68a85cd5b360c1987f87235c3c845d62489e33acf85d53fa3561fe3a3aee18924588d9c6eba4edb7a4d106b31173e42929f6f0c48c80ce6a72d54eca7c0fe870068b7a7c89c63cdda593f5b32d3cb4ea8a32c39f00ab449155757172d66763ed9527019d6de6c9f2416aa6203f4d11c9ebee1e1d3845099e55504446448027212616167eb36035726daa7698b075286f5379cd3e93cb3e0cf4f9cb8d017facbb5550ed32d5ec5400ae57e47e2bf78d1eaeff9480cc765ceff39db500",
|
||||
285900L,
|
||||
87381L
|
||||
},
|
||||
{
|
||||
"00000000000000000000000000000000000000000000000000000000000000ff2a1e5300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
null,
|
||||
Long.MAX_VALUE,
|
||||
Long.MAX_VALUE
|
||||
},
|
||||
{
|
||||
"0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010001",
|
||||
null,
|
||||
Long.MAX_VALUE,
|
||||
Long.MAX_VALUE
|
||||
},
|
||||
{
|
||||
"00000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000",
|
||||
null,
|
||||
1580L,
|
||||
280L
|
||||
},
|
||||
{
|
||||
"00000000008000000000000000000000000000000000000000000000000000000000000400000000000000000000000a",
|
||||
null,
|
||||
Long.MAX_VALUE,
|
||||
Long.MAX_VALUE
|
||||
},
|
||||
{
|
||||
"0x00000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
null,
|
||||
28928590731427686L,
|
||||
Long.MAX_VALUE,
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -160,10 +191,13 @@ public class MODEXPPrecompiledContractTest {
|
||||
|
||||
@Test
|
||||
public void testPrecompiledContract() {
|
||||
assumeThat(precompiledResult).isNotNull();
|
||||
final Bytes input = Bytes.fromHexString(this.input);
|
||||
final Bytes expected = Bytes.fromHexString(precompiledResult);
|
||||
assertThat(byzantiumContract.compute(input, messageFrame)).isEqualTo(expected);
|
||||
assertThat(berlinContract.compute(input, messageFrame)).isEqualTo(expected);
|
||||
assertThat(byzantiumContract.computePrecompile(input, messageFrame).getOutput())
|
||||
.isEqualTo(expected);
|
||||
assertThat(berlinContract.computePrecompile(input, messageFrame).getOutput())
|
||||
.isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -3874,6 +3874,11 @@
|
||||
<sha256 value="c363f28eade2e7486a0961d43b571421456e8d79363b58ae6a763f0ad338c0b4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.eclipse.platform" name="org.eclipse.swt" version="3.122.0">
|
||||
<artifact name="org.eclipse.swt-3.122.0.pom">
|
||||
<sha256 value="256e0626d5d690afc08479e01b9901aaa4cecd029d91b8f2c41f814e7a97aa83" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.eclipse.platform" name="org.eclipse.text" version="3.12.0">
|
||||
<artifact name="org.eclipse.text-3.12.0.jar">
|
||||
<sha256 value="457c1f8af07e870acce65130a2d9aa1e0fd95c92a7667bbd2db5bf7f9f19dd31" origin="Generated by Gradle"/>
|
||||
@@ -3953,48 +3958,59 @@
|
||||
<sha256 value="6d535f94efb663bdb682c9f27a50335394688009642ba7a9677504bc1be4129b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="blake2bf" version="0.6.1">
|
||||
<artifact name="blake2bf-0.6.1.jar">
|
||||
<sha256 value="809715f55a410fe6da444eacecd26f7065414c3ed40988b956c20b3a8e11abe2" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="arithmetic" version="0.7.1">
|
||||
<artifact name="arithmetic-0.7.1.jar">
|
||||
<sha256 value="38d5039419b5fc7c74da78be86cac2e11ce35bbfa9cd047f18da65b84ae2c2b4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="blake2bf-0.6.1.module">
|
||||
<sha256 value="e1e33b9398e192aa886ee4daee145e7c13359011e115fb7e3f4cb208546d1c23" origin="Generated by Gradle"/>
|
||||
<artifact name="arithmetic-0.7.1.module">
|
||||
<sha256 value="d508c4971ddaacdb75b7bec400fb292bbc2cec934ddad17106965dade7fffe4d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="blake2bf-0.6.1.pom">
|
||||
<sha256 value="c59f7a81e169b9099d5da38c346b69b93e84a5ace7ab3a9d17d042929ed42614" origin="Generated by Gradle"/>
|
||||
<artifact name="arithmetic-0.7.1.pom">
|
||||
<sha256 value="125ed16e300f225a36c5b64c5d24b6d01d7dd607a16ba906aac563d9f1584183" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="bls12-381" version="0.6.1">
|
||||
<artifact name="bls12-381-0.6.1.jar">
|
||||
<sha256 value="b2a6d139a7d13e453272aa68ad448989c4651d69c0e24cd1632f76a3cdfad0ee" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="blake2bf" version="0.7.1">
|
||||
<artifact name="blake2bf-0.7.1.jar">
|
||||
<sha256 value="e06429773d69d6fe5006ef7d7c45f11c2df56dc69f00a15e29519f17cc53754e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="bls12-381-0.6.1.module">
|
||||
<sha256 value="281ab4d15d0e5a39dd63520c84c39c14e6a8d2eb75abe3da3e6d6fd01e3dfda2" origin="Generated by Gradle"/>
|
||||
<artifact name="blake2bf-0.7.1.module">
|
||||
<sha256 value="001b26fa58ac344c50e343866a76d0e26b36580de16043cc89c8c40fb22f5d7b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="bls12-381-0.6.1.pom">
|
||||
<sha256 value="8cecb17d0ed5de8ab1059b8aee8da2928272e5601185f1a19a42b080b5724026" origin="Generated by Gradle"/>
|
||||
<artifact name="blake2bf-0.7.1.pom">
|
||||
<sha256 value="58d501993a559e26cfab9151abcd52636386bd26029c84541c7f5f52e063f580" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="secp256k1" version="0.6.1">
|
||||
<artifact name="secp256k1-0.6.1.jar">
|
||||
<sha256 value="c12e0ed581a727240bd16c67e137ee30ca1cda2a55238e58e745378a6159478e" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="bls12-381" version="0.7.1">
|
||||
<artifact name="bls12-381-0.7.1.jar">
|
||||
<sha256 value="bf116b267489302805cf0b89f07cde139f1ab41089336cf0779dd269463b2acb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256k1-0.6.1.module">
|
||||
<sha256 value="93fa3b93096072e3934b5e0f9d863405c57158461c5d303dbc1978090613c865" origin="Generated by Gradle"/>
|
||||
<artifact name="bls12-381-0.7.1.module">
|
||||
<sha256 value="2d5677e9d4c9894c6fea7826c2a3ce50cf13d37a6874b03d4198587576aeed02" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256k1-0.6.1.pom">
|
||||
<sha256 value="f322921a5ef98b9012c6d4f83611bd8e5f56f3e26b26d3750179f1f47b153a72" origin="Generated by Gradle"/>
|
||||
<artifact name="bls12-381-0.7.1.pom">
|
||||
<sha256 value="eb939df4f6ad29183c8f216e193a8aa83690b3e6314ed9f5627c9f9e8b9dd762" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="secp256r1" version="0.6.1">
|
||||
<artifact name="secp256r1-0.6.1.jar">
|
||||
<sha256 value="f0af26c128616a65616df3419bafeb14675079f3bbda12dfea829e37ab831e10" origin="Generated by Gradle"/>
|
||||
<component group="org.hyperledger.besu" name="secp256k1" version="0.7.1">
|
||||
<artifact name="secp256k1-0.7.1.jar">
|
||||
<sha256 value="80e5650d89099976c7932b4dfdfba0e09ecdd1650cdf0d27f45b9ade8e5ee71f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256r1-0.6.1.module">
|
||||
<sha256 value="399ea9bc9cfa7bd9ef95e8b8c3fff9839be61e3a3b4fe2fe4daa6d392aa7538c" origin="Generated by Gradle"/>
|
||||
<artifact name="secp256k1-0.7.1.module">
|
||||
<sha256 value="bdb425e3cee659f63eedbe1828d7cb4957a4f7ae2feca2364724fb5cb2dea8a1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256r1-0.6.1.pom">
|
||||
<sha256 value="81017f26ffedf193875f64f6850d16b09e730dd43bf236360fbc97bc44dee722" origin="Generated by Gradle"/>
|
||||
<artifact name="secp256k1-0.7.1.pom">
|
||||
<sha256 value="f1685ec3024a025df9a87c36936fc607915f2178586aa8e5cea2f572920836c1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.hyperledger.besu" name="secp256r1" version="0.7.1">
|
||||
<artifact name="secp256r1-0.7.1.jar">
|
||||
<sha256 value="520f2d2b8d97ab070af317a740fb5be3c052b04c177e96779e46b0a8502aa35a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256r1-0.7.1.module">
|
||||
<sha256 value="bb5179249597b5f685bcac1937af2d8f747797aff4d0bfe871513994aa66fc09" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="secp256r1-0.7.1.pom">
|
||||
<sha256 value="b1bd15999f2f6d8a9ed8ac269d625b463055e7c60f6c6dbe5456d950a63c0a2a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.immutables" name="immutables" version="2.9.0">
|
||||
|
||||
@@ -153,10 +153,13 @@ dependencyManagement {
|
||||
|
||||
dependency 'org.fusesource.jansi:jansi:2.4.0'
|
||||
|
||||
dependency 'org.hyperledger.besu:bls12-381:0.6.1'
|
||||
dependency 'org.hyperledger.besu:secp256k1:0.6.1'
|
||||
dependency 'org.hyperledger.besu:secp256r1:0.6.1'
|
||||
dependency 'org.hyperledger.besu:blake2bf:0.6.1'
|
||||
dependencySet(group: 'org.hyperledger.besu', version: '0.7.1') {
|
||||
entry 'arithmetic'
|
||||
entry 'bls12-381'
|
||||
entry 'secp256k1'
|
||||
entry 'secp256r1'
|
||||
entry 'blake2bf'
|
||||
}
|
||||
|
||||
dependency 'org.immutables:value-annotations:2.9.0'
|
||||
dependency 'org.immutables:value:2.9.0'
|
||||
|
||||
Reference in New Issue
Block a user