示例#1
0
    def test_verify_proof(self):
        claim1_name = 97  # 'a'
        claim1_txid = 'bd9fa7ffd57d810d4ce14de76beea29d847b8ac34e8e536802534ecb1ca43b68'
        claim1_outpoint = 0
        claim1_height = 10
        claim1_node_hash = get_hash_for_outpoint(
            unhexlify(claim1_txid)[::-1], claim1_outpoint, claim1_height)

        claim2_name = 98  # 'b'
        claim2_txid = 'ad9fa7ffd57d810d4ce14de76beea29d847b8ac34e8e536802534ecb1ca43b68'
        claim2_outpoint = 1
        claim2_height = 5
        claim2_node_hash = get_hash_for_outpoint(
            unhexlify(claim2_txid)[::-1], claim2_outpoint, claim2_height)
        to_hash1 = claim1_node_hash
        hash1 = double_sha256(to_hash1)
        to_hash2 = bytes((claim1_name,)) + hash1 + bytes((claim2_name,)) + claim2_node_hash

        root_hash = double_sha256(to_hash2)

        proof = {
            'last takeover height': claim1_height, 'txhash': claim1_txid, 'nOut': claim1_outpoint,
            'nodes': [
                {'children': [
                    {'character': 97},
                    {
                        'character': 98,
                        'nodeHash': hexlify(claim2_node_hash[::-1])
                    }
                ]},
                {'children': []},
            ]
        }
        out = verify_proof(proof, hexlify(root_hash[::-1]), 'a')
        self.assertTrue(out)
示例#2
0
 def header_hash_to_pow_hash(header_hash: bytes):
     header_hash_bytes = unhexlify(header_hash)[::-1]
     h = sha512(header_hash_bytes)
     pow_hash = double_sha256(
         ripemd160(h[:len(h) // 2]) +
         ripemd160(h[len(h) // 2:])
     )
     return hexlify(pow_hash[::-1])
示例#3
0
 def get_root_of_merkle_tree(branches, branch_positions, working_branch):
     for i, branch in enumerate(branches):
         other_branch = unhexlify(branch)[::-1]
         other_branch_on_left = bool((branch_positions >> i) & 1)
         if other_branch_on_left:
             combined = other_branch + working_branch
         else:
             combined = working_branch + other_branch
         working_branch = double_sha256(combined)
     return hexlify(working_branch[::-1])
示例#4
0
def aes_encrypt(secret: str, value: str, init_vector: bytes = None) -> str:
    if init_vector is not None:
        assert len(init_vector) == 16
    else:
        init_vector = os.urandom(16)
    key = double_sha256(secret.encode())
    encryptor = Cipher(AES(key), modes.CBC(init_vector),
                       default_backend()).encryptor()
    padder = PKCS7(AES.block_size).padder()
    padded_data = padder.update(value.encode()) + padder.finalize()
    encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
    return base64.b64encode(init_vector + encrypted_data).decode()
示例#5
0
def aes_decrypt(secret: str, value: str) -> typing.Tuple[str, bytes]:
    try:
        data = base64.b64decode(value.encode())
        key = double_sha256(secret.encode())
        init_vector, data = data[:16], data[16:]
        decryptor = Cipher(AES(key), modes.CBC(init_vector),
                           default_backend()).decryptor()
        unpadder = PKCS7(AES.block_size).unpadder()
        result = unpadder.update(decryptor.update(data)) + unpadder.finalize()
        return result.decode(), init_vector
    except ValueError as e:
        if e.args[0] == 'Invalid padding bytes.':
            raise InvalidPasswordError()
        raise
示例#6
0
 def hash160_to_address(cls, h160):
     raw_address = cls.pubkey_address_prefix + h160
     return Base58.encode(
         bytearray(raw_address + double_sha256(raw_address)[0:4]))
示例#7
0
 def hash_header(header: bytes) -> bytes:
     if header is None:
         return b'0' * 64
     return hexlify(double_sha256(header)[::-1])
示例#8
0
def get_hash_for_outpoint(txhash, nout, height_of_last_takeover):
    return double_sha256(
        double_sha256(txhash) +
        double_sha256(str(nout).encode()) +
        double_sha256(struct.pack('>Q', height_of_last_takeover))
    )
示例#9
0
def verify_proof(proof, root_hash, name):
    previous_computed_hash = None
    reverse_computed_name = ''
    verified_value = False
    for i, node in enumerate(proof['nodes'][::-1]):
        found_child_in_chain = False
        to_hash = b''
        previous_child_character = None
        for child in node['children']:
            if child['character'] < 0 or child['character'] > 255:
                raise InvalidProofError("child character not int between 0 and 255")
            if previous_child_character:
                if previous_child_character >= child['character']:
                    raise InvalidProofError("children not in increasing order")
            previous_child_character = child['character']
            to_hash += bytes((child['character'],))
            if 'nodeHash' in child:
                if len(child['nodeHash']) != 64:
                    raise InvalidProofError("invalid child nodeHash")
                to_hash += binascii.unhexlify(child['nodeHash'])[::-1]
            else:
                if previous_computed_hash is None:
                    raise InvalidProofError("previous computed hash is None")
                if found_child_in_chain is True:
                    raise InvalidProofError("already found the next child in the chain")
                found_child_in_chain = True
                reverse_computed_name += chr(child['character'])
                to_hash += previous_computed_hash

        if not found_child_in_chain:
            if i != 0:
                raise InvalidProofError("did not find the alleged child")
        if i == 0 and 'txhash' in proof and 'nOut' in proof and 'last takeover height' in proof:
            if len(proof['txhash']) != 64:
                raise InvalidProofError(f"txhash was invalid: {proof['txhash']}")
            if not isinstance(proof['nOut'], int):
                raise InvalidProofError(f"nOut was invalid: {proof['nOut']}")
            if not isinstance(proof['last takeover height'], int):
                raise InvalidProofError(
                    f"last takeover height was invalid: {proof['last takeover height']}")
            to_hash += get_hash_for_outpoint(
                binascii.unhexlify(proof['txhash'])[::-1],
                proof['nOut'],
                proof['last takeover height']
            )
            verified_value = True
        elif 'valueHash' in node:
            if len(node['valueHash']) != 64:
                raise InvalidProofError("valueHash was invalid")
            to_hash += binascii.unhexlify(node['valueHash'])[::-1]

        previous_computed_hash = double_sha256(to_hash)

    if previous_computed_hash != binascii.unhexlify(root_hash)[::-1]:
        raise InvalidProofError("computed hash does not match roothash")
    if 'txhash' in proof and 'nOut' in proof:
        if not verified_value:
            raise InvalidProofError("mismatch between proof claim and outcome")
    target = reverse_computed_name[::-1].encode('ISO-8859-1').decode()
    if 'txhash' in proof and 'nOut' in proof:
        if name != target:
            raise InvalidProofError("name did not match proof")
    if not name.startswith(target):
        raise InvalidProofError("name fragment does not match proof")
    return True