Esempio n. 1
0
 def __init__(self, operator, root_chain):
     self.operator = operator
     self.root_chain = root_chain
     self.chain = {}
     self.tree = MerkleTree(2)
     self.roots = {}
     self.nullifiers = {}
     self.height = 0
     self.current_block = Block()
Esempio n. 2
0
class AccountManager(object):
    def __init__(self, tree_size):
        self._accounts = []
        self._key2idx = dict()
        self._tree = MerkleTree(tree_size)

    def lookup_accounts(self, *args):
        return [self.lookup_account(_) for _ in args]

    def lookup_account(self, index):
        if isinstance(index, AccountState):
            assert index.index is not None
            index = index.index
        elif isinstance(index, Point):
            index = self._key2idx[index]
        return self._accounts[index]

    def new_account(self, balance=0):
        secret, pubkey = eddsa_random_keypair()
        return secret, self.add_account(pubkey, balance)

    def add_account(self, pubkey, balance=0, nonce=0):
        assert isinstance(pubkey, Point)
        state = AccountState(pubkey, balance, nonce)
        state.index = self._tree.append(state.hash())
        self._accounts.append(state)
        self._key2idx[pubkey] = state.index
        return state

    def new_transaction(self, from_account, to_account, amount):
        from_account, to_account = self.lookup_accounts(from_account, to_account)
        return OnchainTransaction(from_account.index, to_account.index, amount)

    def apply_transaction(self, stx):
        """
        Records the state transition of the transaction being applied to the tree
        """
        assert isinstance(stx, SignedTransaction)
        tx = stx.tx
        from_account, to_account = self.lookup_accounts(tx.from_idx, tx.to_idx)

        if from_account.balance < tx.amount:
            raise RuntimeError("Balance not sufficient to perform transfer")

        merkle_root = self._tree.root

        # Update `from` leaf, recording its state before modification
        state_from = deepcopy(from_account)
        from_account.nonce += 1
        from_account.balance -= tx.amount
        proof_before_from = self._tree.proof(tx.from_idx)
        self._tree.update(tx.from_idx, from_account.hash())

        # Update `to` leaf, recording its state before modification
        state_to = deepcopy(to_account)
        to_account.balance += tx.amount
        proof_before_to = self._tree.proof(tx.to_idx)
        self._tree.update(tx.to_idx, to_account.hash())

        return TransactionProof(merkle_root, stx, state_from, state_to, proof_before_from, proof_before_to)
Esempio n. 3
0
    def test_make_proof(self):
        n_items = 2 << 28
        tree = MerkleTree(n_items)
        for n in range(0, 2):
            tree.append(random_element())

        exthash = random_element()
        nullifier = random_element()
        spend_preimage = random_element()
        spend_hash_IV = 0
        spend_hash = LongsightL12p5_MP([spend_preimage, nullifier],
                                       spend_hash_IV)
        leaf_hash_IV = 0
        leaf_hash = LongsightL12p5_MP([nullifier, spend_hash], leaf_hash_IV)
        leaf_idx = tree.append(leaf_hash)
        self.assertEqual(leaf_idx, tree.index(leaf_hash))

        # Verify it exists in true
        leaf_proof = tree.proof(leaf_idx)
        self.assertTrue(leaf_proof.verify(tree.root))

        # Generate proof
        wrapper = Miximus(NATIVE_LIB_PATH, VK_PATH, PK_PATH)
        tree_depth = wrapper.tree_depth
        snark_proof = wrapper.prove(tree.root, nullifier, spend_preimage,
                                    exthash, leaf_proof.address,
                                    leaf_proof.path)

        self.assertTrue(wrapper.verify(snark_proof))
Esempio n. 4
0
    def test_make_proof(self):
        wrapper = Mixer(NATIVE_LIB_PATH, VK_PATH, PK_PATH)
        tree_depth = wrapper.tree_depth

        n_items = 2 << (tree_depth - 1)
        tree = MerkleTree(n_items)
        for n in range(0, 2):
            tree.append(int(FQ.random()))

        wallet_address = int(FQ.random())
        nullifier_secret = int(FQ.random())
        nullifier_hash = mimc_hash([nullifier_secret, nullifier_secret])
        leaf_hash = int(
            get_sha256_hash(to_hex(nullifier_secret), to_hex(wallet_address)),
            16)

        leaf_idx = tree.append(leaf_hash)
        self.assertEqual(leaf_idx, tree.index(leaf_hash))

        # Verify it exists in true
        leaf_proof = tree.proof(leaf_idx)
        self.assertTrue(leaf_proof.verify(tree.root))

        # Generate proof
        snark_proof = wrapper.prove(
            tree.root,
            wallet_address,
            nullifier_hash,
            nullifier_secret,
            # (index)_2 bits reversed, i.e. [LSB, ... , MSB]
            leaf_proof.address,
            leaf_proof.path)

        self.assertTrue(wrapper.verify(snark_proof))
Esempio n. 5
0
    def test_make_proof(self):
        n_items = 2 << 28
        tree = MerkleTree(n_items)
        for n in range(0, 2):
            tree.append(int(FQ.random()))

            exthash = int(FQ.random())
            prehash = int(FQ.random())
            secret = int(FQ.random())
            msg = int(FQ.random())
            leaf_hash = mimc_hash([secret])
            sig_msg_hash = mimc_hash([msg])
            leaf_idx = tree.append(leaf_hash)
            self.assertEqual(leaf_idx, tree.index(leaf_hash))

        # Verify it exists in true
        leaf_proof = tree.proof(leaf_idx)
        self.assertTrue(leaf_proof.verify(tree.root))
        self.assertTrue(prehash, sig_msg_hash)

        # Generate proof
        wrapper = Ssles(NATIVE_LIB_PATH, VK_PATH, PK_PATH)
        tree_depth = wrapper.tree_depth
        snark_proof = wrapper.prove(tree.root, secret, msg, exthash, prehash,
                                    leaf_proof.address, leaf_proof.path)

        self.assertTrue(wrapper.verify(snark_proof))

        if __name__ == "__main__":
            unittest.main()
	def test_make_proof(self):
		n_items = 2<<28
		tree = MerkleTree(n_items)
		for n in range(0, 2):
			tree.append(int(FQ.random()))

		exthash = int(FQ.random())
		secret = int(FQ.random())
		leaf_hash = mimc_hash([secret])
		leaf_idx = tree.append(leaf_hash)
		self.assertEqual(leaf_idx, tree.index(leaf_hash))

		# Verify it exists in true
		leaf_proof = tree.proof(leaf_idx)
		self.assertTrue(leaf_proof.verify(tree.root))

		# Generate proof		
		wrapper = Miximus(NATIVE_LIB_PATH, VK_PATH, PK_PATH)
		tree_depth = wrapper.tree_depth
		snark_proof = wrapper.prove(
			tree.root,
			secret,
			exthash,
			leaf_proof.address,
			leaf_proof.path)

		self.assertTrue(wrapper.verify(snark_proof))
Esempio n. 7
0
    def test_known1(self):
        tree = MerkleTree(2)

        item_a = 3703141493535563179657531719960160174296085208671919316200479060314459804651
        tree.append(item_a)

        item_b = 134551314051432487569247388144051420116740427803855572138106146683954151557
        tree.append(item_b)

        self.assertEqual(tree.root, 3075442268020138823380831368198734873612490112867968717790651410945045657947)

        proof_a = tree.proof(0)
        self.assertEqual(proof_a.path, [item_b])

        proof_b = tree.proof(1)
        self.assertEqual(proof_b.path, [item_a])
Esempio n. 8
0
    def test_known1(self):
        tree = MerkleTree(2)

        item_a = 3703141493535563179657531719960160174296085208671919316200479060314459804651
        tree.append(item_a)

        item_b = 134551314051432487569247388144051420116740427803855572138106146683954151557
        tree.append(item_b)

        self.assertEqual(
            tree.root,
            13981856331482487152452149678096232821987624395720231314895268163963385035507
        )

        proof_a = tree.proof(0)
        self.assertEqual(proof_a.path, [item_b])

        proof_b = tree.proof(1)
        self.assertEqual(proof_b.path, [item_a])
Esempio n. 9
0
    def test_known1(self):
        tree = MerkleTree(2)

        item_a = 3703141493535563179657531719960160174296085208671919316200479060314459804651
        tree.append(item_a)

        item_b = 134551314051432487569247388144051420116740427803855572138106146683954151557
        tree.append(item_b)

        self.assertEqual(
            tree.root,
            12232803403448551110711645741717605608347940439638387632993385741901727947062
        )

        proof_a = tree.proof(0)
        self.assertEqual(proof_a.path, [item_b])

        proof_b = tree.proof(1)
        self.assertEqual(proof_b.path, [item_a])
Esempio n. 10
0
    def test_known_2pow28(self):
        tree = MerkleTree(2 << 28)

        item_a = 3703141493535563179657531719960160174296085208671919316200479060314459804651
        tree.append(item_a)

        item_b = 134551314051432487569247388144051420116740427803855572138106146683954151557
        tree.append(item_b)

        self.assertEqual(
            tree.root,
            10928083011190212400724282287039881565290562079447442292540304400330695864757
        )
Esempio n. 11
0
    def test_incremental_sha256(self):
        n_items = 100
        tree = MerkleTree(n_items, MerkleHasherSHA256)
        self.assertEqual(tree.root, None)
        self.assertEqual(len(tree), 0)

        previous_root = None
        for n in range(0, n_items):
            item = bytes([n]) * 32
            tree.append(item)
            self.assertEqual(len(tree), n + 1)

            self.assertNotEqual(tree.root, previous_root)
            previous_root = tree.root
            proof = tree.proof(n)
            self.assertTrue(proof.verify(tree.root))

            # Then verify all existing items can also be proven to be in the tree
            for m in range(0, len(tree) - 1):
                self.assertTrue(tree.proof(m).verify(tree.root))
Esempio n. 12
0
    def test_tree(self):
        n_items = 32
        tree = MerkleTree(n_items)
        self.assertEqual(tree.root, None)
        self.assertEqual(len(tree), 0)

        previous_root = None
        hasher = hashlib.sha256()
        for n in range(0, n_items):
            hasher.update(bytes([n]) * 32)
            item = int.from_bytes(hasher.digest(), 'big') % SNARK_SCALAR_FIELD
            tree.append(item)
            self.assertEqual(len(tree), n + 1)
            self.assertNotEqual(tree.root, previous_root)
            previous_root = tree.root
            proof = tree.proof(n)
            self.assertTrue(proof.verify(tree.root))

            # Then verify all existing items can also be proven to be in the tree
            for m in range(0, len(tree) - 1):
                self.assertTrue(tree.proof(m).verify(tree.root))
Esempio n. 13
0
    def test_incremental_longsight(self):
        n_items = 100
        tree = MerkleTree(n_items, MerkleHasherLongsightF)
        self.assertEqual(tree.root, None)
        self.assertEqual(len(tree), 0)

        previous_root = None
        for n in range(0, n_items):
            hasher = hashlib.sha256()
            hasher.update(bytes([n]) * 32)
            item = int.from_bytes(hasher.digest(), 'little') % curve_order
            tree.append(item)
            self.assertEqual(len(tree), n + 1)

            self.assertNotEqual(tree.root, previous_root)
            previous_root = tree.root
            proof = tree.proof(n)
            self.assertTrue(proof.verify(tree.root))

            # Then verify all existing items can also be proven to be in the tree
            for m in range(0, len(tree) - 1):
                self.assertTrue(tree.proof(m).verify(tree.root))
Esempio n. 14
0
    def test_known_2pow28(self):
        tree = MerkleTree(2 << 28)

        item_a = 3703141493535563179657531719960160174296085208671919316200479060314459804651
        tree.append(item_a)

        item_b = 134551314051432487569247388144051420116740427803855572138106146683954151557
        tree.append(item_b)

        self.assertEqual(
            tree.root,
            12880293998234311228895747943713504338160238149993004139365982527556885579681
        )

        proof_a = tree.proof(0)
        self.assertTrue(proof_a.verify(tree.root))

        proof_b = tree.proof(1)
        self.assertTrue(proof_b.verify(tree.root))

        self.assertEqual(
            tree.leaf(0, 0),
            3703141493535563179657531719960160174296085208671919316200479060314459804651
        )
        self.assertEqual(
            tree.leaf(1, 0),
            13981856331482487152452149678096232821987624395720231314895268163963385035507
        )
        self.assertEqual(
            tree.leaf(2, 0),
            4008582766686307301250960594183893449903725811265984514032955228389672705119
        )

        self.assertEqual(
            tree.leaf(1, 1),
            17296471688945713021042054900108821045192859417413320566181654591511652308323
        )
        self.assertEqual(
            tree.leaf(2, 1),
            4832852105446597958495745596582249246190817345027389430471458078394903639834
        )
        self.assertEqual(
            tree.leaf(13, 1),
            14116139569958633576637617144876714429777518811711593939929091541932333542283
        )
        self.assertEqual(
            tree.leaf(22, 1),
            16077039334695461958102978289003547153551663194787878097275872631374489043531
        )
Esempio n. 15
0
class ChildChain(object):
    def __init__(self, operator, root_chain):
        self.operator = operator
        self.root_chain = root_chain
        self.chain = {}
        self.tree = MerkleTree(2)
        self.roots = {}
        self.nullifiers = {}
        self.height = 0
        self.current_block = Block()

    def apply_exit(self):
        # TODO
        return

    def apply_deposit(self):
        # TODO
        return

    def apply_transaction(self, transaction):
        tx = Transaction(transaction["serialNumbers"],
                         transaction["newRecords"], transaction["memo"],
                         transaction["in_root"], transaction["in_proof"])

        assert (self.approve_transaction(tx.serialNumbers, tx.newRecords,
                                         tx.memo, tx.in_root, tx.in_root))

        # insert into tree
        for i in range(len(tx.newRecords)):
            self.insert(tx.newRecords[i])
            print("Added new commitment: ", tx.newRecords[i])
            print("Added new memo: ", tx.memo[i])

        self.current_block.add(tx, self.get_root())

        # For now, 1 tx = 1 block!
        self.submit_block(self.current_block)

    def submit_block(self, block):
        self.chain[self.height] = block
        self.root_chain.submitBlock(self.operator, block.root)

        self.height += 1
        self.current_block = Block(number=self.height)

    def get_root(self):
        return self.tree.root

    def insert(self, leaf):
        # insert leaf to merkle tree
        self.tree.append(leaf)
        self.roots[self.get_root()] = True

    def is_spent(self, nullifier):
        # check if utxo is spent
        return self.nullifiers[nullifier]

    def approve_transaction(self, serialNumbers, newRecords, memo, in_root,
                            in_proof):
        # verify transaction
        assert (len(newRecords) > 0)
        assert (len(newRecords) == len(memo))
        assert (len(serialNumbers) > 0)
        # assert(self.roots[in_root])

        is_valid = self.verify_proof(serialNumbers, newRecords, memo, in_root,
                                     in_proof)

        assert (is_valid)

        # check if record is dummy
        for sn in serialNumbers:
            # assert(self.nullifiers[sn])
            self.nullifiers[sn] = True

        return True

    def verify_proof(self, serialNumbers, newRecords, memo, in_root, in_proof):
        # construct SNARK input
        snark_input = self.hash_public_inputs(serialNumbers, newRecords, memo,
                                              in_root)

        # return verifier.verify(self.vk, self.vk_gammaABC, in_proof, snark_input)
        return True

    def hash_public_inputs(self, serialNumbers, newRecords, memo, in_root):
        inputs_to_hash = []

        for sn in serialNumbers:
            inputs_to_hash.append(int(sn))

        for commit in newRecords:
            inputs_to_hash.append(int(commit))

        for m in memo:
            inputs_to_hash.append(int(m))

        inputs_to_hash.append(int(in_root))

        return mimc_hash(inputs_to_hash)
Esempio n. 16
0
    def test_update(self):
        """
        Verify that items in the tree can be updated
        """
        tree = MerkleTree(2)
        tree.append(FQ.random())
        tree.append(FQ.random())
        proof_0_before = tree.proof(0)
        proof_1_before = tree.proof(1)
        root_before = tree.root
        self.assertTrue(proof_0_before.verify(tree.root))
        self.assertTrue(proof_1_before.verify(tree.root))

        leaf_0_after = FQ.random()
        tree.update(0, leaf_0_after)
        root_after_0 = tree.root
        proof_0_after = tree.proof(0)
        self.assertTrue(proof_0_after.verify(tree.root))
        self.assertNotEqual(root_before, root_after_0)

        leaf_1_after = FQ.random()
        tree.update(1, leaf_1_after)
        root_after_1 = tree.root
        proof_1_after = tree.proof(1)
        self.assertTrue(proof_1_after.verify(tree.root))
        self.assertNotEqual(root_before, root_after_1)
        self.assertNotEqual(root_after_0, root_after_1)
Esempio n. 17
0
    def test_known_2pow28(self):
        tree = MerkleTree(2<<28)

        item_a = 3703141493535563179657531719960160174296085208671919316200479060314459804651
        tree.append(item_a)

        item_b = 134551314051432487569247388144051420116740427803855572138106146683954151557
        tree.append(item_b)

        self.assertEqual(tree.root, 14972246236048249827985830600768475898195156734731557762844426864943654467818)

        proof_a = tree.proof(0)
        self.assertTrue(proof_a.verify(tree.root))

        proof_b = tree.proof(1)
        self.assertTrue(proof_b.verify(tree.root))

        self.assertEqual(tree.leaf(0, 0), 3703141493535563179657531719960160174296085208671919316200479060314459804651)
        self.assertEqual(tree.leaf(1, 0), 3075442268020138823380831368198734873612490112867968717790651410945045657947)
        self.assertEqual(tree.leaf(2, 0), 10399465128272526817755257959020023025563587559350936053132523411421423507430)

        self.assertEqual(tree.leaf(1, 1), 17296471688945713021042054900108821045192859417413320566181654591511652308323)
        self.assertEqual(tree.leaf(2, 1), 4832852105446597958495745596582249246190817345027389430471458078394903639834)
        self.assertEqual(tree.leaf(13, 1), 14116139569958633576637617144876714429777518811711593939929091541932333542283)
        self.assertEqual(tree.leaf(22, 1), 16077039334695461958102978289003547153551663194787878097275872631374489043531)
Esempio n. 18
0
 def __init__(self, tree_size):
     self._accounts = []
     self._key2idx = dict()
     self._tree = MerkleTree(tree_size)