src/eric7/Utilities/crypto/py3AES.py

branch
eric7
changeset 10928
46651e194fbe
parent 10927
ce599998be7d
child 10929
edfd452bb9be
--- a/src/eric7/Utilities/crypto/py3AES.py	Thu Sep 26 09:48:49 2024 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1662 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# aes.py: implements AES - Advanced Encryption Standard
-# from the SlowAES project, http://code.google.com/p/slowaes/
-#
-# Copyright (c) 2008    Josh Davis ( http://www.josh-davis.org ),
-#           Alex Martelli ( http://www.aleax.it )
-#
-# Ported from C code written by Laurent Haan
-# ( http://www.progressive-coding.com )
-#
-# Licensed under the Apache License, Version 2.0
-# http://www.apache.org/licenses/
-#
-
-#
-# Ported to Python3
-#
-# Copyright (c) 2011 - 2024 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing classes for encryption according
-Advanced Encryption Standard.
-"""
-
-import math
-import os
-
-
-def append_PKCS7_padding(b):
-    """
-    Function to pad the given data to a multiple of 16-bytes by PKCS7 padding.
-
-    @param b data to be padded
-    @type bytes
-    @return padded data
-    @rtype bytes
-    """
-    numpads = 16 - (len(b) % 16)
-    return b + numpads * bytes(chr(numpads), encoding="ascii")
-
-
-def strip_PKCS7_padding(b):
-    """
-    Function to strip off PKCS7 padding.
-
-    @param b data to be stripped
-    @type bytes
-    @return stripped data
-    @rtype bytes
-    @exception ValueError data padding is invalid
-    """
-    if len(b) % 16 or not b:
-        raise ValueError("Data of len {0} can't be PCKS7-padded".format(len(b)))
-    numpads = b[-1]
-    if numpads > 16:
-        raise ValueError("Data ending with {0} can't be PCKS7-padded".format(b[-1]))
-    return b[:-numpads]
-
-
-class AES:
-    """
-    Class implementing the Advanced Encryption Standard algorithm.
-    """
-
-    # valid key sizes
-    KeySize = {
-        "SIZE_128": 16,
-        "SIZE_192": 24,
-        "SIZE_256": 32,
-    }
-
-    # Rijndael S-box
-    sbox = [
-        0x63,
-        0x7C,
-        0x77,
-        0x7B,
-        0xF2,
-        0x6B,
-        0x6F,
-        0xC5,
-        0x30,
-        0x01,
-        0x67,
-        0x2B,
-        0xFE,
-        0xD7,
-        0xAB,
-        0x76,
-        0xCA,
-        0x82,
-        0xC9,
-        0x7D,
-        0xFA,
-        0x59,
-        0x47,
-        0xF0,
-        0xAD,
-        0xD4,
-        0xA2,
-        0xAF,
-        0x9C,
-        0xA4,
-        0x72,
-        0xC0,
-        0xB7,
-        0xFD,
-        0x93,
-        0x26,
-        0x36,
-        0x3F,
-        0xF7,
-        0xCC,
-        0x34,
-        0xA5,
-        0xE5,
-        0xF1,
-        0x71,
-        0xD8,
-        0x31,
-        0x15,
-        0x04,
-        0xC7,
-        0x23,
-        0xC3,
-        0x18,
-        0x96,
-        0x05,
-        0x9A,
-        0x07,
-        0x12,
-        0x80,
-        0xE2,
-        0xEB,
-        0x27,
-        0xB2,
-        0x75,
-        0x09,
-        0x83,
-        0x2C,
-        0x1A,
-        0x1B,
-        0x6E,
-        0x5A,
-        0xA0,
-        0x52,
-        0x3B,
-        0xD6,
-        0xB3,
-        0x29,
-        0xE3,
-        0x2F,
-        0x84,
-        0x53,
-        0xD1,
-        0x00,
-        0xED,
-        0x20,
-        0xFC,
-        0xB1,
-        0x5B,
-        0x6A,
-        0xCB,
-        0xBE,
-        0x39,
-        0x4A,
-        0x4C,
-        0x58,
-        0xCF,
-        0xD0,
-        0xEF,
-        0xAA,
-        0xFB,
-        0x43,
-        0x4D,
-        0x33,
-        0x85,
-        0x45,
-        0xF9,
-        0x02,
-        0x7F,
-        0x50,
-        0x3C,
-        0x9F,
-        0xA8,
-        0x51,
-        0xA3,
-        0x40,
-        0x8F,
-        0x92,
-        0x9D,
-        0x38,
-        0xF5,
-        0xBC,
-        0xB6,
-        0xDA,
-        0x21,
-        0x10,
-        0xFF,
-        0xF3,
-        0xD2,
-        0xCD,
-        0x0C,
-        0x13,
-        0xEC,
-        0x5F,
-        0x97,
-        0x44,
-        0x17,
-        0xC4,
-        0xA7,
-        0x7E,
-        0x3D,
-        0x64,
-        0x5D,
-        0x19,
-        0x73,
-        0x60,
-        0x81,
-        0x4F,
-        0xDC,
-        0x22,
-        0x2A,
-        0x90,
-        0x88,
-        0x46,
-        0xEE,
-        0xB8,
-        0x14,
-        0xDE,
-        0x5E,
-        0x0B,
-        0xDB,
-        0xE0,
-        0x32,
-        0x3A,
-        0x0A,
-        0x49,
-        0x06,
-        0x24,
-        0x5C,
-        0xC2,
-        0xD3,
-        0xAC,
-        0x62,
-        0x91,
-        0x95,
-        0xE4,
-        0x79,
-        0xE7,
-        0xC8,
-        0x37,
-        0x6D,
-        0x8D,
-        0xD5,
-        0x4E,
-        0xA9,
-        0x6C,
-        0x56,
-        0xF4,
-        0xEA,
-        0x65,
-        0x7A,
-        0xAE,
-        0x08,
-        0xBA,
-        0x78,
-        0x25,
-        0x2E,
-        0x1C,
-        0xA6,
-        0xB4,
-        0xC6,
-        0xE8,
-        0xDD,
-        0x74,
-        0x1F,
-        0x4B,
-        0xBD,
-        0x8B,
-        0x8A,
-        0x70,
-        0x3E,
-        0xB5,
-        0x66,
-        0x48,
-        0x03,
-        0xF6,
-        0x0E,
-        0x61,
-        0x35,
-        0x57,
-        0xB9,
-        0x86,
-        0xC1,
-        0x1D,
-        0x9E,
-        0xE1,
-        0xF8,
-        0x98,
-        0x11,
-        0x69,
-        0xD9,
-        0x8E,
-        0x94,
-        0x9B,
-        0x1E,
-        0x87,
-        0xE9,
-        0xCE,
-        0x55,
-        0x28,
-        0xDF,
-        0x8C,
-        0xA1,
-        0x89,
-        0x0D,
-        0xBF,
-        0xE6,
-        0x42,
-        0x68,
-        0x41,
-        0x99,
-        0x2D,
-        0x0F,
-        0xB0,
-        0x54,
-        0xBB,
-        0x16,
-    ]
-
-    # Rijndael Inverted S-box
-    rsbox = [
-        0x52,
-        0x09,
-        0x6A,
-        0xD5,
-        0x30,
-        0x36,
-        0xA5,
-        0x38,
-        0xBF,
-        0x40,
-        0xA3,
-        0x9E,
-        0x81,
-        0xF3,
-        0xD7,
-        0xFB,
-        0x7C,
-        0xE3,
-        0x39,
-        0x82,
-        0x9B,
-        0x2F,
-        0xFF,
-        0x87,
-        0x34,
-        0x8E,
-        0x43,
-        0x44,
-        0xC4,
-        0xDE,
-        0xE9,
-        0xCB,
-        0x54,
-        0x7B,
-        0x94,
-        0x32,
-        0xA6,
-        0xC2,
-        0x23,
-        0x3D,
-        0xEE,
-        0x4C,
-        0x95,
-        0x0B,
-        0x42,
-        0xFA,
-        0xC3,
-        0x4E,
-        0x08,
-        0x2E,
-        0xA1,
-        0x66,
-        0x28,
-        0xD9,
-        0x24,
-        0xB2,
-        0x76,
-        0x5B,
-        0xA2,
-        0x49,
-        0x6D,
-        0x8B,
-        0xD1,
-        0x25,
-        0x72,
-        0xF8,
-        0xF6,
-        0x64,
-        0x86,
-        0x68,
-        0x98,
-        0x16,
-        0xD4,
-        0xA4,
-        0x5C,
-        0xCC,
-        0x5D,
-        0x65,
-        0xB6,
-        0x92,
-        0x6C,
-        0x70,
-        0x48,
-        0x50,
-        0xFD,
-        0xED,
-        0xB9,
-        0xDA,
-        0x5E,
-        0x15,
-        0x46,
-        0x57,
-        0xA7,
-        0x8D,
-        0x9D,
-        0x84,
-        0x90,
-        0xD8,
-        0xAB,
-        0x00,
-        0x8C,
-        0xBC,
-        0xD3,
-        0x0A,
-        0xF7,
-        0xE4,
-        0x58,
-        0x05,
-        0xB8,
-        0xB3,
-        0x45,
-        0x06,
-        0xD0,
-        0x2C,
-        0x1E,
-        0x8F,
-        0xCA,
-        0x3F,
-        0x0F,
-        0x02,
-        0xC1,
-        0xAF,
-        0xBD,
-        0x03,
-        0x01,
-        0x13,
-        0x8A,
-        0x6B,
-        0x3A,
-        0x91,
-        0x11,
-        0x41,
-        0x4F,
-        0x67,
-        0xDC,
-        0xEA,
-        0x97,
-        0xF2,
-        0xCF,
-        0xCE,
-        0xF0,
-        0xB4,
-        0xE6,
-        0x73,
-        0x96,
-        0xAC,
-        0x74,
-        0x22,
-        0xE7,
-        0xAD,
-        0x35,
-        0x85,
-        0xE2,
-        0xF9,
-        0x37,
-        0xE8,
-        0x1C,
-        0x75,
-        0xDF,
-        0x6E,
-        0x47,
-        0xF1,
-        0x1A,
-        0x71,
-        0x1D,
-        0x29,
-        0xC5,
-        0x89,
-        0x6F,
-        0xB7,
-        0x62,
-        0x0E,
-        0xAA,
-        0x18,
-        0xBE,
-        0x1B,
-        0xFC,
-        0x56,
-        0x3E,
-        0x4B,
-        0xC6,
-        0xD2,
-        0x79,
-        0x20,
-        0x9A,
-        0xDB,
-        0xC0,
-        0xFE,
-        0x78,
-        0xCD,
-        0x5A,
-        0xF4,
-        0x1F,
-        0xDD,
-        0xA8,
-        0x33,
-        0x88,
-        0x07,
-        0xC7,
-        0x31,
-        0xB1,
-        0x12,
-        0x10,
-        0x59,
-        0x27,
-        0x80,
-        0xEC,
-        0x5F,
-        0x60,
-        0x51,
-        0x7F,
-        0xA9,
-        0x19,
-        0xB5,
-        0x4A,
-        0x0D,
-        0x2D,
-        0xE5,
-        0x7A,
-        0x9F,
-        0x93,
-        0xC9,
-        0x9C,
-        0xEF,
-        0xA0,
-        0xE0,
-        0x3B,
-        0x4D,
-        0xAE,
-        0x2A,
-        0xF5,
-        0xB0,
-        0xC8,
-        0xEB,
-        0xBB,
-        0x3C,
-        0x83,
-        0x53,
-        0x99,
-        0x61,
-        0x17,
-        0x2B,
-        0x04,
-        0x7E,
-        0xBA,
-        0x77,
-        0xD6,
-        0x26,
-        0xE1,
-        0x69,
-        0x14,
-        0x63,
-        0x55,
-        0x21,
-        0x0C,
-        0x7D,
-    ]
-
-    # Rijndael Rcon
-    Rcon = [
-        0x8D,
-        0x01,
-        0x02,
-        0x04,
-        0x08,
-        0x10,
-        0x20,
-        0x40,
-        0x80,
-        0x1B,
-        0x36,
-        0x6C,
-        0xD8,
-        0xAB,
-        0x4D,
-        0x9A,
-        0x2F,
-        0x5E,
-        0xBC,
-        0x63,
-        0xC6,
-        0x97,
-        0x35,
-        0x6A,
-        0xD4,
-        0xB3,
-        0x7D,
-        0xFA,
-        0xEF,
-        0xC5,
-        0x91,
-        0x39,
-        0x72,
-        0xE4,
-        0xD3,
-        0xBD,
-        0x61,
-        0xC2,
-        0x9F,
-        0x25,
-        0x4A,
-        0x94,
-        0x33,
-        0x66,
-        0xCC,
-        0x83,
-        0x1D,
-        0x3A,
-        0x74,
-        0xE8,
-        0xCB,
-        0x8D,
-        0x01,
-        0x02,
-        0x04,
-        0x08,
-        0x10,
-        0x20,
-        0x40,
-        0x80,
-        0x1B,
-        0x36,
-        0x6C,
-        0xD8,
-        0xAB,
-        0x4D,
-        0x9A,
-        0x2F,
-        0x5E,
-        0xBC,
-        0x63,
-        0xC6,
-        0x97,
-        0x35,
-        0x6A,
-        0xD4,
-        0xB3,
-        0x7D,
-        0xFA,
-        0xEF,
-        0xC5,
-        0x91,
-        0x39,
-        0x72,
-        0xE4,
-        0xD3,
-        0xBD,
-        0x61,
-        0xC2,
-        0x9F,
-        0x25,
-        0x4A,
-        0x94,
-        0x33,
-        0x66,
-        0xCC,
-        0x83,
-        0x1D,
-        0x3A,
-        0x74,
-        0xE8,
-        0xCB,
-        0x8D,
-        0x01,
-        0x02,
-        0x04,
-        0x08,
-        0x10,
-        0x20,
-        0x40,
-        0x80,
-        0x1B,
-        0x36,
-        0x6C,
-        0xD8,
-        0xAB,
-        0x4D,
-        0x9A,
-        0x2F,
-        0x5E,
-        0xBC,
-        0x63,
-        0xC6,
-        0x97,
-        0x35,
-        0x6A,
-        0xD4,
-        0xB3,
-        0x7D,
-        0xFA,
-        0xEF,
-        0xC5,
-        0x91,
-        0x39,
-        0x72,
-        0xE4,
-        0xD3,
-        0xBD,
-        0x61,
-        0xC2,
-        0x9F,
-        0x25,
-        0x4A,
-        0x94,
-        0x33,
-        0x66,
-        0xCC,
-        0x83,
-        0x1D,
-        0x3A,
-        0x74,
-        0xE8,
-        0xCB,
-        0x8D,
-        0x01,
-        0x02,
-        0x04,
-        0x08,
-        0x10,
-        0x20,
-        0x40,
-        0x80,
-        0x1B,
-        0x36,
-        0x6C,
-        0xD8,
-        0xAB,
-        0x4D,
-        0x9A,
-        0x2F,
-        0x5E,
-        0xBC,
-        0x63,
-        0xC6,
-        0x97,
-        0x35,
-        0x6A,
-        0xD4,
-        0xB3,
-        0x7D,
-        0xFA,
-        0xEF,
-        0xC5,
-        0x91,
-        0x39,
-        0x72,
-        0xE4,
-        0xD3,
-        0xBD,
-        0x61,
-        0xC2,
-        0x9F,
-        0x25,
-        0x4A,
-        0x94,
-        0x33,
-        0x66,
-        0xCC,
-        0x83,
-        0x1D,
-        0x3A,
-        0x74,
-        0xE8,
-        0xCB,
-        0x8D,
-        0x01,
-        0x02,
-        0x04,
-        0x08,
-        0x10,
-        0x20,
-        0x40,
-        0x80,
-        0x1B,
-        0x36,
-        0x6C,
-        0xD8,
-        0xAB,
-        0x4D,
-        0x9A,
-        0x2F,
-        0x5E,
-        0xBC,
-        0x63,
-        0xC6,
-        0x97,
-        0x35,
-        0x6A,
-        0xD4,
-        0xB3,
-        0x7D,
-        0xFA,
-        0xEF,
-        0xC5,
-        0x91,
-        0x39,
-        0x72,
-        0xE4,
-        0xD3,
-        0xBD,
-        0x61,
-        0xC2,
-        0x9F,
-        0x25,
-        0x4A,
-        0x94,
-        0x33,
-        0x66,
-        0xCC,
-        0x83,
-        0x1D,
-        0x3A,
-        0x74,
-        0xE8,
-        0xCB,
-    ]
-
-    def __getSBoxValue(self, num):
-        """
-        Private method to retrieve a given S-Box value.
-
-        @param num position of the value
-        @type int
-        @return value of the S-Box
-        @rtype int
-        """
-        return self.sbox[num]
-
-    def __getSBoxInvert(self, num):
-        """
-        Private method to retrieve a given Inverted S-Box value.
-
-        @param num position of the value
-        @type int
-        @return value of the Inverted S-Box
-        @rtype int
-        """
-        return self.rsbox[num]
-
-    def __rotate(self, data):
-        """
-        Private method performing Rijndael's key schedule rotate operation.
-
-        Rotate the data word eight bits to the left: eg,
-        rotate(1d2c3a4f) == 2c3a4f1d.
-
-        @param data data of size 4
-        @type bytearray
-        @return rotated data
-        @rtype bytearray
-        """
-        return data[1:] + data[:1]
-
-    def __getRconValue(self, num):
-        """
-        Private method to retrieve a given Rcon value.
-
-        @param num position of the value
-        @type int
-        @return Rcon value
-        @rtype int
-        """
-        return self.Rcon[num]
-
-    def __core(self, data, iteration):
-        """
-        Private method performing the key schedule core operation.
-
-        @param data data to operate on
-        @type bytearray
-        @param iteration iteration counter
-        @type int
-        @return modified data
-        @rtype bytearray
-        """
-        # rotate the 32-bit word 8 bits to the left
-        data = self.__rotate(data)
-        # apply S-Box substitution on all 4 parts of the 32-bit word
-        for i in range(4):
-            data[i] = self.__getSBoxValue(data[i])
-        # XOR the output of the rcon operation with i to the first part
-        # (leftmost) only
-        data[0] = data[0] ^ self.__getRconValue(iteration)
-        return data
-
-    def __expandKey(self, key, size, expandedKeySize):
-        """
-        Private method performing Rijndael's key expansion.
-
-        Expands a 128, 192 or 256 bit key into a 176, 208 or 240 bit key.
-
-        @param key key to be expanded
-        @type bytes or bytearray
-        @param size size of the key in bytes (16, 24 or 32)
-        @type int
-        @param expandedKeySize size of the expanded key
-        @type int
-        @return expanded key
-        @rtype bytearray
-        """
-        # current expanded keySize, in bytes
-        currentSize = 0
-        rconIteration = 1
-        expandedKey = bytearray(expandedKeySize)
-
-        # set the 16, 24, 32 bytes of the expanded key to the input key
-        for j in range(size):
-            expandedKey[j] = key[j]
-        currentSize += size
-
-        while currentSize < expandedKeySize:
-            # assign the previous 4 bytes to the temporary value t
-            t = expandedKey[currentSize - 4 : currentSize]
-
-            # every 16, 24, 32 bytes we apply the core schedule to t
-            # and increment rconIteration afterwards
-            if currentSize % size == 0:
-                t = self.__core(t, rconIteration)
-                rconIteration += 1
-            # For 256-bit keys, we add an extra sbox to the calculation
-            if size == self.KeySize["SIZE_256"] and ((currentSize % size) == 16):
-                for ll in range(4):
-                    t[ll] = self.__getSBoxValue(t[ll])
-
-            # We XOR t with the four-byte block 16, 24, 32 bytes before the new
-            # expanded key. This becomes the next four bytes in the expanded
-            # key.
-            for m in range(4):
-                expandedKey[currentSize] = expandedKey[currentSize - size] ^ t[m]
-                currentSize += 1  # noqa: Y113
-
-        return expandedKey
-
-    def __addRoundKey(self, state, roundKey):
-        """
-        Private method to add (XORs) the round key to the state.
-
-        @param state state to be changed
-        @type bytearray
-        @param roundKey key to be used for the modification
-        @type bytearray
-        @return modified state
-        @rtype bytearray
-        """
-        buf = state[:]
-        for i in range(16):
-            buf[i] ^= roundKey[i]
-        return buf
-
-    def __createRoundKey(self, expandedKey, roundKeyPointer):
-        """
-        Private method to create a round key.
-
-        @param expandedKey expanded key to be used
-        @type bytearray
-        @param roundKeyPointer position within the expanded key
-        @type int
-        @return round key
-        @rtype bytearray
-        """
-        roundKey = bytearray(16)
-        for i in range(4):
-            for j in range(4):
-                roundKey[j * 4 + i] = expandedKey[roundKeyPointer + i * 4 + j]
-        return roundKey
-
-    def __galois_multiplication(self, a, b):
-        """
-        Private method to perform a Galois multiplication of 8 bit characters
-        a and b.
-
-        @param a first factor
-        @type bytes
-        @param b second factor
-        @type bytes
-        @return result
-        @rtype bytes
-        """
-        p = 0
-        for _counter in range(8):
-            if b & 1:
-                p ^= a
-            hi_bit_set = a & 0x80
-            a <<= 1
-            # keep a 8 bit
-            a &= 0xFF
-            if hi_bit_set:
-                a ^= 0x1B
-            b >>= 1
-        return p
-
-    def __subBytes(self, state, isInv):
-        """
-        Private method to substitute all the values from the state with the
-        value in the SBox using the state value as index for the SBox.
-
-        @param state state to be worked on
-        @type bytearray
-        @param isInv flag indicating an inverse operation
-        @type bool
-        @return modified state
-        @rtype bytearray
-        """
-        state = state[:]
-        getter = self.__getSBoxInvert if isInv else self.__getSBoxValue
-        for i in range(16):
-            state[i] = getter(state[i])
-        return state
-
-    def __shiftRows(self, state, isInv):
-        """
-        Private method to iterate over the 4 rows and call __shiftRow() with
-        that row.
-
-        @param state state to be worked on
-        @type bytearray
-        @param isInv flag indicating an inverse operation
-        @type bool
-        @return modified state
-        @rtype bytearray
-        """
-        state = state[:]
-        for i in range(4):
-            state = self.__shiftRow(state, i * 4, i, isInv)
-        return state
-
-    def __shiftRow(self, state, statePointer, nbr, isInv):
-        """
-        Private method to shift the bytes of a row to the left.
-
-        @param state state to be worked on
-        @type bytearray
-        @param statePointer index into the state
-        @type int
-        @param nbr number of positions to shift
-        @type int
-        @param isInv flag indicating an inverse operation
-        @type bool
-        @return modified state
-        @rtype bytearray
-        """
-        state = state[:]
-        for _ in range(nbr):
-            if isInv:
-                state[statePointer : statePointer + 4] = (
-                    state[statePointer + 3 : statePointer + 4]
-                    + state[statePointer : statePointer + 3]
-                )
-            else:
-                state[statePointer : statePointer + 4] = (
-                    state[statePointer + 1 : statePointer + 4]
-                    + state[statePointer : statePointer + 1]
-                )
-        return state
-
-    def __mixColumns(self, state, isInv):
-        """
-        Private method to perform a galois multiplication of the 4x4 matrix.
-
-        @param state state to be worked on
-        @type bytearray
-        @param isInv flag indicating an inverse operation
-        @type bool
-        @return modified state
-        @rtype bytearray
-        """
-        state = state[:]
-        # iterate over the 4 columns
-        for i in range(4):
-            # construct one column by slicing over the 4 rows
-            column = state[i : i + 16 : 4]
-            # apply the __mixColumn on one column
-            column = self.__mixColumn(column, isInv)
-            # put the values back into the state
-            state[i : i + 16 : 4] = column
-
-        return state
-
-    # galois multiplication of 1 column of the 4x4 matrix
-    def __mixColumn(self, column, isInv):
-        """
-        Private method to perform a galois multiplication of 1 column the
-        4x4 matrix.
-
-        @param column column to be worked on
-        @type bytearray
-        @param isInv flag indicating an inverse operation
-        @type bool
-        @return modified column
-        @rtype bytearray
-        """
-        column = column[:]
-        mult = [14, 9, 13, 11] if isInv else [2, 1, 1, 3]
-        cpy = column[:]
-        g = self.__galois_multiplication
-
-        column[0] = (
-            g(cpy[0], mult[0])
-            ^ g(cpy[3], mult[1])
-            ^ g(cpy[2], mult[2])
-            ^ g(cpy[1], mult[3])
-        )
-        column[1] = (
-            g(cpy[1], mult[0])
-            ^ g(cpy[0], mult[1])
-            ^ g(cpy[3], mult[2])
-            ^ g(cpy[2], mult[3])
-        )
-        column[2] = (
-            g(cpy[2], mult[0])
-            ^ g(cpy[1], mult[1])
-            ^ g(cpy[0], mult[2])
-            ^ g(cpy[3], mult[3])
-        )
-        column[3] = (
-            g(cpy[3], mult[0])
-            ^ g(cpy[2], mult[1])
-            ^ g(cpy[1], mult[2])
-            ^ g(cpy[0], mult[3])
-        )
-        return column
-
-    def __aes_round(self, state, roundKey):
-        """
-        Private method to apply the 4 operations of the forward round in
-        sequence.
-
-        @param state state to be worked on
-        @type bytearray
-        @param roundKey round key to be used
-        @type bytearray
-        @return modified state
-        @rtype bytearray
-        """
-        state = self.__subBytes(state, False)
-        state = self.__shiftRows(state, False)
-        state = self.__mixColumns(state, False)
-        state = self.__addRoundKey(state, roundKey)
-        return state
-
-    def __aes_invRound(self, state, roundKey):
-        """
-        Private method to apply the 4 operations of the inverse round in
-        sequence.
-
-        @param state state to be worked on
-        @type bytearray
-        @param roundKey round key to be used
-        @type bytearray
-        @return modified state
-        @rtype bytearray
-        """
-        state = self.__shiftRows(state, True)
-        state = self.__subBytes(state, True)
-        state = self.__addRoundKey(state, roundKey)
-        state = self.__mixColumns(state, True)
-        return state
-
-    def __aes_main(self, state, expandedKey, nbrRounds):
-        """
-        Private method to do the AES encryption for one round.
-
-        Perform the initial operations, the standard round, and the
-        final operations of the forward AES, creating a round key for
-        each round.
-
-        @param state state to be worked on
-        @type bytearray
-        @param expandedKey expanded key to be used
-        @type bytearray
-        @param nbrRounds number of rounds to be done
-        @type int
-        @return modified state
-        @rtype bytearray
-        """
-        state = self.__addRoundKey(state, self.__createRoundKey(expandedKey, 0))
-        i = 1
-        while i < nbrRounds:
-            state = self.__aes_round(state, self.__createRoundKey(expandedKey, 16 * i))
-            i += 1
-        state = self.__subBytes(state, False)
-        state = self.__shiftRows(state, False)
-        state = self.__addRoundKey(
-            state, self.__createRoundKey(expandedKey, 16 * nbrRounds)
-        )
-        return state
-
-    def __aes_invMain(self, state, expandedKey, nbrRounds):
-        """
-        Private method to do the inverse AES encryption for one round.
-
-        Perform the initial operations, the standard round, and the
-        final operations of the inverse AES, creating a round key for
-        each round.
-
-        @param state state to be worked on
-        @type bytearray
-        @param expandedKey expanded key to be used
-        @type bytearray
-        @param nbrRounds number of rounds to be done
-        @type int
-        @return modified state
-        @rtype bytearray
-        """
-        state = self.__addRoundKey(
-            state, self.__createRoundKey(expandedKey, 16 * nbrRounds)
-        )
-        i = nbrRounds - 1
-        while i > 0:
-            state = self.__aes_invRound(
-                state, self.__createRoundKey(expandedKey, 16 * i)
-            )
-            i -= 1
-        state = self.__shiftRows(state, True)
-        state = self.__subBytes(state, True)
-        state = self.__addRoundKey(state, self.__createRoundKey(expandedKey, 0))
-        return state
-
-    def encrypt(self, iput, key, size):
-        """
-        Public method to encrypt a 128 bit input block against the given key
-        of size specified.
-
-        @param iput input data
-        @type bytearray
-        @param key key to be used
-        @type bytes or bytearray
-        @param size key size (16, 24 or 32)
-        @type int
-        @return encrypted data
-        @rtype bytes
-        @exception ValueError key size is invalid
-        """
-        if size not in self.KeySize.values():
-            raise ValueError("Wrong key size given ({0}).".format(size))
-
-        output = bytearray(16)
-        # the number of rounds
-        nbrRounds = 0
-        # the 128 bit block to encode
-        block = bytearray(16)
-        # set the number of rounds
-        if size == self.KeySize["SIZE_128"]:
-            nbrRounds = 10
-        elif size == self.KeySize["SIZE_192"]:
-            nbrRounds = 12
-        else:
-            nbrRounds = 14
-
-        # the expanded keySize
-        expandedKeySize = 16 * (nbrRounds + 1)
-
-        # Set the block values, for the block:
-        # a0,0 a0,1 a0,2 a0,3
-        # a1,0 a1,1 a1,2 a1,3
-        # a2,0 a2,1 a2,2 a2,3
-        # a3,0 a3,1 a3,2 a3,3
-        # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
-        #
-        # iterate over the columns
-        for i in range(4):
-            # iterate over the rows
-            for j in range(4):
-                block[i + j * 4] = iput[i * 4 + j]
-
-        # expand the key into an 176, 208, 240 bytes key
-        # the expanded key
-        expandedKey = self.__expandKey(key, size, expandedKeySize)
-
-        # encrypt the block using the expandedKey
-        block = self.__aes_main(block, expandedKey, nbrRounds)
-
-        # unmap the block again into the output
-        for kk in range(4):
-            # iterate over the rows
-            for ll in range(4):
-                output[kk * 4 + ll] = block[kk + ll * 4]
-        return bytes(output)
-
-    # decrypts a 128 bit input block against the given key of size specified
-    def decrypt(self, iput, key, size):
-        """
-        Public method to decrypt a 128 bit input block against the given key
-        of size specified.
-
-        @param iput input data
-        @type bytearray
-        @param key key to be used
-        @type bytes or bytearray
-        @param size key size (16, 24 or 32)
-        @type int
-        @return decrypted data
-        @rtype bytes
-        @exception ValueError key size is invalid
-        """
-        if size not in self.KeySize.values():
-            raise ValueError("Wrong key size given ({0}).".format(size))
-
-        output = bytearray(16)
-        # the number of rounds
-        nbrRounds = 0
-        # the 128 bit block to decode
-        block = bytearray(16)
-        # set the number of rounds
-
-        if size == self.KeySize["SIZE_128"]:
-            nbrRounds = 10
-        elif size == self.KeySize["SIZE_192"]:
-            nbrRounds = 12
-        else:
-            nbrRounds = 14
-
-        # the expanded keySize
-        expandedKeySize = 16 * (nbrRounds + 1)
-
-        # Set the block values, for the block:
-        # a0,0 a0,1 a0,2 a0,3
-        # a1,0 a1,1 a1,2 a1,3
-        # a2,0 a2,1 a2,2 a2,3
-        # a3,0 a3,1 a3,2 a3,3
-        # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
-
-        # iterate over the columns
-        for i in range(4):
-            # iterate over the rows
-            for j in range(4):
-                block[i + j * 4] = iput[i * 4 + j]
-        # expand the key into an 176, 208, 240 bytes key
-        expandedKey = self.__expandKey(key, size, expandedKeySize)
-        # decrypt the block using the expandedKey
-        block = self.__aes_invMain(block, expandedKey, nbrRounds)
-        # unmap the block again into the output
-        for kk in range(4):
-            # iterate over the rows
-            for ll in range(4):
-                output[kk * 4 + ll] = block[kk + ll * 4]
-        return output
-
-
-class AESModeOfOperation:
-    """
-    Class implementing the different AES mode of operations.
-    """
-
-    aes = AES()
-
-    # structure of supported modes of operation
-    ModeOfOperation = {
-        "OFB": 0,
-        "CFB": 1,
-        "CBC": 2,
-    }
-
-    def __extractBytes(self, inputData, start, end, mode):
-        """
-        Private method to extract a range of bytes from the input.
-
-        @param inputData input data
-        @type bytes
-        @param start start index
-        @type int
-        @param end end index
-        @type int
-        @param mode mode of operation (0, 1, 2)
-        @type int
-        @return extracted bytes
-        @rtype bytearray
-        """
-        if end - start > 16:
-            end = start + 16
-        ar = bytearray(16) if mode == self.ModeOfOperation["CBC"] else bytearray()
-
-        i = start
-        j = 0
-        while len(ar) < end - start:
-            ar.append(0)
-        while i < end:
-            ar[j] = inputData[i]
-            j += 1
-            i += 1
-        return ar
-
-    def encrypt(self, inputData, mode, key, size, IV):
-        """
-        Public method to perform the encryption operation.
-
-        @param inputData data to be encrypted
-        @type bytes
-        @param mode mode of operation (0, 1 or 2)
-        @type int
-        @param key key to be used
-        @type bytes
-        @param size length of the key (16, 24 or 32)
-        @type int
-        @param IV initialisation vector
-        @type bytearray
-        @return tuple with mode of operation, length of the input data and
-            the encrypted data
-        @rtype tuple of (int, int, bytes)
-        @exception ValueError key size is invalid or decrypted data is invalid
-        """
-        if len(key) % size:
-            raise ValueError("Illegal size ({0}) for key '{1}'.".format(size, key))
-        if len(IV) % 16:
-            raise ValueError("IV is not a multiple of 16.")
-        # the AES input/output
-        iput = bytearray(16)
-        output = bytearray()
-        ciphertext = bytearray(16)
-        # the output cipher string
-        cipherOut = bytearray()
-        # char firstRound
-        firstRound = True
-        if inputData:
-            for j in range(int(math.ceil(float(len(inputData)) / 16))):
-                start = j * 16
-                end = j * 16 + 16
-                if end > len(inputData):
-                    end = len(inputData)
-                plaintext = self.__extractBytes(inputData, start, end, mode)
-                if mode == self.ModeOfOperation["CFB"]:
-                    if firstRound:
-                        output = self.aes.encrypt(IV, key, size)
-                        firstRound = False
-                    else:
-                        output = self.aes.encrypt(iput, key, size)
-                    for i in range(16):
-                        if len(plaintext) - 1 < i:
-                            ciphertext[i] = 0 ^ output[i]
-                        elif len(output) - 1 < i:
-                            ciphertext[i] = plaintext[i] ^ 0
-                        elif len(plaintext) - 1 < i and len(output) < i:
-                            ciphertext[i] = 0 ^ 0
-                        else:
-                            ciphertext[i] = plaintext[i] ^ output[i]
-                    for k in range(end - start):
-                        cipherOut.append(ciphertext[k])
-                    iput = ciphertext
-                elif mode == self.ModeOfOperation["OFB"]:
-                    if firstRound:
-                        output = self.aes.encrypt(IV, key, size)
-                        firstRound = False
-                    else:
-                        output = self.aes.encrypt(iput, key, size)
-                    for i in range(16):
-                        if len(plaintext) - 1 < i:
-                            ciphertext[i] = 0 ^ output[i]
-                        elif len(output) - 1 < i:
-                            ciphertext[i] = plaintext[i] ^ 0
-                        elif len(plaintext) - 1 < i and len(output) < i:
-                            ciphertext[i] = 0 ^ 0
-                        else:
-                            ciphertext[i] = plaintext[i] ^ output[i]
-                    for k in range(end - start):
-                        cipherOut.append(ciphertext[k])
-                    iput = output
-                elif mode == self.ModeOfOperation["CBC"]:
-                    for i in range(16):
-                        if firstRound:
-                            iput[i] = plaintext[i] ^ IV[i]
-                        else:
-                            iput[i] = plaintext[i] ^ ciphertext[i]
-                    firstRound = False
-                    ciphertext = self.aes.encrypt(iput, key, size)
-                    # always 16 bytes because of the padding for CBC
-                    for k in range(16):
-                        cipherOut.append(ciphertext[k])
-        return mode, len(inputData), bytes(cipherOut)
-
-    # Mode of Operation Decryption
-    # cipherIn - Encrypted String
-    # originalsize - The unencrypted string length - required for CBC
-    # mode - mode of type modeOfOperation
-    # key - a number array of the bit length size
-    # size - the bit length of the key
-    # IV - the 128 bit number array Initilization Vector
-    def decrypt(self, cipherIn, originalsize, mode, key, size, IV):
-        """
-        Public method to perform the decryption operation.
-
-        @param cipherIn data to be decrypted
-        @type bytes
-        @param originalsize unencrypted string length (required for CBC)
-        @type int
-        @param mode mode of operation (0, 1 or 2)
-        @type int
-        @param key key to be used
-        @type bytes
-        @param size length of the key (16, 24 or 32)
-        @type int
-        @param IV initialisation vector
-        @type bytearray
-        @return decrypted data
-        @rtype bytes
-        @exception ValueError key size is invalid or decrypted data is invalid
-        """
-        if len(key) % size:
-            raise ValueError("Illegal size ({0}) for key '{1}'.".format(size, key))
-        if len(IV) % 16:
-            raise ValueError("IV is not a multiple of 16.")
-        # the AES input/output
-        ciphertext = bytearray()
-        iput = bytearray()
-        output = bytearray()
-        plaintext = bytearray(16)
-        # the output bytes
-        bytesOut = bytearray()
-        # char firstRound
-        firstRound = True
-        if cipherIn is not None:
-            for j in range(int(math.ceil(float(len(cipherIn)) / 16))):
-                start = j * 16
-                end = j * 16 + 16
-                if j * 16 + 16 > len(cipherIn):
-                    end = len(cipherIn)
-                ciphertext = cipherIn[start:end]
-                if mode == self.ModeOfOperation["CFB"]:
-                    if firstRound:
-                        output = self.aes.encrypt(IV, key, size)
-                        firstRound = False
-                    else:
-                        output = self.aes.encrypt(iput, key, size)
-                    for i in range(16):
-                        if len(output) - 1 < i:
-                            plaintext[i] = 0 ^ ciphertext[i]
-                        elif len(ciphertext) - 1 < i:
-                            plaintext[i] = output[i] ^ 0
-                        elif len(output) - 1 < i and len(ciphertext) < i:
-                            plaintext[i] = 0 ^ 0
-                        else:
-                            plaintext[i] = output[i] ^ ciphertext[i]
-                    for k in range(end - start):
-                        bytesOut.append(plaintext[k])
-                    iput = ciphertext
-                elif mode == self.ModeOfOperation["OFB"]:
-                    if firstRound:
-                        output = self.aes.encrypt(IV, key, size)
-                        firstRound = False
-                    else:
-                        output = self.aes.encrypt(iput, key, size)
-                    for i in range(16):
-                        if len(output) - 1 < i:
-                            plaintext[i] = 0 ^ ciphertext[i]
-                        elif len(ciphertext) - 1 < i:
-                            plaintext[i] = output[i] ^ 0
-                        elif len(output) - 1 < i and len(ciphertext) < i:
-                            plaintext[i] = 0 ^ 0
-                        else:
-                            plaintext[i] = output[i] ^ ciphertext[i]
-                    for k in range(end - start):
-                        bytesOut.append(plaintext[k])
-                    iput = output
-                elif mode == self.ModeOfOperation["CBC"]:
-                    output = self.aes.decrypt(ciphertext, key, size)
-                    for i in range(16):
-                        if firstRound:
-                            plaintext[i] = IV[i] ^ output[i]
-                        else:
-                            plaintext[i] = iput[i] ^ output[i]
-                    firstRound = False
-                    if originalsize is not None and originalsize < end:
-                        for k in range(originalsize - start):
-                            bytesOut.append(plaintext[k])
-                    else:
-                        for k in range(end - start):
-                            bytesOut.append(plaintext[k])
-                    iput = ciphertext
-        return bytes(bytesOut)
-
-
-def encryptData(key, data, mode=AESModeOfOperation.ModeOfOperation["CBC"]):
-    """
-    Module function to encrypt the given data with the given key.
-
-    @param key key to be used for encryption
-    @type bytes
-    @param data data to be encrypted
-    @type bytes
-    @param mode mode of operations (0, 1 or 2)
-    @type int
-    @return encrypted data prepended with the initialization vector
-    @rtype bytes
-    @exception ValueError raised to indicate an invalid key size
-    """
-    key = bytearray(key)
-    if mode == AESModeOfOperation.ModeOfOperation["CBC"]:
-        data = append_PKCS7_padding(data)
-    keysize = len(key)
-    if keysize not in AES.KeySize.values():
-        raise ValueError("invalid key size: {0}".format(keysize))
-    # create a new iv using random data
-    iv = bytearray(list(os.urandom(16)))
-    moo = AESModeOfOperation()
-    _mode, _length, ciph = moo.encrypt(data, mode, key, keysize, iv)
-    # With padding, the original length does not need to be known. It's a bad
-    # idea to store the original message length.
-    # prepend the iv.
-    return bytes(iv) + bytes(ciph)
-
-
-def decryptData(key, data, mode=AESModeOfOperation.ModeOfOperation["CBC"]):
-    """
-    Module function to decrypt the given data with the given key.
-
-    @param key key to be used for decryption
-    @type bytes
-    @param data data to be decrypted (with initialization vector prepended)
-    @type bytes
-    @param mode mode of operations (0, 1 or 2)
-    @type int
-    @return decrypted data
-    @rtype bytes
-    @exception ValueError raised to indicate an invalid key size
-    """
-    key = bytearray(key)
-    keysize = len(key)
-    if keysize not in AES.KeySize.values():
-        raise ValueError("invalid key size: {0}".format(keysize))
-    # iv is first 16 bytes
-    iv = bytearray(data[:16])
-    data = bytearray(data[16:])
-    moo = AESModeOfOperation()
-    decr = moo.decrypt(data, None, mode, key, keysize, iv)
-    if mode == AESModeOfOperation.ModeOfOperation["CBC"]:
-        decr = strip_PKCS7_padding(decr)
-    return bytes(decr)

eric ide

mercurial