def test_des_decrypt_delta_r_last_rounds_with_alternative_args(): sf = des.selection_functions.decrypt.DeltaRLastRounds(plaintext_tag='foo', words=slice(2, 8), guesses=_alt_guesses, key_tag='thekey') assert sf.guesses.tolist() == _alt_guesses.tolist() assert sf.words == slice(2, 8, None) assert sf.target_tag == 'foo' assert isinstance(sf, selection_functions.SelectionFunction) data = np.random.randint(0, 255, (10, 8), dtype='uint8') expected = np.empty((10, len(_alt_guesses), 8), dtype='uint8') for i, guess in enumerate(_alt_guesses): expanded_guess = np.bitwise_xor(np.zeros((128), dtype=np.uint8), guess) expected[:, i, :] = des.encrypt( data, expanded_guess, at_round=0, after_step=des.Steps.INV_PERMUTATION_P_DELTA_RIGHT) assert np.array_equal(expected[:, :, slice(2, 8)], sf(foo=data)) master_key = np.random.randint(0, 255, (8, ), dtype='uint8') expected_key = des.key_schedule(master_key)[0] assert np.array_equal(expected_key, sf.compute_expected_key(thekey=master_key)) assert sf.key_tag == 'thekey' assert isinstance(str(sf), str)
def test_full_decrypt_with_expanded_keys(decrypt_cases): if decrypt_cases['keys'].shape[-1] >= 8: if decrypt_cases['keys'].ndim == 2: expanded_key1 = des.key_schedule(decrypt_cases['keys'][:, 0:8]) expanded_key = expanded_key1.reshape(expanded_key1.shape[:-2] + (-1, )) else: expanded_key1 = des.key_schedule(decrypt_cases['keys'][0:8]) expanded_key = expanded_key1.reshape(expanded_key1.shape[:-2] + (-1, )) if decrypt_cases['keys'].shape[-1] >= 16: if decrypt_cases['keys'].ndim == 2: expanded_key2 = des.key_schedule(decrypt_cases['keys'][:, 8:16]) expanded_key2 = expanded_key2.reshape(expanded_key2.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key2, axis=1) else: expanded_key2 = des.key_schedule(decrypt_cases['keys'][8:16]) expanded_key2 = expanded_key2.reshape(expanded_key2.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key2, axis=0) if decrypt_cases['keys'].shape[-1] == 24: if decrypt_cases['keys'].ndim == 2: expanded_key3 = des.key_schedule(decrypt_cases['keys'][:, 16:24]) expanded_key3 = expanded_key3.reshape(expanded_key3.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key3, axis=1) else: expanded_key3 = des.key_schedule(decrypt_cases['keys'][16:24]) expanded_key3 = expanded_key3.reshape(expanded_key3.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key3, axis=0) assert np.array_equal( decrypt_cases['expected'], des.decrypt(ciphertext=decrypt_cases['state'], key=expanded_key))
def test_get_master_key_retrieves_des_master_key_able_to_decrypt_the_ciphertext( ): des_key = np.random.randint(256, size=8, dtype=np.uint8) plaintext = np.random.randint(256, size=8, dtype=np.uint8) expected_ciphertext = des.encrypt(plaintext, des_key) des_key_schedule = des.key_schedule(des_key) for round_index, round_key in enumerate(des_key_schedule): found_master_key = des.get_master_key(round_key, round_index, plaintext, expected_ciphertext) assert found_master_key is not None plaintext_from_found_key = np.frombuffer(crypto_des.DESCipher( found_master_key).decrypt(expected_ciphertext), dtype='uint8') assert np.array_equal(plaintext_from_found_key, plaintext)
def test_des_decrypt_last_sboxes_with_default_arguments(): sf = des.selection_functions.decrypt.LastSboxes() assert sf.guesses.tolist() == list(range(64)) assert sf.words is Ellipsis assert sf.target_tag == 'plaintext' assert isinstance(sf, selection_functions.SelectionFunction) data = np.random.randint(0, 255, (10, 8), dtype='uint8') expected = np.empty((10, 64, 8), dtype='uint8') for i in np.arange(64, dtype='uint8'): expanded_guess = np.bitwise_xor(np.zeros((128), dtype=np.uint8), i) expected[:, i, :] = des.encrypt(data, expanded_guess, at_round=0, after_step=des.Steps.SBOXES) assert np.array_equal(expected, sf(plaintext=data)) master_key = np.random.randint(0, 255, (8, ), dtype='uint8') expected_key = des.key_schedule(master_key)[0] assert np.array_equal(expected_key, sf.compute_expected_key(key=master_key)) assert sf.key_tag == 'key' assert isinstance(str(sf), str)
def test_des_encrypt_first_round_key_with_alternative_args(): sf = des.selection_functions.encrypt.FirstAddRoundKey( plaintext_tag='plain', words=6, guesses=_alt_guesses, key_tag='thekey') assert sf.guesses.tolist() == _alt_guesses.tolist() assert sf.words == 6 assert sf.target_tag == 'plain' assert sf.key_tag == 'thekey' assert isinstance(sf, selection_functions.SelectionFunction) data = np.random.randint(0, 255, (10, 8), dtype='uint8') expected = np.empty((10, len(_alt_guesses), 8), dtype='uint8') for i, guess in enumerate(_alt_guesses): expanded_guess = np.bitwise_xor(np.zeros((128), dtype=np.uint8), guess) expected[:, i, :] = des.encrypt(data, expanded_guess, at_round=0, after_step=des.Steps.ADD_ROUND_KEY) assert np.array_equal(expected[:, :, 6], sf(plain=data)) master_key = np.random.randint(0, 255, (8, ), dtype='uint8') expected_key = des.key_schedule(master_key)[0] assert np.array_equal(expected_key, sf.compute_expected_key(thekey=master_key)) assert isinstance(str(sf), str)
def test_full_encrypt_with_expanded_keys(encrypt_cases): if encrypt_cases['keys'].shape[-1] >= 8: # we expand only first 8 bytes of the key if encrypt_cases['keys'].ndim == 2: expanded_key1 = des.key_schedule(encrypt_cases['keys'][:, 0:8]) expanded_key = expanded_key1.reshape(expanded_key1.shape[:-2] + (-1, )) else: expanded_key1 = des.key_schedule(encrypt_cases['keys'][0:8]) expanded_key = expanded_key1.reshape(expanded_key1.shape[:-2] + (-1, )) if encrypt_cases['keys'].shape[-1] >= 16: # we expand second 8 bytes of the key if encrypt_cases['keys'].ndim == 2: expanded_key2 = des.key_schedule(encrypt_cases['keys'][:, 8:16]) expanded_key2 = expanded_key2.reshape(expanded_key2.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key2, axis=1) else: expanded_key2 = des.key_schedule(encrypt_cases['keys'][8:16]) expanded_key2 = expanded_key2.reshape(expanded_key2.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key2, axis=0) if encrypt_cases['keys'].shape[-1] == 24: # we expand third 8 bytes of the key if encrypt_cases['keys'].ndim == 2: expanded_key3 = des.key_schedule(encrypt_cases['keys'][:, 16:24]) expanded_key3 = expanded_key3.reshape(expanded_key3.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key3, axis=1) else: expanded_key3 = des.key_schedule(encrypt_cases['keys'][16:24]) expanded_key3 = expanded_key3.reshape(expanded_key3.shape[:-2] + (-1, )) expanded_key = np.append(expanded_key, expanded_key3, axis=0) assert np.array_equal( encrypt_cases['expected'], des.encrypt(plaintext=encrypt_cases['state'], key=expanded_key))
def test_key_schedule_raises_exception_if_key_isnt_int8_array(): with pytest.raises(ValueError): key = np.random.randint(0, 255, size=(8, ), dtype='uint16') des.key_schedule(key=key)
def test_key_schedule_raises_exception_if_interrupt_after_round_isnt_int(): with pytest.raises(TypeError): key = np.random.randint(0, 255, (8, ), dtype='uint8') des.key_schedule(key=key, interrupt_after_round='foo')
def test_key_schedule_raises_exception_if_key_isnt_array(): with pytest.raises(TypeError): des.key_schedule(key='foo')
def test_key_schedule_returns_array_of_6bits_numbers(): keys = np.random.randint(0, 255, (100, 8), dtype='uint8') expected_keys = des.key_schedule(keys) for element in np.nditer(expected_keys): assert element <= 63
def test_key_schedule_returns_correct_shape_with_several_keys(): output = des.key_schedule(np.random.randint(0, 255, (15, 8), dtype='uint8')) assert output.shape == (15, 16, 8)
def test_key_schedule_returns_appropriate_key_for_des_key(des_data): output = des.key_schedule(des_data['des_key']) assert np.array_equal(output, des_data['des_key_schedule_output']) assert output.shape == (16, 8)
def test_key_schedule_raises_exception_if_key_hasnt_a_valid_size(): with pytest.raises(ValueError): key = np.random.randint(0, 255, size=(16, ), dtype='uint8') des.key_schedule(key=key)