def test_initialize_with_leaves(num_leaves):
    depth = math.ceil(math.log(num_leaves, 2))
    leaves = [b'asdf'] * num_leaves

    hashed_leaves = [sha3(leaf) for leaf in leaves]
    empty_leaves = [sha3(NULL_HASH)] * (2**depth - num_leaves)

    assert FixedMerkle(depth, leaves).leaves == hashed_leaves + empty_leaves
def test_create_membership_proof():
    leaf = b'c'
    leaves = [b'a', b'b', leaf]
    proof = FixedMerkle(2, leaves).create_membership_proof(leaf)
    sibling_hash = sha3(LEAF_SALT + NULL_HASH)
    node_hash = sha3(NODE_SALT + sha3(LEAF_SALT + leaves[0]) +
                     sha3(LEAF_SALT + leaves[1]))
    assert proof == sibling_hash + node_hash
    def check_membership(self, leaf, index, proof):
        hashed_leaf = sha3(leaf)
        computed_hash = hashed_leaf
        computed_index = index

        for i in range(0, self.depth * 32, 32):
            proof_segment = proof[i:i + 32]

            if computed_index % 2 == 0:
                computed_hash = sha3(computed_hash + proof_segment)
            else:
                computed_hash = sha3(proof_segment + computed_hash)
            computed_index = computed_index // 2

        return computed_hash == self.root
    def __init__(self, depth, leaves=[]):
        if depth < 1:
            raise ValueError('depth must be at least 1')

        self.depth = depth
        self.leaf_count = 2 ** depth

        if len(leaves) > self.leaf_count:
            raise ValueError('number of leaves should be at most depth ** 2')

        leaves = [sha3(leaf) for leaf in leaves]

        self.leaves = leaves + [sha3(NULL_HASH)] * (self.leaf_count - len(leaves))
        self.tree = [self.__create_nodes(self.leaves)]
        self.__create_tree(self.tree[0])
    def __create_tree(self, leaves):
        if len(leaves) == 1:
            self.root = leaves[0].data
            return

        next_level = len(leaves)
        tree_level = []

        for i in range(0, next_level, 2):
            combined = sha3(leaves[i].data + leaves[i + 1].data)
            next_node = MerkleNode(combined, leaves[i], leaves[i + 1])
            tree_level.append(next_node)

        self.tree.append(tree_level)
        self.__create_tree(tree_level)
    def create_membership_proof(self, leaf):
        hashed_leaf = sha3(leaf)
        if not self.__is_member(hashed_leaf):
            raise MemberNotExistException('leaf is not in the merkle tree')

        index = self.leaves.index(hashed_leaf)
        proof = b''

        for i in range(0, self.depth, 1):
            if index % 2 == 0:
                sibling_index = index + 1
            else:
                sibling_index = index - 1
            index = index // 2

            proof += self.tree[i][sibling_index].data

        return proof
Example #7
0
def make_keystore_json(priv, pw, kdf="pbkdf2", cipher="aes-128-ctr"):
    
    # Get the hash function and default parameters
    if kdf not in kdfs:
        raise Exception("Hash algo %s not supported" % kdf)
    kdfeval = kdfs[kdf]["calc"]
    kdfparams = kdfs[kdf]["mkparams"]()
    # Compute derived key
    derivedkey = kdfeval(pw, kdfparams)
    # Get the cipher and default parameters
    if cipher not in ciphers:
        raise Exception("Encryption algo %s not supported" % cipher)
    encrypt = ciphers[cipher]["encrypt"]
    cipherparams = ciphers[cipher]["mkparams"]()
    # Produce the encryption key and encrypt
    enckey = derivedkey[:16]
    c = encrypt(priv, enckey, cipherparams)
    # Compute the MAC
    mac = sha3(derivedkey[16:32] + c)
    # Make a UUID
    u = encode_hex(os.urandom(16))
    uuid = b'-'.join((u[:8], u[8:12], u[12:16], u[16:20], u[20:]))
    addr = privtoaddr(priv).encode('hex')
    # Return the keystore json
    return {
        "address":  addr,
        "crypto": {
            "cipher": cipher,
            "ciphertext": encode_hex(c),
            "cipherparams": cipherparams,
            "kdf": kdf,
            "kdfparams": kdfparams,
            "mac": encode_hex(mac),
            "version": 1
        },
        "id": uuid,
        "version": 3
    }
Example #8
0
def decode_keystore_json(jsondata, pw):
    # Get KDF function and parameters
    if "crypto" in jsondata:
        cryptdata = jsondata["crypto"]
    elif "Crypto" in jsondata:
        cryptdata = jsondata["Crypto"]
    else:
        raise Exception("JSON data must contain \"crypto\" object")
    kdfparams = cryptdata["kdfparams"]
    kdf = cryptdata["kdf"]
    if cryptdata["kdf"] not in kdfs:
        raise HashNotSupportedError("Hash algo %s not supported" % kdf)
    kdfeval = kdfs[kdf]["calc"]
    # Get cipher and parameters
    cipherparams = cryptdata["cipherparams"]
    cipher = cryptdata["cipher"]
    if cryptdata["cipher"] not in ciphers:
        raise EncryptionNotSupportedError("Encryption algo %s not supported" % cipher)
    decrypt = ciphers[cipher]["decrypt"]
    # Compute the derived key
    derivedkey = kdfeval(pw, kdfparams)
    assert len(derivedkey) >= 32, \
        "Derived key must be at least 32 bytes long"
    # print(b'derivedkey: ' + encode_hex(derivedkey))
    enckey = derivedkey[:16]
    # print(b'enckey: ' + encode_hex(enckey))
    ctext = decode_hex(cryptdata["ciphertext"])
    # Decrypt the ciphertext
    o = decrypt(ctext, enckey, cipherparams)
    # Compare the provided MAC with a locally computed MAC
    # print(b'macdata: ' + encode_hex(derivedkey[16:32] + ctext))
    mac1 = sha3(derivedkey[16:32] + ctext)
    mac2 = decode_hex(cryptdata["mac"])
    if mac1 != mac2:
        raise PasswordError("MAC mismatch. Password incorrect?")
    return o
Example #9
0
def privtoaddr(x):
    if len(x) > 32:
        x = decode_hex(x)
    return sha3(bitcoin.privtopub(x)[1:])[12:]
def get_empty_tree_hash(depth):
    root = sha3(NULL_HASH)
    for _ in range(depth):
        root = sha3(root + root)
    return root
def test_create_membership_proof():
    leaves = [b'a', b'b', b'c']
    proof = FixedMerkle(2, leaves).create_membership_proof(leaves[2])
    assert proof == sha3(NULL_HASH) + sha3(sha3(leaves[0]) + sha3(leaves[1]))
def test_initial_state(depth):
    assert FixedMerkle(depth).leaves == [sha3(NULL_HASH)] * (2**depth)
def get_empty_tree_hash(depth):
    root = sha3(LEAF_SALT + NULL_HASH)
    for _ in range(depth):
        root = sha3(NODE_SALT + root + root)
    return root