Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 48caef7

Browse files
committed
Implement EIP-2565 (option B)
1 parent eee06b3 commit 48caef7

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

ethcore/builtin/src/lib.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::{
3030
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
3131
use common_types::errors::EthcoreError;
3232
use ethereum_types::{H256, U256};
33+
use ethjson::spec::builtin::ModexpMultComplexity;
3334
use parity_crypto::publickey::{recover_allowing_all_zero_message, Signature, ZeroesAllowedMessage};
3435
use keccak_hash::keccak;
3536
use log::{warn, trace};
@@ -102,6 +103,7 @@ struct Linear {
102103
#[derive(Debug)]
103104
struct ModexpPricer {
104105
divisor: u64,
106+
mult_complexity_formula: ModexpMultComplexity,
105107
}
106108

107109
impl Pricer for Linear {
@@ -180,7 +182,12 @@ impl Pricer for ModexpPricer {
180182

181183
let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low);
182184

183-
let (gas, overflow) = Self::mult_complexity(m).overflowing_mul(max(adjusted_exp_len, 1));
185+
let complexity_formula = match self.mult_complexity_formula {
186+
ModexpMultComplexity::Eip198 => Self::mult_complexity,
187+
ModexpMultComplexity::Eip2565 => Self::mult_complexity_new,
188+
};
189+
190+
let (gas, overflow) = (complexity_formula)(m).overflowing_mul(max(adjusted_exp_len, 1));
184191
if overflow {
185192
return U256::max_value();
186193
}
@@ -205,6 +212,10 @@ impl ModexpPricer {
205212
x => (x * x) / 16 + 480 * x - 199_680,
206213
}
207214
}
215+
216+
fn mult_complexity_new(x: u64) -> u64 {
217+
((x / 64) + if x % 64 == 0 { 0 } else { 1 }) ^ 2
218+
}
208219
}
209220

210221
/// Pricing scheme, execution definition, and activation block for a built-in contract.
@@ -281,7 +292,8 @@ impl From<ethjson::spec::builtin::Pricing> for Pricing {
281292
10
282293
} else {
283294
exp.divisor
284-
}
295+
},
296+
mult_complexity_formula: exp.mult_complexity_formula,
285297
})
286298
}
287299
ethjson::spec::builtin::Pricing::AltBn128Pairing(pricer) => {
@@ -758,6 +770,7 @@ impl Bn128Pairing {
758770

759771
#[cfg(test)]
760772
mod tests {
773+
use super::*;
761774
use std::convert::TryFrom;
762775
use ethereum_types::U256;
763776
use ethjson::spec::builtin::{
@@ -1037,7 +1050,7 @@ mod tests {
10371050
#[test]
10381051
fn modexp() {
10391052
let f = Builtin {
1040-
pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20 })],
1053+
pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20, mult_complexity_formula: ModexpMultComplexity::Eip198 })],
10411054
native: EthereumBuiltin::from_str("modexp").unwrap(),
10421055
};
10431056

ethcore/res/ethereum/foundation.json

+7-3
Original file line numberDiff line numberDiff line change
@@ -4827,10 +4827,14 @@
48274827
"0x0000000000000000000000000000000000000005": {
48284828
"builtin": {
48294829
"name": "modexp",
4830-
"activate_at": "0x42ae50",
48314830
"pricing": {
4832-
"modexp": {
4833-
"divisor": 20
4831+
"0x42ae50": {
4832+
"price": {
4833+
"modexp": {
4834+
"divisor": 20,
4835+
"mult_complexity_formula": "eip198"
4836+
}
4837+
}
48344838
}
48354839
}
48364840
}

json/src/spec/builtin.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,24 @@ pub struct Linear {
3030
/// Price for word.
3131
pub word: u64,
3232
}
33+
/// Computational complexity for modular exponentiation.
34+
#[derive(Debug, PartialEq, Deserialize, Clone)]
35+
#[serde(rename_all = "lowercase", deny_unknown_fields)]
36+
pub enum ModexpMultComplexity {
37+
/// Computational complexity formula as defined in EIP-198
38+
Eip198,
39+
/// Computational complexity formula as defined in EIP-2565
40+
Eip2565,
41+
}
3342

3443
/// Pricing for modular exponentiation.
3544
#[derive(Debug, PartialEq, Deserialize, Clone)]
3645
#[serde(deny_unknown_fields)]
3746
pub struct Modexp {
3847
/// Price divisor.
3948
pub divisor: u64,
49+
/// Computational complexity function
50+
pub mult_complexity_formula: ModexpMultComplexity,
4051
}
4152

4253
/// Pricing for constant alt_bn128 operations (ECADD and ECMUL)
@@ -139,7 +150,7 @@ pub struct PricingAt {
139150

140151
#[cfg(test)]
141152
mod tests {
142-
use super::{Builtin, BuiltinCompat, Pricing, PricingAt, Linear, Modexp, AltBn128ConstOperations};
153+
use super::*;
143154
use maplit::btreemap;
144155

145156
#[test]
@@ -238,7 +249,7 @@ mod tests {
238249
assert_eq!(builtin.pricing, btreemap![
239250
100_000 => PricingAt {
240251
info: None,
241-
price: Pricing::Modexp(Modexp { divisor: 5 })
252+
price: Pricing::Modexp(Modexp { divisor: 5, mult_complexity_formula: ModexpMultComplexity::Eip198 })
242253
}
243254
]);
244255
}

0 commit comments

Comments
 (0)