Example #1
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SPECK with
        the given parameters.
        """
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if wordsize == 16:
            self.rot_alpha = 7
            self.rot_beta = 2
        elif "rotationconstants" in parameters:
            self.rot_alpha = parameters["rotationconstants"][0]
            self.rot_beta = parameters["rotationconstants"][1]

        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% Speck w={} alpha={} beta={} "
                           "rounds={}\n\n\n".format(wordsize, self.rot_alpha,
                                                    self.rot_beta, rounds))

            # Setup variable
            # x = left, y = right
            # w = weight
            x = ["x{}".format(i) for i in range(rounds + 1)]
            y = ["y{}".format(i) for i in range(rounds + 1)]
            w = ["w{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)

            # Ignore MSB
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize, 1)

            for i in range(rounds):
                self.setupSpeckRound(stp_file, x[i], y[i], x[i+1], y[i+1], w[i],
                                     wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x + y, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])
                stpcommands.assertVariableValue(stp_file, y[0], y[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #2
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for Salsa with
        the given parameters.
        """
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% Salsa w={}"
                           "rounds={}\n\n\n".format(wordsize, rounds))

            # Setup variables
            a = ["a{}r{}".format(j, i) for i in range(rounds + 1) for j in range(16)]
            b = ["b{}r{}".format(j, i) for i in range(rounds) for j in range(16)]
            w = ["w{}r{}".format(j, i) for i in range(rounds) for j in range(16)]

            stpcommands.setupVariables(stp_file, a, wordsize)
            stpcommands.setupVariables(stp_file, b, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)

            # Ignore MSB
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize, 1)

            for rnd in range(rounds):
                if rnd % 2 != 0:
                    #Rowround
                    for row in range(4):
                        a_in = [a[(i + row) % 4 + 4 * row + 16 * rnd] for i in range(4)]
                        a_out = [a[(i + row) % 4 + 4 * row + 16 * (rnd + 1)] for i in range(4)]
                        tmp_b = [b[i + 4 * row + 16 * rnd] for i in range(4)]
                        tmp_w = [w[i + 4 * row + 16 * rnd] for i in range(4)]
                        self.setupQuarterRound(stp_file, a_in, tmp_b, a_out, tmp_w, wordsize)
                else:
                    #Columnround
                    for col in range(4): 
                        a_in = [a[(i * 4 + 4 * col + col) % 16 + 16 * rnd] for i in range(4)]
                        a_out = [a[(i * 4 + 4 * col + col) % 16 + 16 * (rnd + 1)] for i in range(4)]
                        tmp_b = [b[i * 4 + col + 16 * rnd] for i in range(4)]
                        tmp_w = [w[i * 4 + col + 16 * rnd] for i in range(4)]
                        self.setupQuarterRound(stp_file, a_in, tmp_b, a_out, tmp_w, wordsize)

            #stp_file.write("ASSERT(({}[31:31]) = 0b0);\n".format(a[0]))
            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, a, wordsize)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #3
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a differnetial trail for Skinny with
        the given parameters.
        """

        blocksize = parameters["blocksize"]
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if blocksize != 64:
            print("Only blocksize of 64-bit supported.")
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% Skinny w={}"
                      "rounds={}\n\n\n".format(blocksize, rounds))
            stp_file.write(header)

            # Setup variables
            sc = ["SC{}".format(i) for i in range(rounds + 1)]
            sr = ["SR{}".format(i) for i in range(rounds)]
            mc = ["MC{}".format(i) for i in range(rounds)]

            # w = weight
            w = ["w{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, sc, blocksize)
            stpcommands.setupVariables(stp_file, sr, blocksize)
            stpcommands.setupVariables(stp_file, mc, blocksize)
            stpcommands.setupVariables(stp_file, w, blocksize)

            stpcommands.setupWeightComputation(stp_file, weight, w, blocksize)

            for i in range(rounds):
                self.setupSkinnyRound(stp_file, sc[i], sr[i], mc[i], sc[i+1], 
                                      w[i], blocksize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, sc, blocksize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, sc[0], sc[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, blocksize)

            stpcommands.setupQuery(stp_file)

        return
Example #4
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for PRESENT with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if wordsize != 64:
            print("Only wordsize of 64-bit supported.")
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% PRESENT w={}"
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            s = ["S{}".format(i) for i in range(rounds + 1)]
            p = ["P{}".format(i) for i in range(rounds)]

            # w = weight
            w = ["w{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, s, wordsize)
            stpcommands.setupVariables(stp_file, p, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            for i in range(rounds):
                self.setupPresentRound(stp_file, s[i], p[i], s[i+1], 
                                      w[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, s, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, s[0], s[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #5
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file for Ascon.
        """
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        sboxsize = 5 # TODO: support arbitrary sizes
        capacity = 0
        rate = (wordsize * sboxsize) - capacity

        if "rate" in parameters:
            rate = parameters["rate"]

        if "capacity" in parameters:
            capacity = parameters["capacity"]

        assert (rate + capacity) == wordsize * sboxsize

        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% Ascon w={} rate={} "
                           "capacity={} round={}\n\n\n".format(wordsize,
                                                               rate, capacity,
                                                               rounds))

            # Setup variables
            # 5 x wordsize state
            s = ["s{}{}".format(x, i) for i in range(rounds+1)
                 for x in range(sboxsize)]

            # Output after S-box Linear part 1
            a = ["a{}{}".format(x, i) for i in range(rounds+1)
                 for x in range(sboxsize)]
            # Output after S-box Non-Linear part
            b = ["b{}{}".format(x, i) for i in range(rounds+1)
                 for x in range(sboxsize)]
            # Output after S-box Linear part 2
            c = ["c{}{}".format(x, i) for i in range(rounds+1)
                 for x in range(sboxsize)]


            # Inputs/Output to the S-box
            xin = ["inx{}{}{}".format(y, z, i) for i in range(rounds)
                   for y in range(sboxsize) for z in range (wordsize)]
            xout = ["outx{}{}{}".format(y, z, i) for i in range(rounds)
                    for y in range(sboxsize) for z in range (wordsize)]
            andout = ["andout{}{}{}".format(y, z, i) for i in range(rounds)
                      for y in range(sboxsize) for z in range (wordsize)]

	        # w = weight
            w = ["w{}".format(i) for i in range(rounds)]
            tmp = ["tmp{}{}{}".format(y, z, i) for i in range(rounds)
                   for y in range(sboxsize) for z in range (wordsize)]

            stpcommands.setupVariables(stp_file, s, wordsize)
            stpcommands.setupVariables(stp_file, a, wordsize)
            stpcommands.setupVariables(stp_file, b, wordsize)
            stpcommands.setupVariables(stp_file, c, wordsize)
            stpcommands.setupVariables(stp_file, w, 16)
            stpcommands.setupVariables(stp_file, tmp, sboxsize)
            stpcommands.setupWeightComputationSum(stp_file, weight, w, wordsize)
            stpcommands.setupVariables(stp_file, xin, sboxsize)
            stpcommands.setupVariables(stp_file, xout, sboxsize)
            stpcommands.setupVariables(stp_file, andout, sboxsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, s, wordsize)

            # Fix variables for capacity, only works if rate/capacity is
            # multiple of wordsize.
            for i in range(rate // wordsize, (rate + capacity) // wordsize):
                stpcommands.assertVariableValue(stp_file, s[i],
                                                "0hex{}".format("0"*(wordsize // 4)))

            for rnd in range(rounds):
                self.setupAsconRound(stp_file, rnd, s, a, b, c, wordsize, tmp,
                                     w, xin, xout, andout)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #6
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SPARX with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% SPARX w={}"
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            # x0, x1 = left, y0, y1 = right
            x0 = ["X0{}".format(i) for i in range(rounds + 1)]
            x1 = ["X1{}".format(i) for i in range(rounds + 1)]
            x0_after_A0 = ["X0A0{}".format(i) for i in range(rounds)]
            x1_after_A0 = ["X1A0{}".format(i) for i in range(rounds)]
            x0_after_A1 = ["X0A1{}".format(i) for i in range(rounds)]
            x1_after_A1 = ["X1A1{}".format(i) for i in range(rounds)]
            x0_after_A2 = ["X0A2{}".format(i) for i in range(rounds)]
            x1_after_A2 = ["X1A2{}".format(i) for i in range(rounds)]
            x0_after_L = ["X0L{}".format(i) for i in range(rounds)]
            x1_after_L = ["X1L{}".format(i) for i in range(rounds)]
            y0 = ["Y0{}".format(i) for i in range(rounds + 1)]
            y1 = ["Y1{}".format(i) for i in range(rounds + 1)]
            y0_after_A0 = ["Y0A0{}".format(i) for i in range(rounds)]
            y1_after_A0 = ["Y1A0{}".format(i) for i in range(rounds)]
            y0_after_A1 = ["Y0A1{}".format(i) for i in range(rounds)]
            y1_after_A1 = ["Y1A1{}".format(i) for i in range(rounds)]
            y0_after_A2 = ["Y0A2{}".format(i) for i in range(rounds)]
            y1_after_A2 = ["Y1A2{}".format(i) for i in range(rounds)]

            # w = weight
            w = ["w{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x0, wordsize)
            stpcommands.setupVariables(stp_file, x1, wordsize)
            stpcommands.setupVariables(stp_file, x0_after_A0, wordsize)
            stpcommands.setupVariables(stp_file, x1_after_A0, wordsize)
            stpcommands.setupVariables(stp_file, x0_after_A1, wordsize)
            stpcommands.setupVariables(stp_file, x1_after_A1, wordsize)
            stpcommands.setupVariables(stp_file, x0_after_A2, wordsize)
            stpcommands.setupVariables(stp_file, x1_after_A2, wordsize)
            stpcommands.setupVariables(stp_file, x0_after_L, wordsize)
            stpcommands.setupVariables(stp_file, x1_after_L, wordsize)
            stpcommands.setupVariables(stp_file, y0, wordsize)
            stpcommands.setupVariables(stp_file, y1, wordsize)
            stpcommands.setupVariables(stp_file, y0_after_A0, wordsize)
            stpcommands.setupVariables(stp_file, y1_after_A0, wordsize)
            stpcommands.setupVariables(stp_file, y0_after_A1, wordsize)
            stpcommands.setupVariables(stp_file, y1_after_A1, wordsize)
            stpcommands.setupVariables(stp_file, y0_after_A2, wordsize)
            stpcommands.setupVariables(stp_file, y1_after_A2, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            for i in range(rounds):
                self.setupSPARXRound(
                    stp_file, x0[i], x1[i], y0[i], y1[i], x0_after_A0[i],
                    x1_after_A0[i], x0_after_A1[i], x1_after_A1[i],
                    x0_after_A2[i], x1_after_A2[i], x0_after_L[i],
                    x1_after_L[i], y0_after_A0[i], y1_after_A0[i],
                    y0_after_A1[i], y1_after_A1[i], y0_after_A2[i],
                    y1_after_A2[i], x0[i + 1], x1[i + 1], y0[i + 1], y1[i + 1],
                    w[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x0 + x1 + y0 + y1, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x0[0], x0[rounds])
                stpcommands.assertVariableValue(stp_file, x1[0], x1[rounds])
                stpcommands.assertVariableValue(stp_file, y0[0], y0[rounds])
                stpcommands.assertVariableValue(stp_file, y1[0], y1[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #7
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for PRINCE with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if wordsize != 4:
            print("PRINCE only supports a wordsize of 4 bits.")
            exit(1)

        if (rounds - 1) % 2 != 0:
            print(
                "PRINCE only supports a multiple of 2 as the number of rounds."
            )
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% Prince w={}"
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            # State is represented as nibbles
            # 0 4  8 12
            # 1 5  9 13
            # 2 6 10 14
            # 3 7 11 15

            sb = [
                "SB{}r{}".format(j, i) for i in range(rounds + 1)
                for j in range(16)
            ]
            sr = [
                "SR{}r{}".format(j, i) for i in range(rounds)
                for j in range(16)
            ]
            mc = [
                "MC{}r{}".format(j, i) for i in range(rounds)
                for j in range(16)
            ]

            # wn = weight of each S-box
            wn = [
                "wn{}r{}".format(j, i) for i in range(rounds + 1)
                for j in range(16)
            ]  # One Extra for middle round

            stpcommands.setupVariables(stp_file, sb, wordsize)
            stpcommands.setupVariables(stp_file, sr, wordsize)
            stpcommands.setupVariables(stp_file, mc, wordsize)
            stpcommands.setupVariables(stp_file, wn, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, wn, wordsize)

            # Forward rounds
            for rnd in range(rounds // 2):
                si = 16 * rnd
                ei = 16 * (rnd + 1)
                self.setupPrinceForwardRound(stp_file, sb[si:ei], sr[si:ei],
                                             mc[si:ei], sb[ei:ei + 16],
                                             wn[si:ei], wordsize)

            # Middle round
            si = 16 * (rounds // 2)
            ei = 16 * ((rounds // 2) + 1)
            self.setupPrinceMiddleRound(stp_file, sb[si:ei], sr[si:ei],
                                        mc[si:ei], sb[ei:ei + 16], wn[si:ei],
                                        wn[ei:ei + 16], wordsize)

            # Backward round
            for rnd in range(rounds // 2 + 1, rounds):
                si = 16 * rnd
                ei = 16 * (rnd + 1)
                self.setupPrinceBackwardRound(stp_file, sb[si:ei], sr[si:ei],
                                              mc[si:ei], sb[ei:ei + 16],
                                              wn[si + 16:ei + 16], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, sb, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, sb[0], sb[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for ChasKey
        with the given parameters.
        """
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        self.num_messages = parameters["nummessages"]

        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% ChasKeyMac w={} rounds={}"
                           "\n\n\n".format(wordsize, rounds))

            # Setup variables
            # state = v0, v1, v2, v3
            # intermediate values = a0, a1, a2, a3
            v0 = ["v0{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v1 = ["v1{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v2 = ["v2{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v3 = ["v3{}".format(i) for i in range((rounds + 1) * self.num_messages)]

            # w = weight of each modular addition
            w0 = ["w0{}".format(i) for i in range(rounds * self.num_messages)]
            w1 = ["w1{}".format(i) for i in range(rounds * self.num_messages)]

            stpcommands.setupVariables(stp_file, v0, wordsize)
            stpcommands.setupVariables(stp_file, v1, wordsize)
            stpcommands.setupVariables(stp_file, v2, wordsize)
            stpcommands.setupVariables(stp_file, v3, wordsize)
            stpcommands.setupVariables(stp_file, w0, wordsize)
            stpcommands.setupVariables(stp_file, w1, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, w0 + w1, wordsize, 1)

            #Minimize Weight in middle rounds
            #stpcommands.limitWeight(stp_file, 10, w0[2:4] + w1[2:4], wordsize, 1)

            for i in range(rounds):
                self.setupChasKeyRound(stp_file, i, v0[i], v1[i], v2[i], v3[i],
                                       v0[i + 1], v1[i + 1], v2[i + 1], v3[i + 1],
                                       w0[i], w1[i], wordsize)

            # Message Collision
            stpcommands.assertNonZero(stp_file, v0 + v1 + v2 + v3, wordsize)
            # zeroString = "0hex" + "0"*(wordsize / 4)
            # stpcommands.assertVariableValue(stp_file, v0[rounds], zeroString)
            # stpcommands.assertVariableValue(stp_file, v1[rounds], zeroString)
            # stpcommands.assertVariableValue(stp_file, v2[rounds], zeroString)
            # stpcommands.assertVariableValue(stp_file, v3[rounds], zeroString)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #9
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file for SIMON.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        # Replace with custom if set in parameters.
        if "rotationconstants" in parameters:
            self.rot_alpha = parameters["rotationconstants"][0] 
            self.rot_beta = parameters["rotationconstants"][1]
            self.rot_gamma = parameters["rotationconstants"][2]

        self.num_messages = parameters["nummessages"]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% Simon w={} alpha={} beta={}"
                      " gamma={} rounds={}\n\n\n".format(wordsize,
                                                         self.rot_alpha,
                                                         self.rot_beta,
                                                         self.rot_gamma,
                                                         rounds))
            stp_file.write(header)

            # Setup key
            key = ["key{}".format(i) for i in range(rounds + 1)]
            tmp_key = ["tmpkey{}".format(i) for i in range(rounds + 1)]

            stpcommands.setupVariables(stp_file, key, wordsize)
            stpcommands.setupVariables(stp_file, tmp_key, wordsize)

            #TODO Add constant addition
            self.setupKeySchedule(stp_file, key, tmp_key, rounds, wordsize)

            # Setup variables
            # x = left, y = right
            for msg in range(self.num_messages):
                x = ["x{}r{}".format(msg, i) for i in range(rounds + 1)]
                y = ["y{}r{}".format(msg, i) for i in range(rounds + 1)]
                and_out = ["andout{}r{}".format(msg, i) for i in range(rounds + 1)]
                stpcommands.setupVariables(stp_file, x, wordsize)
                stpcommands.setupVariables(stp_file, y, wordsize)
                stpcommands.setupVariables(stp_file, and_out, wordsize)

                #Setup Rounds
                for i in range(rounds):
                    self.setupSimonRound(stp_file, x[i], y[i], x[i+1], y[i+1],
                                         and_out[i], key[i], wordsize)

            #Differences between x_0 and x_i
            for msg in range(1, self.num_messages):
                delta_x = ["dx{}r{}".format(msg, i) for i in range(rounds + 1)]
                delta_y = ["dy{}r{}".format(msg, i) for i in range(rounds + 1)]
                stpcommands.setupVariables(stp_file, delta_x, wordsize)
                stpcommands.setupVariables(stp_file, delta_y, wordsize)
                for i in range(rounds + 1):
                    stp_file.write("ASSERT({} = BVXOR({}, {}));\n".format(
                        delta_x[i], "x0r{}".format(i),
                        "x{}r{}".format(msg, i)))
                    stp_file.write("ASSERT({} = BVXOR({}, {}));\n".format(
                        delta_y[i], "y0r{}".format(i),
                        "y{}r{}".format(msg, i)))

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #10
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SIMON with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        # Replace with custom if set in parameters.
        if "rotationconstants" in parameters:
            self.rot_alpha = parameters["rotationconstants"][0]
            self.rot_beta = parameters["rotationconstants"][1]
            self.rot_gamma = parameters["rotationconstants"][2]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% Simon w={} alpha={} beta={}"
                      " gamma={} rounds={}\n\n\n".format(wordsize,
                                                         self.rot_alpha,
                                                         self.rot_beta,
                                                         self.rot_gamma,
                                                         rounds))
            stp_file.write(header)

            # Setup variables
            # x = left, y = right
            x = ["x{}".format(i) for i in range(rounds + 1)]
            y = ["y{}".format(i) for i in range(rounds + 1)]
            and_out = ["andout{}".format(i) for i in range(rounds + 1)]

            # w = weight
            w = ["w{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, and_out, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            for i in range(rounds):
                self.setupSimonRound(stp_file, x[i], y[i], x[i+1], y[i+1],
                                     and_out[i], w[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x + y, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])
                stpcommands.assertVariableValue(stp_file, y[0], y[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #11
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SPARX with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% SPARX w={}"
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            # x0, x1 = left, y0, y1 = right
            x0 = ["X0{}".format(i) for i in range(rounds + 1)]
            x1 = ["X1{}".format(i) for i in range(rounds + 1)]
            x0_after_A = ["X0A{}".format(i) for i in range(rounds + 1)]
            x1_after_A = ["X1A{}".format(i) for i in range(rounds + 1)]
            x0_after_L = ["X0L{}".format(i) for i in range(rounds + 1)]
            x1_after_L = ["X1L{}".format(i) for i in range(rounds + 1)]
            y0 = ["Y0{}".format(i) for i in range(rounds + 1)]
            y1 = ["Y1{}".format(i) for i in range(rounds + 1)]
            y0_after_A = ["Y0A{}".format(i) for i in range(rounds + 1)]
            y1_after_A = ["Y1A{}".format(i) for i in range(rounds + 1)]

            # w = weight
            wleft = ["wl{}".format(i) for i in range(rounds)]
            wright = ["wr{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x0, wordsize)
            stpcommands.setupVariables(stp_file, x1, wordsize)
            stpcommands.setupVariables(stp_file, x0_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x1_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x0_after_L, wordsize)
            stpcommands.setupVariables(stp_file, x1_after_L, wordsize)
            stpcommands.setupVariables(stp_file, y0, wordsize)
            stpcommands.setupVariables(stp_file, y1, wordsize)
            stpcommands.setupVariables(stp_file, y0_after_A, wordsize)
            stpcommands.setupVariables(stp_file, y1_after_A, wordsize)
            stpcommands.setupVariables(stp_file, wleft, wordsize)
            stpcommands.setupVariables(stp_file, wright, wordsize)

            # Ignore MSB
            stpcommands.setupWeightComputation(stp_file, weight,
                                               wleft + wright, wordsize, 1)

            for i in range(rounds):

                if i < 2:
                    if ((i + 1) % 2) == 0:
                        #do round function left (SPECKEY)
                        self.setupSPECKEYRound(stp_file, x0[i], x1[i],
                                               x0_after_A[i], x1_after_A[i],
                                               wleft[i], wordsize)

                        #do round function right (SPECKEY)
                        self.setupSPECKEYRound(stp_file, y0[i], y1[i],
                                               y0_after_A[i], y1_after_A[i],
                                               wright[i], wordsize)

                        #every step do L-box and feistel
                        self.setupSPARXRound(stp_file, x0_after_A[i],
                                             x1_after_A[i], y0_after_A[i],
                                             y1_after_A[i], x0_after_L[i],
                                             x1_after_L[i], x0[i + 1],
                                             x1[i + 1], y0[i + 1], y1[i + 1])
                    else:
                        #do round function left (SPECKEY)
                        self.setupSPECKEYRound(stp_file, x0[i], x1[i],
                                               x0[i + 1], x1[i + 1], wleft[i],
                                               wordsize)

                        #do round function right (SPECKEY)
                        self.setupSPECKEYRound(stp_file, y0[i], y1[i],
                                               y0[i + 1], y1[i + 1], wright[i],
                                               wordsize)
                else:
                    if ((i - 1) % self.rounds_per_step) == 0:
                        #do round function left (SPECKEY)
                        self.setupSPECKEYRound(stp_file, x0[i], x1[i],
                                               x0_after_A[i], x1_after_A[i],
                                               wleft[i], wordsize)

                        #do round function right (SPECKEY)
                        self.setupSPECKEYRound(stp_file, y0[i], y1[i],
                                               y0_after_A[i], y1_after_A[i],
                                               wright[i], wordsize)

                        #every step do L-box and feistel
                        self.setupSPARXRound(stp_file, x0_after_A[i],
                                             x1_after_A[i], y0_after_A[i],
                                             y1_after_A[i], x0_after_L[i],
                                             x1_after_L[i], x0[i + 1],
                                             x1[i + 1], y0[i + 1], y1[i + 1])
                    else:
                        #do round function left (SPECKEY)
                        self.setupSPECKEYRound(stp_file, x0[i], x1[i],
                                               x0[i + 1], x1[i + 1], wleft[i],
                                               wordsize)

                        #do round function right (SPECKEY)
                        self.setupSPECKEYRound(stp_file, y0[i], y1[i],
                                               y0[i + 1], y1[i + 1], wright[i],
                                               wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x0 + x1 + y0 + y1, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x0[0], x0[rounds])
                stpcommands.assertVariableValue(stp_file, x1[0], x1[rounds])
                stpcommands.assertVariableValue(stp_file, y0[0], y0[rounds])
                stpcommands.assertVariableValue(stp_file, y1[0], y1[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #12
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for BAT nibble with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds   = parameters["rounds"]
        weight   = parameters["sweight"]
        if wordsize == 32:
            p = [7, 4, 1, 6, 3, 0, 5, 2]
        elif wordsize == 64:
            p = [14, 15, 8, 9, 2, 3, 12, 13, 6, 7, 0, 1, 10, 11, 4, 5]
        else:
            raise Exception("Wrong wordsize!")
        self.PERM = GenPerm.GenNibblePerms(wordsize, p)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP: BAT linear actsbox\n"
                      "% w = {} alpha = {} beta = {}\n"
                      "% rounds = {}\n\n".format(
                        wordsize,
                        self.rot_alpha, self.rot_beta,
                        rounds))
            stp_file.write(header)

            # Setup variables
            # x = left, y = right
            x = ["x{}".format(i) for i in range(rounds + 1)]
            y = ["y{}".format(i) for i in range(rounds + 1)]
            in_S = ["inS{}".format(i) for i in range(rounds)]
            bef_P = ["befP{}".format(i) for i in range(rounds)]
            aft_P = ["aftP{}".format(i) for i in range(rounds)]

            # w = weight
            w = ["sumw{}".format(i) for i in range(rounds)]
            w_i_0 = ["wiR{}".format(i) for i in range(rounds)]
            w_i_1 = ["wi1R{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, in_S, wordsize)
            stpcommands.setupVariables(stp_file, bef_P, wordsize)
            stpcommands.setupVariables(stp_file, aft_P, wordsize)
            stpcommands.setupVariables(stp_file, w, 16)
            stpcommands.setupVariables(stp_file, w_i_0, wordsize // 4)
            stpcommands.setupVariables(stp_file, w_i_1, wordsize // 4)

            stpcommands.setupWeightComputationSum(stp_file, weight, w, 16)

            self.SBOX_ACT_ASSERT(stp_file)

            for i in range(rounds):
                self.setupRound(stp_file,
                                     x[i], y[i],
                                     x[i+1], y[i+1],
                                     in_S[i],
                                     bef_P[i], aft_P[i],
                                     w[i], w_i_0[i], w_i_1[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, [x[0], y[0]], wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])
                stpcommands.assertVariableValue(stp_file, y[0], y[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #13
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for NOEKEON with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% NOEKEON w={}"
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            #
            a0 = ["A0{}".format(i) for i in range(rounds + 1)]
            a1 = ["A1{}".format(i) for i in range(rounds + 1)]
            a2 = ["A2{}".format(i) for i in range(rounds + 1)]
            a3 = ["A3{}".format(i) for i in range(rounds + 1)]

            theta0 = ["T0{}".format(i) for i in range(rounds)]
            theta1 = ["T1{}".format(i) for i in range(rounds)]
            theta2 = ["T2{}".format(i) for i in range(rounds)]
            theta3 = ["T3{}".format(i) for i in range(rounds)]

            pi10 = ["PI10{}".format(i) for i in range(rounds)]
            pi11 = ["PI11{}".format(i) for i in range(rounds)]
            pi12 = ["PI12{}".format(i) for i in range(rounds)]
            pi13 = ["PI13{}".format(i) for i in range(rounds)]

            gamma0 = ["G0{}".format(i) for i in range(rounds)]
            gamma1 = ["G1{}".format(i) for i in range(rounds)]
            gamma2 = ["G2{}".format(i) for i in range(rounds)]
            gamma3 = ["G3{}".format(i) for i in range(rounds)]

            pi20 = ["PI20{}".format(i) for i in range(rounds)]
            pi21 = ["PI21{}".format(i) for i in range(rounds)]
            pi22 = ["PI22{}".format(i) for i in range(rounds)]
            pi23 = ["PI23{}".format(i) for i in range(rounds)]

            # w = weight
            w = ["w{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, a0, wordsize)
            stpcommands.setupVariables(stp_file, a1, wordsize)
            stpcommands.setupVariables(stp_file, a2, wordsize)
            stpcommands.setupVariables(stp_file, a3, wordsize)

            stpcommands.setupVariables(stp_file, theta0, wordsize)
            stpcommands.setupVariables(stp_file, theta1, wordsize)
            stpcommands.setupVariables(stp_file, theta2, wordsize)
            stpcommands.setupVariables(stp_file, theta3, wordsize)

            stpcommands.setupVariables(stp_file, pi10, wordsize)
            stpcommands.setupVariables(stp_file, pi11, wordsize)
            stpcommands.setupVariables(stp_file, pi12, wordsize)
            stpcommands.setupVariables(stp_file, pi13, wordsize)

            stpcommands.setupVariables(stp_file, pi20, wordsize)
            stpcommands.setupVariables(stp_file, pi21, wordsize)
            stpcommands.setupVariables(stp_file, pi22, wordsize)
            stpcommands.setupVariables(stp_file, pi23, wordsize)

            stpcommands.setupVariables(stp_file, gamma0, wordsize)
            stpcommands.setupVariables(stp_file, gamma1, wordsize)
            stpcommands.setupVariables(stp_file, gamma2, wordsize)
            stpcommands.setupVariables(stp_file, gamma3, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize * 4)

            stpcommands.setupWeightComputation(stp_file, weight, w,
                                               wordsize * 4)

            for i in range(rounds):
                self.setupNoekeonRound(stp_file, a0[i], a1[i], a2[i], a3[i],
                                       theta0[i], theta1[i], theta2[i],
                                       theta3[i], gamma0[i], gamma1[i],
                                       gamma2[i], gamma3[i], pi10[i], pi11[i],
                                       pi12[i], pi13[i], pi20[i], pi21[i],
                                       pi22[i], pi23[i], a0[i + 1], a1[i + 1],
                                       a2[i + 1], a3[i + 1], w[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, a0 + a1 + a2 + a3, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, a0[0], a0[rounds])
                stpcommands.assertVariableValue(stp_file, a1[0], a1[rounds])
                stpcommands.assertVariableValue(stp_file, a2[0], a2[rounds])
                stpcommands.assertVariableValue(stp_file, a3[0], a3[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #14
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SipHash with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]
        
        self.num_messages = parameters["nummessages"]

        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% Siphash w={} "
                           "rounds={}\n\n\n".format(wordsize, rounds))

            # Setup variables
            # state = v0, v1, v2, v3
            # intermediate values = a0, a1, a2, a3
            v0 = ["v0{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v1 = ["v1{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v2 = ["v2{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v3 = ["v3{}".format(i) for i in range((rounds + 1) * self.num_messages)]

            a0 = ["a0{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            a1 = ["a1{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            a2 = ["a2{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            a3 = ["a3{}".format(i) for i in range((rounds + 1) * self.num_messages)]

            m = ["m{}".format(i) for i in range(self.num_messages)]

            # w = weight of each modular addition
            w0 = ["w0{}".format(i) for i in range(rounds * self.num_messages)]
            w1 = ["w1{}".format(i) for i in range(rounds * self.num_messages)]
            w2 = ["w2{}".format(i) for i in range(rounds * self.num_messages)]
            w3 = ["w3{}".format(i) for i in range(rounds * self.num_messages)]

            stpcommands.setupVariables(stp_file, v0 + v1 + v2 + v3, wordsize)
            stpcommands.setupVariables(stp_file, a0 + a1 + a2 + a3, wordsize)
            stpcommands.setupVariables(stp_file, w0 + w1 + w2 + w3, wordsize)
            stpcommands.setupVariables(stp_file, m, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, w0 + w1 + w2 + w3,
                                               wordsize, 1)

            for block in range(self.num_messages):
                self.setupSipBlock(stp_file, block, rounds, m, v0, v1, v2, v3,
                                   a0, a1, a2, a3, w0, w1, w2, w3, wordsize)

            # TODO: There are many different attack scenarios interesting here,
            #       but no interface exists at the moment to support this
            #       without using different "ciphers".

            ## Uncomment to search for internal collision
            # zero_string = "0hex" + "0"*(wordsize / 4)
            # stpcommands.assertVariableValue(stp_file, v0[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v1[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v0[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v1[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[0], zero_string)
            # stpcommands.assertNonZero(stp_file, m, wordsize)
            # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds],
            #                v2[rounds], v3[rounds], wordsize))

            ## Uncomment to search for internal collision for a single block
            # zero_string = "0hex" + "0"*(wordsize / 4)
            # stpcommands.assertVariableValue(stp_file, v0[rounds], zero_string)
            # #stpcommands.assertVariableValue(stp_file, v1[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v0[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v1[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[0], v1[rounds])
            # stpcommands.assertVariableValue(stp_file, m[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, m[1], zero_string)
            # stpcommands.assertNonZero(stp_file, [v3[0]], wordsize)
            # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds],
            #                v2[rounds], v3[rounds], wordsize))

            ## Uncomment to search for Key Collisions
            # stpcommands.assertNonZero(stp_file, [v0[0], v1[0]], wordsize)
            # stpcommands.assertVariableValue(stp_file, v0[0], v3[0])
            # stpcommands.assertVariableValue(stp_file, v1[0], v2[0])
            # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds],
            #                v2[rounds], v3[rounds], wordsize))

            ## Uncomment to search for message collision
            stpcommands.assertNonZero(stp_file, m, wordsize)
            zero_string = "0hex" + "0"*(wordsize / 4)
            stpcommands.assertVariableValue(stp_file, v0[0], zero_string)
            stpcommands.assertVariableValue(stp_file, v1[0], zero_string)
            stpcommands.assertVariableValue(stp_file, v2[0], zero_string)
            stpcommands.assertVariableValue(stp_file, v3[0], zero_string)
            stp_file.write(self.getStringForCollision(v0[rounds*self.num_messages],
                                                      v1[rounds*self.num_messages],
                                                      v2[rounds*self.num_messages],
                                                      v3[rounds*self.num_messages],
                                                      wordsize))

            ## Uncomment to search for characteristic / distinguisher
            # for i in m:
            #     zero_string = "0hex" + "0"*(wordsize / 4)
            #     stpcommands.assertVariableValue(stp_file, i, zero_string)

            # stpcommands.assertNonZero(stp_file, v0 + v1 + v2 + v3, wordsize)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #15
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file for SIMON.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        # Replace with custom if set in parameters.
        if "rotationconstants" in parameters:
            self.rot_alpha = parameters["rotationconstants"][0]
            self.rot_beta = parameters["rotationconstants"][1]
            self.rot_gamma = parameters["rotationconstants"][2]

        self.num_messages = parameters["nummessages"]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% Simon w={} alpha={} beta={}"
                      " gamma={} rounds={}\n\n\n".format(
                          wordsize, self.rot_alpha, self.rot_beta,
                          self.rot_gamma, rounds))
            stp_file.write(header)

            # Setup key
            key = ["key{}".format(i) for i in range(rounds + 1)]
            tmp_key = ["tmpkey{}".format(i) for i in range(rounds + 1)]

            stpcommands.setupVariables(stp_file, key, wordsize)
            stpcommands.setupVariables(stp_file, tmp_key, wordsize)

            #TODO Add constant addition
            self.setupKeySchedule(stp_file, key, tmp_key, rounds, wordsize)

            # Setup variables
            # x = left, y = right
            for msg in range(self.num_messages):
                x = ["x{}r{}".format(msg, i) for i in range(rounds + 1)]
                y = ["y{}r{}".format(msg, i) for i in range(rounds + 1)]
                and_out = [
                    "andout{}r{}".format(msg, i) for i in range(rounds + 1)
                ]
                stpcommands.setupVariables(stp_file, x, wordsize)
                stpcommands.setupVariables(stp_file, y, wordsize)
                stpcommands.setupVariables(stp_file, and_out, wordsize)

                #Setup Rounds
                for i in range(rounds):
                    self.setupSimonRound(stp_file, x[i], y[i], x[i + 1],
                                         y[i + 1], and_out[i], key[i],
                                         wordsize)

            #Differences between x_0 and x_i
            for msg in range(1, self.num_messages):
                delta_x = ["dx{}r{}".format(msg, i) for i in range(rounds + 1)]
                delta_y = ["dy{}r{}".format(msg, i) for i in range(rounds + 1)]
                stpcommands.setupVariables(stp_file, delta_x, wordsize)
                stpcommands.setupVariables(stp_file, delta_y, wordsize)
                for i in range(rounds + 1):
                    stp_file.write("ASSERT({} = BVXOR({}, {}));\n".format(
                        delta_x[i], "x0r{}".format(i), "x{}r{}".format(msg,
                                                                       i)))
                    stp_file.write("ASSERT({} = BVXOR({}, {}));\n".format(
                        delta_y[i], "y0r{}".format(i), "y{}r{}".format(msg,
                                                                       i)))

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #16
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a differential trail for Gimli with
        the given parameters.
        """
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if "rotationconstants" in parameters:
            self.d = parameters["rotationconstants"][0]
            self.e = parameters["rotationconstants"][1]
            self.f = parameters["rotationconstants"][2]


        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% Gimli w={}"
                           "rounds={}\n\n\n".format(wordsize, rounds))

            # Setup variables
            x = ["x{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)]
            xsb = ["xsb{}r{}".format(j, i) for i in range(rounds) for j in range(4)]
            y = ["y{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)]
            ysb = ["ysb{}r{}".format(j, i) for i in range(rounds) for j in range(4)]
            z = ["z{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)]
            zsb = ["zsb{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)]
            w = ["rw{}".format(i) for i in range(rounds)]
            wp = ["rwp{}r{}".format(j, i) for i in range(rounds) for j in range(4)]

            xtmp = ["xtmp{}r{}".format(j, i) for i in range(rounds) for j in range(4)]
            ytmp = ["ytmp{}r{}".format(j, i) for i in range(rounds) for j in range(4)]
            ztmp = ["ztmp{}r{}".format(j, i) for i in range(rounds) for j in range(4)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, z, wordsize)
            stpcommands.setupVariables(stp_file, xtmp, wordsize)
            stpcommands.setupVariables(stp_file, ytmp, wordsize)
            stpcommands.setupVariables(stp_file, ztmp, wordsize)
            stpcommands.setupVariables(stp_file, xsb, wordsize)
            stpcommands.setupVariables(stp_file, ysb, wordsize)
            stpcommands.setupVariables(stp_file, zsb, wordsize)
            stpcommands.setupVariables(stp_file, wp, wordsize)
            stpcommands.setupVariables(stp_file, w, 16)

            for rnd in range(rounds):
                stp_file.write(stpcommands.getWeightString(wp[4*rnd:4*rnd + 4], 
                               wordsize, 0, w[rnd]) + "\n")

            stpcommands.setupWeightComputationSum(stp_file, weight, w, wordsize)

            # Rounds
            for rnd in range(rounds):
                if ((rnd) & 3) == 0:
                    # Small Swap
                    for perm in range(4):
                        self.setupRound(stp_file,
                                        x[4*rnd + perm],
                                        y[4*rnd + perm],
                                        z[4*rnd + perm],
                                        xtmp[4*rnd + perm],
                                        ytmp[4*rnd + perm],
                                        ztmp[4*rnd + perm],
                                        xsb[4*rnd + perm],
                                        ysb[4*rnd + perm],
                                        zsb[4*rnd + perm],
                                        wp[4*rnd + perm],
                                        wordsize)

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1)], xtmp[4*rnd + 1]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1)], ytmp[4*rnd]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1)], ztmp[4*rnd]))

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 1], xtmp[4*rnd]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 1], ytmp[4*rnd + 1]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 1], ztmp[4*rnd + 1]))

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 2], xtmp[4*rnd + 3]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 2], ytmp[4*rnd + 2]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 2], ztmp[4*rnd + 2]))

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 3], xtmp[4*rnd + 2]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 3], ytmp[4*rnd + 3]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 3], ztmp[4*rnd + 3]))

                elif ((rnd) & 3) == 2:
                    # Big Swap
                    for perm in range(4):
                        self.setupRound(stp_file,
                                        x[4*rnd + perm],
                                        y[4*rnd + perm],
                                        z[4*rnd + perm],
                                        xtmp[4*rnd + perm],
                                        ytmp[4*rnd + perm],
                                        ztmp[4*rnd + perm],
                                        xsb[4*rnd + perm],
                                        ysb[4*rnd + perm],
                                        zsb[4*rnd + perm],
                                        wp[4*rnd + perm],
                                        wordsize)

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1)], xtmp[4*rnd + 2]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1)], ytmp[4*rnd]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1)], ztmp[4*rnd]))

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 1], xtmp[4*rnd + 3]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 1], ytmp[4*rnd + 1]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 1], ztmp[4*rnd + 1]))

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 2], xtmp[4*rnd]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 2], ytmp[4*rnd + 2]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 2], ztmp[4*rnd + 2]))

                    stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 3], xtmp[4*rnd + 1]))
                    stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 3], ytmp[4*rnd + 3]))
                    stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 3], ztmp[4*rnd + 3]))
                else:
                    # No Swap
                    for perm in range(4):
                        self.setupRound(stp_file,
                                        x[4*rnd + perm],
                                        y[4*rnd + perm],
                                        z[4*rnd + perm],
                                        x[4*(rnd + 1) + perm],
                                        y[4*(rnd + 1) + perm],
                                        z[4*(rnd + 1) + perm],
                                        xsb[4*rnd + perm],
                                        ysb[4*rnd + perm],
                                        zsb[4*rnd + perm],
                                        wp[4*rnd + perm],
                                        wordsize)


            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x + y + z, wordsize)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #17
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for trifle with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        self.rounds = rounds
        weight = parameters["sweight"]

        if wordsize != 128:
            print("Only wordsize of 128-bit supported.")
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% trifle w={} "
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            """            
            x(r) is a variable modeling the 128-bit input difference to the (r+1)'th round
            y(r) is a variable modeling the 128-bit output difference from SubNibbles of the (r+1)'th round            

            Example:
            x0 = x0[127, ..., 0]            
            x0[3:0]     :   nibble 0
            x0[127:124] :   nibble 31                        
            """
            # note that the last integer index in the name of a variable \
            # always shows the round's number in the CryptoSMT
            x = ["x%d" % i for i in range(rounds + 1)]
            y = ["y%d" % i for i in range(rounds)]
            k = ["k%d" % i for i in range(rounds + 1)]
            # w = weight
            w = ["w%d" % i for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, k, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            for i in range(rounds):
                self.setupTrifleRound(stp_file, x[i], y[i], k[i], k[i + 1],
                                      x[i + 1], w[i], wordsize)
            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, [x[0]], wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])
                stpcommands.assertVariableValue(stp_file, k[0], k[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)
        return
Example #18
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for CRAFT with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if wordsize != 64:
            print("Only wordsize of 64-bit supported.")
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% CRAFT w={} "
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            """
            x(roundNumber), other variables are like this one. 
            x(r) is a variable modeling the 64-bit input difference to the (r+1)'th round
            y(r) is a variable modeling the 64-bit output difference from MixColumn of the (r+1)'th round
            z(r) is a variable modeling the 64-bit output difference from PermuteNibble of the (r+1)'th round
            x(r+1) is a variable modeling the 64-bit output differenece from the (r+1)'th round
            Example:
            x0 = x0[63, 62, ..., 0]            
            x0[3:0]:     nibble 0
            x0[63:60]:   nibble 15
            It is supposed that the input difference is as bellow:
            [x[3:0], x[7:4], ..., x[63:60]]            
            """
            # note that the last integer index in the name of a variable \
            # always shows the round's number in the CryptoSMT
            x = ["x%d" % i for i in range(2)]
            y = ["y%d" % i for i in range(2)]
            z = ["z%d" % i for i in range(3)]
            # w = weight
            w = ["w%d" % i for i in range(2)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, z, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            for i in [1, 6, 10, 14]:
                self.setupMembership(stp_file, "z0", i)
            for i in [1, 6, 10, 14]:
                self.setupMembership(stp_file, "z2", i)

            for i in range(2):
                self.setupSbox(stp_file, z[i], x[i], w[i], wordsize)
                self.setupMixColumn(stp_file, x[i], y[i], wordsize)
                self.setupPermuteNibble(stp_file, y[i], z[i + 1], wordsize)                        
                

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, [z[0]], wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])                
                
            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)                                

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #19
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SIMON in the
        related-key scenario with the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        # Replace with custom if set in parameters.
        if "rotationconstants" in parameters:
            self.rot_alpha = parameters["rotationconstants"][0]
            self.rot_beta = parameters["rotationconstants"][1]
            self.rot_gamma = parameters["rotationconstants"][2]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% Simon w={} alpha={} beta={}"
                      " gamma={} rounds={}\n\n\n".format(
                          wordsize, self.rot_alpha, self.rot_beta,
                          self.rot_gamma, rounds))
            stp_file.write(header)

            # Setup variable
            # x = left, y = right
            x = ["x{}".format(i) for i in range(rounds + 1)]
            y = ["y{}".format(i) for i in range(rounds + 1)]
            k = ["k{}".format(i) for i in range(rounds)]
            and_out = ["andout{}".format(i) for i in range(rounds + 1)]

            # w = weight
            w = ["w{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, k, wordsize)
            stpcommands.setupVariables(stp_file, and_out, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            #Key Schedule
            self.setupSimonKey(stp_file, k, rounds, wordsize)

            for i in range(rounds):
                self.setupSimonRound(stp_file, x[i], y[i], k[i], x[i + 1],
                                     y[i + 1], and_out[i], w[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x + y, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])
                stpcommands.assertVariableValue(stp_file, y[0], y[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)
        return
Example #20
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for CRAFT with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if wordsize != 64:
            print("Only wordsize of 64-bit supported.")
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% CRAFT w={} "
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            """
            x(roundNumber), other variables are like this one.
            x(r) is a 64-bit variable modeling the 64-bit input difference to the (r+1)'th round
            y(r) is a 64-bit variable modeling the 64-bit output difference from MixColumn of the (r+1)'th round
            z(r) is a 64-bit variable modeling the 64-bit difference after AddRoundkey of the (r+1)'th round
            x(r+1) is a 64-bit variable modeling the 64-bit output differenece from the (r+1)'th round
            Example:
            x0 = x0[63, 62, ..., 0]
            x0[3:0]:     nibble 0
            x0[63:60]:   nibble 15
            """
            # note that the last integer index in the name of a variable \
            # always shows the round's number in the CryptoSMT
            x = ["x%d" % i for i in range(rounds + 1)]
            y = ["y%d" % i for i in range(rounds)]
            z = ["z%d" % i for i in range(rounds)]
            t = ["t0"]
            k0 = ["k0"]
            k1 = ["k1"]
            k2 = ["k2"]
            k3 = ["k3"]
            tk0 = ["tk0"]
            tk1 = ["tk1"]
            tk2 = ["tk2"]
            tk3 = ["tk3"]
            tk = [tk0[0], tk1[0], tk2[0], tk3[0]]
            # w = weight
            w = ["w%d" % i for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, z, wordsize)
            stpcommands.setupVariables(stp_file, tk0, wordsize)
            stpcommands.setupVariables(stp_file, tk1, wordsize)
            stpcommands.setupVariables(stp_file, tk2, wordsize)
            stpcommands.setupVariables(stp_file, tk3, wordsize)
            stpcommands.setupVariables(stp_file, t, wordsize)
            stpcommands.setupVariables(stp_file, k0, wordsize)
            stpcommands.setupVariables(stp_file, k1, wordsize)
            stpcommands.setupVariables(stp_file, k2, wordsize)
            stpcommands.setupVariables(stp_file, k3, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)
            # initialize tweakeys 
            command = self.init_tweakey(k0[0], k1[0], t[0])
            stp_file.write(command)
            # write rounds constraints
            for i in range(rounds):
                self.setupCraftRound(stp_file, x[i], y[i], z[i], tk[(i + 1) % 4], x[i+1],
                                     w[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #21
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for Salsa with
        the given parameters.
        """
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% Salsa w={}"
                           "rounds={}\n\n\n".format(wordsize, rounds))

            # Setup variables
            a = [
                "a{}r{}".format(j, i) for i in range(rounds + 1)
                for j in range(16)
            ]
            b = [
                "b{}r{}".format(j, i) for i in range(rounds) for j in range(16)
            ]
            w = [
                "w{}r{}".format(j, i) for i in range(rounds) for j in range(16)
            ]

            stpcommands.setupVariables(stp_file, a, wordsize)
            stpcommands.setupVariables(stp_file, b, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)

            # Ignore MSB
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize,
                                               1)

            for rnd in range(rounds):
                if rnd % 2 != 0:
                    #Rowround
                    for row in range(4):
                        a_in = [
                            a[(i + row) % 4 + 4 * row + 16 * rnd]
                            for i in range(4)
                        ]
                        a_out = [
                            a[(i + row) % 4 + 4 * row + 16 * (rnd + 1)]
                            for i in range(4)
                        ]
                        tmp_b = [b[i + 4 * row + 16 * rnd] for i in range(4)]
                        tmp_w = [w[i + 4 * row + 16 * rnd] for i in range(4)]
                        self.setupQuarterRound(stp_file, a_in, tmp_b, a_out,
                                               tmp_w, wordsize)
                else:
                    #Columnround
                    for col in range(4):
                        a_in = [
                            a[(i * 4 + 4 * col + col) % 16 + 16 * rnd]
                            for i in range(4)
                        ]
                        a_out = [
                            a[(i * 4 + 4 * col + col) % 16 + 16 * (rnd + 1)]
                            for i in range(4)
                        ]
                        tmp_b = [b[i * 4 + col + 16 * rnd] for i in range(4)]
                        tmp_w = [w[i * 4 + col + 16 * rnd] for i in range(4)]
                        self.setupQuarterRound(stp_file, a_in, tmp_b, a_out,
                                               tmp_w, wordsize)

            #stp_file.write("ASSERT(({}[31:31]) = 0b0);\n".format(a[0]))
            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, a, wordsize)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #22
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for CRAFT with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if wordsize != 64:
            print("Only wordsize of 64-bit supported.")
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% CRAFT w={} "
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            """
            x(roundNumber), other variables are like this one. 
            x(r) is a variable modeling the 64-bit input difference to the (r+1)'th round
            y(r) is a variable modeling the 64-bit output difference from MixColumn of the (r+1)'th round
            z(r) is a variable modeling the 64-bit output difference from PermuteNibble of the (r+1)'th round
            x(r+1) is a variable modeling the 64-bit output differenece from the (r+1)'th round
            Example:
            x0 = x0[63, 62, ..., 0]            
            x0[3:0]:     nibble 0
            x0[63:60]:   nibble 15
            It is supposed that the input difference is as bellow:
            [x[3:0], x[7:4], ..., x[63:60]]            
            """
            # note that the last integer index in the name of a variable \
            # always shows the round's number in the CryptoSMT
            x = ["x%d" % i for i in range(rounds + 1)]
            y = ["y%d" % i for i in range(rounds)]
            z = ["z%d" % i for i in range(rounds)]
            # w = weight
            w = ["w%d" % i for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, z, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            for i in range(rounds):
                self.setupCraftRound(stp_file, x[i], y[i], z[i], x[i+1],
                                     w[i], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, x, wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #23
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SipHash with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        self.num_messages = parameters["nummessages"]

        with open(stp_filename, 'w') as stp_file:
            stp_file.write("% Input File for STP\n% Siphash w={} "
                           "rounds={}\n\n\n".format(wordsize, rounds))

            # Setup variables
            # state = v0, v1, v2, v3
            # intermediate values = a0, a1, a2, a3
            v0 = [
                "v0{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]
            v1 = [
                "v1{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]
            v2 = [
                "v2{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]
            v3 = [
                "v3{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]

            a0 = [
                "a0{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]
            a1 = [
                "a1{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]
            a2 = [
                "a2{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]
            a3 = [
                "a3{}".format(i)
                for i in range((rounds + 1) * self.num_messages)
            ]

            m = ["m{}".format(i) for i in range(self.num_messages)]

            # w = weight of each modular addition
            w0 = ["w0{}".format(i) for i in range(rounds * self.num_messages)]
            w1 = ["w1{}".format(i) for i in range(rounds * self.num_messages)]
            w2 = ["w2{}".format(i) for i in range(rounds * self.num_messages)]
            w3 = ["w3{}".format(i) for i in range(rounds * self.num_messages)]

            stpcommands.setupVariables(stp_file, v0 + v1 + v2 + v3, wordsize)
            stpcommands.setupVariables(stp_file, a0 + a1 + a2 + a3, wordsize)
            stpcommands.setupVariables(stp_file, w0 + w1 + w2 + w3, wordsize)
            stpcommands.setupVariables(stp_file, m, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight,
                                               w0 + w1 + w2 + w3, wordsize, 1)

            for block in range(self.num_messages):
                self.setupSipBlock(stp_file, block, rounds, m, v0, v1, v2, v3,
                                   a0, a1, a2, a3, w0, w1, w2, w3, wordsize)

            # TODO: There are many different attack scenarios interesting here,
            #       but no interface exists at the moment to support this
            #       without using different "ciphers".

            ## Uncomment to search for internal collision
            # zero_string = "0hex" + "0"*(wordsize / 4)
            # stpcommands.assertVariableValue(stp_file, v0[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v1[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v0[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v1[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[0], zero_string)
            # stpcommands.assertNonZero(stp_file, m, wordsize)
            # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds],
            #                v2[rounds], v3[rounds], wordsize))

            ## Uncomment to search for internal collision for a single block
            # zero_string = "0hex" + "0"*(wordsize / 4)
            # stpcommands.assertVariableValue(stp_file, v0[rounds], zero_string)
            # #stpcommands.assertVariableValue(stp_file, v1[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[rounds], zero_string)
            # stpcommands.assertVariableValue(stp_file, v0[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v1[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v2[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, v3[0], v1[rounds])
            # stpcommands.assertVariableValue(stp_file, m[0], zero_string)
            # stpcommands.assertVariableValue(stp_file, m[1], zero_string)
            # stpcommands.assertNonZero(stp_file, [v3[0]], wordsize)
            # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds],
            #                v2[rounds], v3[rounds], wordsize))

            ## Uncomment to search for Key Collisions
            # stpcommands.assertNonZero(stp_file, [v0[0], v1[0]], wordsize)
            # stpcommands.assertVariableValue(stp_file, v0[0], v3[0])
            # stpcommands.assertVariableValue(stp_file, v1[0], v2[0])
            # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds],
            #                v2[rounds], v3[rounds], wordsize))

            ## Uncomment to search for message collision
            stpcommands.assertNonZero(stp_file, m, wordsize)
            zero_string = "0hex" + "0" * (wordsize / 4)
            stpcommands.assertVariableValue(stp_file, v0[0], zero_string)
            stpcommands.assertVariableValue(stp_file, v1[0], zero_string)
            stpcommands.assertVariableValue(stp_file, v2[0], zero_string)
            stpcommands.assertVariableValue(stp_file, v3[0], zero_string)
            stp_file.write(
                self.getStringForCollision(v0[rounds * self.num_messages],
                                           v1[rounds * self.num_messages],
                                           v2[rounds * self.num_messages],
                                           v3[rounds * self.num_messages],
                                           wordsize))

            ## Uncomment to search for characteristic / distinguisher
            # for i in m:
            #     zero_string = "0hex" + "0"*(wordsize / 4)
            #     stpcommands.assertVariableValue(stp_file, i, zero_string)

            # stpcommands.assertNonZero(stp_file, v0 + v1 + v2 + v3, wordsize)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #24
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for SPARX with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% SPARX w={}"
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            x0l = ["X0L{}".format(i) for i in range(rounds + 1)]
            x0r = ["X0R{}".format(i) for i in range(rounds + 1)]
            x1l = ["X1L{}".format(i) for i in range(rounds + 1)]
            x1r = ["X1R{}".format(i) for i in range(rounds + 1)]
            x2l = ["X2L{}".format(i) for i in range(rounds + 1)]
            x2r = ["X2R{}".format(i) for i in range(rounds + 1)]
            x3l = ["X3L{}".format(i) for i in range(rounds + 1)]
            x3r = ["X3R{}".format(i) for i in range(rounds + 1)]

            x0l_after_A = ["X0LA{}".format(i) for i in range(rounds + 1)]
            x0r_after_A = ["X0RA{}".format(i) for i in range(rounds + 1)]
            x1l_after_A = ["X1LA{}".format(i) for i in range(rounds + 1)]
            x1r_after_A = ["X1RA{}".format(i) for i in range(rounds + 1)]
            x2l_after_A = ["X2LA{}".format(i) for i in range(rounds + 1)]
            x2r_after_A = ["X2RA{}".format(i) for i in range(rounds + 1)]
            x3l_after_A = ["X3LA{}".format(i) for i in range(rounds + 1)]
            x3r_after_A = ["X3RA{}".format(i) for i in range(rounds + 1)]

            x0l_after_L = ["LX0L{}".format(i) for i in range(rounds + 1)]
            x0r_after_L = ["LX0R{}".format(i) for i in range(rounds + 1)]
            x1l_after_L = ["LX1L{}".format(i) for i in range(rounds + 1)]
            x1r_after_L = ["LX1R{}".format(i) for i in range(rounds + 1)]

            # w = weight
            wx0 = ["wx0{}".format(i) for i in range(rounds)]
            wx1 = ["wx1{}".format(i) for i in range(rounds)]
            wx2 = ["wx2{}".format(i) for i in range(rounds)]
            wx3 = ["wx3{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x0l, wordsize)
            stpcommands.setupVariables(stp_file, x0r, wordsize)
            stpcommands.setupVariables(stp_file, x1l, wordsize)
            stpcommands.setupVariables(stp_file, x1r, wordsize)
            stpcommands.setupVariables(stp_file, x2l, wordsize)
            stpcommands.setupVariables(stp_file, x2r, wordsize)
            stpcommands.setupVariables(stp_file, x3l, wordsize)
            stpcommands.setupVariables(stp_file, x3r, wordsize)

            stpcommands.setupVariables(stp_file, x0l_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x0r_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x1l_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x1r_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x2l_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x2r_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x3l_after_A, wordsize)
            stpcommands.setupVariables(stp_file, x3r_after_A, wordsize)

            stpcommands.setupVariables(stp_file, x0l_after_L, wordsize)
            stpcommands.setupVariables(stp_file, x0r_after_L, wordsize)
            stpcommands.setupVariables(stp_file, x1l_after_L, wordsize)
            stpcommands.setupVariables(stp_file, x1r_after_L, wordsize)

            stpcommands.setupVariables(stp_file, wx0, wordsize)
            stpcommands.setupVariables(stp_file, wx1, wordsize)
            stpcommands.setupVariables(stp_file, wx2, wordsize)
            stpcommands.setupVariables(stp_file, wx3, wordsize)

            # Ignore MSB
            stpcommands.setupWeightComputation(stp_file, weight,
                                               wx0 + wx1 + wx2 + wx3, wordsize,
                                               1)

            for i in range(rounds):
                if ((i + 1) % self.rounds_per_step) == 0:
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x0l[i], x0r[i],
                                           x0l_after_A[i], x0r_after_A[i],
                                           wx0[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x1l[i], x1r[i],
                                           x1l_after_A[i], x1r_after_A[i],
                                           wx1[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x2l[i], x2r[i],
                                           x2l_after_A[i], x2r_after_A[i],
                                           wx2[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x3l[i], x3r[i],
                                           x3l_after_A[i], x3r_after_A[i],
                                           wx3[i], wordsize)

                    #every step do L-box and feistel
                    self.setupSPARXRound(
                        stp_file, x0l_after_A[i], x0r_after_A[i],
                        x1l_after_A[i], x1r_after_A[i], x2l_after_A[i],
                        x2r_after_A[i], x3l_after_A[i], x3r_after_A[i],
                        x0l_after_L[i], x0r_after_L[i], x1l_after_L[i],
                        x1r_after_L[i], x0l[i + 1], x0r[i + 1], x1l[i + 1],
                        x1r[i + 1], x2l[i + 1], x2r[i + 1], x3l[i + 1],
                        x3r[i + 1])
                else:
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x0l[i], x0r[i],
                                           x0l[i + 1], x0r[i + 1], wx0[i],
                                           wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x1l[i], x1r[i],
                                           x1l[i + 1], x1r[i + 1], wx1[i],
                                           wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x2l[i], x2r[i],
                                           x2l[i + 1], x2r[i + 1], wx2[i],
                                           wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x3l[i], x3r[i],
                                           x3l[i + 1], x3r[i + 1], wx3[i],
                                           wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(
                stp_file, x0l + x0r + x1l + x1r + x2l + x2r + x3l + x3r,
                wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x0l[0], x0l[rounds])
                stpcommands.assertVariableValue(stp_file, x0r[0], x0r[rounds])
                stpcommands.assertVariableValue(stp_file, x1l[0], x1l[rounds])
                stpcommands.assertVariableValue(stp_file, x1r[0], x1r[rounds])
                stpcommands.assertVariableValue(stp_file, x2l[0], x2l[rounds])
                stpcommands.assertVariableValue(stp_file, x2r[0], x2r[rounds])
                stpcommands.assertVariableValue(stp_file, x3l[0], x3l[rounds])
                stpcommands.assertVariableValue(stp_file, x3r[0], x3r[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #25
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for ChasKey
        with the given parameters.
        """
        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        self.num_messages = parameters["nummessages"]

        with open(stp_filename, "w") as stp_file:
            stp_file.write("% Input File for STP\n% ChasKeyMac w={} rounds={}" "\n\n\n".format(wordsize, rounds))

            # Setup variables
            # state = v0, v1, v2, v3
            # intermediate values = a0, a1, a2, a3
            v0 = ["v0{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v1 = ["v1{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v2 = ["v2{}".format(i) for i in range((rounds + 1) * self.num_messages)]
            v3 = ["v3{}".format(i) for i in range((rounds + 1) * self.num_messages)]

            # w = weight of each modular addition
            w0 = ["w0{}".format(i) for i in range(rounds * self.num_messages)]
            w1 = ["w1{}".format(i) for i in range(rounds * self.num_messages)]

            stpcommands.setupVariables(stp_file, v0, wordsize)
            stpcommands.setupVariables(stp_file, v1, wordsize)
            stpcommands.setupVariables(stp_file, v2, wordsize)
            stpcommands.setupVariables(stp_file, v3, wordsize)
            stpcommands.setupVariables(stp_file, w0, wordsize)
            stpcommands.setupVariables(stp_file, w1, wordsize)

            stpcommands.setupWeightComputation(stp_file, weight, w0 + w1, wordsize, 1)

            # Minimize Weight in middle rounds
            # stpcommands.limitWeight(stp_file, 10, w0[2:4] + w1[2:4], wordsize, 1)

            for i in range(rounds):
                self.setupChasKeyRound(
                    stp_file,
                    i,
                    v0[i],
                    v1[i],
                    v2[i],
                    v3[i],
                    v0[i + 1],
                    v1[i + 1],
                    v2[i + 1],
                    v3[i + 1],
                    w0[i],
                    w1[i],
                    wordsize,
                )

            # Message Collision
            stpcommands.assertNonZero(stp_file, v0 + v1 + v2 + v3, wordsize)
            # zeroString = "0hex" + "0"*(wordsize / 4)
            # stpcommands.assertVariableValue(stp_file, v0[rounds], zeroString)
            # stpcommands.assertVariableValue(stp_file, v1[rounds], zeroString)
            # stpcommands.assertVariableValue(stp_file, v2[rounds], zeroString)
            # stpcommands.assertVariableValue(stp_file, v3[rounds], zeroString)

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #26
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for CRAFT with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]

        if wordsize != 64:
            print("Only wordsize of 64-bit supported.")
            exit(1)

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP\n% CRAFT w={} "
                      "rounds={}\n\n\n".format(wordsize, rounds))
            stp_file.write(header)

            # Setup variables
            """
            x(roundNumber), other variables are like this one. 
            x(r) is a variable modeling the 64-bit input difference to the (r+1)'th round
            y(r) is a variable modeling the 64-bit output difference from MixColumn of the (r+1)'th round
            z(r) is a variable modeling the 64-bit output difference from PermuteNibble of the (r+1)'th round
            x(r+1) is a variable modeling the 64-bit output differenece from the (r+1)'th round
            Example:
            x0 = x0[63, 62, ..., 0]            
            x0[3:0]:     nibble 0
            x0[63:60]:   nibble 15
            It is supposed that the input difference is as bellow:
            [x[3:0], x[7:4], ..., x[63:60]]            
            """
            # note that the last integer index in the name of a variable \
            # always shows the round's number in the CryptoSMT
            x = ["x%d" % i for i in range(7)]
            y = ["y%d" % i for i in range(7)]
            z = ["z%d" % i for i in range(7)]
            # w = weight
            w = ["w%d" % i for i in range(6)]

            stpcommands.setupVariables(stp_file, x, wordsize)
            stpcommands.setupVariables(stp_file, y, wordsize)
            stpcommands.setupVariables(stp_file, z, wordsize)
            stpcommands.setupVariables(stp_file, w, wordsize)
            stpcommands.setupWeightComputation(stp_file, weight, w, wordsize)

            # - z4[15:12] in {0x5, 0x7, 0xA, 0xD, 0xF}
            # - z4[19:16] in {0x5, 0x7, 0xA, 0xD, 0xF}
            # - z4[35:32] in {0x5, 0x7, 0xA, 0xD, 0xF}
            # - z4[51:48] in {0x5, 0x7, 0xA, 0xD, 0xF}
            """
            ASSERT((z4[14:14] | ~z4[12:12]) & (~z4[14:14] | z4[12:12]) & (z4[13:13] | z4[12:12]) & (z4[15:15] | z4[12:12]) = 0bin1);
            ASSERT((z4[18:18] | ~z4[16:16]) & (~z4[18:18] | z4[16:16]) & (z4[17:17] | z4[16:16]) & (z4[19:19] | z4[16:16]) = 0bin1);
            ASSERT((z4[34:34] | ~z4[32:32]) & (~z4[34:34] | z4[32:32]) & (z4[33:33] | z4[32:32]) & (z4[35:35] | z4[32:32]) = 0bin1);
            ASSERT((z4[50:50] | ~z4[48:48]) & (~z4[50:50] | z4[48:48]) & (z4[49:49] | z4[48:48]) & (z4[51:51] | z4[48:48]) = 0bin1);
            """
            for i in [3, 4, 8, 12]:
                self.setupMembership(stp_file, "z4", i)

            for i in range(6):
                self.setupMixColumn(stp_file, x[i], y[i], wordsize)
                self.setupPermuteNibble(stp_file, y[i], z[i], wordsize)
                self.setupSbox(stp_file, z[i], x[i + 1], w[i], wordsize)
            self.setupMixColumn(stp_file, x[6], y[6], wordsize)
            self.setupPermuteNibble(stp_file, y[6], z[6], wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, [x[0]], wordsize)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize)

            stpcommands.setupQuery(stp_file)

        return
Example #27
0
    def createSTP(self, stp_filename, parameters):
        """
        Creates an STP file to find a characteristic for BAT diff pattern with
        the given parameters.
        """

        wordsize = parameters["wordsize"]
        rounds = parameters["rounds"]
        weight = parameters["sweight"]
        if wordsize == 32:
            self.PERM = [7, 4, 1, 6, 3, 0, 5, 2]
        elif wordsize == 64:
            self.PERM = [14, 15, 8, 9, 2, 3, 12, 13, 6, 7, 0, 1, 10, 11, 4, 5]
        else:
            raise Exception("Wrong wordsize!")

        with open(stp_filename, 'w') as stp_file:
            header = ("% Input File for STP: BAT diff pattern\n"
                      "% w = {} alpha = {} beta = {}\n"
                      "% rounds = {}\n\n".format(wordsize, self.rot_alpha,
                                                 self.rot_beta, rounds))
            stp_file.write(header)

            # Setup variables
            # x as left, y as right
            x = ["x{}".format(i) for i in range(rounds + 1)]
            y = ["y{}".format(i) for i in range(rounds + 1)]
            in_G0 = ["inG0{}".format(i) for i in range(rounds)]
            in_G1 = ["inG1{}".format(i) for i in range(rounds)]
            xor_G = ["xorG{}".format(i) for i in range(rounds)]
            perm_G = ["permG{}".format(i) for i in range(rounds)]

            # w = weight
            w = ["sumw{}".format(i) for i in range(rounds)]

            stpcommands.setupVariables(stp_file, x, wordsize // 4)
            stpcommands.setupVariables(stp_file, y, wordsize // 4)
            stpcommands.setupVariables(stp_file, in_G0, wordsize // 4)
            stpcommands.setupVariables(stp_file, in_G1, wordsize // 4)
            stpcommands.setupVariables(stp_file, xor_G, wordsize // 4)
            stpcommands.setupVariables(stp_file, perm_G, wordsize // 4)
            stpcommands.setupVariables(stp_file, w, 16)

            stpcommands.setupWeightComputationSum(stp_file, weight, w, 16)

            for i in range(rounds):
                self.setupRound(stp_file, x[i], y[i], x[i + 1], y[i + 1],
                                in_G0[i], in_G1[i], xor_G[i], perm_G[i], w[i],
                                wordsize)

            # No all zero characteristic
            stpcommands.assertNonZero(stp_file, [x[0], y[0]], wordsize // 4)

            # Iterative characteristics only
            # Input difference = Output difference
            if parameters["iterative"]:
                stpcommands.assertVariableValue(stp_file, x[0], x[rounds])
                stpcommands.assertVariableValue(stp_file, y[0], y[rounds])

            for key, value in parameters["fixedVariables"].items():
                stpcommands.assertVariableValue(stp_file, key, value)

            for char in parameters["blockedCharacteristics"]:
                stpcommands.blockCharacteristic(stp_file, char, wordsize // 4)

            stpcommands.setupQuery(stp_file)

        return