Exemple #1
0
    def ShiftRow(cost=False):
        """
        TEST:
            >>> Tests.ShiftRow()
            Testing ShiftRow
        """
        print("%s ShiftRow" % ("Costing" if cost else "Testing"))
        from QTests.AES import ShiftRow  # pylint: disable=no-name-in-module,import-error

        def bits_to_int(bits):
            return sum([1 << i if bits[i] == 1 else 0 for i in range(8)])

        state = {
            'Nb': 4,
            'a': [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
        }
        qstate = [[GF256Element(state['a'][j][i]).coeffs for i in range(4)]
                  for j in range(4)]
        qstate = [[e for sub in qstate[j] for e in sub] for j in range(4)]
        qstate = [i for e in qstate for i in e]
        if cost:
            return ShiftRow.estimate_resources(_state=qstate, costing=True)
        aes.ShiftRow(state)
        qstate = ShiftRow.toffoli_simulate(_state=qstate, costing=False)
        qstate = [[
            bits_to_int(qstate[j][i * 8:(i + 1) * 8]) for i in range(4)
        ] for j in range(4)]
        assert (state['a'] == qstate)
Exemple #2
0
    def AddRoundKey(cost=False):
        """
        TEST:
            >>> Tests.AddRoundKey()
            Testing AddRoundKey
        """
        print("%s AddRoundKey" % ("Costing" if cost else "Testing"))
        from random import randint
        from QTests.AES import AddRoundKey  # pylint: disable=no-name-in-module,import-error

        def bits_to_int(bits):
            return sum([1 << i if bits[i] == 1 else 0 for i in range(8)])

        trials = 128
        res = []
        for t in range(trials):
            state = {
                'Nb': 4,
                'a': [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11],
                      [12, 13, 14, 15]]
            }
            key = [[randint(0, 255) for i in range(4)] for j in range(4)]
            qstate = [[
                GF256Element(state['a'][j][i]).coeffs for i in range(4)
            ] for j in range(4)]
            qstate = [[e for sub in qstate[j] for e in sub] for j in range(4)]
            qstate = [i for e in qstate for i in e]
            qkey = [[GF256Element(key[j][i]).coeffs for i in range(4)]
                    for j in range(4)]
            qkey = [[e for sub in qkey[j] for e in sub] for j in range(4)]
            qkey = [i for e in qkey for i in e]
            if cost:
                return AddRoundKey.estimate_resources(_state=qstate,
                                                      _round_key=qkey)
            aes.AddRoundKey(state, key)
            qstate = AddRoundKey.toffoli_simulate(_state=qstate,
                                                  _round_key=qkey)
            qstate = [[
                bits_to_int(qstate[j][i * 8:(i + 1) * 8]) for i in range(4)
            ] for j in range(4)]
            res.append(state['a'] == qstate)
        assert (res == [True] * trials)
Exemple #3
0
    def MixColumn(in_place=True, cost=False):
        """
        TEST:
            >>> Tests.MixColumn(in_place=True)
            Testing MixColumn(in_place=True)
            >>> Tests.MixColumn(in_place=False)
            Testing MixColumn(in_place=False)
        """
        from random import randint
        print("%s MixColumn(in_place=%s)" %
              ("Costing" if cost else "Testing", in_place))
        from QTests.AES import MixColumn  # pylint: disable=no-name-in-module,import-error

        trials = 128
        res = []
        for _ in range(trials):
            state = {
                'Nb': 4,
                'a': [[randint(0, 255) for _ in range(4)] for __ in range(4)]
            }
            # state = {'Nb': 4, 'a': [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]}
            qstate = [[
                GF256Element(state['a'][j][i]).coeffs for i in range(4)
            ] for j in range(4)]
            qstate = [[e for sub in qstate[j] for e in sub] for j in range(4)]
            qstate = [i for e in qstate for i in e]

            if cost:
                return MixColumn.estimate_resources(_state=qstate,
                                                    in_place=in_place,
                                                    costing=True)

            def bits_to_int(bits):
                return sum([1 << i if bits[i] == 1 else 0 for i in range(8)])

            # Mixcols using GF256 library
            aes.MixColumn(state)

            # Mixcols using Q#
            qstate = MixColumn.toffoli_simulate(_state=qstate,
                                                in_place=in_place,
                                                costing=False)
            qstate = [[
                bits_to_int(qstate[j][i * 8:(i + 1) * 8]) for i in range(4)
            ] for j in range(4)]

            res.append(state['a'] == qstate)
            if state['a'] != qstate:
                print(" state: ", state['a'])
                print("qstate: ", qstate)
        assert (res == [True] * trials)
Exemple #4
0
    def Sixteenth(cost=False):
        """
        TESTS:
            >>> Tests.Sixteenth()
            Testing Sixteenth
        """
        print("%s Sixteenth" % ("Costing" if cost else "Testing"))
        from QTests.GF256 import Sixteenth  # pylint: disable=no-name-in-module,import-error
        res = []
        for _x in range(256):
            x = GF256Element(_x)
            if cost:
                return Sixteenth.estimate_resources(_a=x.coeffs, costing=True)

            x16 = x**16
            _x16 = GF256Element(
                Sixteenth.toffoli_simulate(_a=x.coeffs, costing=False))
            res.append(x16 == _x16)
            if (x16 != _x16):
                print("Error")
                print("  x:", x)
                print(" x16:", x16)
                print("qx16:", _x16)
Exemple #5
0
    def Inverse(cost=False):
        """
        TESTS:
            >>> Tests.Inverse()
            Testing Inverse
        """
        print("%s Inverse" % ("Costing" if cost else "Testing"))
        from QTests.GF256 import Inverse  # pylint: disable=no-name-in-module,import-error
        res = []
        for _x in range(256):
            x = GF256Element(_x)
            if cost:
                return Inverse.estimate_resources(_a=x.coeffs, costing=True)

            x16 = x.inverse()
            _x16 = GF256Element(
                Inverse.toffoli_simulate(_a=x.coeffs, costing=False))
            res.append(x16 == _x16)
            if (x16 != _x16):
                print("Error")
                print("  x:", x)
                print(" x16:", x16)
                print("qx16:", _x16)
        pass
Exemple #6
0
def KeyExpansion(key, Nr, debug=False):
    Nb = key['Nb']
    Nk = key['Nk']
    W = [[0] * 4 for _ in range(Nb * (Nr + 1))]
    x = GF256Element(2)

    for i in range(Nk):
        W[i] = key['k'][i]

    for i in range(Nk, Nb * (Nr + 1)):
        temp = W[i - 1]

        if i % Nk == 0:
            temp = SubByte(RotByte(temp))
            if debug:
                # print(i//Nk, (i//Nk - 1) % 255, hex(int(x ** ((i//Nk - 1) % 255))))
                pass
            temp[0] ^= int(x**((i // Nk - 1) % 255))
        elif i % Nk == 4 and Nk > 6:
            temp = SubByte(temp)
        W[i] = [W[i - Nk][j] ^ temp[j] for j in range(4)]

    return [W[i:i + Nb] for i in range(0, Nb * (Nr + 1), Nb)]
Exemple #7
0
    def GroverOracle(smart_wide=True,
                     Nr=10,
                     Nk=4,
                     pairs=1,
                     in_place_mixcolumn=False,
                     cost=False):
        """
        TEST:
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=10, Nk=4, pairs=1)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=10, Nk=4, pairs=1)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=10, Nk=4, pairs=2)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=10, Nk=4, pairs=2)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=12, Nk=6, pairs=1)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=12, Nk=6, pairs=1)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=12, Nk=6, pairs=2)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=12, Nk=6, pairs=2)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8, pairs=1)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8, pairs=1)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8, pairs=2)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8, pairs=2)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=10, Nk=4, pairs=1)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=10, Nk=4, pairs=1)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=10, Nk=4, pairs=2)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=10, Nk=4, pairs=2)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=12, Nk=6, pairs=1)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=12, Nk=6, pairs=1)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=12, Nk=6, pairs=2)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=12, Nk=6, pairs=2)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8, pairs=1)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8, pairs=1)
            >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8, pairs=2)
            Testing GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8, pairs=2)

        # >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8, pairs=3)
        # Testing GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8, pairs=3)
        # >>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8, pairs=3)
        # Testing GroverOracle(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8, pairs=3)
        """
        print(
            "%s GroverOracle(smart_wide=%s, in_place_mixcolumn=%s, Nr=%d, Nk=%d, pairs=%d)"
            % ("Costing" if cost else "Testing", smart_wide,
               in_place_mixcolumn, Nr, Nk, pairs))
        from random import randint
        if smart_wide:
            from QTests.AES import SmartWideGroverOracle as GroverOracle  # pylint: disable=no-name-in-module,import-error

        def bits_to_int(bits):
            return sum([1 << i if bits[i] == 1 else 0 for i in range(8)])

        trials = 10
        res = []
        for t in range(trials):
            message = {
                'Nb':
                4,
                'a':
                [[randint(0, 255) for i in range(4)] for j in range(4 * pairs)]
            }
            qmessage = [[
                GF256Element(message['a'][j][i]).coeffs for i in range(4)
            ] for j in range(4 * pairs)]
            qmessage = [[e for sub in qmessage[j] for e in sub]
                        for j in range(4 * pairs)]
            qmessage = [i for e in qmessage for i in e]

            key = {
                'Nb': 4,
                'Nk': Nk,
                'k': [[randint(0, 255) for i in range(4)] for j in range(Nk)]
            }
            qkey = [[GF256Element(key['k'][j][i]).coeffs for i in range(4)]
                    for j in range(Nk)]
            qkey = [[e for sub in qkey[j] for e in sub] for j in range(Nk)]
            qkey = [i for e in qkey for i in e]

            # compute p-c pairs
            ciphertexts = []
            for _ in range(pairs):
                ciphertext = {'Nb': 4, 'a': message['a'][_ * 4:(_ + 1) * 4]}
                aes.InnerRijndael(key, ciphertext, Nb=4, Nk=Nk, Nr=Nr)
                ciphertexts.append(ciphertext)

            target_ciphertext = [[
                GF256Element(c['a'][j][i]).coeffs for i in range(4)
            ] for c in ciphertexts for j in range(4)]
            target_ciphertext = [[
                e for sub in target_ciphertext[j] for e in sub
            ] for j in range(4 * pairs)]
            target_ciphertext = [i for e in target_ciphertext for i in e]

            # test also that we correctly fail to identify wrong keys
            flip = bool(randint(0, 1))
            if flip:
                qkey[0] = 0 if qkey[0] == 1 else 1

            qgrover = GroverOracle.toffoli_simulate(
                _key=qkey,
                _plaintexts=qmessage,
                target_ciphertext=target_ciphertext,
                pairs=pairs,
                Nr=Nr,
                Nk=Nk,
                in_place_mixcolumn=in_place_mixcolumn,
                costing=False)
            res.append(qgrover == int(not flip))
        assert (res == [True] * trials)
Exemple #8
0
    def Rijndael(smart_wide=True,
                 Nr=10,
                 Nk=4,
                 in_place_mixcolumn=False,
                 cost=False):
        """
        TEST:
            >>> Tests.Rijndael(smart_wide=True, in_place_mixcolumn=False, Nr=10, Nk=4)
            Testing Rijndael(smart_wide=True, in_place_mixcolumn=False, Nr=10, Nk=4)
            >>> Tests.Rijndael(smart_wide=True, in_place_mixcolumn=False, Nr=12, Nk=6)
            Testing Rijndael(smart_wide=True, in_place_mixcolumn=False, Nr=12, Nk=6)
            >>> Tests.Rijndael(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8)
            Testing Rijndael(smart_wide=True, in_place_mixcolumn=False, Nr=14, Nk=8)
            >>> Tests.Rijndael(smart_wide=True, in_place_mixcolumn=True, Nr=10, Nk=4)
            Testing Rijndael(smart_wide=True, in_place_mixcolumn=True, Nr=10, Nk=4)
            >>> Tests.Rijndael(smart_wide=True, in_place_mixcolumn=True, Nr=12, Nk=6)
            Testing Rijndael(smart_wide=True, in_place_mixcolumn=True, Nr=12, Nk=6)
            >>> Tests.Rijndael(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8)
            Testing Rijndael(smart_wide=True, in_place_mixcolumn=True, Nr=14, Nk=8)
            >>> Tests.Rijndael(smart_wide=False, in_place_mixcolumn=True, Nr=10, Nk=4)
            Testing Rijndael(smart_wide=False, in_place_mixcolumn=True, Nr=10, Nk=4)
            >>> Tests.Rijndael(smart_wide=False, in_place_mixcolumn=True, Nr=12, Nk=6)
            Testing Rijndael(smart_wide=False, in_place_mixcolumn=True, Nr=12, Nk=6)
            >>> Tests.Rijndael(smart_wide=False, in_place_mixcolumn=True, Nr=14, Nk=8)
            Testing Rijndael(smart_wide=False, in_place_mixcolumn=True, Nr=14, Nk=8)
        """
        print(
            "%s Rijndael(smart_wide=%s, in_place_mixcolumn=%s, Nr=%d, Nk=%d)" %
            ("Costing" if cost else "Testing", smart_wide, in_place_mixcolumn,
             Nr, Nk))
        from random import randint
        if smart_wide:
            from QTests.AES import SmartWideRijndael as Rijndael  # pylint: disable=no-name-in-module,import-error
        else:
            from QTests.AES import WideRijndael as Rijndael  # pylint: disable=no-name-in-module,import-error

        def bits_to_int(bits):
            return sum([1 << i if bits[i] == 1 else 0 for i in range(8)])

        trials = 4
        res = []
        for t in range(trials):
            message = {
                'Nb': 4,
                'a': [[randint(0, 255) for i in range(4)] for j in range(4)]
            }
            key = {
                'Nb': 4,
                'Nk': Nk,
                'k': [[randint(0, 255) for i in range(4)] for j in range(Nk)]
            }
            qmessage = [[
                GF256Element(message['a'][j][i]).coeffs for i in range(4)
            ] for j in range(4)]
            qmessage = [[e for sub in qmessage[j] for e in sub]
                        for j in range(4)]
            qmessage = [i for e in qmessage for i in e]
            qkey = [[GF256Element(key['k'][j][i]).coeffs for i in range(4)]
                    for j in range(Nk)]
            qkey = [[e for sub in qkey[j] for e in sub] for j in range(Nk)]
            qkey = [i for e in qkey for i in e]
            if cost:
                return Rijndael.estimate_resources(
                    _message=qmessage,
                    _key=qkey,
                    Nr=Nr,
                    Nk=Nk,
                    in_place_mixcolumn=in_place_mixcolumn,
                    costing=True)
            # qstate = [e for sub in qstate for e in sub]
            aes.InnerRijndael(key, message, Nb=4, Nk=Nk, Nr=Nr)
            qmessage = Rijndael.toffoli_simulate(
                _message=qmessage,
                _key=qkey,
                Nr=Nr,
                Nk=Nk,
                in_place_mixcolumn=in_place_mixcolumn,
                costing=False)
            qmessage = [[
                bits_to_int(qmessage[j][i * 8:(i + 1) * 8]) for i in range(4)
            ] for j in range(4)]
            if message['a'] != qmessage:
                print('c', message['a'])
                print('q', qmessage)
                print()
            res.append(message['a'] == qmessage)
        assert (res == [True] * trials)
Exemple #9
0
    def KeyExpansion(in_place=False, cost=False, Nr=10, Nk=4):
        """
        TEST:
            >>> Tests.KeyExpansion(in_place=True, Nr=10, Nk=4)
            Testing KeyExpansion(in_place=True, Nr=10, Nk=4)
            >>> Tests.KeyExpansion(in_place=True, Nr=12, Nk=6)
            Testing KeyExpansion(in_place=True, Nr=12, Nk=6)
            >>> Tests.KeyExpansion(in_place=True, Nr=14, Nk=8)
            Testing KeyExpansion(in_place=True, Nr=14, Nk=8)
            >>> Tests.KeyExpansion(in_place=False, Nr=10, Nk=4)
            Testing KeyExpansion(in_place=False, Nr=10, Nk=4)
            >>> Tests.KeyExpansion(in_place=False, Nr=12, Nk=6)
            Testing KeyExpansion(in_place=False, Nr=12, Nk=6)
            >>> Tests.KeyExpansion(in_place=False, Nr=14, Nk=8)
            Testing KeyExpansion(in_place=False, Nr=14, Nk=8)
        """
        print("%s KeyExpansion(in_place=%s, Nr=%d, Nk=%d)" %
              ("Costing" if cost else "Testing", in_place, Nr, Nk))
        from random import randint
        if in_place:
            from QTests.AES import InPlaceKeyExpansion as KeyExpansion  # pylint: disable=no-name-in-module,import-error
        else:
            from QTests.AES import KeyExpansion  # pylint: disable=no-name-in-module,import-error

        def bits_to_int(bits):
            return sum([1 << i if bits[i] == 1 else 0 for i in range(8)])

        trials = 1
        res = []
        for t in range(trials):
            key = {
                'Nb': 4,
                'Nk': Nk,
                'k': [[randint(0, 255) for i in range(4)] for j in range(Nk)]
            }
            qkey = [
                GF256Element(key['k'][j][i]).coeffs for j in range(Nk)
                for i in range(4)
            ]
            qkey = [e for sub in qkey for e in sub]
            if cost:
                return KeyExpansion.estimate_resources(_key=qkey,
                                                       Nr=Nr,
                                                       Nk=Nk,
                                                       costing=True)

            key = aes.KeyExpansion(key, Nr)
            qkey = KeyExpansion.toffoli_simulate(_key=qkey,
                                                 Nr=Nr,
                                                 Nk=Nk,
                                                 costing=False)
            qkey = [
                bits_to_int(qkey[i * 8:(i + 1) * 8])
                for i in range(len(qkey) // 8)
            ]
            qkey = [qkey[i * 4:(i + 1) * 4] for i in range(len(qkey) // 4)]
            qkey = [qkey[i * 4:(i + 1) * 4] for i in range(len(qkey) // 4)]
            if key != qkey:
                print('c', key)
                print('q', qkey)
            res.append(key == qkey)
        assert (res == [True] * trials)