Source code for playcrypt.ideal.block_cipher

from playcrypt.primitives import *

[docs]class BlockCipher(): """ This class simulates a block cipher. It can emulate a block cipher with any key or message size (in bytes). Example Usage: .. testcode:: from playcrypt.primitives import * from playcrypt.ideal.block_cipher import BlockCipher b = BlockCipher(16, 12) key = random_string(16) cipher_text = b.encrypt(key, "Hello World!") decrypted_message = b.decrypt(key, cipher_text) print decrypted_message .. testoutput:: Hello World! """ def __init__(self, key_len, block_len): """ :param key_len: Key length for block cipher in bytes. :param block_len: Block length for block cipher in bytes. """ self.key_len, self.block_len = key_len, block_len self.messages = {} self.ciphers = {}
[docs] def encrypt(self, key, block): """ This is a simulated encryption function. Simply use a key and message with the proper block length. :param key: Key to use for simulated encryption, so this must be of length ``self.key_len``. :param block: Message to be encrypted, so this must be of length ``self.block_len``. :return: The cipher text for the block or ``None`` if the length parameters are not met. """ if len(key) is not self.key_len: raise ValueError("Invalid key length, key length was: " + \ str(len(key)) + " should be: " + str(self.key_len) + ".") if len(block) is not self.block_len: raise ValueError("Invalid block length, block length was: " + \ str(len(block)) + " should be: " + str(self.block_len) + ".") if not (key, block) in self.ciphers: cipher = self._new_element(key, self.messages) self.ciphers[(key, block)] = cipher self.messages[(key, cipher)] = block return self.ciphers[(key, block)]
[docs] def decrypt(self, key, cipher): """ This is a simulated decryption function. Use of the correct key and cipher text will result in correct decryption. The cipher and key must have correct lengths. :param key: Key to use for simulated decryption, this must be of length, ``self.key_len``. :param cipher: Cipher text to be decrypted, this must be of length ``self.block_len``. :return: The correct message for the cipher text, cipher, or ``None`` if parameters are not met. """ if len(key) is not self.key_len: raise ValueError("Invalid key length, key length was: " + \ str(len(key)) + " should be: " + str(self.key_len) + ".") if len(cipher) is not self.block_len: raise ValueError("Invalid block length, block length was: " + \ str(len(cipher)) + " should be: " + str(self.block_len) + ".") if not (key, cipher) in self.messages: message = self._new_element(key, self.ciphers) self.messages[(key, cipher)] = message self.ciphers[(key, message)] = cipher return self.messages[(key, cipher)]
def _new_element(self, key, l): """ Returns an element that has not yet been picked. We need this function because the cipher must be a bijection. :param key: Key to index into in list. :param l: List of two tuples to generate a new element in. :return: An element that is not yet in the list with the given key. """ e = random_string(self.block_len) while (key, e) in l: e = random_string(self.block_len) return e