def test_encrypt_raises_exception_if_step_is_incorrect(des_data): des_key = des_data['des_key'] plain = des_data['plaintext'] with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=des_key, after_step=-1) with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=des_key, after_step=10)
def test_encrypt_raises_exception_if_plaintext_and_keys_multiple_are_incompatible( ): with pytest.raises(ValueError): des.encrypt(plaintext=np.random.randint(0, 255, (10, 8), dtype='uint8'), key=np.random.randint(0, 255, (9, 8), dtype='uint8')) with pytest.raises(ValueError): des.encrypt(plaintext=np.random.randint(0, 255, (2, 10, 8), dtype='uint8'), key=np.random.randint(0, 255, (10, 8), dtype='uint8'))
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_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 _generate_test_data_for_intermediate_values(key, plain, des_number, output_name): # this function is not a test but a helper to update expected test results result = np.zeros((des_number, 16, 10, 8), dtype=np.uint8) for des_number in range(des_number): for round_number in range(16): for step_number in range(10): result[des_number][round_number][step_number] = des.encrypt( plain, key, at_des=des_number, at_round=round_number, after_step=step_number) d_des = dict(np.load('tests/samples/des_data_tests.npz')) d_des[output_name] = result np.savez('tests/samples/des_data_tests.npz', **d_des)
def test_encrypt_raises_exception_if_improper_round_or_step_or_des_type( des_data): key = des_data['des_key'] plain = des_data['plaintext'] with pytest.raises(TypeError): des.encrypt(plaintext=plain, key=key, at_round='foo') with pytest.raises(TypeError): des.encrypt(plaintext=plain, key=key, after_step='foo') with pytest.raises(TypeError): des.encrypt(plaintext=plain, key=key, at_des='foo')
def test_encrypt_stop_at_intermediate_value_with_tdes3(des_data): int_values = des_data['tdes3_encrypt_intermediate_outputs'] key = des_data['tdes3_key'] plain = des_data['plaintext'] for des_number, des_value in enumerate(int_values): for round_number, round_value in enumerate(des_value): for step_number, step_value in enumerate(round_value): value = des.encrypt(plaintext=plain, key=key, at_des=des_number, at_round=round_number, after_step=step_number) assert np.array_equal(step_value, value) def _generate_values_for_test_encrypt_stop_at_intermediate_value_with_des( des_data): _generate_test_data_for_intermediate_values( des_data['tdes3_key'], des_data['plaintext'], 3, 'tdes3_encrypt_intermediate_outputs')
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_encrypt_raises_exception_if_at_des_is_negative_or_too_high(des_data): des_key = des_data['des_key'] tdes2_key = des_data['tdes2_key'] tdes3_key = des_data['tdes3_key'] plain = des_data['plaintext'] with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=des_key, at_des=-1) with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=des_key, at_des=1) with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=tdes2_key, at_des=-1) with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=tdes2_key, at_des=3) with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=tdes3_key, at_des=-1) with pytest.raises(ValueError): des.encrypt(plaintext=plain, key=tdes3_key, at_des=3)
def test_simple_encrypt_with_des_key(des_data): key = des_data['des_key'] plain = des_data['plaintext'] expected_cipher = des_data['des_ciphertext'] cipher = des.encrypt(key=key, plaintext=plain) assert np.array_equal(expected_cipher, cipher)
def test_full_encrypt(encrypt_cases): assert np.array_equal( encrypt_cases['expected'], des.encrypt(plaintext=encrypt_cases['state'], key=encrypt_cases['keys']))
def test_encrypt_raises_exception_if_plaintext_or_key_is_not_a_byte_array_of_appropriate_length( ): with pytest.raises(TypeError): des.encrypt(plaintext='foo', key=np.random.randint(0, 255, (8), dtype='uint8')) with pytest.raises(TypeError): des.encrypt(plaintext=12, key=np.random.randint(0, 255, (8), dtype='uint8')) with pytest.raises(ValueError): des.encrypt(plaintext=np.random.randint(0, 255, (12), dtype='uint8'), key=np.random.randint(0, 255, (8), dtype='uint8')) with pytest.raises(ValueError): des.encrypt(plaintext=np.random.randint(0, 255, (8), dtype='uint16'), key=np.random.randint(0, 255, (8), dtype='uint8')) with pytest.raises(TypeError): des.encrypt(key='foo', plaintext=np.random.randint(0, 255, (8), dtype='uint8')) with pytest.raises(TypeError): des.encrypt(key=12, plaintext=np.random.randint(0, 255, (8), dtype='uint8')) with pytest.raises(ValueError): des.encrypt(key=np.random.randint(0, 255, (12), dtype='uint8'), plaintext=np.random.randint(0, 255, (8), dtype='uint8')) with pytest.raises(ValueError): des.encrypt(key=np.random.randint(0, 255, (8), dtype='uint16'), plaintext=np.random.randint(0, 255, (8), dtype='uint8'))