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

Commit

Permalink
Implement EIP-2565 (option B)
Browse files Browse the repository at this point in the history
  • Loading branch information
vorot93 committed May 21, 2020
1 parent eee06b3 commit 48caef7
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
19 changes: 16 additions & 3 deletions ethcore/builtin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use std::{
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
use common_types::errors::EthcoreError;
use ethereum_types::{H256, U256};
use ethjson::spec::builtin::ModexpMultComplexity;
use parity_crypto::publickey::{recover_allowing_all_zero_message, Signature, ZeroesAllowedMessage};
use keccak_hash::keccak;
use log::{warn, trace};
Expand Down Expand Up @@ -102,6 +103,7 @@ struct Linear {
#[derive(Debug)]
struct ModexpPricer {
divisor: u64,
mult_complexity_formula: ModexpMultComplexity,
}

impl Pricer for Linear {
Expand Down Expand Up @@ -180,7 +182,12 @@ 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 = match self.mult_complexity_formula {
ModexpMultComplexity::Eip198 => Self::mult_complexity,
ModexpMultComplexity::Eip2565 => Self::mult_complexity_new,
};

let (gas, overflow) = (complexity_formula)(m).overflowing_mul(max(adjusted_exp_len, 1));
if overflow {
return U256::max_value();
}
Expand All @@ -205,6 +212,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
}
}

/// Pricing scheme, execution definition, and activation block for a built-in contract.
Expand Down Expand Up @@ -281,7 +292,8 @@ impl From<ethjson::spec::builtin::Pricing> for Pricing {
10
} else {
exp.divisor
}
},
mult_complexity_formula: exp.mult_complexity_formula,
})
}
ethjson::spec::builtin::Pricing::AltBn128Pairing(pricer) => {
Expand Down Expand Up @@ -758,6 +770,7 @@ impl Bn128Pairing {

#[cfg(test)]
mod tests {
use super::*;
use std::convert::TryFrom;
use ethereum_types::U256;
use ethjson::spec::builtin::{
Expand Down Expand Up @@ -1037,7 +1050,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, mult_complexity_formula: ModexpMultComplexity::Eip198 })],
native: EthereumBuiltin::from_str("modexp").unwrap(),
};

Expand Down
10 changes: 7 additions & 3 deletions ethcore/res/ethereum/foundation.json
Original file line number Diff line number Diff line change
Expand Up @@ -4827,10 +4827,14 @@
"0x0000000000000000000000000000000000000005": {
"builtin": {
"name": "modexp",
"activate_at": "0x42ae50",
"pricing": {
"modexp": {
"divisor": 20
"0x42ae50": {
"price": {
"modexp": {
"divisor": 20,
"mult_complexity_formula": "eip198"
}
}
}
}
}
Expand Down
15 changes: 13 additions & 2 deletions json/src/spec/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,24 @@ pub struct Linear {
/// Price for word.
pub word: u64,
}
/// Computational complexity for modular exponentiation.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(rename_all = "lowercase", deny_unknown_fields)]
pub enum ModexpMultComplexity {
/// Computational complexity formula as defined in EIP-198
Eip198,
/// Computational complexity formula as defined in EIP-2565
Eip2565,
}

/// Pricing for modular exponentiation.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Modexp {
/// Price divisor.
pub divisor: u64,
/// Computational complexity function
pub mult_complexity_formula: ModexpMultComplexity,
}

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

#[cfg(test)]
mod tests {
use super::{Builtin, BuiltinCompat, Pricing, PricingAt, Linear, Modexp, AltBn128ConstOperations};
use super::*;
use maplit::btreemap;

#[test]
Expand Down Expand Up @@ -238,7 +249,7 @@ mod tests {
assert_eq!(builtin.pricing, btreemap![
100_000 => PricingAt {
info: None,
price: Pricing::Modexp(Modexp { divisor: 5 })
price: Pricing::Modexp(Modexp { divisor: 5, mult_complexity_formula: ModexpMultComplexity::Eip198 })
}
]);
}
Expand Down

0 comments on commit 48caef7

Please sign in to comment.