How-To

In this section practical solutions to problems are shown.

New mode of operation

For this example a fictional blockcipher mode of operation is added, lets call it “mask codebook mode”: A fixed mask is xored to each plaintext block, everything else works like ECB.

1. Set Constant

Which mode of operation is used is passed at initialization of the cipher object.

Following name / number assigments are common:

Constant Number
MODE_ECB 1
MODE_CBC 2
MODE_CFB 3
MODE_PGP 4
MODE_OFB 5
MODE_CTR 6
MODE_OPENPGP 7
MODE_CCM or MODE_XTS 8
MODE_EAX 9
MODE_SIV 10
MODE_GCM 11
MODE_OCB 12

To avoid incompatabilities, the correspondenting number should not be on of above.

MODE_MCB = 500

seems a solid choice.

2. Skeleton

A subclass of PEP272Cipher is made, with a new init parameter mask:

from pep272_encryption import PEP272Cipher

class MCBCapableCipher(PEP272Cipher):
    def __init__(self, key, mode, **kwargs):
        self.mask = kwargs.pop(mask, b'\x00'*self.block_size)
        PEP272Cipher.__init__(self, key, mode, **kwargs)

    def encrypt(self, string):
        if self.mode == MODE_MCB:
            ...
        else:
            PEP272Cipher.encrypt(string)

    def decrypt(self, string):
        if self.mode == MODE_MCB:
            ...
        else:
            PEP272Cipher.decrypt(string)

3. Implementation

Obviously the new mode bust be implemented. To use the blocks of a message and raise errors the helper function _block(bytestring, blocksize) exists.

def encrypt(self, string):
    if self.mode == MODE_MCB:
        out = []
        for block in _block(string, self.block_size):
            masked = xor_string(self.mask, block)
            encrypted = self.encrypt_block(masked)
            out.append(encrypted)
        return b"".join(masked)

    else:
        PEP272Cipher.encrypt(string)

def decrypt(self, string):
    if self.mode == MODE_MCB:
        out = []
        for block in _block(string, self.block_size):
            maksed = self.decrypt_block(block)
            plain = xor_string(self.mask, masked)
            out.append(plain)
        return b"".join(masked)
    else:
        PEP272Cipher.decrypt(string)

That’s it!