Strict input length metering for crypto precompiles (#2941)

For operations where input length as a maximum, only send that amount of
data to the native methods.

Signed-off-by: Danno Ferrin (shemnon) <danno.ferrin@shemnon.com>
pull/2948/head
Danno Ferrin 3 years ago committed by GitHub
parent 7a78ac0b27
commit 54c53a537e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java
  2. 13
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java
  3. 8
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java
  4. 8
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java
  5. 6
      evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java
  6. 4
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContract.java
  7. 4
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContract.java
  8. 9
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContract.java
  9. 4
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContract.java
  10. 4
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContract.java
  11. 9
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContract.java
  12. 7
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContract.java
  13. 7
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContract.java
  14. 9
      evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContract.java

@ -42,11 +42,16 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil
}
private final byte operationId;
private final int inputLen;
AbstractAltBnPrecompiledContract(
final String name, final GasCalculator gasCalculator, final byte operationId) {
final String name,
final GasCalculator gasCalculator,
final byte operationId,
final int inputLen) {
super(name, gasCalculator);
this.operationId = operationId;
this.inputLen = inputLen + 1;
if (!LibEthPairings.ENABLED) {
LOG.info("Native alt bn128 not available");
@ -61,9 +66,16 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil
new IntByReference(LibEthPairings.EIP196_PREALLOCATE_FOR_RESULT_BYTES);
final IntByReference err_len =
new IntByReference(LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES);
int inputSize = Math.min(inputLen, input.size());
final int errorNo =
LibEthPairings.eip196_perform_operation(
operationId, input.toArrayUnsafe(), input.size(), result, o_len, error, err_len);
operationId,
input.slice(0, inputSize).toArrayUnsafe(),
inputSize,
result,
o_len,
error,
err_len);
if (errorNo == 0) {
return Bytes.wrap(result, 0, o_len.getValue());
} else {

@ -48,10 +48,12 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon
private final String name;
private final byte operationId;
private final int inputLen;
AbstractBLS12PrecompiledContract(final String name, final byte operationId) {
AbstractBLS12PrecompiledContract(final String name, final byte operationId, final int inputLen) {
this.name = name;
this.operationId = operationId;
this.inputLen = inputLen + 1;
}
@Override
@ -68,9 +70,16 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon
new IntByReference(LibEthPairings.EIP2537_PREALLOCATE_FOR_RESULT_BYTES);
final IntByReference err_len =
new IntByReference(LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES);
final int inputSize = Math.min(inputLen, input.size());
final int errorNo =
LibEthPairings.eip2537_perform_operation(
operationId, input.toArrayUnsafe(), input.size(), result, o_len, error, err_len);
operationId,
input.slice(0, inputSize).toArrayUnsafe(),
inputSize,
result,
o_len,
error,
err_len);
if (errorNo == 0) {
return Bytes.wrap(result, 0, o_len.getValue());
} else {

@ -29,10 +29,16 @@ import org.apache.tuweni.bytes.MutableBytes;
public class AltBN128AddPrecompiledContract extends AbstractAltBnPrecompiledContract {
private static final int PARAMETER_LENGTH = 128;
private final Gas gasCost;
private AltBN128AddPrecompiledContract(final GasCalculator gasCalculator, final Gas gasCost) {
super("AltBN128Add", gasCalculator, LibEthPairings.EIP196_ADD_OPERATION_RAW_VALUE);
super(
"AltBN128Add",
gasCalculator,
LibEthPairings.EIP196_ADD_OPERATION_RAW_VALUE,
PARAMETER_LENGTH);
this.gasCost = gasCost;
}

@ -29,6 +29,8 @@ import org.apache.tuweni.bytes.MutableBytes;
public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledContract {
private static final int PARAMETER_LENGTH = 96;
private static final BigInteger MAX_N =
new BigInteger(
"115792089237316195423570985008687907853269984665640564039457584007913129639935");
@ -36,7 +38,11 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont
private final Gas gasCost;
private AltBN128MulPrecompiledContract(final GasCalculator gasCalculator, final Gas gasCost) {
super("AltBN128Mul", gasCalculator, LibEthPairings.EIP196_MUL_OPERATION_RAW_VALUE);
super(
"AltBN128Mul",
gasCalculator,
LibEthPairings.EIP196_MUL_OPERATION_RAW_VALUE,
PARAMETER_LENGTH);
this.gasCost = gasCost;
}

@ -47,7 +47,11 @@ public class AltBN128PairingPrecompiledContract extends AbstractAltBnPrecompiled
private AltBN128PairingPrecompiledContract(
final GasCalculator gasCalculator, final Gas pairingGasCost, final Gas baseGasCost) {
super("AltBN128Pairing", gasCalculator, LibEthPairings.EIP196_PAIR_OPERATION_RAW_VALUE);
super(
"AltBN128Pairing",
gasCalculator,
LibEthPairings.EIP196_PAIR_OPERATION_RAW_VALUE,
Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH);
this.pairingGasCost = pairingGasCost;
this.baseGasCost = baseGasCost;
}

@ -22,8 +22,10 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12G1AddPrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 256;
public BLS12G1AddPrecompiledContract() {
super("BLS12_G1ADD", LibEthPairings.BLS12_G1ADD_OPERATION_RAW_VALUE);
super("BLS12_G1ADD", LibEthPairings.BLS12_G1ADD_OPERATION_RAW_VALUE, PARAMETER_LENGTH);
}
@Override

@ -22,8 +22,10 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12G1MulPrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 160;
public BLS12G1MulPrecompiledContract() {
super("BLS12_G1MUL", LibEthPairings.BLS12_G1MUL_OPERATION_RAW_VALUE);
super("BLS12_G1MUL", LibEthPairings.BLS12_G1MUL_OPERATION_RAW_VALUE, PARAMETER_LENGTH);
}
@Override

@ -22,13 +22,18 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12G1MultiExpPrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 160;
public BLS12G1MultiExpPrecompiledContract() {
super("BLS12_G1MULTIEXP", LibEthPairings.BLS12_G1MULTIEXP_OPERATION_RAW_VALUE);
super(
"BLS12_G1MULTIEXP",
LibEthPairings.BLS12_G1MULTIEXP_OPERATION_RAW_VALUE,
Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH);
}
@Override
public Gas gasRequirement(final Bytes input) {
final int k = input.size() / 160;
final int k = input.size() / PARAMETER_LENGTH;
return Gas.of(12L * k * getDiscount(k));
}
}

@ -22,8 +22,10 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12G2AddPrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 512;
public BLS12G2AddPrecompiledContract() {
super("BLS12_G2ADD", LibEthPairings.BLS12_G2ADD_OPERATION_RAW_VALUE);
super("BLS12_G2ADD", LibEthPairings.BLS12_G2ADD_OPERATION_RAW_VALUE, PARAMETER_LENGTH);
}
@Override

@ -22,8 +22,10 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12G2MulPrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 288;
public BLS12G2MulPrecompiledContract() {
super("BLS12_G2MUL", LibEthPairings.BLS12_G2MUL_OPERATION_RAW_VALUE);
super("BLS12_G2MUL", LibEthPairings.BLS12_G2MUL_OPERATION_RAW_VALUE, PARAMETER_LENGTH);
}
@Override

@ -22,13 +22,18 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12G2MultiExpPrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 288;
public BLS12G2MultiExpPrecompiledContract() {
super("BLS12_G2MULTIEXP", LibEthPairings.BLS12_G2MULTIEXP_OPERATION_RAW_VALUE);
super(
"BLS12_G2MULTIEXP",
LibEthPairings.BLS12_G2MULTIEXP_OPERATION_RAW_VALUE,
Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH);
}
@Override
public Gas gasRequirement(final Bytes input) {
final int k = input.size() / 288;
final int k = input.size() / PARAMETER_LENGTH;
return Gas.of(55L * k * getDiscount(k));
}
}

@ -22,8 +22,13 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12MapFp2ToG2PrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 128;
public BLS12MapFp2ToG2PrecompiledContract() {
super("BLS12_MAP_FIELD_TO_CURVE", LibEthPairings.BLS12_MAP_FP2_TO_G2_OPERATION_RAW_VALUE);
super(
"BLS12_MAP_FIELD_TO_CURVE",
LibEthPairings.BLS12_MAP_FP2_TO_G2_OPERATION_RAW_VALUE,
PARAMETER_LENGTH);
}
@Override

@ -22,8 +22,13 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12MapFpToG1PrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 64;
public BLS12MapFpToG1PrecompiledContract() {
super("BLS12_MAP_FIELD_TO_CURVE", LibEthPairings.BLS12_MAP_FP_TO_G1_OPERATION_RAW_VALUE);
super(
"BLS12_MAP_FIELD_TO_CURVE",
LibEthPairings.BLS12_MAP_FP_TO_G1_OPERATION_RAW_VALUE,
PARAMETER_LENGTH);
}
@Override

@ -22,13 +22,18 @@ import org.apache.tuweni.bytes.Bytes;
public class BLS12PairingPrecompiledContract extends AbstractBLS12PrecompiledContract {
private static final int PARAMETER_LENGTH = 384;
public BLS12PairingPrecompiledContract() {
super("BLS12_PAIRING", LibEthPairings.BLS12_PAIR_OPERATION_RAW_VALUE);
super(
"BLS12_PAIRING",
LibEthPairings.BLS12_PAIR_OPERATION_RAW_VALUE,
Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH);
}
@Override
public Gas gasRequirement(final Bytes input) {
final int k = input.size() / 384;
final int k = input.size() / PARAMETER_LENGTH;
return Gas.of(23_000L * k + 115_000);
}
}

Loading…
Cancel
Save