Frontier's modexp precompile is slow for even modulus
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.
| Package | Affected versions | Patched versions |
|---|---|---|
pallet-evm-precompile-modexpcrates.io | <= 1.0.0 | — |
Affected products
2- Range: <= 0.1.0
Patches
15af12e94d7dfIncrease modexp gas cost when mod is even (#1017)
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- github.com/advisories/GHSA-fcmm-54jp-7vf6ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-28431ghsaADVISORY
- github.com/paritytech/frontier/commit/5af12e94d7dfc8a0208a290643a800f55de7b219ghsax_refsource_MISCWEB
- github.com/paritytech/frontier/pull/1017ghsax_refsource_MISCWEB
- github.com/paritytech/frontier/security/advisories/GHSA-fcmm-54jp-7vf6ghsax_refsource_CONFIRMWEB
- github.com/rust-num/num-bigint/blob/6f2b8e0fc218dbd0f49bebb8db2d1a771fe6bafa/src/biguint/power.rsghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.