Skip to content

Instantly share code, notes, and snippets.

@ineffectualproperty
Created October 6, 2020 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ineffectualproperty/60e34f15c31850c5b60c8cf3a28cd423 to your computer and use it in GitHub Desktop.
Save ineffectualproperty/60e34f15c31850c5b60c8cf3a28cd423 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
import json
import math
# New EIP
def calculate_multiplication_complexity(base_length, modulus_length):
max_length = max(base_length, modulus_length)
words = math.ceil(max_length / 8)
return words**2
def calculate_iteration_count(exponent_length, exponent): # same as ADUSTED_EXPONENT_LENGTH in EIP-198
iteration_count = 0
if exponent_length <= 32 and exponent == 0: iteration_count = 0
elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1
elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1)
return max(iteration_count, 1)
def calculate_gas_cost(base_length, modulus_length, exponent_length, exponent):
multiplication_complexity = calculate_multiplication_complexity(base_length, modulus_length)
iteration_count = calculate_iteration_count(exponent_length, exponent)
return max(200, math.floor(multiplication_complexity * iteration_count / 3))
# Orig EIP 198
def calculate_old_multiplication_complexity(x):
if x <= 64: return x ** 2
elif x <= 1024: return ((x ** 2) // 4) + ((96 * x) - 3072)
else: return ((x ** 2) // 16) + ((480 * x) - 199680)
def calculate_old_gas_cost(base_length, modulus_length, exponent_length, exponent):
GQUADDIVISOR = 20
mul_complex = calculate_old_multiplication_complexity(max(base_length, modulus_length))
adj_exp_len = calculate_iteration_count(exponent_length, exponent)
return math.floor(mul_complex * max(adj_exp_len, 1) / GQUADDIVISOR)
# Download EIP-198 test vectors - wget https://raw.githubusercontent.com/ethereum/go-ethereum/master/core/vm/testdata/precompiles/modexp.json
f = open('modexp.json')
vectors = json.load(f)
print("{:22} {:8} {:8} {:8}".format('Name', 'Old Gas', 'Exp old', 'New Gas'))
for v in vectors:
baselen = int(v['Input'][0:64], 16)
explen = int(v['Input'][64:128], 16)
modlen = int(v['Input'][128:192], 16)
exp = int(v['Input'][(192 + (baselen * 2)):(192 + ((baselen + explen) * 2))], 16)
old_gas = calculate_old_gas_cost(baselen, modlen, explen, exp)
exp_old_gas = v['Gas']
new_gas = calculate_gas_cost(baselen, modlen, explen, exp)
print("{:22} {:8} {:8} {:8}".format(v['Name'], old_gas, exp_old_gas, new_gas))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment