Exemple #1
0
    def setUp(self):
        p2p_factory = Mock(spec=P2PFactory)
        p2p_factory.sync_state = SyncState()
        p2p_factory.num_connections = 23
        p2p_factory.pow = Mock()
        b = Block()
        self.chain_manager = Mock(spec=ChainManager)
        self.chain_manager.height = 0
        self.chain_manager.get_last_block = MagicMock(return_value=b)
        self.chain_manager.get_block_header_hash_by_number = MagicMock(
            return_value=b.headerhash)

        self.qrlnode = QRLNode(mining_address=b'')
        self.qrlnode.set_chain_manager(self.chain_manager)
        self.qrlnode._p2pfactory = p2p_factory
        self.qrlnode._pow = p2p_factory.pow

        self.block_header_params = {
            "dev_config": config.dev,
            "blocknumber": 10,
            "prev_headerhash": sha256(b'prevblock'),
            "prev_timestamp": 1234567890,
            "hashedtransactions": sha256(b'tx1'),
            "fee_reward": 1,
            "seed_height": 0,
            "seed_hash": None,
        }

        self.service = MiningAPIService(self.qrlnode)
Exemple #2
0
    def __init__(self, chain):
        self.blockheader = BlockHeader()
        self.blockheader.create(chain=chain,
                                blocknumber=0,
                                hashchain_link='genesis',
                                prev_blockheaderhash=sha256(config.dev.genesis_prev_headerhash),
                                hashedtransactions=sha256('0'),
                                reveal_list=[],
                                vote_hashes=[])
        self.transactions = []
        self.stake = []
        self.state = []

        package_directory = os.path.dirname(os.path.abspath(__file__))
        genesis_data_path = os.path.join(package_directory, 'genesis.yml')
        with open(genesis_data_path) as f:
            dataMap = yaml.safe_load(f)
            genesis_info.update(dataMap['genesis_info'])

        for key in genesis_info:
            self.state.append([key, [0, genesis_info[key] * 100000000, []]])

        self.stake_list = []
        for stake in self.state:
            self.stake_list.append(stake[0])

        self.stake_seed = '1a02aa2cbe25c60f491aeb03131976be2f9b5e9d0bc6b6d9e0e7c7fd19c8a076c29e028f5f3924b4'
Exemple #3
0
def hashchain_reveal(xmss, n=config.dev.blocks_per_epoch, epoch=0):
    """
    :param n:
    :type xmss: XMSS
    :param epoch:
    :type epoch: int
    :return:
    """
    half = int(config.dev.blocks_per_epoch / 2)
    x = GEN(xmss._private_SEED, half + epoch, l=32)
    y = GEN(x, half, l=32)
    z = GEN(y, half, l=32)
    z = hexlify(z)

    z = GEN_range(z, 1, config.dev.hashchain_nums)
    hc = []
    for hash_chain in z:
        hc.append([hash_chain])
    tmp_hc_terminator = []
    for hash_chain in hc[:-1]:
        for x in range(n):
            hash_chain.append(sha256(hash_chain[-1]))
        tmp_hc_terminator.append(hash_chain[-1])

    for hash_chain in hc[-1:]:
        for x in range(n + 1):
            hash_chain.append(sha256(hash_chain[-1]))
        tmp_hc_terminator.append(hash_chain[-1])

    return tmp_hc_terminator
Exemple #4
0
    def _verify_auth(auth_route, i_bms, pub, PK):
        """
        verify an XMSS auth root path..requires the xmss authentication route,
        OTS public key and XMSS public key (containing merkle root, x and l bitmasks) and i
        regenerate leaf from pub[i] and l_bm, use auth route to navigate up
        merkle tree to regenerate the root and compare with PK[0]
        :param auth_route:
        :param i_bms:
        :param pub:
        :param PK:
        :return:
        """
        root = PK[0]
        x_bms = PK[1]
        l_bms = PK[2]

        leaf = XMSS._l_tree(pub, l_bms)

        h = len(auth_route)

        node = None
        for x in range(h - 1):  # last check is simply to confirm root = pair, no need for sha xor..
            if i_bms[x][0] == 'L':
                node = sha256(hex(int(leaf, 16) ^ int(x_bms[i_bms[x][1]], 16))[2:-1] + hex(
                    int(auth_route[x], 16) ^ int(x_bms[i_bms[x][2]], 16))[2:-1])
            else:
                node = sha256(hex(int(auth_route[x], 16) ^ int(x_bms[i_bms[x][0]], 16))[2:-1] + hex(
                    int(leaf, 16) ^ int(x_bms[i_bms[x][1]], 16))[2:-1])

            leaf = node

        if node == root:
            return True

        return False
Exemple #5
0
 def test_init2(self):
     with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
         time_mock.return_value = 1615270948
         block_header = BlockHeader.create(1, sha256(b'prev'),
                                           time_mock.return_value,
                                           sha256(b'txs'), 10)
         self.assertIsNotNone(block_header)  # just to avoid warnings
Exemple #6
0
    def generate_reboot_hash(self, key, nonce=None, blocknumber=0):
        reboot_data = [
            '2920c8ec34f04f59b7df4284a4b41ca8cbec82ccdde331dd2d64cc89156af653',
            0
        ]

        try:
            reboot_data = self.state.db.get('reboot_data')
        except:
            pass
        if nonce:
            if reboot_data[1] > nonce:
                return None, 'Nonce must be greater than or equals to ' + str(
                    reboot_data[1]) + '\r\n'
            reboot_data[1] = int(nonce)

        output = sha256(key)
        for i in range(0, 40000 - reboot_data[1]):
            output = sha256(output)

        status, error = self.validate_reboot(output, reboot_data[1])
        if not status:
            return None, error

        return json.dumps({
            'hash': output,
            'nonce': reboot_data[1],
            'blocknumber': int(blocknumber)
        }), "Reboot Initiated\r\n"
Exemple #7
0
    def validate_tx(self):
        if self.subtype != TX_SUBTYPE_TX:
            return False

        # FIXME: what does this comment means?
        # sanity check: this is not how the economy is supposed to work!
        if self.amount <= 0:
            logger.info(
                'State validation failed for %s because negative or zero',
                self.txhash)
            logger.info('Amount %d', self.amount)
            return False

        # FIXME: Duplication. Risk of mismatch (create & verification)
        txhash = sha256(
            bytes(
                ''.join(self.txfrom + self.txto + str(self.amount) +
                        str(self.fee)), 'utf-8'))
        txhash = sha256(txhash + self.pubhash)

        # cryptographic checks
        if self.txhash != txhash:
            return False

        if not self._validate_signed_hash():
            return False

        return True
Exemple #8
0
 def reveal_to_terminator(self, reveal, blocknumber, add_loop=0):
     tmp = sha256(reveal)
     epoch = blocknumber // config.dev.blocks_per_epoch
     for _ in range(blocknumber - (epoch * config.dev.blocks_per_epoch) +
                    add_loop):
         tmp = sha256(tmp)
     return tmp
    def test_GetBlockMiningCompatible(self):
        p2p_factory = Mock(spec=P2PFactory)
        p2p_factory.sync_state = SyncState()
        p2p_factory.num_connections = 23
        p2p_factory.pow = Mock()

        chain_manager = Mock(spec=ChainManager)
        chain_manager.height = 0
        chain_manager.get_last_block = MagicMock(return_value=Block())

        qrlnode = QRLNode(mining_address=b'')
        qrlnode.set_chain_manager(chain_manager)
        qrlnode._p2pfactory = p2p_factory
        qrlnode._pow = p2p_factory.pow

        block_header = BlockHeader.create(blocknumber=10,
                                          prev_headerhash=sha256(b'prevblock'),
                                          prev_timestamp=1234567890,
                                          hashedtransactions=sha256(b'tx1'),
                                          fee_reward=1)

        qrlnode.get_blockheader_and_metadata = MagicMock(
            return_value=[block_header, BlockMetadata()])

        service = MiningAPIService(qrlnode)
        req = qrlmining_pb2.GetBlockMiningCompatibleReq(height=10)

        answer = service.GetBlockMiningCompatible(request=req, context=None)

        self.assertEqual(10, answer.blockheader.block_number)
        self.assertEqual(1, answer.blockheader.reward_fee)
Exemple #10
0
    def test_create(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())

        staking_address = bytes(alice_xmss.get_address().encode())

        h0 = sha256(b'hashchain_seed')
        h1 = sha256(h0)
        h2 = sha256(h1)

        stake_transaction = StakeTransaction.create(activation_blocknumber=0,
                                                    xmss=alice_xmss,
                                                    slavePK=slave_xmss.pk(),
                                                    hashchain_terminator=h2)

        sv = StakeValidator(100, stake_transaction)

        self.assertEqual(staking_address, sv.address)
        self.assertEqual(slave_xmss.pk(), sv.slave_public_key)
        self.assertEqual(h2, sv.terminator_hash)

        self.assertEqual(100, sv.balance)
        self.assertEqual(0, sv.nonce)
        self.assertFalse(sv.is_banned)
        self.assertTrue(sv.is_active)
Exemple #11
0
    def pos_block_pool(self, n=1.5):
        """
        create a snapshot of the transaction pool to account for network traversal time (probably less than 300ms, but let's give a window of 1.5 seconds).
        :param n:
        :return: list of merkle root hashes of the tx pool over last 1.5 seconds
        """
        timestamp = time()
        start_time = timestamp - n

        x = self.sorted_tx_pool(start_time)
        y = self.sorted_tx_pool(timestamp)
        if not y:  # if pool is empty -> return sha256 null
            return [sha256('')], [[]]
        elif x == y:  # if the pool isnt empty but there is no difference then return the only merkle hash possible..
            return [merkle_tx_hash(y)], [y]
        else:  # there is a difference in contents of pool over last 1.5 seconds..
            merkle_hashes = []
            txhashes = []
            if not x:
                merkle_hashes.append(sha256(''))
                x = []
                txhashes.append(x)
            else:
                merkle_hashes.append(merkle_tx_hash(x))
                txhashes.append(x)
            tmp_txhashes = x

            for tx in reversed(self.transaction_pool):
                if tx.txhash in y and tx.txhash not in x:
                    tmp_txhashes.append(tx.txhash)
                    tmp_txhashes.sort()
                    merkle_hashes.append(merkle_tx_hash(tmp_txhashes))
                    txhashes.append(tmp_txhashes)

            return merkle_hashes, txhashes
Exemple #12
0
    def _set_txhash(self):
        tmptxhash = sha256(
                           self._get_concatenated_fields()
                          )
        for index in range(0, len(self.slave_pks)):
            tmptxhash = sha256(tmptxhash + self.slave_pks[index] + str(self.access_types[index]).encode())

        self._data.transaction_hash = tmptxhash
 def test_blob(self, time_mock):
     block_header = BlockHeader.create(1, sha256(b'prev'),
                                       time_mock.return_value,
                                       sha256(b'txs'), 10)
     self.assertEquals(
         '00501846b24200c31fca7172a7f701ae50322579cfdf1d7777daab4ce6ead70b76debb2c51a1'
         'c700000000000000000000000000000000002b80aecec05ad5c7c4f2259c8f69e2966a6ce102',
         bin2hstr(block_header.mining_blob))
     self.assertEquals(config.dev.mining_blob_size,
                       len(block_header.mining_blob))
Exemple #14
0
    def _xmss_route(x_bms, x_tree, i=0):
        # type: (object, object, int) -> tuple
        """
        generate the xmss tree merkle auth route for a given ots key (starts at 0)
        :param x_bms:
        :param x_tree:
        :param i:
        :return:
        """
        auth_route = []
        i_bms = []
        nodehash_list = [item for sublist in x_tree for item in sublist]
        h = len(x_tree)
        leaf = x_tree[0][i]
        for x in range(h):

            if len(x_tree[x]) == 1:  # must be at root layer
                if node == ''.join(x_tree[x]):
                    auth_route.append(''.join(x_tree[x]))
                else:
                    logger.info('Failed..root')
                    return

            elif i == len(x_tree[x]) - 1 and leaf in x_tree[
                        x + 1]:  # for an odd node it goes up a level each time until it branches..
                i = x_tree[x + 1].index(leaf)
                n = nodehash_list.index(leaf)
                nodehash_list[n] = None  # stops at first duplicate in list..need next so wipe..

            else:
                n = nodehash_list.index(leaf)  # position in the list == bitmask..
                if i % 2 == 0:  # left leaf, go right..
                    # logger.info((  'left'
                    node = sha256(hex(int(leaf, 16) ^ int(x_bms[n], 16))[2:-1] + hex(
                        int(nodehash_list[n + 1], 16) ^ int(x_bms[n + 1], 16))[2:-1])
                    pair = nodehash_list[n + 1]
                    auth_route.append(pair)
                    i_bms.append(('L', n, n + 1))

                elif i % 2 == 1:  # right leaf go left..
                    node = sha256(hex(int(nodehash_list[n - 1], 16) ^ int(x_bms[n - 1], 16))[2:-1] + hex(
                        int(leaf, 16) ^ int(x_bms[n], 16))[2:-1])
                    pair = nodehash_list[n - 1]
                    auth_route.append(pair)
                    i_bms.append((n - 1, n))

                try:
                    x_tree[x + 1].index(node)  # confirm node matches a hash in next layer up?
                except:
                    logger.warning(('Failed at height', str(x)))
                    return
                leaf = node
                i = x_tree[x + 1].index(leaf)

        return auth_route, i_bms
Exemple #15
0
    def test_blob(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              sha256(b'txs'), 10)
            self.assertEquals(
                '74aa496ffe19107faaf418b720fb5b8446ba4b595c178fcf099c99b3dee99860d788c77910a9ed000000'
                '000000000000000000e0d022b37421b81b7bbcf5b497fb89408c05c7d713c5e1e5187b02aa9344cf83bb',
                bin2hstr(block_header.mining_blob))
            self.assertEquals(config.dev.mining_blob_size,
                              len(block_header.mining_blob))
Exemple #16
0
 def test_create_fails_when_prev_timestamp_is_negative(self, time_mock):
     # The only way to get it to fail in this mode is to pass a negative timestamp. Which should never happen IRL.
     time_mock.return_value = 0
     b = BlockHeader.create(config.dev,
                            1,
                            sha256(b'prev'),
                            -10,
                            sha256(b'txs'),
                            10,
                            seed_height=0,
                            seed_hash=None)
     self.assertIsNone(b)
Exemple #17
0
    def test_blob(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              time_mock.return_value,
                                              sha256(b'txs'), 10)
            self.assertEquals(
                '00501846b24200c31fca7172a7f701ae50322579cfdf1d7777daab4ce6ead70b76debb2c51a1'
                'c70000000000000000000000002b80aecec05ad5c7c4f2259c8f69e2966a6ce102d4609af2cd',
                bin2hstr(block_header.mining_blob))
            self.assertEquals(config.dev.mining_blob_size,
                              len(block_header.mining_blob))
Exemple #18
0
    def test_addr_tx_hashes(self):
        with set_data_dir('no_data'):
            with State() as state:
                alice_xmss = get_alice_xmss()
                alice_address = bytes(alice_xmss.get_address().encode())  # FIXME: This needs to be refactored
                some_hash1 = bin2hstr(sha256(b'some_hash1')).encode()
                some_hash2 = bin2hstr(sha256(b'some_hash2')).encode()

                state.update_address_tx_hashes(alice_address, some_hash1)
                state.update_address_tx_hashes(alice_address, some_hash2)
                result = state.get_address_tx_hashes(alice_address)

                self.assertEqual(some_hash1, result[0])
                self.assertEqual(some_hash2, result[1])
    def test_hash(self, time_mock):
        block_header = BlockHeader.create(1, sha256(b'prev'),
                                          time_mock.return_value,
                                          sha256(b'txs'), 10)
        header_hash = block_header.generate_headerhash()

        self.assertEquals(
            'ac021e63df860ea930ea9de05e350d3f74af35341688134f92957f1dac3a62fb',
            bin2hstr(header_hash))

        self.assertEquals(bin2hstr(header_hash),
                          bin2hstr(block_header.headerhash))

        self.assertEquals(32, len(block_header.headerhash))
Exemple #20
0
    def _set_txhash(self):
        tmptxhash = sha256(
                            self._get_concatenated_fields() +
                            self._data.token.symbol +
                            self._data.token.name +
                            self._data.token.owner +
                            str(self._data.token.decimals).encode()
                          )

        for initial_balance in self._data.token.initial_balances:
            tmptxhash += initial_balance.address
            tmptxhash += str(initial_balance.amount).encode()

        self._data.transaction_hash = sha256(tmptxhash)
Exemple #21
0
    def __init__(self, *args, **kwargs):
        super(TestCoinBase, self).__init__(*args, **kwargs)

        self.alice = get_alice_xmss()
        self.alice.set_ots_index(11)

        self.mock_blockheader = Mock(spec=BlockHeader)
        self.mock_blockheader.stake_selector = self.alice.address
        self.mock_blockheader.block_reward = 50
        self.mock_blockheader.fee_reward = 40
        self.mock_blockheader.prev_blockheaderhash = sha256(b'prev_headerhash')
        self.mock_blockheader.block_number = 1
        self.mock_blockheader.headerhash = sha256(b'headerhash')

        self.maxDiff = None
Exemple #22
0
    def validate_tx(self):
        if not self.validate_subtype(self.subtype, TX_SUBTYPE_LATTICE):
            return False

        txhash = sha256(self.kyber_pk + self.tesla_pk)
        txhash = sha256(txhash + self.pubhash)
        if self.txhash != txhash:
            logger.info('Invalid Txhash')
            logger.warning('Found: %s Expected: %s', self.txhash, txhash)
            return False

        if not self.validate_signed_hash():
            return False

        return True
Exemple #23
0
    def test_create_hashchain(self):
        seed = sha256(b'test_seed')

        HASHCHAIN_SIZE = 100
        hcb = hashchain(seed, 1, HASHCHAIN_SIZE)
        self.assertIsNotNone(hcb)
        self.assertEqual(HASHCHAIN_SIZE + 1, len(hcb.hashchain))

        # FIXME: Why seed comes as an array of tuples?
        self.assertEqual(
            '127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
            bin2hstr(hcb.seed[0]))

        self.assertEqual(
            '1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
            bin2hstr(hcb.hc_terminator))
        self.assertEqual(
            '1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
            bin2hstr(hcb.hashchain[-1]))
        self.assertEqual(
            '127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
            bin2hstr(hcb.hashchain[0]))
        self.assertNotEqual(
            '127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
            bin2hstr(hcb.hashchain[1]))
        self.assertEqual(
            'ff7f4850bc6499e08e104c6967ee66e665e57d7e0e429072e646d14e1b92600a',
            bin2hstr(hcb.hashchain[50]))
 def get_hashable_bytes(self):
     return sha256(
         self.addr_from +
         self.fee.to_bytes(8, byteorder='big', signed=False) +
         self.kyber_pk +
         self.dilithium_pk
     )
Exemple #25
0
    def test_hash(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              sha256(b'txs'), 10)
            header_hash = block_header.generate_headerhash()

            self.assertEquals(
                '584f898a54269d0651cca3403843d4cdb764e5a31655bf51db39bbf8c4883b01',
                bin2hstr(header_hash))

            self.assertEquals(bin2hstr(header_hash),
                              bin2hstr(block_header.headerhash))

            self.assertEquals(32, len(block_header.headerhash))
Exemple #26
0
def score(stake_address: bytes,
          reveal_one: bytes,
          balance: int = 0,
          seed: bytes = None,
          verbose: bool = False):
    if not seed:
        logger.info('Exception Raised due to seed none in score fn')
        raise Exception

    if not balance:
        logger.info(' balance 0 so score none ')
        logger.info(' stake_address %s', stake_address)
        return None

    # FIXME: Review this
    reveal_seed = bin2hstr(sha256(str(reveal_one).encode() + str(seed).encode()))
    score = (Decimal(config.dev.N) - (Decimal(int(reveal_seed, 16)).log10() / Decimal(2).log10())) / Decimal(balance)

    if verbose:
        logger.info('=' * 10)
        logger.info('Score - %s', score)
        logger.info('reveal_one - %s', reveal_one)
        logger.info('seed - %s', seed)
        logger.info('balance - %s', balance)

    return score
Exemple #27
0
 def create(self, xmss, kyber_pk, tesla_pk):
     self.txfrom = xmss.address
     self.kyber_pk = kyber_pk
     self.tesla_pk = tesla_pk
     self.txhash = sha256(self.kyber_pk + self.tesla_pk)
     self.process_XMSS(xmss.address, self.txhash, xmss)
     return self
Exemple #28
0
    def test_getBlockByNumber(self):
        db_state = Mock(spec=State)
        db_state.get_tx_metadata = MagicMock(return_value=None)
        db_state.get_block = MagicMock(return_value=None)

        p2p_factory = Mock(spec=P2PFactory)
        p2p_factory.pow = Mock(spec=POW)

        chain_manager = ChainManager(db_state)

        qrlnode = QRLNode(mining_address=b'')
        qrlnode.set_chain_manager(chain_manager)
        qrlnode._p2pfactory = p2p_factory
        qrlnode._pow = p2p_factory.pow
        qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

        service = PublicAPIService(qrlnode)

        alice_xmss = get_alice_xmss()
        b = Block.create(block_number=1,
                         prev_headerhash=sha256(b'reveal'),
                         prev_timestamp=10,
                         transactions=[],
                         miner_address=alice_xmss.address)
        db_state.get_block_by_number = MagicMock(return_value=b)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetBlockByNumberReq(block_number=b.block_number)
        response = service.GetBlockByNumber(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertEqual(1, response.block.header.block_number)
Exemple #29
0
    def validate_reboot(self, mhash, nonce):
        reboot_data = [
            '2920c8ec34f04f59b7df4284a4b41ca8cbec82ccdde331dd2d64cc89156af653',
            0
        ]
        try:
            reboot_data_db = self.state.db.get('reboot_data')
            reboot_data = reboot_data_db
        except:
            pass

        if reboot_data[1] >= nonce:  # already used
            msg = 'nonce in db ' + str(reboot_data[1])
            msg += '\nnonce provided ' + str(nonce)
            return None, msg

        reboot_data[1] = nonce
        output = mhash
        for i in range(0, reboot_data[1]):
            output = sha256(output)

        if output != reboot_data[0]:
            msg = 'expected hash ' + str(reboot_data[0])
            msg += '\nhash found ' + str(output)
            msg += '\nnonce provided ' + str(nonce) + "\n"
            return None, msg
        # reboot_data[1] += 1
        # self.state.db.put('reboot_data', reboot_data)

        return True, 'Success'
Exemple #30
0
    def validate_hash(self,
                      hash,
                      blocknum,
                      target_chain=config.dev.hashchain_nums - 1,
                      stake_address=None):
        epoch_blocknum = StakeValidator.get_epoch_blocknum(blocknum)
        if hash in self.hash_staker:
            if stake_address and stake_address != self.hash_staker[hash]:
                return False
            return True

        if stake_address:
            if stake_address not in self.sv_list:
                return False
            sv = self.sv_list[stake_address]
            return sv.validate_hash(hash, blocknum, self.hash_staker,
                                    target_chain)

        tmp = hash
        count = epoch_blocknum
        while count >= -1:
            tmp = sha256(tmp)
            if tmp in self.hash_staker:
                stake_address = self.hash_staker[tmp]
                sv = self.sv_list[stake_address]
                sv.update(epoch_blocknum, hash, target_chain, self.hash_staker)
                return True
            count -= 1

        return False
Exemple #31
0
def audit_multisig_addr(qrl_client, addr):
    """ Validate the multi sig address """
    balance = 0
    tx_count = 0
    bad_tx_count = 0
    request_addr = qrl_pb2.GetMultiSigAddressStateReq(
        address=bytes.fromhex(addr[1:]))
    response_addr = qrl_client.GetMultiSigAddressState(request_addr)
    if not response_addr.HasField('state'):
        logging.error('could not find address {}'.format(addr))
        return balance, tx_count, bad_tx_count
    balance = response_addr.state.balance
    request_txs = qrl_pb2.GetMultiSigSpendTxsByAddressReq(
        address=bytes.fromhex(addr[1:]),
        item_per_page=64,
        page_number=1,
        filter_type=qrl_pb2.GetMultiSigSpendTxsByAddressReq.EXECUTED_ONLY)
    response_txs = qrl_client.GetMultiSigSpendTxsByAddress(request_txs)
    tx_count = len(response_txs.transactions_detail)
    for tx_detail in response_txs.transactions_detail:
        tx = tx_detail.tx
        if not tx.HasField('multi_sig_spend'):
            bad_tx_count += 1
            logging.error('txhash {} for addr {} does not exist'.format(
                tx.transaction_hash.hex(), addr))
            continue
        tmptxhash = (tx.master_addr + to_bytes(tx.fee) +
                     tx.multi_sig_spend.multi_sig_address +
                     to_bytes(tx.multi_sig_spend.expiry_block_number) +
                     get_tx_hash(tx.multi_sig_spend))
        if not XmssFast.verify(sha256(tmptxhash), tx.signature, tx.public_key):
            logging.info(
                'txhash {} for addr {} failed XmssFast verification'.format(
                    tx.transaction_hash.hex(), addr))
    return balance, tx_count, bad_tx_count
Exemple #32
0
    def validate_tx(self, chain, blockheader):
        sv_list = chain.block_chain_buffer.stake_list_get(
            blockheader.blocknumber)
        if blockheader.blocknumber > 1 and sv_list[
                self.txto].slave_public_key != self.PK:
            logger.warning('Stake validator doesnt own the Public key')
            logger.warning('Expected public key %s',
                           sv_list[self.txto].slave_public_key)
            logger.warning('Found public key %s', self.PK)
            return False

        if self.txto != self.txfrom:
            logger.warning('Non matching txto and txfrom')
            logger.warning('txto: %s txfrom: %s', self.txto, self.txfrom)
            return False

        # FIXME: Duplication. Risk of mismatch (create & verification)
        txhash = blockheader.prev_blockheaderhash + \
                 tuple([int(char) for char in str(blockheader.blocknumber)]) + \
                 blockheader.headerhash

        # FIXME: This additional transformation happens in a base class
        txhash = sha256(txhash + self.pubhash)

        if self.txhash != txhash:
            logger.warning('Block_headerhash doesnt match')
            logger.warning('Found: %s', self.txhash)
            logger.warning('Expected: %s', txhash)
            return False

        # Slave XMSS is used to sign COINBASE txn having quite low XMSS height
        if not self._validate_signed_hash(height=config.dev.slave_xmss_height):
            return False

        return True
Exemple #33
0
    def create(addr_from, addr_to, amount, fee, xmss_pk, xmss_ots_key):
        transaction = SimpleTransaction()

        transaction.txfrom = addr_from
        transaction.txto = addr_to
        transaction.amount = int(
            amount)  # FIXME: Review conversions for quantities
        transaction.fee = int(fee)  # FIXME: Review conversions for quantities

        # FIXME: This is very confusing and can be a security risk
        # FIXME: Duplication. Risk of mismatch (create & verification)

        transaction.PK = xmss_pk
        transaction.ots_key = xmss_ots_key

        tmppubhash = transaction._get_pubhash()

        tmptxhash = sha256(
            bytes(
                ''.join(transaction.txfrom + transaction.txto +
                        str(transaction.amount) + str(transaction.fee)),
                'utf-8'))

        transaction.txhash = transaction._get_txhash(tmptxhash, tmppubhash)

        return transaction
Exemple #34
0
 def _set_txhash(self):
     self._data.transaction_hash = sha256(
                                           self._get_concatenated_fields() +
                                           self._data.coinbase.addr_to +
                                           str(self._data.coinbase.amount).encode() +
                                           str(self._data.coinbase.block_number).encode() +
                                           self._data.coinbase.headerhash
                                         )
Exemple #35
0
    def test_hashchain_reveal(self):
        seed = sha256(b'test_seed')

        self.assertEqual('1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
                         bin2hstr(hashchain_reveal(seed, 1, 100)))
        self.assertEqual('127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
                         bin2hstr(hashchain_reveal(seed, 1, 0)))
        self.assertEqual('ff7f4850bc6499e08e104c6967ee66e665e57d7e0e429072e646d14e1b92600a',
                         bin2hstr(hashchain_reveal(seed, 1, 50)))
        self.assertNotEqual('ff7f4850bc6499e08e104c6967ee66e665e57d7e0e429072e646d14e1b92600a',
                            bin2hstr(hashchain_reveal(seed, 1, 51)))
Exemple #36
0
    def test_hashchain_verify(self):
        seed = sha256(b'test_seed')

        HASHCHAIN_SIZE = 100
        hcb = hashchain(seed, 1, HASHCHAIN_SIZE)
        self.assertIsNotNone(hcb)
        self.assertEqual(HASHCHAIN_SIZE + 1, len(hcb.hashchain))

        for i, value in enumerate(hcb.hashchain):
            tmp = sha256_n(value, HASHCHAIN_SIZE - i)
            logger.info("{:-4} {} {}".format(i, bin2hstr(value), bin2hstr(tmp)))
            self.assertEqual(hcb.hc_terminator, tmp)
Exemple #37
0
def _calc_hashchain(
        seed_private: bytes,
        epoch: int,
        blocks_per_epoch: int):
    # FIXME: Move to C++
    hc_seed = getHashChainSeed(seed_private, epoch, 1)

    hc = [bytes(hc_seed[0])]

    for x in range(blocks_per_epoch):
        hc.append(sha256(hc[-1]))

    hc_terminator = hc[-1]

    return hc_seed, hc, hc_terminator
Exemple #38
0
    def create(mining_nonce: int,
               block_number: int,
               prevblock_headerhash: bytes,
               transactions: list,
               signing_xmss: XMSS,
               master_address: bytes,
               nonce: int):

        block = Block()
        block._data.transactions.extend([qrl_pb2.Transaction()])  # FIXME: Empty for coinbase?

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend([tx.pbdata])  # copy memory rather than sym link

        if not hashedtransactions:
            hashedtransactions = [sha256(b'')]

        txs_hash = merkle_tx_hash(hashedtransactions)           # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(blocknumber=block_number,
                                             mining_nonce=mining_nonce,
                                             PK=signing_xmss.pk(),
                                             prev_blockheaderhash=prevblock_headerhash,
                                             hashedtransactions=txs_hash,
                                             fee_reward=fee_reward)

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        # Prepare coinbase tx
        coinbase_tx = CoinBase.create(tmp_blockheader, signing_xmss, master_address)
        coinbase_tx.pbdata.nonce = nonce
        coinbase_tx.sign(signing_xmss)  # Sign after nonce has been set

        # Replace first tx
        block._data.transactions[0].CopyFrom(coinbase_tx.pbdata)

        return block
Exemple #39
0
    def test_create_hashchain(self):
        seed = sha256(b'test_seed')

        HASHCHAIN_SIZE = 100
        hcb = hashchain(seed, 1, HASHCHAIN_SIZE)
        self.assertIsNotNone(hcb)
        self.assertEqual(HASHCHAIN_SIZE + 1, len(hcb.hashchain))

        # FIXME: Why seed comes as an array of tuples?
        self.assertEqual('127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
                         bin2hstr(hcb.seed[0]))

        self.assertEqual('1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
                         bin2hstr(hcb.hc_terminator))
        self.assertEqual('1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
                         bin2hstr(hcb.hashchain[-1]))
        self.assertEqual('127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
                         bin2hstr(hcb.hashchain[0]))
        self.assertNotEqual('127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
                            bin2hstr(hcb.hashchain[1]))
        self.assertEqual('ff7f4850bc6499e08e104c6967ee66e665e57d7e0e429072e646d14e1b92600a',
                         bin2hstr(hcb.hashchain[50]))
Exemple #40
0
 def _set_txhash(self):
     self._data.transaction_hash = sha256(
         self._get_concatenated_fields() +
         self._data.latticePK.kyber_pk +
         self._data.latticePK.dilithium_pk
     )
Exemple #41
0
 def _set_txhash(self):
     self._data.transaction_hash = sha256(
                                           self._get_concatenated_fields() +
                                           self._data.message.message_hash
                                         )
Exemple #42
0
 def _set_txhash(self):
     self._data.transaction_hash = sha256(
                                           self._get_concatenated_fields() +
                                           self._data.transfer_token.addr_to +
                                           str(self._data.transfer_token.amount).encode()
                                         )