diff --git a/ethcore/builtin/src/lib.rs b/ethcore/builtin/src/lib.rs index b7a332ba63b..c6a9c868800 100644 --- a/ethcore/builtin/src/lib.rs +++ b/ethcore/builtin/src/lib.rs @@ -116,6 +116,7 @@ struct Linear { #[derive(Debug)] struct ModexpPricer { divisor: u64, + new_formula: bool, } impl Pricer for Linear { @@ -194,7 +195,13 @@ impl Pricer for ModexpPricer { let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low); - let (gas, overflow) = Self::mult_complexity(m).overflowing_mul(max(adjusted_exp_len, 1)); + let complexity_formula = if self.new_formula { + Self::mult_complexity_new + } else { + Self::mult_complexity + }; + + let (gas, overflow) = (complexity_formula)(m).overflowing_mul(max(adjusted_exp_len, 1)); if overflow { return U256::max_value(); } @@ -219,6 +226,10 @@ impl ModexpPricer { x => (x * x) / 16 + 480 * x - 199_680, } } + + fn mult_complexity_new(x: u64) -> u64 { + ((x / 64) + if x % 64 == 0 { 0 } else { 1 }) ^ 2 + } } /// Bls12 pairing price @@ -407,7 +418,19 @@ impl From for Pricing { 10 } else { exp.divisor - } + }, + new_formula: false, + }) + } + ethjson::spec::builtin::Pricing::Modexp2(exp) => { + Pricing::Modexp(ModexpPricer { + divisor: if exp.divisor == 0 { + warn!(target: "builtin", "Zero modexp divisor specified. Falling back to default: 10."); + 10 + } else { + exp.divisor + }, + new_formula: true, }) } ethjson::spec::builtin::Pricing::AltBn128Pairing(pricer) => { @@ -1360,7 +1383,7 @@ mod tests { #[test] fn modexp() { let f = Builtin { - pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20 })], + pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20, new_formula: false })], native: EthereumBuiltin::from_str("modexp").unwrap(), }; diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index bdf8f1168e4..f141d376a8f 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -4827,10 +4827,9 @@ "0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", - "activate_at": "0x42ae50", "pricing": { - "modexp": { - "divisor": 20 + "0x42ae50": { + "price": { "modexp": { "divisor": 20 } } } } } diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index 9a66c3a732a..a5914b01c15 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -104,8 +104,10 @@ pub enum Pricing { }, /// Linear pricing. Linear(Linear), - /// Pricing for modular exponentiation. + /// Pricing for modular exponentiation with original formula from EIP-198. Modexp(Modexp), + /// Pricing for modular exponentiation that includes new formula from EIP-2565. + Modexp2(Modexp), /// Pricing for alt_bn128_pairing exponentiation. AltBn128Pairing(AltBn128Pairing), /// Pricing for constant alt_bn128 operations