VYPR
High severityNVD Advisory· Published Mar 22, 2023· Updated Feb 25, 2025

Frontier's modexp precompile is slow for even modulus

CVE-2023-28431

Description

Frontier's modexp precompile uses num-bigint, which computes even and odd modulus exponents with different algorithms, causing a gas-cost discrepancy exploitable for denial of service.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Frontier's modexp precompile uses num-bigint, which computes even and odd modulus exponents with different algorithms, causing a gas-cost discrepancy exploitable for denial of service.

Vulnerability

Frontier, an Ethereum compatibility layer for Substrate, implements a modexp precompile that computes modular exponentiation. It relies on the num-bigint crate, which uses Montgomery multiplication for odd modulus but a slower plain exponentiation for even modulus [3]. This algorithmic difference was not reflected in the gas cost calculation, leading to underpriced even-modulus operations [1][2].

Exploitation

An attacker can craft a modexp call with an even modulus, causing the precompile to consume significantly more computational resources than the gas cost allows [1]. Since gas is prepaid and the execution is deterministic, this can lead to denial of service by exhausting block gas limits or node resources.

Impact

Successful exploitation results in denial of service, potentially stalling the network or degrading performance for legitimate users.

Mitigation

The fix, merged in pull request #1017, increases the gas cost for even modulus by a factor of 20 [4]. No patch for num-bigint currently exists, so the long-term solution involves either fixing the crate or switching to a different implementation [1]. Users should apply the Frontier patch and ensure their nodes are updated.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pallet-evm-precompile-modexpcrates.io
<= 1.0.0

Affected products

2

Patches

1
5af12e94d7df

Increase modexp gas cost when mod is even (#1017)

https://github.com/paritytech/frontierWei TangMar 15, 2023via ghsa
2 files changed · +12 4
  • frame/evm/precompile/modexp/src/lib.rs+11 3 modified
    @@ -23,7 +23,7 @@ extern crate alloc;
     use alloc::{vec, vec::Vec};
     use core::cmp::max;
     
    -use num::{BigUint, FromPrimitive, One, ToPrimitive, Zero};
    +use num::{BigUint, FromPrimitive, Integer, One, ToPrimitive, Zero};
     
     use fp_evm::{
     	ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput,
    @@ -41,6 +41,7 @@ fn calculate_gas_cost(
     	mod_length: u64,
     	exponent: &BigUint,
     	exponent_bytes: &[u8],
    +	mod_is_even: bool,
     ) -> u64 {
     	fn calculate_multiplication_complexity(base_length: u64, mod_length: u64) -> u64 {
     		let max_length = max(base_length, mod_length);
    @@ -91,6 +92,7 @@ fn calculate_gas_cost(
     		MIN_GAS_COST,
     		multiplication_complexity * iteration_count / 3,
     	)
    +	.saturating_mul(if mod_is_even { 20 } else { 1 })
     }
     
     /// Copy bytes from input to target.
    @@ -196,7 +198,13 @@ impl Precompile for Modexp {
     			let modulus = BigUint::from_bytes_be(&mod_buf);
     
     			// do our gas accounting
    -			let gas_cost = calculate_gas_cost(base_len as u64, mod_len as u64, &exponent, &exp_buf);
    +			let gas_cost = calculate_gas_cost(
    +				base_len as u64,
    +				mod_len as u64,
    +				&exponent,
    +				&exp_buf,
    +				modulus.is_even(),
    +			);
     
     			handle.record_cost(gas_cost)?;
     
    @@ -510,6 +518,6 @@ mod tests {
     
     		let _ = Modexp::execute(&mut handle).expect("Modexp::execute() returned error");
     
    -		assert_eq!(handle.gas_used, 7104); // gas used when ran in geth
    +		assert_eq!(handle.gas_used, 7104 * 20); // gas used when ran in geth (x20)
     	}
     }
    
  • shell.nix+1 1 modified
    @@ -2,7 +2,7 @@ let
       mozillaOverlay =
         import (builtins.fetchGit {
           url = "https://github.com/mozilla/nixpkgs-mozilla.git";
    -      rev = "4a07484cf0e49047f82d83fd119acffbad3b235f";
    +      rev = "78e723925daf5c9e8d0a1837ec27059e61649cb6";
         });
       nixpkgs = import <nixpkgs> { overlays = [ mozillaOverlay ]; };
       rust-nightly = with nixpkgs; ((rustChannelOf { date = "2022-11-16"; channel = "nightly"; }).rust.override {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.