Exemplo n.º 1
0
def ecmul(computation: BaseComputation) -> BaseComputation:
    computation.consume_gas(constants.GAS_ECMUL, reason='ECMUL Precompile')

    try:
        result = _ecmull(computation.msg.data)
    except ValidationError:
        raise VMError("Invalid ECMUL parameters")

    result_x, result_y = result
    result_bytes = b''.join((
        pad32(int_to_big_endian(result_x.n)),
        pad32(int_to_big_endian(result_y.n)),
    ))
    computation.output = result_bytes
    return computation
Exemplo n.º 2
0
def ecrecover(computation: BaseComputation) -> BaseComputation:
    computation.consume_gas(constants.GAS_ECRECOVER, reason="ECRecover Precompile")
    raw_message_hash = computation.msg.data[:32]
    message_hash = pad32r(raw_message_hash)

    v_bytes = pad32r(computation.msg.data[32:64])
    v = big_endian_to_int(v_bytes)

    r_bytes = pad32r(computation.msg.data[64:96])
    r = big_endian_to_int(r_bytes)

    s_bytes = pad32r(computation.msg.data[96:128])
    s = big_endian_to_int(s_bytes)

    try:
        validate_lt_secpk1n(r, title="ECRecover: R")
        validate_lt_secpk1n(s, title="ECRecover: S")
        validate_lte(v, 28, title="ECRecover: V")
        validate_gte(v, 27, title="ECRecover: V")
    except ValidationError:
        return computation

    canonical_v = v - 27

    try:
        signature = keys.Signature(vrs=(canonical_v, r, s))
        public_key = signature.recover_public_key_from_msg_hash(message_hash)
    except BadSignature:
        return computation

    address = public_key.to_canonical_address()
    padded_address = pad32(address)

    computation.output = padded_address
    return computation
Exemplo n.º 3
0
def test_extcodehash(vm_class, address, expected):
    computation = prepare_computation(vm_class)

    computation.stack_push(decode_hex(address))
    computation.opcodes[opcode_values.EXTCODEHASH](computation)

    result = computation.stack_pop(type_hint=constants.BYTES)
    assert encode_hex(pad32(result)) == expected
Exemplo n.º 4
0
def test_sar(vm_class, val1, val2, expected):
    computation = prepare_computation(vm_class)
    computation.stack_push(decode_hex(val1))
    computation.stack_push(decode_hex(val2))
    computation.opcodes[opcode_values.SAR](computation)

    result = computation.stack_pop(type_hint=constants.UINT256)
    assert encode_hex(pad32(int_to_big_endian(result))) == expected
Exemplo n.º 5
0
def ripemd160(computation: BaseComputation) -> BaseComputation:
    word_count = ceil32(len(computation.msg.data)) // 32
    gas_fee = constants.GAS_RIPEMD160 + word_count * constants.GAS_RIPEMD160WORD

    computation.consume_gas(gas_fee, reason="RIPEMD160 Precompile")

    # TODO: this only works if openssl is installed.
    hash = hashlib.new('ripemd160', computation.msg.data).digest()
    padded_hash = pad32(hash)
    computation.output = padded_hash
    return computation
Exemplo n.º 6
0
def ecpairing(computation):
    if len(computation.msg.data) % 192:
        # data length must be an exact multiple of 192
        raise VMError("Invalid ECPAIRING parameters")

    num_points = len(computation.msg.data) // 192
    gas_fee = constants.GAS_ECPAIRING_BASE + num_points * constants.GAS_ECPAIRING_PER_POINT

    computation.consume_gas(gas_fee, reason='ECPAIRING Precompile')

    try:
        result = _ecpairing(computation.msg.data)
    except ValidationError:
        raise VMError("Invalid ECPAIRING parameters")

    if result is True:
        computation.output = pad32(b'\x01')
    elif result is False:
        computation.output = pad32(b'\x00')
    else:
        raise Exception("Invariant: unreachable code path")
    return computation
Exemplo n.º 7
0
    def get_storage(self, address, slot):
        validate_canonical_address(address, title="Storage Address")
        validate_uint256(slot, title="Storage Slot")

        account = self._get_account(address)
        storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root))

        slot_as_key = pad32(int_to_big_endian(slot))

        if slot_as_key in storage:
            encoded_value = storage[slot_as_key]
            return rlp.decode(encoded_value, sedes=rlp.sedes.big_endian_int)
        else:
            return 0
Exemplo n.º 8
0
 def encode_for_smc(self) -> bytes:
     encoded = b"".join([
         int_to_bytes32(self.shard_id),
         self.chunk_root,
         int_to_bytes32(self.period),
         pad32(self.proposer_address),
     ])
     if len(encoded) != self.smc_encoded_size:
         raise ValueError(
             "Encoded header size is {} instead of {} bytes".format(
                 len(encoded),
                 self.smc_encoded_size,
             ))
     return encoded
Exemplo n.º 9
0
    def set_storage(self, address, slot, value):
        validate_uint256(value, title="Storage Value")
        validate_uint256(slot, title="Storage Slot")
        validate_canonical_address(address, title="Storage Address")

        account = self._get_account(address)
        storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root))

        slot_as_key = pad32(int_to_big_endian(slot))

        if value:
            encoded_value = rlp.encode(value)
            storage[slot_as_key] = encoded_value
        else:
            del storage[slot_as_key]

        self._set_account(address, account.copy(storage_root=storage.root_hash))
Exemplo n.º 10
0
def generate_privkey() -> datatypes.PrivateKey:
    """Generate a new SECP256K1 private key and return it"""
    privkey = ec.generate_private_key(CURVE, default_backend())
    return keys.PrivateKey(pad32(int_to_big_endian(privkey.private_numbers().private_value)))
Exemplo n.º 11
0
def generate_random_keypair() -> Tuple[bytes, Address]:
    key_object = keys.PrivateKey(
        pad32(int_to_big_endian(random.getrandbits(8 * 32))))
    return key_object.to_bytes(), key_object.public_key.to_canonical_address()
Exemplo n.º 12
0
def generate_random_keypair_and_address() -> Tuple[PrivateKey, PublicKey, Address]:
    priv_key = keys.PrivateKey(pad32(int_to_big_endian(random.getrandbits(8 * 32))))
    return priv_key, priv_key.public_key, Address(priv_key.public_key.to_canonical_address())
Exemplo n.º 13
0
def test_pad_32(value, expected):
    assert pad32(value) == expected