def _modexp(data: bytes) -> int: base_length, exponent_length, modulus_length = extract_lengths(data) if base_length == 0: return 0 elif modulus_length == 0: return 0 # compute start:end indexes base_end_idx = 96 + base_length exponent_end_idx = base_end_idx + exponent_length modulus_end_dx = exponent_end_idx + modulus_length # extract arguments modulus_bytes = zpad_right( data[exponent_end_idx:modulus_end_dx], to_size=modulus_length, ) modulus = big_endian_to_int(modulus_bytes) if modulus == 0: return 0 base_bytes = zpad_right(data[96:base_end_idx], to_size=base_length) base = big_endian_to_int(base_bytes) exponent_bytes = zpad_right( data[base_end_idx:exponent_end_idx], to_size=exponent_length, ) exponent = big_endian_to_int(exponent_bytes) result = pow(base, exponent, modulus) return result
def _compute_modexp_gas_fee_eip_198(data: bytes) -> int: base_length, exponent_length, modulus_length = extract_lengths(data) first_32_exponent_bytes = zpad_right( data[96 + base_length:96 + base_length + exponent_length], to_size=min(exponent_length, 32), )[:32] adjusted_exponent_length = _compute_adjusted_exponent_length( exponent_length, first_32_exponent_bytes, ) complexity = _compute_complexity(max(modulus_length, base_length)) gas_fee = (complexity * max(adjusted_exponent_length, 1) // constants.GAS_MOD_EXP_QUADRATIC_DENOMINATOR) return gas_fee
def _compute_modexp_gas_fee_eip_2565(data: bytes) -> int: base_length, exponent_length, modulus_length = extract_lengths(data) base_end_idx = 96 + base_length exponent_end_idx = base_end_idx + exponent_length exponent_bytes = zpad_right( data[base_end_idx:exponent_end_idx], to_size=exponent_length, ) multiplication_complexity = _calculate_multiplication_complexity(base_length, modulus_length) iteration_count = compute_adjusted_exponent_length(exponent_length, exponent_bytes) return max(200, multiplication_complexity * iteration_count // constants.GAS_MOD_EXP_QUADRATIC_DENOMINATOR_EIP_2565)
def calc_chunk_root(collation_body: bytes) -> Hash32: check_body_size(collation_body) chunks = list(iterate_chunks(collation_body)) return get_merkle_root_from_items(chunks) def check_body_size(body: bytes) -> bytes: if len(body) != COLLATION_SIZE: raise ValidationError("{} byte collation body exceeds maximum allowed size".format( len(body) )) return body @apply_to_return_value(check_body_size) @apply_to_return_value(lambda v: zpad_right(v, COLLATION_SIZE)) @apply_to_return_value(b"".join) def serialize_blobs(blobs: Iterable[bytes]) -> Iterator[bytes]: """Serialize a sequence of blobs and return a collation body.""" for i, blob in enumerate(blobs): if len(blob) == 0: raise ValidationError("Cannot serialize blob {} of length 0".format(i)) if len(blob) > MAX_BLOB_SIZE: raise ValidationError("Cannot serialize blob {} of size {}".format(i, len(blob))) for blob_index in range(0, len(blob), CHUNK_DATA_SIZE): remaining_blob_bytes = len(blob) - blob_index if remaining_blob_bytes <= CHUNK_DATA_SIZE: length_bits = remaining_blob_bytes else: