ciphers.des_ecb¶
Python program for DES (Data Encryption Standard) using Electronic Codebook (ECB) mode.
DES is a symmetric-key block cipher that encrypts data in fixed-size blocks (64 bits). In ECB mode, the plaintext is divided into 64-bit blocks, and each block is encrypted independently using the same key. This makes ECB the simplest block cipher mode, but also one of the least secure, as identical plaintext blocks will produce identical ciphertext blocks.
This implementation of DES includes key scheduling, encryption, and decryption. It uses standard DES operations such as initial and final permutations, expansion, permutation, and S-box lookups. Padding is applied to ensure the plaintext length is a multiple of 64 bits.
Warning: ECB mode is not secure for most use cases due to its vulnerability to block repetition analysis. Consider using a more secure mode of operation, such as CBC (Cipher Block Chaining), for sensitive data encryption.
References: - Handbook of Applied Cryptography (Algorithm 7.82) - Handbook of Applied Cryptography (Algorithm 7.83) - Handbook of Applied Cryptography (Algorithm 9.29) - https://en.wikipedia.org/wiki/Data_Encryption_Standard
Attributes¶
Classes¶
Module Contents¶
- class ciphers.des_ecb.Des¶
- static decrypt(key: str, cipher_text: str) str¶
Decrypts the given cipher text using DES decryption.
- Args:
key (str): A 16-character hexadecimal string representing a 64-bit key. cipher_text (str): A hexadecimal string representing the encrypted data.
- Returns:
str: The decrypted plain text string.
- Examples:
>>> key = '133457799BBCDFF1' >>> encrypted_string = 'c84e3c8fb646872720b224896db4f60' >>> decrypted = Des.decrypt(key, encrypted_string) >>> decrypted # Checking the cipher to ensure consistency 'Test string'
- static des(keys: list, plain_bitset: list) list¶
Encrypts a plain bitset using the provided subkeys with DES encryption algorithm.
- Args:
keys (list): A list of 16 subkeys, each 48 bits long. plain_bitset (list): A bitset representing the plain text, which should be divisible into 64-bit blocks.
- Returns:
list: The encrypted bitset.
- Examples:
>>> plain_bitset = Operations.string_to_bitset("Test string") >>> plain_bitset = Operations.pad_right_to_multiple_of_n(plain_bitset, 64) >>> keys = Des.key_schedule(Des.generate_key()) >>> cipher_bitset = Des.des(keys, plain_bitset) >>> # The output length should be the same as the input >>> len(cipher_bitset) == len(plain_bitset) True >>> # Decryption should be the inverse of encryption >>> plain_bitset == Des.des(keys[::-1], cipher_bitset) True
- static encrypt(key: str, input_string: str) str¶
Encrypts a given input string using the DES encryption algorithm.
- Args:
key (str): A 16-character hexadecimal string representing a 64-bit key. input_string (str): The plain text string to be encrypted.
- Returns:
str: A hexadecimal string representing the encrypted data.
- Examples:
>>> key = '133457799BBCDFF1' >>> input_string = 'Test string' >>> encrypted = Des.encrypt(key, input_string) >>> encrypted # Checking the cipher to ensure consistency 'c84e3c8fb646872720b224896db4f60'
- static generate_key() str¶
Generates a random hexadecimal key of 16 characters (64 bits).
- Returns:
str: A random hexadecimal key.
- Examples:
>>> key = Des.generate_key() >>> len(key) # Check if the key length is correct 16 >>> # Ensure key only contains valid hex characters >>> all(c in "0123456789abcdef" for c in key) True
- static key_schedule(key: str) list¶
Generates 16 subkeys (round keys) from a given 64-bit hexadecimal key using the DES key schedule.
- Args:
key (str): A 16-character hexadecimal string representing a 64-bit key.
- Returns:
list: A list of 16 subkeys, each of which is a permuted bitset.
- Examples:
>>> subkeys = Des.key_schedule('133457799BBCDFF1') >>> len(subkeys) # Check that 16 subkeys are generated 16 >>> # Ensure each subkey is 48 bits long >>> all(len(subkey) == 48 for subkey in subkeys) True
- class ciphers.des_ecb.Operations¶
- static bitset_to_hex(bitset: list) str¶
Converts a list of binary digits into its 16 digit hexadecimal representation.
- Args:
bitset (list): A list of binary digits (as strings) representing a binary number.
- Returns:
str: The 16 digit hexadecimal representation of the binary number.
- Examples:
>>> Operations.bitset_to_hex(['1', '0', '1', '0', '1', '1', '1', '0']) '00000000000000ae' >>> Operations.bitset_to_hex(['1', '1', '1', '1'] * 16) 'ffffffffffffffff' >>> Operations.bitset_to_hex(['0'] * 64) '0000000000000000'
- static bitset_to_string(bitset: list) str¶
Converts a bitset into a string by interpreting every 8 bits as a character.
- Args:
bitset (list): The list of binary digits (bitset).
- Returns:
str: The decoded string.
- Examples:
>>> Operations.bitset_to_string(['0', '1', '0', '0', '0', '0', '0', '1']) 'A' >>> Operations.bitset_to_string(['0', '1', '0', '0', '0', '1','0', '0', '0', '1', '0', '1', '0', '1', '1', '0']) 'DV'
- static hex_to_bitset(hex_string: str, left_pad: int) list¶
Converts a hexadecimal string to a bitset and pads the bitset to a specified length.
- Args:
hex_string (str): The hexadecimal string to convert. left_pad (int): The length to pad the bitset on the left.
- Returns:
list: The padded bitset.
- Examples:
>>> Operations.hex_to_bitset('ae', 8) ['1', '0', '1', '0', '1', '1', '1', '0'] >>> Operations.hex_to_bitset('1f', 10) ['0', '0', '0', '0', '0', '1', '1', '1', '1', '1']
- static pad_left_to_multiple_of_n(bitset: list, length: int) list¶
Pads the bitset with zeros on the left until its length is a multiple of length.
- Args:
bitset (list): A list of binary digits (as strings) to be padded.
- Returns:
list: The padded bitset, with a length that is a multiple of n.
- Examples:
>>> Operations.pad_left_to_multiple_of_n(['1', '0', '1'], 4) ['0', '1', '0', '1'] >>> len(Operations.pad_left_to_multiple_of_n(['1'] * 64, 64)) % 64 0 >>> len(Operations.pad_left_to_multiple_of_n(['0'] * 63, 64)) % 64 0
- static pad_right_to_multiple_of_n(bitset: list, length: int) list¶
Pads the bitset with zeros on the right until its length is a multiple of length.
- Args:
bitset (list): A list of binary digits (as strings) to be padded.
- Returns:
list: The padded bitset, with a length that is a multiple of n.
- Examples:
>>> Operations.pad_right_to_multiple_of_n(['1', '0', '1'], 4) ['1', '0', '1', '0'] >>> len(Operations.pad_right_to_multiple_of_n(['1'] * 64, 64)) % 64 0 >>> len(Operations.pad_right_to_multiple_of_n(['0'] * 63, 64)) % 64 0
- static permute(bitset: list, permutation: list) list¶
Permutes a bitset according to a given permutation table.
- Args:
bitset (list): The bitset to be permuted. permutation (list): The permutation table specifying the new order.
- Returns:
list: The permuted bitset.
- Examples:
>>> Operations.permute(['1', '0', '1', '0', '1', '1'], [6, 5, 4, 3, 2, 1]) ['1', '1', '0', '1', '0', '1'] >>> Operations.permute(['0', '1', '1', '0', '1', '0'], [3, 1, 6, 5, 4, 2]) ['1', '0', '0', '1', '0', '1'] >>> Operations.permute(['0', '1', '1', '0', '1', '0'], [3, 1, 6, 5, 4, 2, 7]) Traceback (most recent call last): ... ValueError: Permutation values must be within the range of the bitset
- static shift_left(bitset: list, position: int) list¶
Performs a rotated left shift on a bitset by position positions.
- Args:
bitset (list): The bitset to be shifted. n (int): The number of positions to shift.
- Returns:
list: The left-shifted bitset.
- Examples:
>>> Operations.shift_left(['1', '0', '0', '1'], 2) ['0', '1', '1', '0'] >>> Operations.shift_left(['0', '1', '1', '1'], 1) ['1', '1', '1', '0'] >>> Operations.shift_left(['0', '1', '1', '1'], 7) ['1', '0', '1', '1']
- static string_to_bitset(string: str) list¶
Converts a string into a list of binary digits (bitset).
- Args:
string (str): The input string to be converted.
- Returns:
list: A list of binary digits representing the string.
- Examples:
>>> Operations.string_to_bitset('A') ['0', '1', '0', '0', '0', '0', '0', '1'] >>> len(Operations.string_to_bitset('ab')) 16 >>> Operations.string_to_bitset(' ') ['0', '0', '1', '0', '0', '0', '0', '0']
- static xor(bitset1: list, bitset2: list) list¶
Applies a bitwise XOR operation between two bitsets of the same length.
- Args:
bitset1 (list): The first bitset. bitset2 (list): The second bitset.
- Returns:
list: The result of the XOR operation as a new bitset.
- Examples:
>>> Operations.xor(['0', '1', '0', '1'], ['1', '0', '1', '1']) ['1', '1', '1', '0'] >>> Operations.xor(['1', '0', '1', '0'], ['0', '0', '0', '1']) ['1', '0', '1', '1'] >>> Operations.xor(['1', '0', '1', '0', '1'], ['0', '0', '0', '1']) Traceback (most recent call last): ... ValueError: Bitsets must be of the same length >>> Operations.xor(['1', '0', '1', '0'], ['0', '0', '0', '1', '1']) Traceback (most recent call last): ... ValueError: Bitsets must be of the same length
- ciphers.des_ecb.E = [32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18,...¶
- ciphers.des_ecb.IP = [58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6,...¶
- ciphers.des_ecb.IP_INV = [40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30,...¶
- ciphers.des_ecb.P = [16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19,...¶
- ciphers.des_ecb.PC1 = [57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60,...¶
- ciphers.des_ecb.PC2 = [14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52,...¶
- ciphers.des_ecb.S_BOXES¶
- ciphers.des_ecb.mode¶