def do_test_bytes_in_out(self, bytes_in, expected_hex_out): """ Verify that the binary input value hashes to the expected hex output value. """ expected_hex_out = expected_hex_out.lower() expected_bin_out = bytes.fromhex(expected_hex_out) self.assertEqual(len(expected_bin_out), self.DIGEST_SIZE) # shortcut passes bytes to constructor sha = XLSHA2(bytes_in) self.assertEqual(sha.hexdigest(), expected_hex_out) self.assertEqual(sha.digest(), expected_bin_out) # longer version has an explicit update() call sha = XLSHA2() sha.update(bytes_in) self.assertEqual(sha.hexdigest(), expected_hex_out) self.assertEqual(sha.digest(), expected_bin_out) # we can also hash the binary value byte by byte sha = XLSHA2() for b_val in bytes_in: xxx = bytearray(1) xxx[0] = b_val sha.update(xxx) self.assertEqual(sha.hexdigest(), expected_hex_out) self.assertEqual(sha.digest(), expected_bin_out)
def verify_tree_sha256(self, node, path_to_tree): """ Verify that the names (content keys) of files below the node (a Merkletree) have correct content keys, matching the SHA hash of the files. """ if node.nodes is None: self.assertEqual(None, node.bin_hash) else: hash_count = 0 sha = XLSHA2() for node_ in node.nodes: path_to_node = os.path.join(path_to_tree, node_.name) if isinstance(node_, MerkleLeaf): self.verify_leaf_sha256(node_, path_to_node) elif isinstance(node_, MerkleTree): self.verify_tree_sha256(node_, path_to_node) else: print("DEBUG: unknown node type!") self.fail("unknown node type!") if node_.bin_hash is not None: hash_count += 1 sha.update(node_.bin_hash) if hash_count == 0: self.assertEqual(None, node.bin_hash) else: self.assertEqual(sha.digest(), node.bin_hash)
def test_random_value(self): """ Verify that hashlib.sha2 returns the same digest for a few quasi-random values. """ rng = SimpleRNG() for _ in range(4): count = 16 + rng.next_int16(48) data = rng.some_bytes(count) my_hex = XLSHA2(data).hexdigest() expected = hashlib.sha256(data).hexdigest() self.assertEqual(my_hex, expected)
def verify_leaf_sha256(self, node, path_to_file): """ Verify that the content keys of the named file match the SHA hash of its contents. """ self.assertTrue(os.path.exists(path_to_file)) with open(path_to_file, "rb") as file: data = file.read() self.assertFalse(data is None) sha = XLSHA2() sha.update(data) hash_ = sha.digest() self.assertEqual(hash_, node.bin_hash)
def test_constructor(self): """ Verify that behavior of pysha3 is as expected """ sha = XLSHA2() # Verify it has the right properties ... self.assertEqual(sha.hash_name(), self.SHA2_NAME) self.assertEqual(sha.digest_size(), self.DIGEST_SIZE) self.assertEqual(len(sha.digest()), self.DIGEST_SIZE) self.assertEqual(len(sha.hexdigest()), self.DIGEST_SIZE * 2) # byte strings are acceptable parameters XLSHA2(b"foo") XLSHA2(data=b"foo") # None is not an acceptable parameter to the constructor self.assertRaises(TypeError, sha, None) # neitheris unicode self.assertRaises(TypeError, sha, "abcdef") # same constraints on parameters to update() self.assertRaises(TypeError, sha.update, None) self.assertRaises(TypeError, sha.update, "abcdef")
def get_hash_func(hashtype): """ Given a HashType, return the appropriate library SHA hash function or None if there is no matching hash func. XXX THIS METHOD BELONGS IN xlcrypto_py """ sha = None if hashtype == HashTypes.SHA1: sha = XLSHA1() elif hashtype == HashTypes.SHA2: sha = XLSHA2() elif hashtype == HashTypes.SHA3: sha = XLSHA3() elif hashtype == HashTypes.BLAKE2B_256: sha = XLBLAKE2B_256() else: raise NotImplementedError return sha
def verify_leaf_sha(self, node, path_to_file, hashtype): """ Verify a leaf node is hashed correctly, using a specific SHA hash type. """ self.assertTrue(os.path.exists(path_to_file)) with open(path_to_file, "rb") as file: data = file.read() self.assertFalse(data is None) if hashtype == HashTypes.SHA1: sha = XLSHA1() elif hashtype == HashTypes.SHA2: sha = XLSHA2() elif hashtype == HashTypes.SHA3: sha = XLSHA3() elif hashtype == HashTypes.BLAKE2B: sha = XLBLAKE2B_256() else: raise NotImplementedError sha.update(data) hash_ = sha.digest() self.assertEqual(hash_, node.bin_hash)
def verify_tree_hash(self, node, path_to_tree, hashtype): """ Given a MerkleTree, verify that it correctly describes the directory whose path is passed. """ # we assume that the node is a MerkleTree check_hashtype(hashtype) if node.nodes is None: self.assertEqual(None, node.bin_hash) else: hash_count = 0 if hashtype == HashTypes.SHA1: sha = XLSHA1() elif hashtype == HashTypes.SHA2: sha = XLSHA2() elif hashtype == HashTypes.SHA3: # pylint: disable=no-member sha = XLSHA3() elif hashtype == HashTypes.BLAKE2B_256: sha = XLBLAKE2B_256() else: raise NotImplementedError for node_ in node.nodes: path_to_node = os.path.join(path_to_tree, node_.name) if isinstance(node_, MerkleLeaf): self.verify_leaf_hash(node_, path_to_node, hashtype) elif isinstance(node_, MerkleTree): self.verify_tree_hash(node_, path_to_node, hashtype) else: print("DEBUG: unknown node type!") self.fail("unknown node type!") if node_.bin_hash is not None: hash_count += 1 sha.update(node_.bin_hash) if hash_count == 0: self.assertEqual(None, node.bin_hash) else: self.assertEqual(sha.digest(), node.bin_hash)
def verify_tree_sha(self, node, path_to_node, hashtype): """ Verify tree elements are hashed correctly, assuming that the node is a MerkleTree, using a specific SHA hash type. """ if node.nodes is None: self.assertEqual(None, node.bin_hash) else: hash_count = 0 if hashtype == HashTypes.SHA1: sha = XLSHA1() elif hashtype == HashTypes.SHA2: sha = XLSHA2() elif hashtype == HashTypes.SHA3: sha = XLSHA3() elif hashtype == HashTypes.BLAKE2B: sha = XLBLAKE2B_256() else: raise NotImplementedError for node_ in node.nodes: path_to_file = os.path.join(path_to_node, node_.name) if isinstance(node_, MerkleLeaf): self.verify_leaf_sha(node_, path_to_file, hashtype) elif isinstance(node_, MerkleTree): self.verify_tree_sha(node_, path_to_file, hashtype) else: self.fail("unknown node type!") if node_.bin_hash is not None: hash_count += 1 sha.update(node_.bin_hash) # take care to compare values of the same type; # node.binHash is binary, node.hexHash is hex if hash_count == 0: self.assertEqual(None, node.bin_hash) else: self.assertEqual(sha.digest(), node.bin_hash)
def do_test_simple_constructor(self, hashtype): """ Test constructor for specific SHA type. """ check_hashtype(hashtype) if hashtype == HashTypes.SHA1: sha = XLSHA1() elif hashtype == HashTypes.SHA2: sha = XLSHA2() elif hashtype == HashTypes.SHA3: sha = XLSHA3() elif hashtype == HashTypes.BLAKE2B: sha = XLBLAKE2B_256() else: raise NotImplementedError file_name = self.rng.next_file_name(8) nnn = self.rng.some_bytes(8) sha.update(nnn) hash0 = sha.digest() leaf0 = MerkleLeaf(file_name, hashtype, hash0) self.assertEqual(file_name, leaf0.name) self.assertEqual(hash0, leaf0.bin_hash) file_name2 = file_name while file_name2 == file_name: file_name2 = self.rng.next_file_name(8) nnn = self.rng.some_bytes(8) self.rng.next_bytes(nnn) sha.update(nnn) hash1 = sha.digest() leaf1 = MerkleLeaf(file_name2, hashtype, hash1) self.assertEqual(file_name2, leaf1.name) self.assertEqual(hash1, leaf1.bin_hash) self.assertTrue(leaf0 == leaf0) self.assertFalse(leaf0 == leaf1)
def verify_leaf_hash(self, node, path_to_file, hashtype): """ Verify that a MerkleLeaf correctly describes a file, given a hash type. """ check_hashtype(hashtype) self.assertTrue(os.path.exists(path_to_file)) with open(path_to_file, "rb") as file: data = file.read() self.assertFalse(data is None) if hashtype == HashTypes.SHA1: sha = XLSHA1() elif hashtype == HashTypes.SHA2: sha = XLSHA2() elif hashtype == HashTypes.SHA3: # pylint: disable=no-member sha = XLSHA3() elif hashtype == HashTypes.BLAKE2B_256: # pylint: disable=no-member sha = XLBLAKE2B_256() else: raise NotImplementedError sha.update(data) hash_ = sha.digest() self.assertEqual(hash_, node.bin_hash)
def test_constants(self): """ Verify that the value of SHA2_{BIN,HEX}_NONE is as expected. """ sha = XLSHA2() sha.update(b'') self.assertEqual(sha.hexdigest(), SHA2_HEX_NONE) self.assertEqual(sha.digest(), SHA2_BIN_NONE)