Exemple #1
0
    def verify(self, uid, proof):
        """ Checks if the proof for the leaf at `uid` is valid"""
        # assert (len(proof) -8 % 32) == 0
        assert len(proof) <= 2056

        proofbits = int.from_bytes((proof[0:8]), byteorder='big')
        index = uid
        p = 8
        if index in self.leaves:
            computed_hash = self.leaves[index]
        # in case the tx is not included, computed_hash is the default leaf
        else:
            computed_hash = self.default_nodes[-1]

        for d in range(self.depth):
            if proofbits % 2 == 0:
                proof_element = self.default_nodes[d]
            else:
                proof_element = proof[p:p + 32]
                p += 32
            if index % 2 == 0:
                computed_hash = keccak(computed_hash + proof_element)
            else:
                computed_hash = keccak(proof_element + computed_hash)
            proofbits = proofbits // 2
            index = index // 2
        return computed_hash == self.root
Exemple #2
0
 def create_default_nodes(self, depth):
     # Default nodes are the nodes whose children are both empty nodes at
     # each level.
     default_hash = keccak(b'\x00' * 32)
     default_nodes = [default_hash]
     for level in range(1, depth + 1):
         prev_default = default_nodes[level - 1]
         default_nodes.append(keccak(prev_default * 2))
     return default_nodes
Exemple #3
0
def test_encode_basic_types():
    class TestStruct(EIP712Struct):
        address = Address()
        boolean = Boolean()
        dyn_bytes = Bytes()
        bytes_1 = Bytes(1)
        bytes_32 = Bytes(32)
        int_32 = Int(32)
        int_256 = Int(256)
        string = String()
        uint_32 = Uint(32)
        uint_256 = Uint(256)

    values = dict()
    values['address'] = os.urandom(20)
    values['boolean'] = False
    values['dyn_bytes'] = os.urandom(random.choice(range(33, 100)))
    values['bytes_1'] = os.urandom(1)
    values['bytes_32'] = os.urandom(32)
    values['int_32'] = random.randint(*signed_min_max(32))
    values['int_256'] = random.randint(*signed_min_max(256))
    values['string'] = ''.join(
        [random.choice(string.ascii_letters) for _ in range(100)])
    values['uint_32'] = random.randint(0, unsigned_max(32))
    values['uint_256'] = random.randint(0, unsigned_max(256))

    expected_data = list()
    expected_data.append(bytes(12) + values['address'])
    expected_data.append(bytes(32))
    expected_data.append(keccak(values['dyn_bytes']))
    expected_data.append(values['bytes_1'] + bytes(31))
    expected_data.append(values['bytes_32'])
    expected_data.append(values['int_32'].to_bytes(32,
                                                   byteorder='big',
                                                   signed=True))
    expected_data.append(values['int_256'].to_bytes(32,
                                                    byteorder='big',
                                                    signed=True))
    expected_data.append(keccak(text=values['string']))
    expected_data.append(values['uint_32'].to_bytes(32,
                                                    byteorder='big',
                                                    signed=False))
    expected_data.append(values['uint_256'].to_bytes(32,
                                                     byteorder='big',
                                                     signed=False))

    s = TestStruct(**values)
    encoded_data = s.encode_value()
    encoded_bytes = list()

    # Compare each byte range itself to find offenders
    for i in range(0, len(encoded_data), 32):
        encoded_bytes.append(encoded_data[i:i + 32])

    assert encoded_bytes == expected_data
Exemple #4
0
def test_encode_nested_structs():
    class SubStruct(EIP712Struct):
        s = String()

    class MainStruct(EIP712Struct):
        sub_1 = SubStruct
        sub_2 = String()
        sub_3 = SubStruct

    s1 = 'foo'
    s2 = 'bar'
    s3 = 'baz'

    sub_1 = SubStruct(s=s1)
    sub_3 = SubStruct(s=s3)

    s = MainStruct(
        sub_1=sub_1,
        sub_2=s2,
        sub_3=sub_3,
    )

    expected_encoded_vals = b''.join(
        [sub_1.hash_struct(),
         keccak(text=s2),
         sub_3.hash_struct()])
    assert s.encode_value() == expected_encoded_vals
Exemple #5
0
def test_sign():
    print("sign test")
    # ac = Account.create("123456")
    # print("account priv key: ", ac.privateKey)
    privkey = "52413c714e418cc6fb06afb1bc3f6c54449c89a82a17c9a117a5aa0bad56a9cd"
    binprivkey = codecs.decode(privkey, "hex")
    pubkey = private_key_to_public_key(binprivkey)

    print("binary priv key: ", decode_hex(privkey))
    print("binary pub key: ", pubkey)
    acforverify = Account.from_key(binprivkey)
    msg = b"this is a test"
    msghash = keccak(msg)
    sig = acforverify._key_obj.sign_msg_hash(msghash)
    print("pulic key :", acforverify.publickey)
    vresult = sig.verify_msg_hash(msghash, acforverify.publickey)
    print("verify result ", vresult)
    (v, r, s) = ecdsa_raw_sign(msghash, decode_hex(privkey))

    vres = ecdsa_raw_verify(msghash, (r, s), pubkey)
    print("ecdsa raw verify: ", vres)

    recoverres = ecdsa_raw_recover(msghash, (v, r, s))
    print("raw recover result", recoverres)
    print("hex recover result", encode_hex(recoverres))
def test_signable_bytes():
    class Foo(EIP712Struct):
        s = String()
        i = Int(256)

    domain = make_domain(name='hello')
    foo = Foo(s='hello', i=1234)

    start_bytes = b'\x19\x01'
    exp_domain_bytes = keccak(domain.type_hash() + domain.encode_value())
    exp_struct_bytes = keccak(foo.type_hash() + foo.encode_value())

    sign_bytes = foo.signable_bytes(domain)
    assert sign_bytes[0:2] == start_bytes
    assert sign_bytes[2:34] == exp_domain_bytes
    assert sign_bytes[34:] == exp_struct_bytes
Exemple #7
0
def hash_struct(tx, domain=None, verifyingContract=None):
    if domain and verifyingContract:
        raise RuntimeError("verifyingContract supplied but ignored")

    verifying_address = verifyingContract.address if verifyingContract else NULL_ADDRESS

    inputs = [
        Input(blknum=i.blknum, txindex=i.txindex, oindex=i.oindex)
        for i in tx.inputs
    ]
    outputs = [
        Output(owner=o.output_guard, currency=o.token, amount=o.amount)
        for o in tx.outputs
    ]

    domain = domain or make_domain(
        name='OMG Network',
        version='1',
        verifyingContract=verifying_address,
        salt=bytes.fromhex(
            'fad5c7f626d80f9256ef01929f3beb96e058b8b4b0e3fe52d84f054c0e2a7a83')
    )

    type = Transaction().encode_type() + Input.encode_type(
    ) + Output.encode_type()
    values = [_hash_typed(t)
              for t in inputs] + [_hash_typed(t) for t in outputs
                                  ] + [tx.metadata or NULL_HASH]

    return keccak(b'\x19\x01' + _hash_typed(domain) +
                  _hash_struct(type, b''.join(values)))
    def create_tree(self, ordered_leaves, depth, default_nodes):
        for leaf in ordered_leaves:
            ordered_leaves[leaf] = '0x' + keccak(ordered_leaves[leaf][0]).hex()

        tree = [ordered_leaves]
        tree_level = ordered_leaves
        for level in range(depth):
            next_level = {}
            for index, value in tree_level.items():
                if index % 2 == 0:
                    co_index = index + 1
                    if co_index in tree_level:
                        next_level[index // 2] = self.hashPadded(
                            value, tree_level[co_index])
                    else:
                        next_level[index // 2] = self.hashPadded(
                            value, default_nodes[level])
                else:
                    # If the node is a right node, check if its left sibling is
                    # a default node.
                    co_index = index - 1
                    if co_index not in tree_level:
                        next_level[index // 2] = self.hashPadded(
                            default_nodes[level], value)
            tree_level = next_level
            tree.append(tree_level)
        return tree
Exemple #9
0
 def test_create_merkle_proof(self):
     leaves = {0: dummy_val, 2: dummy_val, 3: dummy_val_2}
     tree = SparseMerkleTree(depth=2, leaves=leaves)
     mid_left_val = keccak(dummy_val + default_hash)
     mid_right_val = keccak(dummy_val + dummy_val_2)
     assert (
         tree.create_merkle_proof(0) == (2).to_bytes(8, byteorder='big') +
         mid_right_val)
     assert (
         tree.create_merkle_proof(1) == (3).to_bytes(8, byteorder='big') +
         dummy_val + mid_right_val)
     assert (
         tree.create_merkle_proof(2) == (3).to_bytes(8, byteorder='big') +
         dummy_val_2 + mid_left_val)
     assert (
         tree.create_merkle_proof(3) == (3).to_bytes(8, byteorder='big') +
         dummy_val + mid_left_val)
def test_encode_array():
    class TestStruct(EIP712Struct):
        byte_array = Array(Bytes(32), 4)

    byte_array = [os.urandom(32) for _ in range(4)]

    s = TestStruct(byte_array=byte_array)
    assert s.encode_value() == keccak(b''.join(byte_array))
Exemple #11
0
 def to_eth(self) -> str:
     if self.version == Version.PRIVATE:
         return self.key.get_private_bytes().hex()
     else:
         if isinstance(self.key, Secp256k1Pub):
             return Web3.toChecksumAddress(keccak(self.key.key.public_bytes(Encoding.X962, PublicFormat.UncompressedPoint)[1:]).hex()[24:])
         else:
             raise NotImplementedError("eth addr from non-public secp256k1")
Exemple #12
0
    def combine_hash(first: bytes, second: bytes) -> bytes:
        if not first:
            return second

        if not second:
            return first

        return keccak(primitive=b"".join(sorted([first, second])))
Exemple #13
0
def generate_test_data(priv=None, msg=None):
    # return msg_hash, signature, pubkey
    if not priv:
        priv = os.urandom(32)
    pk = keys.PrivateKey(priv)
    if not msg:
        msg = os.urandom(randint(0, 1024))
    signature = pk.sign_msg(msg)
    return keccak(msg).hex(), signature, pk.public_key.to_address()[2:]
Exemple #14
0
def test_none_replacement():
    class Foo(EIP712Struct):
        s = String()
        i = Int(256)

    foo = Foo(**{})
    encoded_val = foo.encode_value()
    assert len(encoded_val) == 64

    empty_string_hash = keccak(text='')
    assert encoded_val[0:32] == empty_string_hash
    assert encoded_val[32:] == bytes(32)
Exemple #15
0
def sha3(primitive=None, text=None, hexstr=None):
    if isinstance(primitive, (bytes, int, type(None))):
        input_bytes = to_bytes(primitive, hexstr=hexstr, text=text)
        return keccak(input_bytes)

    raise TypeError(
        "You called sha3 with first arg %r and keywords %r. You must call it with one of "
        "these approaches: sha3(text='txt'), sha3(hexstr='0x747874'), "
        "sha3(b'\\x74\\x78\\x74'), or sha3(0x747874)." % (primitive, {
            'text': text,
            'hexstr': hexstr
        }))
Exemple #16
0
def test_domain_sep_types():
    salt = os.urandom(32)
    contract = os.urandom(20)

    domain_struct = make_domain(name='name',
                                version='version',
                                chainId=1,
                                verifyingContract=contract,
                                salt=salt)

    encoded_data = [
        keccak(text='name'),
        keccak(text='version'),
        int(1).to_bytes(32, 'big', signed=False),
        bytes(12) + contract, salt
    ]

    expected_result = 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)'
    assert domain_struct.encode_type() == expected_result

    expected_data = b''.join(encoded_data)
    assert domain_struct.encode_value() == expected_data
Exemple #17
0
    def signed_tx(cls, sutx, v, r, s):
        enctx = encode_transaction(sutx, (v, r, s))
        transaction_hash = keccak(enctx)

        attr_dict = AttributeDict({
            'rawTransaction': HexBytes(enctx),
            'hash': HexBytes(transaction_hash),
            'r': r,
            's': s,
            'v': v,
        })

        return attr_dict
Exemple #18
0
def test_domain_sep_create():
    salt = os.urandom(32)
    domain_struct = make_domain(name='name', salt=salt)

    expected_result = 'EIP712Domain(string name,bytes32 salt)'
    assert domain_struct.encode_type() == expected_result

    expected_data = b''.join([keccak(text='name'), salt])
    assert domain_struct.encode_value() == expected_data

    with pytest.raises(ValueError,
                       match='At least one argument must be given'):
        make_domain()
Exemple #19
0
    def _encode_value(self, value):
        """Static bytesN types are encoded by right-padding to 32 bytes. Dynamic bytes types are keccak256 hashed."""
        if isinstance(value, str):
            # Try converting to a bytestring, assuming that it's been given as hex
            value = to_bytes(hexstr=value)

        if self.length == 0:
            return keccak(value)
        else:
            if len(value) > self.length:
                raise ValueError(
                    f'{self.type_name} was given bytes with length {len(value)}'
                )
            padding = bytes(32 - len(value))
            return value + padding
Exemple #20
0
 def create_tree(self, ordered_leaves, depth, default_nodes):
     tree = [ordered_leaves]
     tree_level = ordered_leaves
     for level in range(depth):
         next_level = {}
         for index, value in tree_level.items():
             if index % 2 == 0:
                 co_index = index + 1
                 if co_index in tree_level:
                     next_level[index // 2] = keccak(value +
                                                     tree_level[co_index])
                 else:
                     next_level[index // 2] = keccak(value +
                                                     default_nodes[level])
             else:
                 # If the node is a right node, check if its left sibling is
                 # a default node.
                 co_index = index - 1
                 if co_index not in tree_level:
                     next_level[index // 2] = keccak(default_nodes[level] +
                                                     value)
         tree_level = next_level
         tree.append(tree_level)
     return tree
Exemple #21
0
    def parse_sign_result(cls, tx, exchange_result):
        sign_v = exchange_result[0]
        sign_r = int((exchange_result[1:1 + 32]).hex(), 16)
        sign_s = int((exchange_result[1 + 32:1 + 32 + 32]).hex(), 16)
        enctx = encode_transaction(tx, (sign_v, sign_r, sign_s))
        transaction_hash = keccak(enctx)

        signed_txn = AttributeDict({
            'rawTransaction': HexBytes(enctx),
            'hash': HexBytes(transaction_hash),
            'v': sign_v,
            'r': sign_r,
            's': sign_s,
        })
        return signed_txn
Exemple #22
0
    def _encode_value(self, value):
        """Static bytesN types are encoded by right-padding to 32 bytes. Dynamic bytes types are keccak256 hashed."""
        if isinstance(value, str):
            # Try converting to a bytestring, assuming that it's been given as hex
            if value.startswith('0x'):
                value = value[2:]
            else:
                raise ValueError(
                    f'{self.type_name} was given an invalid hex string, not starting with "0x"'
                )
            value = to_bytes(hexstr=HexStr(value))

        if self.length == 0:
            return keccak(value)
        else:
            if len(value) != self.length:
                raise ValueError(
                    f'{self.type_name} was given bytes with length {len(value)}'
                )
            padding = bytes(32 - len(value))
            return value + padding
Exemple #23
0
def _hash_struct(type, value):
    return keccak(keccak(text=type) + value)
Exemple #24
0
 def _encode_value(self, value):
     """Arrays are encoded by concatenating their encoded contents, and taking the keccak256 hash."""
     encoder = self.member_type
     encoded_values = [encoder.encode_value(v) for v in value]
     return keccak(b''.join(encoded_values))
Exemple #25
0
def func_sign_to_4bytes(event_signature):
    """ASCII Keccak hash 4bytes
    """
    return keccak(text=event_signature.replace(' ', ''))[:4]
 def topic_from_string(value):
     s = encode_hex(keccak(bytes(value, "utf-8")))[2:]
     return "0x" + s
Exemple #27
0
import pytest
from eth_utils.crypto import keccak
from hexbytes import HexBytes

from utils.merkle.sparse_merkle_tree import SparseMerkleTree

empty_val = b'\x00' * 32
default_hash = keccak(empty_val)
dummy_val = keccak(2)
dummy_val_2 = keccak(3)


class TestSparseMerkleTree(object):
    def test_size_limits(self):
        with pytest.raises(SparseMerkleTree.TreeSizeExceededException):
            SparseMerkleTree(depth=0, leaves={0: '0', 1: '1'})
        with pytest.raises(SparseMerkleTree.TreeSizeExceededException):
            SparseMerkleTree(depth=1,
                             leaves={
                                 0: empty_val,
                                 1: empty_val,
                                 2: empty_val
                             })

    def test_empty_SMT(self):
        emptyTree = SparseMerkleTree(64, {})
        assert len(emptyTree.leaves) == 0

    def test_all_leaves_with_val(self):
        leaves = {0: dummy_val, 1: dummy_val, 2: dummy_val, 3: dummy_val}
        tree = SparseMerkleTree(depth=2, leaves=leaves)
Exemple #28
0
 def test_all_leaves_with_val(self):
     leaves = {0: dummy_val, 1: dummy_val, 2: dummy_val, 3: dummy_val}
     tree = SparseMerkleTree(depth=2, leaves=leaves)
     mid_level_val = keccak(dummy_val * 2)
     assert tree.root == keccak(mid_level_val + mid_level_val)
Exemple #29
0
 def test_empty_leaves(self):
     tree = SparseMerkleTree(depth=2)
     mid_level_val = keccak(default_hash * 2)
     assert tree.root == keccak(mid_level_val * 2)
Exemple #30
0
 def test_empty_right_leave(self):
     leaves = {0: dummy_val, 2: dummy_val, 3: dummy_val}
     tree = SparseMerkleTree(depth=2, leaves=leaves)
     mid_left_val = keccak(dummy_val + default_hash)
     mid_right_val = keccak(dummy_val * 2)
     assert tree.root == keccak(mid_left_val + mid_right_val)