From 72f36530ba13fa15a23b54485731f03fa0734e82 Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Sun, 2 Jul 2023 17:14:50 +0200 Subject: [PATCH] Fix Fuzz 5: off-by-1 in even modexp (#247) --- constantine.nimble | 1 + .../arithmetic/bigints_views.nim | 2 +- constantine/platforms/primitives.nim | 4 +- tests/t_ethereum_evm_modexp.nim | 43 +++++++++++++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 tests/t_ethereum_evm_modexp.nim diff --git a/constantine.nimble b/constantine.nimble index 1fbd283..c5766b0 100644 --- a/constantine.nimble +++ b/constantine.nimble @@ -488,6 +488,7 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[ # Protocols # ---------------------------------------------------------- + ("tests/t_ethereum_evm_modexp.nim", false), ("tests/t_ethereum_evm_precompiles.nim", false), ("tests/t_ethereum_bls_signatures.nim", false), ("tests/t_ethereum_eip2333_bls12381_key_derivation.nim", false), diff --git a/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim b/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim index 43661c1..e7bae35 100644 --- a/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim +++ b/constantine/math_arbitrary_precision/arithmetic/bigints_views.nim @@ -147,7 +147,7 @@ func powMod_vartime*( # ------------------------------------------------------------------- if mBits-ctz == 1: # The modulus is a power of 2 - r.powMod2k_vartime(a, exponent, k = uint mBits) + r.powMod2k_vartime(a, exponent, k = uint ctz) return # Even modulus: general case diff --git a/constantine/platforms/primitives.nim b/constantine/platforms/primitives.nim index 4354904..5df7757 100644 --- a/constantine/platforms/primitives.nim +++ b/constantine/platforms/primitives.nim @@ -102,8 +102,8 @@ func rawCopy*( ## Unlike the standard library, this cannot throw ## even a defect. debug: - doAssert 0 <= dStart and dStart+len <= dst.len.uint, "dStart: " & $dStart & ", dStart+len: " & $(dStart+len) & ", dst.len: " & $dst.len - doAssert 0 <= sStart and sStart+len <= src.len.uint, "sStart: " & $sStart & ", sStart+len: " & $(sStart+len) & ", src.len: " & $src.len + doAssert 0 <= dStart and int(dStart+len) <= dst.len, "dStart: " & $dStart & ", dStart+len: " & $(dStart+len) & ", dst.len: " & $dst.len + doAssert 0 <= sStart and int(sStart+len) <= src.len, "sStart: " & $sStart & ", sStart+len: " & $(sStart+len) & ", src.len: " & $src.len {.push checks: off.} # No OverflowError or IndexError allowed for i in 0 ..< len: diff --git a/tests/t_ethereum_evm_modexp.nim b/tests/t_ethereum_evm_modexp.nim new file mode 100644 index 0000000..01f37fc --- /dev/null +++ b/tests/t_ethereum_evm_modexp.nim @@ -0,0 +1,43 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + ../constantine/ethereum_evm_precompiles, + std/unittest + +suite "EVM ModExp precompile (EIP-198)": + test "Audit #5 - Fuzz failure with even modulus": + let input = [ + + # Length of base (1) + uint8 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + + # Length of exponent (1) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + + # Length of modulus (1) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + + # Base + 0x06, + + # Exponent + 0x02, + + # Modulus + 0x04 + ] + + var r = newSeq[byte](1) + let status = r.eth_evm_modexp(input) + doAssert status == cttEVM_Success + doAssert r[0] == 0, ". Result was " & $r[0]