def test_cbc_symmetric(self): for _ in range(100): pt = pad2(urandom(randint(0, 16 * 2)), 16) iv = urandom(8 * 2) ciph = GOST3412Magma(urandom(32)) ct = cbc_encrypt(ciph.encrypt, 8, pt, iv) self.assertSequenceEqual(cbc_decrypt(ciph.decrypt, 8, ct, iv), pt)
def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX, mesh=False): """ CBC encryption mode of operation :param bytes key: encryption key :param bytes data: plaintext :param iv: initialization vector :type iv: bytes, BLOCKSIZE length :type bool pad: perform ISO/IEC 7816-4 padding :param sbox: S-box parameters to use :type sbox: str, SBOXES'es key :param bool mesh: enable key meshing :returns: ciphertext :rtype: bytes 34.13-2015 padding method 2 is used. """ validate_key(key) validate_iv(iv) validate_sbox(sbox) if not data: raise ValueError("No data supplied") if pad: data = pad2(data, BLOCKSIZE) if len(data) % BLOCKSIZE != 0: raise ValueError("Data is not blocksize aligned") ciphertext = [iv] for i in xrange(0, len(data), BLOCKSIZE): if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0: key, _ = meshing(key, iv, sbox=sbox) ciphertext.append(ns2block(encrypt(sbox, key, block2ns( strxor(ciphertext[-1], data[i:i + BLOCKSIZE]) )))) return b"".join(ciphertext)
def test_symmetric(self): for _ in range(100): for blocksize in (8, 16): data = urandom(randint(0, blocksize * 3)) self.assertSequenceEqual( unpad2(pad2(data, blocksize), blocksize), data, )
def __init__(self, blockcipher, pad=None, unpad=None): self.enc = blockcipher.encrypt self.dec = blockcipher.decrypt self.blen = blockcipher.blen if pad == None: self.padding = lambda x: gost3413.pad2(x, self.blen) else: self.padding = pad if unpad == None: self.unpadding = lambda x: gost3413.unpad2(x, self.blen) else: self.unpadding = unpad
def test_ecb_symmetric(self): for _ in range(100): pt = pad2(urandom(randint(0, 16 * 2)), 16) ciph = GOST3412Kuznechik(urandom(32)) ct = ecb_encrypt(ciph.encrypt, 16, pt) self.assertSequenceEqual(ecb_decrypt(ciph.decrypt, 16, ct), pt)