Beispiel #1
0
 def test_add(self):
     aset = AddressSet(self.TABLE_LEN)
     addr = "".join(chr(b) for b in xrange(20))
     self.assertNotIn(addr, aset)
     aset.add(addr)
     self.assertIn(addr, aset)
     self.assertEqual(len(aset), 1)
Beispiel #2
0
 def test_false_positives(self):
     aset = AddressSet(131072, bytes_per_addr=5)  # reduce bytes_per_addr to increase failure probability
     rand_byte_count = aset._hash_bytes + aset._bytes_per_addr
     nonrand_prefix  = (20 - rand_byte_count) * "\0"
     for i in xrange(aset._max_len):
         aset.add(nonrand_prefix + "".join(chr(random.randrange(256)) for i in xrange(rand_byte_count)))
     for i in xrange(524288):
         self.assertNotIn(
             nonrand_prefix + "".join(chr(random.randrange(256)) for i in xrange(rand_byte_count)),
             aset)
Beispiel #3
0
 def test_false_positives(self):
     aset = AddressSet(1024, bytes_per_addr=8)
     rand_byte_count = aset._hash_bytes + aset._bytes_per_addr
     nonrand_prefix = (20 - rand_byte_count) * "\0"
     for i in range(aset._max_len):
         aset.add(nonrand_prefix + "".join(
             chr(random.randrange(256)) for i in range(rand_byte_count)))
     for i in range(8192):
         self.assertNotIn(
             nonrand_prefix + "".join(
                 chr(random.randrange(256))
                 for i in range(rand_byte_count)), aset)
Beispiel #4
0
    def addressdb_tester(self, wallet_type, the_address_limit,
                         correct_mnemonic, **kwds):
        assert the_address_limit > 1

        addressdb = AddressSet.fromfile(open(btcrseed.ADDRESSDB_DEF_FILENAME,
                                             "rb"),
                                        preload=False)
        wallet = wallet_type.create_from_params(
            hash160s=addressdb, address_limit=the_address_limit)

        # Convert the mnemonic string into a mnemonic_ids_guess
        wallet.config_mnemonic(correct_mnemonic, **kwds)
        correct_mnemonic_ids = btcrseed.mnemonic_ids_guess

        # Creates wrong mnemonic id guesses
        wrong_mnemonic_iter = wallet.performance_iterator()

        self.assertEqual(
            wallet.return_verified_password_or_false(
                (wrong_mnemonic_iter.next(), wrong_mnemonic_iter.next())),
            (False, 2))
        self.assertEqual(
            wallet.return_verified_password_or_false(
                (wrong_mnemonic_iter.next(), correct_mnemonic_ids,
                 wrong_mnemonic_iter.next())), (correct_mnemonic_ids, 2))

        # Make sure the address_limit is respected (note the "the_address_limit-1" below)
        wallet = wallet_type.create_from_params(
            hash160s=addressdb, address_limit=the_address_limit - 1)
        wallet.config_mnemonic(correct_mnemonic, **kwds)
        self.assertEqual(
            wallet.return_verified_password_or_false((correct_mnemonic_ids, )),
            (False, 1))
Beispiel #5
0
 def test_collision(self):
     aset = AddressSet(self.TABLE_LEN)
     # the last HASH_BYTES (1) bytes are the "hash", and only the next BYTES_PER_ADDR (8) rightmost bytes are stored
     addr1 = "".join(chr(b) for b in xrange(20))
     addr2 = addr1.replace(chr(20 - self.HASH_BYTES - self.BYTES_PER_ADDR),
                           "\0")  # the leftmost byte that's stored
     self.collision_tester(aset, addr1, addr2)
Beispiel #6
0
    def addressdb_tester(self, wallet_type, the_address_limit, correct_mnemonic, test_path, test_address_db, **kwds):
        assert the_address_limit > 1

        #Check to see if the AddressDB exists (and if not, skip)
        if not os.path.isfile("./btcrecover/test/test-addressdbs/" + test_address_db):
            raise unittest.SkipTest("requires ./btcrecover/test/test-addressdbs/" + test_address_db)

        # Test Basic BIP44 AddressDB Search
        addressdb = AddressSet.fromfile(open("./btcrecover/test/test-addressdbs/" + test_address_db, "rb"), preload=False)
        wallet = wallet_type.create_from_params(hash160s=addressdb, address_limit=the_address_limit, path=test_path)

        # Convert the mnemonic string into a mnemonic_ids_guess
        wallet.config_mnemonic(correct_mnemonic, **kwds)
        correct_mnemonic_ids = btcrseed.mnemonic_ids_guess

        # Creates wrong mnemonic id guesses
        wrong_mnemonic_iter = wallet.performance_iterator()

        self.assertEqual(wallet.return_verified_password_or_false(
            (wrong_mnemonic_iter.next(), wrong_mnemonic_iter.next())), (False, 2))
        self.assertEqual(wallet.return_verified_password_or_false(
            (wrong_mnemonic_iter.next(), correct_mnemonic_ids, wrong_mnemonic_iter.next())), (correct_mnemonic_ids, 2))

        # Make sure the address_limit is respected (note the "the_address_limit-1" below)
        wallet = wallet_type.create_from_params(hash160s=addressdb, address_limit=the_address_limit-1, path=test_path)
        wallet.config_mnemonic(correct_mnemonic, **kwds)
        self.assertEqual(wallet.return_verified_password_or_false(
            (correct_mnemonic_ids,)), (False, 1))
Beispiel #7
0
 def test_collision_fail(self):
     aset  = AddressSet(self.TABLE_LEN)
     # the last 1 (HASH_BYTES) bytes are the "hash", and only the next 8 (BYTES_PER_ADDR) rightmost bytes are stored
     addr1 = "".join(chr(b) for b in xrange(20))
     addr2 = addr1.replace(chr(20 - self.HASH_BYTES - self.BYTES_PER_ADDR - 1), "\0")  # the rightmost byte not stored
     self.assertRaises(unittest.TestCase.failureException, self.collision_tester, aset, addr1, addr2)
     self.assertEqual(len(aset), 1)
Beispiel #8
0
 def test_file(self):
     aset = AddressSet(self.TABLE_LEN)
     addr = "".join(chr(b) for b in xrange(20))
     aset.add(addr)
     dbfile = tempfile.TemporaryFile()
     aset.tofile(dbfile)
     dbfile.seek(0)
     aset = AddressSet.fromfile(dbfile)
     self.assertTrue(dbfile.closed)  # should be closed by AddressSet in read-only mode
     self.assertIn(addr, aset)
     self.assertEqual(len(aset), 1)
Beispiel #9
0
 def test_pickle_mmap(self):
     aset = AddressSet(self.TABLE_LEN)
     addr = "".join(chr(b) for b in xrange(20))
     aset.add(addr)
     dbfile = tempfile.NamedTemporaryFile(delete=False)
     try:
         aset.tofile(dbfile)
         dbfile.seek(0)
         aset = AddressSet.fromfile(dbfile)  # now it's an mmap
         pickled = pickle.dumps(aset, protocol=pickle.HIGHEST_PROTOCOL)
         aset.close()  # also closes the file
         aset = pickle.loads(pickled)
         self.assertIn(addr, aset)
         self.assertEqual(len(aset), 1)
     finally:
         aset.close()
         dbfile.close()
         os.remove(dbfile.name)
Beispiel #10
0
 def test_file_update(self):
     aset = AddressSet(self.TABLE_LEN)
     dbfile = tempfile.NamedTemporaryFile(delete=False)
     try:
         aset.tofile(dbfile)
         dbfile.seek(0)
         aset = AddressSet.fromfile(dbfile, mmap_access=mmap.ACCESS_WRITE)
         addr = "".join(chr(b) for b in xrange(20))
         aset.add(addr)
         aset.close()
         self.assertTrue(dbfile.closed)
         dbfile = open(dbfile.name, "rb")
         aset = AddressSet.fromfile(dbfile)
         self.assertIn(addr, aset)
         self.assertEqual(len(aset), 1)
     finally:
         aset.close()
         dbfile.close()
         os.remove(dbfile.name)
Beispiel #11
0
 def test_null(self):
     aset = AddressSet(self.TABLE_LEN)
     addr = 20 * "\0"
     aset.add(addr)
     self.assertNotIn(addr, aset)
     self.assertEqual(len(aset), 0)
Beispiel #12
0
class TestAddressSet(unittest.TestCase):
    HASH_BYTES = 1
    TABLE_LEN = 2**(8 * HASH_BYTES)
    BYTES_PER_ADDR = AddressSet(1)._bytes_per_addr

    def test_add(self):
        aset = AddressSet(self.TABLE_LEN)
        addr = "".join(chr(b) for b in xrange(20))
        self.assertNotIn(addr, aset)
        aset.add(addr)
        self.assertIn(addr, aset)
        self.assertEqual(len(aset), 1)

    def collision_tester(self, aset, addr1, addr2):
        aset.add(addr1)
        self.assertIn(addr1, aset)
        self.assertNotIn(addr2, aset)
        self.assertEqual(len(aset), 1)
        aset.add(addr2)
        self.assertIn(addr1, aset)
        self.assertIn(addr2, aset)
        self.assertEqual(len(aset), 2)
        return aset

    #
    def test_collision(self):
        aset = AddressSet(self.TABLE_LEN)
        # the last HASH_BYTES (1) bytes are the "hash", and only the next BYTES_PER_ADDR (8) rightmost bytes are stored
        addr1 = "".join(chr(b) for b in xrange(20))
        addr2 = addr1.replace(chr(20 - self.HASH_BYTES - self.BYTES_PER_ADDR),
                              "\0")  # the leftmost byte that's stored
        self.collision_tester(aset, addr1, addr2)

    #
    def test_collision_fail(self):
        aset = AddressSet(self.TABLE_LEN)
        # the last 1 (HASH_BYTES) bytes are the "hash", and only the next 8 (BYTES_PER_ADDR) rightmost bytes are stored
        addr1 = "".join(chr(b) for b in xrange(20))
        addr2 = addr1.replace(
            chr(20 - self.HASH_BYTES - self.BYTES_PER_ADDR - 1),
            "\0")  # the rightmost byte not stored
        self.assertRaises(unittest.TestCase.failureException,
                          self.collision_tester, aset, addr1, addr2)
        self.assertEqual(len(aset), 1)

    def test_null(self):
        aset = AddressSet(self.TABLE_LEN)
        addr = 20 * "\0"
        aset.add(addr)
        self.assertNotIn(addr, aset)
        self.assertEqual(len(aset), 0)

    # very unlikely to fail; if it does, there's probably a significant problem
    def test_false_positives(self):
        aset = AddressSet(
            131072, bytes_per_addr=5
        )  # reduce bytes_per_addr to increase failure probability
        rand_byte_count = aset._hash_bytes + aset._bytes_per_addr
        nonrand_prefix = (20 - rand_byte_count) * "\0"
        for i in xrange(aset._max_len):
            aset.add(nonrand_prefix + "".join(
                chr(random.randrange(256)) for i in xrange(rand_byte_count)))
        for i in xrange(524288):
            self.assertNotIn(
                nonrand_prefix + "".join(
                    chr(random.randrange(256))
                    for i in xrange(rand_byte_count)), aset)

    def test_file(self):
        aset = AddressSet(self.TABLE_LEN)
        addr = "".join(chr(b) for b in xrange(20))
        aset.add(addr)
        dbfile = tempfile.TemporaryFile()
        aset.tofile(dbfile)
        dbfile.seek(0)
        aset = AddressSet.fromfile(dbfile)
        self.assertTrue(
            dbfile.closed)  # should be closed by AddressSet in read-only mode
        self.assertIn(addr, aset)
        self.assertEqual(len(aset), 1)

    def test_file_update(self):
        aset = AddressSet(self.TABLE_LEN)
        dbfile = tempfile.NamedTemporaryFile(delete=False)
        try:
            aset.tofile(dbfile)
            dbfile.seek(0)
            aset = AddressSet.fromfile(dbfile, mmap_access=mmap.ACCESS_WRITE)
            addr = "".join(chr(b) for b in xrange(20))
            aset.add(addr)
            aset.close()
            self.assertTrue(dbfile.closed)
            dbfile = open(dbfile.name, "rb")
            aset = AddressSet.fromfile(dbfile)
            self.assertIn(addr, aset)
            self.assertEqual(len(aset), 1)
        finally:
            aset.close()
            dbfile.close()
            os.remove(dbfile.name)

    def test_pickle_mmap(self):
        aset = AddressSet(self.TABLE_LEN)
        addr = "".join(chr(b) for b in xrange(20))
        aset.add(addr)
        dbfile = tempfile.NamedTemporaryFile(delete=False)
        try:
            aset.tofile(dbfile)
            dbfile.seek(0)
            aset = AddressSet.fromfile(dbfile)  # now it's an mmap
            pickled = pickle.dumps(aset, protocol=pickle.HIGHEST_PROTOCOL)
            aset.close()  # also closes the file
            aset = pickle.loads(pickled)
            self.assertIn(addr, aset)
            self.assertEqual(len(aset), 1)
        finally:
            aset.close()
            dbfile.close()
            os.remove(dbfile.name)