diff --git a/.gitmodules b/.gitmodules index 289491594b..6ee0551bce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -226,3 +226,6 @@ path = vendor/nim-minilru url = https://github.com/status-im/nim-minilru.git branch = master +[submodule "vendor/constantine"] + path = vendor/constantine + url = https://github.com/mratsim/constantine diff --git a/config.nims b/config.nims index 60e7f2cf3a..53d0711957 100644 --- a/config.nims +++ b/config.nims @@ -57,6 +57,9 @@ if defined(release) and not defined(disableLTO): switch("passC", "-fvisibility=hidden") if defined(windows): + # Constantine + switch("passC", "-fomit-frame-pointer") + switch("passL", "-fomit-frame-pointer") # disable timestamps in Windows PE headers - https://wiki.debian.org/ReproducibleBuilds/TimestampsInPEBinaries switch("passL", "-Wl,--no-insert-timestamp") # increase stack size, unless something else is setting the stack size @@ -171,6 +174,9 @@ switch("warning", "Deprecated:off") # disable nim-kzg's blst switch("define", "kzgExternalBlst") +# Constantine missing operand zero assumed error suppression +switch("warning", "User:off") + # We lock down rocksdb to a particular version # TODO self-build rocksdb dll on windows when not defined(use_system_rocksdb) and not defined(windows): @@ -200,6 +206,27 @@ put("secp256k1.always", "-fno-lto -fomit-frame-pointer") # Unfortunately this is filename based instead of path-based # Assumes GCC +# Constantine +put("limbs_asm_bigint_arm64.always", "-fno-lto") +put("limbs_asm_bigint_x86.always", "-fno-lto") +put("limbs_asm_crandall_x86.always", "-fno-lto") +put("limbs_asm_crandall_x86_adx_bmi2.always", "-fno-lto") +put("limbs_asm_modular_arm64.always", "-fno-lto") +put("limbs_asm_modular_dbl_prec_x86.always", "-fno-lto") +put("limbs_asm_modular_x86.always", "-fno-lto") +put("limbs_asm_mul_arm64.always", "-fno-lto") +put("limbs_asm_mul_mont_arm64.always", "-fno-lto") +put("limbs_asm_mul_mont_x86.always", "-fno-lto") +put("limbs_asm_mul_mont_x86_adx_bmi2.always", "-fno-lto") +put("limbs_asm_mul_x86.always", "-fno-lto") +put("limbs_asm_mul_x86_adx_bmi2.always", "-fno-lto") +put("limbs_asm_redc_mont_arm64.always", "-fno-lto") +put("limbs_asm_redc_mont_x86.always", "-fno-lto") +put("limbs_asm_redc_mont_x86_adx_bmi2.always", "-fno-lto") + +put("bls12_381_pairings.always", "-fno-lto") +put("ec_multi_scalar_mul_scheduler.always", "-fno-lto") + # BLST put("server.always", "-fno-lto") put("assembly.always", "-fno-lto") diff --git a/execution_chain/evm/precompiles.nim b/execution_chain/evm/precompiles.nim index f9e3d43951..b08af59244 100644 --- a/execution_chain/evm/precompiles.nim +++ b/execution_chain/evm/precompiles.nim @@ -11,6 +11,7 @@ import std/[macros], results, + constantine/ethereum_evm_precompiles, "."/[types, blake2b_f, blscurve], ./interpreter/[gas_meter, gas_costs, utils/utils_numeric], eth/common/keys, @@ -233,7 +234,11 @@ func sha256(c: Computation): EvmResultVoid = gasFee = GasSHA256 + wordCount.GasInt * GasSHA256Word ? c.gasMeter.consumeGas(gasFee, reason="SHA256 Precompile") - assign(c.output, sha2.sha256.digest(c.msg.data).data) + c.output.setLen(32) + let res = c.output.eth_evm_sha256(c.msg.data) + + if res != cttEVM_Success: + return err(prcErr(PrcInvalidParam)) ok() func ripemd160(c: Computation): EvmResultVoid = @@ -243,7 +248,10 @@ func ripemd160(c: Computation): EvmResultVoid = ? c.gasMeter.consumeGas(gasFee, reason="RIPEMD160 Precompile") c.output.setLen(32) - assign(c.output.toOpenArray(12, 31), ripemd.ripemd160.digest(c.msg.data).data) + let res =c.output.eth_evm_ripemd160(c.msg.data) + + if res != cttEVM_Success: + return err(prcErr(PrcInvalidParam)) ok() func identity(c: Computation): EvmResultVoid = @@ -385,19 +393,14 @@ func bn256ecAdd(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid = let gasFee = if fork < FkIstanbul: GasECAdd else: GasECAddIstanbul ? c.gasMeter.consumeGas(gasFee, reason = "ecAdd Precompile") - var - input: array[128, byte] - # Padding data - let len = min(c.msg.data.len, 128) - 1 - input[0..len] = c.msg.data[0..len] - var p1 = ? G1.getPoint(input.toOpenArray(0, 63)) - var p2 = ? G1.getPoint(input.toOpenArray(64, 127)) - var apo = (p1 + p2).toAffine() + var output: array[64, byte] + let res = output.eth_evm_bn254_g1add(c.msg.data) + + if res != cttEVM_Success: + return err(prcErr(PrcInvalidParam)) c.output.setLen(64) - if isSome(apo): - # we can discard here because we supply proper buffer - discard apo.get().toBytes(c.output) + assign(c.output, output) ok() @@ -405,20 +408,14 @@ func bn256ecMul(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid = let gasFee = if fork < FkIstanbul: GasECMul else: GasECMulIstanbul ? c.gasMeter.consumeGas(gasFee, reason="ecMul Precompile") - var - input: array[96, byte] + var output: array[64, byte] + let res = output.eth_evm_bn254_g1mul(c.msg.data) - # Padding data - let len = min(c.msg.data.len, 96) - 1 - assign(input.toOpenArray(0, len), c.msg.data.toOpenArray(0, len)) - var p1 = ? G1.getPoint(input.toOpenArray(0, 63)) - var fr = ? getFR(input.toOpenArray(64, 95)) - var apo = (p1 * fr).toAffine() + if res != cttEVM_Success: + return err(prcErr(PrcInvalidParam)) c.output.setLen(64) - if isSome(apo): - # we can discard here because we supply buffer of proper size - discard apo.get().toBytes(c.output) + assign(c.output, output) ok() @@ -457,7 +454,7 @@ func bn256ecPairing(c: Computation, fork: EVMFork = FkByzantium): EvmResultVoid if acc == FQ12.one(): # we can discard here because we supply buffer of proper size discard BNU256.one().toBytesBE(c.output) - + ok() func blake2bf(c: Computation): EvmResultVoid = @@ -485,18 +482,15 @@ func blsG1Add(c: Computation): EvmResultVoid = ? c.gasMeter.consumeGas(Bls12381G1AddGas, reason="blsG1Add Precompile") - var a, b: BLS_G1 - if not a.decodePoint(input.toOpenArray(0, 127)): - return err(prcErr(PrcInvalidPoint)) - - if not b.decodePoint(input.toOpenArray(128, 255)): - return err(prcErr(PrcInvalidPoint)) + var output: array[128, byte] + let res = output.eth_evm_bls12381_g1add(c.msg.data) - a.add b + if res != cttEVM_Success: + return err(prcErr(PrcInvalidParam)) c.output.setLen(128) - if not encodePoint(a, c.output): - return err(prcErr(PrcInvalidPoint)) + assign(c.output, output) + ok() const @@ -560,35 +554,15 @@ func blsG1MultiExp(c: Computation): EvmResultVoid = ? c.gasMeter.consumeGas(gas, reason="blsG1MultiExp Precompile") - var - p: BLS_G1 - s: BLS_SCALAR - acc: BLS_G1 + var output: array[128, byte] + let res = output.eth_evm_bls12381_g1msm(input) - # Decode point scalar pairs - for i in 0..