Exemplo n.º 1
0
    def theta(self, in0, in1, in2, in3, out0, out1, out2, out3, wordsize):
        """
        Model for the Theta function in NOEKEON
        """
        command = ""

        in1xorin3 = "BVXOR({0}[31:0], {1}[31:0])".format(in1, in3)
        in1xorin3lr = rotl(in1xorin3, 8, wordsize)
        in1xorin3rr = rotr(in1xorin3, 8, wordsize)
        l = "BVXOR({0}, BVXOR({1}, {2}))".format(in1xorin3lr, in1xorin3,
                                                 in1xorin3rr)

        in0xorin2 = "BVXOR({0}[31:0], {1}[31:0])".format(in0, in2)
        in0xorin2lr = rotl(in0xorin2, 8, wordsize)
        in0xorin2rr = rotr(in0xorin2, 8, wordsize)
        r = "BVXOR({0}, BVXOR({1}, {2}))".format(in0xorin2lr, in0xorin2,
                                                 in0xorin2rr)

        command += "ASSERT({0}[31:0] = BVXOR({1}[31:0], {2}[31:0]));\n".format(
            out0, in0, l)
        command += "ASSERT({0}[31:0] = BVXOR({1}[31:0], {2}[31:0]));\n".format(
            out1, in1, r)
        command += "ASSERT({0}[31:0] = BVXOR({1}[31:0], {2}[31:0]));\n".format(
            out2, in2, l)
        command += "ASSERT({0}[31:0] = BVXOR({1}[31:0], {2}[31:0]));\n".format(
            out3, in3, r)

        return command
Exemplo n.º 2
0
    def setupChasKeyRound(self, stp_file, rnd, v0_in, v1_in, v2_in, v3_in,
                          v0_out, v1_out, v2_out, v3_out, w0, w1, wordsize):
        """
        Half a round of ChasKey

        a0 = (v1 + v0) <<< 32
        a1 = (v1 + v0) ^ (v1 <<< 13)
        a2 = (v2 + v3)
        a3 = (v2 + v3) ^ (v3 <<< 16)
        """
        command = ""

        if (rnd % 2) == 0:
            rot_one = self.rot_v1_up
            rot_two = self.rot_v3_up
            rot_three = self.rot_v0_up
        else:
            rot_one = self.rot_v1_down
            rot_two = self.rot_v3_down
            rot_three = self.rot_v0_down

        #Assert intermediate values
        #Rotate right to get correct output value

        #v0_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(v2_in, v3_in, v0_out, wordsize)
        command += ");\n"

        #v1_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            v1_out, rotl(v1_in, rot_one, wordsize),
            rotr(v2_out, rot_three, wordsize))

        #v2_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(v1_in, v0_in,
                                            rotr(v2_out, rot_three, wordsize),
                                            wordsize)
        command += ");\n"

        #v3_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            v3_out, rotl(v3_in, rot_two, wordsize), v0_out)

        # Compute Weights for modular addition
        # Lipmaa and Moriai

        command += "ASSERT({0} = ~".format(w0)
        command += stpcommands.getStringEq(v1_in, v0_in,
                                           rotr(v2_out, rot_three, wordsize))
        command += ");\n"

        command += "ASSERT({0} = ~".format(w1)
        command += stpcommands.getStringEq(v2_in, v3_in, v0_out)
        command += ");\n"

        stp_file.write(command)
        return
Exemplo n.º 3
0
    def setupChasKeyRound(
        self, stp_file, rnd, v0_in, v1_in, v2_in, v3_in, v0_out, v1_out, v2_out, v3_out, w0, w1, wordsize
    ):

        """
        Half a round of ChasKey

        a0 = (v1 + v0) <<< 32
        a1 = (v1 + v0) ^ (v1 <<< 13)
        a2 = (v2 + v3)
        a3 = (v2 + v3) ^ (v3 <<< 16)
        """
        command = ""

        if (rnd % 2) == 0:
            rot_one = 5
            rot_two = 8
        else:
            rot_one = 7
            rot_two = 13

        # Assert intermediate values
        # Rotate right to get correct output value

        # v0_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(v2_in, v3_in, v0_out, wordsize)
        command += ");\n"

        # v1_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            v1_out, rotl(v1_in, rot_one, wordsize), rotr(v2_out, 16, wordsize)
        )

        # v2_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(v1_in, v0_in, rotr(v2_out, 16, wordsize), wordsize)
        command += ");\n"

        # v3_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(v3_out, rotl(v3_in, rot_two, wordsize), v0_out)

        # Compute Weights for modular addition
        # Lipmaa and Moriai

        command += "ASSERT({0} = ~".format(w0)
        command += stpcommands.getStringEq(v1_in, v0_in, rotr(v2_out, 16, wordsize))
        command += ");\n"

        command += "ASSERT({0} = ~".format(w1)
        command += stpcommands.getStringEq(v2_in, v3_in, v0_out)
        command += ");\n"

        stp_file.write(command)
        return
Exemplo n.º 4
0
    def setupQuarterRound(self, stp_file, a, tmp, c, w, wordsize):
        """
        ChaCha quarter round:
            (c0, c1, c2, c3) = Quarterround(a0, a1, a2, a3)
        """
        command = ""
        # a += b
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(a[0], a[1], tmp[0], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[0],
            stpcommands.getStringEq(a[0], a[1], tmp[0]))

        # d ^= a; d <<<= 16; (a = tmp[0] after last step)
        d = rotl("BVXOR({}, {})".format(tmp[0], a[3]), 16, wordsize)

        # c += d;
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(a[2], d, tmp[1], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[1],
            stpcommands.getStringEq(a[2], d, tmp[1]))

        # b ^= c; b <<<= 12; (c = tmp[1] after last step)
        b = rotl("BVXOR({}, {})".format(a[1], tmp[1]), 12, wordsize)

        # a += b;
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(tmp[0], b, tmp[2], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[2],
            stpcommands.getStringEq(tmp[0], b, tmp[2]))

        # d ^= a; d <<<= 8; (a = tmp[2] after last step)
        d = rotl("BVXOR({}, {})".format(tmp[2], d), 8, wordsize)

        # c += d
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(tmp[1], d, tmp[3], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[1],
            stpcommands.getStringEq(tmp[1], d, tmp[3]))

        # b ^= c; b <<<= 7; (c = tmp[3] after last step)
        b = rotl("BVXOR({}, {})".format(b, tmp[3]), 7, wordsize)

        # Output
        command += "ASSERT({} = {});\n".format(c[0], tmp[2])
        command += "ASSERT({} = {});\n".format(c[1], b)
        command += "ASSERT({} = {});\n".format(c[2], tmp[3])
        command += "ASSERT({} = {});\n".format(c[3], d)

        stp_file.write(command)
        return
Exemplo n.º 5
0
    def setupKeccakRound(self, stp_file, rnd, s, a, b, c, d, wordsize):
        """
        Model for one round of Keccak.
        """
        command = ""

        #Compute Parity for each column
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR({}, BVXOR({}, {})))));\n".format(
                c[i + 5 * rnd], s[i + 5 * 0 + 25 * rnd],
                s[i + 5 * 1 + 25 * rnd], s[i + 5 * 2 + 25 * rnd],
                s[i + 5 * 3 + 25 * rnd], s[i + 5 * 4 + 25 * rnd])

        #Compute intermediate values
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, {}));\n".format(
                d[i + 5 * rnd], c[(i - 1) % 5 + 5 * rnd],
                rotl(c[(i + 1) % 5 + 5 * rnd], 1, wordsize))

        #Rho and Pi
        for x in range(5):
            for y in range(5):
                #x + 5*y + 25*rnd -> y + 5*((2*x + 3*y) % 5) + 25*rnd
                new_b_index = y + 5 * ((2 * x + 3 * y) % 5) + 25 * rnd
                tmp_xor = "BVXOR({}, {})".format(s[x + 5 * y + 25 * rnd],
                                                 d[x + 5 * rnd])
                command += "ASSERT({} = {});\n".format(
                    b[new_b_index], rotl(tmp_xor, self.RO[x][y], wordsize))

        #Chi
        for x in range(5):
            for y in range(5):
                chiTmp = "BVXOR({}, ~{} & {})".format(
                    b[(x + 0) % 5 + 5 * y + 25 * rnd],
                    b[(x + 1) % 5 + 5 * y + 25 * rnd],
                    b[(x + 2) % 5 + 5 * y + 25 * rnd])
                command += "ASSERT({} = {});\n".format(a[x + 5 * y + 25 * rnd],
                                                       chiTmp)

        #Add rnd constant
        for x in range(5):
            for y in range(5):
                if x == 0 and y == 0:
                    command += "ASSERT({} = BVXOR({}, {}));\n".format(
                        s[25 * (rnd + 1)], a[25 * rnd], self.RC[rnd])
                else:
                    command += "ASSERT({} = {});\n".format(
                        s[x + 5 * y + 25 * (rnd + 1)], a[x + 5 * y + 25 * rnd])

        stp_file.write(command)
        return
Exemplo n.º 6
0
    def pi1(self, in0, in1, in2, in3, out0, out1, out2, out3, wordsize):
        """
        Model for the Pi1 function in NOEKEON - which is the inverse of pi2
        """
        command = ""

        command += "ASSERT({0}[31:0] = {1}[31:0]);\n".format(in0, out0)
        command += "ASSERT({0}[31:0] = {1}[31:0]);\n".format(
            rotl(in1, 1, wordsize), out1)
        command += "ASSERT({0}[31:0] = {1}[31:0]);\n".format(
            rotl(in2, 5, wordsize), out2)
        command += "ASSERT({0}[31:0] = {1}[31:0]);\n".format(
            rotl(in3, 2, wordsize), out3)

        return command
Exemplo n.º 7
0
    def setupQuarterRound(self, stp_file, a, b, c, w, wordsize):
        """
        Salsa quarter round:
            (c0, c1, c2, c3) = Quarterround(a0, a1, a2, a3)
            b0, b1, b2 and b3 are used for the modular addition.
        """
        command = ""
        # First addition
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(a[0], a[3], b[0], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[0],
            stpcommands.getStringEq(a[0], a[3], b[0]))


        # Second addition
        tmp_xor0 = "BVXOR({}, {})".format(rotl(b[0], 7, wordsize), a[1])
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(a[0], tmp_xor0, b[1], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[1],
            stpcommands.getStringEq(a[0], tmp_xor0, b[1]))


        # Third addition
        tmp_xor1 = "BVXOR({}, {})".format(rotl(b[1], 9, wordsize), a[2])
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(tmp_xor0, tmp_xor1, b[2], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[2],
            stpcommands.getStringEq(tmp_xor0, tmp_xor1, b[2]))

        # Fourth addition
        tmp_xor2 = "BVXOR({}, {})".format(rotl(b[2], 13, wordsize), a[3])
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(tmp_xor1, tmp_xor2, b[3], wordsize))

        command += "ASSERT({} = ~{});\n".format(w[3],
            stpcommands.getStringEq(tmp_xor1, tmp_xor2, b[3]))

        # Outputs
        command += "ASSERT({} = BVXOR({}, {}));\n".format(c[0], a[0], rotl(b[3], 18, wordsize))
        command += "ASSERT({} = {});\n".format(c[1], tmp_xor0)
        command += "ASSERT({} = {});\n".format(c[2], tmp_xor1)
        command += "ASSERT({} = {});\n".format(c[3], tmp_xor2)

        stp_file.write(command)
        return
Exemplo n.º 8
0
    def L(self, x0l_in, x0r_in, x1l_in, x1r_in, x0l_out, x0r_out, x1l_out,
          x1r_out):
        """
        Model for the L' function in SPARX-128. L' is the Feistel function
        """
        command = ""

        # (x_in xor y_in)
        xor_x0 = "BVXOR(" + x0l_in + " , " + x0r_in + ")"
        xor_x1 = "BVXOR(" + x1l_in + " , " + x1r_in + ")"
        xor_x0_x1 = "BVXOR(" + xor_x0 + " , " + xor_x1 + ")"
        #(x_in xor y_in) <<< 8)
        rot_x0_x1 = rotl(xor_x0_x1, 8, 16)

        # exchange x0l_out and x1l_out
        command += "ASSERT(" + x1l_out + " = "
        command += "BVXOR(" + x0l_in + " , " + rot_x0_x1 + "));\n"
        command += "ASSERT(" + x0r_out + " = "
        command += "BVXOR(" + x0r_in + " , " + rot_x0_x1 + "));\n"
        command += "ASSERT(" + x0l_out + " = "
        command += "BVXOR(" + x1l_in + " , " + rot_x0_x1 + "));\n"
        command += "ASSERT(" + x1r_out + " = "
        command += "BVXOR(" + x1r_in + " , " + rot_x0_x1 + "));\n"

        return command
Exemplo n.º 9
0
    def setupSPECKEYRound(self, stp_file, x_in, y_in, x_out, y_out, w,
                          wordsize):
        """
        Model for the ARX box (round) function of SPARX which is the
        same as SPECKEY.
        """
        command = ""

        #Assert((x_in >>> 7) + y_in = x_out)
        command += "ASSERT("
        command += stpcommands.getStringAdd(rotr(x_in, 7, wordsize), y_in,
                                            x_out, wordsize)
        command += ");\n"

        #Assert(x_out xor (y_in <<< 2) = y_out)
        command += "ASSERT(" + y_out + " = "
        command += "BVXOR(" + x_out + ","
        command += rotl(y_in, 2, wordsize)
        command += "));\n"

        #For weight computation
        command += "ASSERT({0} = ~".format(w)
        command += stpcommands.getStringEq(rotr(x_in, 7, wordsize), y_in,
                                           x_out)
        command += ");\n"

        stp_file.write(command)
        return
Exemplo n.º 10
0
    def A(self, x_in, y_in, x_out, y_out, w, wordsize):
        """
        Model for the ARX box (round) function of SPARX. A^a denotes a 
        rounds of SPECKEY.
        """
        command = ""

        #Assert((x_in >>> 7) + y_in = x_out)
        command += "ASSERT("
        command += stpcommands.getStringAdd(rotr(x_in, 7, wordsize), y_in,
                                            x_out, wordsize)
        command += ");\n"

        #Assert(x_out xor (y_in <<< 2) = y_out)
        command += "ASSERT(" + y_out + " = "
        command += "BVXOR(" + x_out + ","
        command += rotl(y_in, 2, wordsize)
        command += "));\n"

        #For weight computation
        command += "ASSERT({0} = ~".format(w)
        command += stpcommands.getStringEq(rotr(x_in, 7, wordsize), y_in,
                                           x_out)
        command += ");\n"

        return command
Exemplo n.º 11
0
    def setupSpeckRound(self, stp_file, x_in, y_in, x_out, y_out, w, wordsize):
        """
        Model for differential behaviour of one round SPECK
        """
        command = ""

        #Assert(x_in >>> self.rot_alpha + y_in = x_out)
        command += "ASSERT("
        command += stpcommands.getStringAdd(
            rotr(x_in, self.rot_alpha, wordsize), y_in, x_out, wordsize)
        command += ");\n"

        #Assert(x_out xor (y_in <<< self.rot_beta) = x_in)
        command += "ASSERT(" + y_out + " = "
        command += "BVXOR(" + x_out + ","
        command += rotl(y_in, self.rot_beta, wordsize)
        command += "));\n"

        #For weight computation
        command += "ASSERT({0} = ~".format(w)
        command += stpcommands.getStringEq(
            rotr(x_in, self.rot_alpha, wordsize), y_in, x_out)
        command += ");\n"

        stp_file.write(command)
        return
Exemplo n.º 12
0
    def setupSpeckRound(self, stp_file, x_in, y_in, x_out, y_out, w, wordsize):
        """
        Model for differential behaviour of one round SPECK
        """
        command = ""

        #Assert(x_in >>> self.rot_alpha + y_in = x_out)
        command += "ASSERT("
        command += stpcommands.getStringAdd(rotr(x_in, self.rot_alpha, wordsize),
                                            y_in, x_out, wordsize)
        command += ");\n"

        #Assert(x_out xor (y_in <<< self.rot_beta) = x_in)
        command += "ASSERT(" + y_out + " = "
        command += "BVXOR(" + x_out + ","
        command += rotl(y_in, self.rot_beta, wordsize)
        command += "));\n"

        #For weight computation
        command += "ASSERT({0} = ~".format(w)
        command += stpcommands.getStringEq(rotr(x_in, self.rot_alpha, wordsize),
                                           y_in, x_out)
        command += ");\n"

        stp_file.write(command)
        return
Exemplo n.º 13
0
    def setupQuarterRound(self, stp_file, a, b, c, w, wordsize):
        """
        Salsa quarter round:
            (c0, c1, c2, c3) = Quarterround(a0, a1, a2, a3)
            b0, b1, b2 and b3 are used for the modular addition.
        """
        command = ""
        # First addition
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(a[0], a[3], b[0], wordsize))

        command += "ASSERT({} = ~{});\n".format(
            w[0], stpcommands.getStringEq(a[0], a[3], b[0]))

        # Second addition
        tmp_xor0 = "BVXOR({}, {})".format(rotl(b[0], 7, wordsize), a[1])
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(a[0], tmp_xor0, b[1], wordsize))

        command += "ASSERT({} = ~{});\n".format(
            w[1], stpcommands.getStringEq(a[0], tmp_xor0, b[1]))

        # Third addition
        tmp_xor1 = "BVXOR({}, {})".format(rotl(b[1], 9, wordsize), a[2])
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(tmp_xor0, tmp_xor1, b[2], wordsize))

        command += "ASSERT({} = ~{});\n".format(
            w[2], stpcommands.getStringEq(tmp_xor0, tmp_xor1, b[2]))

        # Fourth addition
        tmp_xor2 = "BVXOR({}, {})".format(rotl(b[2], 13, wordsize), a[3])
        command += "ASSERT({});\n".format(
            stpcommands.getStringAdd(tmp_xor1, tmp_xor2, b[3], wordsize))

        command += "ASSERT({} = ~{});\n".format(
            w[3], stpcommands.getStringEq(tmp_xor1, tmp_xor2, b[3]))

        # Outputs
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            c[0], a[0], rotl(b[3], 18, wordsize))
        command += "ASSERT({} = {});\n".format(c[1], tmp_xor0)
        command += "ASSERT({} = {});\n".format(c[2], tmp_xor1)
        command += "ASSERT({} = {});\n".format(c[3], tmp_xor2)

        stp_file.write(command)
        return
Exemplo n.º 14
0
    def setupKeccakRound(self, stp_file, rnd, s, a, b, c, d, wordsize):
        """
        Model for one round of Keccak.
        """
        command = ""

        #Compute Parity for each column
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR({}, BVXOR({}, {})))));\n".format(
                c[i + 5*rnd], s[i + 5*0 + 25*rnd], s[i + 5*1 + 25*rnd],
                s[i + 5*2 + 25*rnd], s[i + 5*3 + 25*rnd], s[i + 5*4 + 25*rnd])

        #Compute intermediate values
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, {}));\n".format(
                d[i + 5*rnd], c[(i - 1) % 5 + 5*rnd],
                rotl(c[(i + 1) % 5 + 5*rnd], 1, wordsize))

        #Rho and Pi
        for x in range(5):
            for y in range(5):
                #x + 5*y + 25*rnd -> y + 5*((2*x + 3*y) % 5) + 25*rnd
                new_b_index = y + 5*((2*x + 3*y) % 5) + 25*rnd
                tmp_xor = "BVXOR({}, {})".format(s[x + 5*y + 25*rnd], d[x + 5*rnd])
                command += "ASSERT({} = {});\n".format(
                    b[new_b_index], rotl(tmp_xor, self.RO[x][y], wordsize))

        #Chi
        for x in range(5):
            for y in range(5):
                chiTmp = "BVXOR({}, ~{} & {})".format(b[(x + 0) % 5 + 5*y + 25*rnd],
                                                      b[(x + 1) % 5 + 5*y + 25*rnd],
                                                      b[(x + 2) % 5 + 5*y + 25*rnd])
                command += "ASSERT({} = {});\n".format(a[x + 5*y + 25*rnd], chiTmp)

        #Add rnd constant
        for x in range(5):
            for y in range(5):
                if x == 0 and y == 0:
                    command += "ASSERT({} = BVXOR({}, {}));\n".format(
                        s[25*(rnd + 1)], a[25*rnd], self.RC[rnd])
                else:
                    command += "ASSERT({} = {});\n".format(
                        s[x + 5*y + 25*(rnd + 1)], a[x + 5*y + 25*rnd])

        stp_file.write(command)
        return
Exemplo n.º 15
0
    def setupRound(self, stp_file, xin, yin, zin, xout, yout, zout,
                   xsb, ysb, zsb, w, wordsize):
        """
        Gimli round:
            x = (x xor (z << 1) xor (y & z) << a) <<< d
            y = (y xor x xor (x | z) << b) <<< e
            z = (y xor z xor (x & y) << c) <<< f
        """
        command = ""

        # Conditions for non-linear layer
        xnl = "({} & ~({}|{}))".format(xsb, yin, zin)
        ynl = "({} & ~({}|{}))".format(ysb, xin, zin)
        znl = "({} & ~({}|{}))".format(zsb, xin, yin)

        command += "ASSERT(({} | {} | {}) = 0x{});\n".format(xnl, ynl, znl, "0" * (wordsize // 4))

        # Dependency between bits
        # (x & y & ~z) & ~(xout ^ yout)
        xcond = "(({} & {} & ~{}) & ~(BVXOR({}, {})))".format(xin, yin, zin, xsb, ysb)
        # (x & ~y & z) & (xout ^ zout)
        ycond = "(({} & ~{} & {}) & (BVXOR({}, {})))".format(xin, yin, zin, xsb, zsb)
        # (~x & y & z) & ~(yout ^ zout)
        zcond = "((~{} & {} & {}) & ~(BVXOR({}, {})))".format(xin, yin, zin, ysb, zsb)
        # (x & y & z) & (~(xout ^ yout ^ zout))
        fcond = "(({} & {} & {}) & ~(BVXOR(BVXOR({}, {}), {})))".format(xin, yin, zin, xsb, ysb, zsb)
        command += "ASSERT(({} | {} | {} | {}) = 0x{});\n".format(xcond, ycond, zcond, fcond, "0" * (wordsize // 4))

        xshift = "BVXOR({0}, BVXOR(({1} << 1)[{4}:0], ({2} << {3})[{4}:0]))".format(xin, zin, xsb, self.a, wordsize - 1)
        command += "ASSERT({} = {});\n".format(zout, rotl(xshift, self.d, wordsize))

        yshift = "BVXOR({}, BVXOR({}, ({} << {})[{}:0]))".format(yin, xin, ysb, self.b, wordsize - 1)
        command += "ASSERT({} = {});\n".format(yout, rotl(yshift, self.e, wordsize))

        zshift = "BVXOR({}, BVXOR({}, ({} << {})[{}:0]))".format(zin, yin, zsb, self.c, wordsize - 1)
        command += "ASSERT({} = {});\n".format(xout, rotl(zshift, self.f, wordsize))

        # Probability
        wxtmp = "((((({0} | {1}) << {2})[{3}:0]) >> {2})[{3}:0])".format(yin, zin, self.a, wordsize - 1)
        wytmp = "((((({0} | {1}) << {2})[{3}:0]) >> {2})[{3}:0])".format(xin, zin, self.b, wordsize - 1)
        wztmp = "((((({0} | {1}) << {2})[{3}:0]) >> {2})[{3}:0])".format(xin, yin, self.c, wordsize - 1)

        command += "ASSERT({0} = ({1} | {2} | {3}));\n".format(w, wxtmp, wytmp, wztmp)


        stp_file.write(command)
        return
Exemplo n.º 16
0
    def setupSimonRound(self, stp_file, x_in, y_in, x_out, y_out, and_out, w,
                        wordsize):
        """
        Model for differential behaviour of one round SIMON
        y[i+1] = x[i]
        x[i+1] = (x[i] <<< 1) & (x[i] <<< 8) ^ y[i] ^ (x[i] << 2)

        This model is only correct if gcd(self.rot_alpha - self.rot_beta, wordsize) = 1
        and self.rot_alpha > self.rot_beta
        """
        command = ""

        #Assert(y_out = x_in)
        command += "ASSERT({} = {});\n".format(y_out, x_in)

        x_in_rotalpha = rotl(x_in, self.rot_alpha, wordsize)
        x_in_rotbeta = rotl(x_in, self.rot_beta, wordsize)

        #Deal with dependent inputs
        varibits = "({0} | {1})".format(x_in_rotalpha, x_in_rotbeta)
        doublebits = self.getDoubleBits(x_in, wordsize)

        #Check for valid difference
        firstcheck = "({} & ~{})".format(and_out, varibits)
        secondcheck = "(BVXOR({}, {}) & {})".format(
            and_out, rotl(and_out, self.rot_alpha - self.rot_beta, wordsize), doublebits)
        thirdcheck = "(IF {0} = 0x{1} THEN BVMOD({2}, {0}, 0x{3}2) ELSE 0x{4} ENDIF)".format(
            x_in, "f" * (wordsize // 4), wordsize, "0" * (wordsize // 4 - 1),
            "0" * (wordsize // 4))

        command += "ASSERT(({} | {} | {}) = 0x{});\n".format(
            firstcheck, secondcheck, thirdcheck, "0" * (wordsize // 4))

        #Assert XORs
        command += "ASSERT({} = BVXOR({}, BVXOR({}, {})));\n".format(
            x_out, rotl(x_in, self.rot_gamma, wordsize), y_in, and_out)

        #Weight computation
        command += "ASSERT({0} = (IF {1} = 0x{4} THEN BVSUB({5},0x{4},0x{6}1) \
                    ELSE BVXOR({2}, {3}) ENDIF));\n".format(
                        w, x_in, varibits, doublebits, "f" * (wordsize // 4),
                        wordsize, "0"*((wordsize // 4) - 1))


        stp_file.write(command)
        return
Exemplo n.º 17
0
    def setupCHAMRound(self, stp_file, x0_in, x1_in, x2_in, x3_in,
                       x0_out, x1_out, x2_out, x3_out, x0x1,
                       rot_x0, rot_x1, w, wordsize):
        """
        Model for differential behaviour of one round CHAM
        """
        command = ""

        # even rounds:
        # X_{i+1}[3] = (X_{i}[0] + (X_{i}[1] << 1)) << 8
        # odd rounds:
        # X_{i+1}[3] = (X_{i}[0] + (X_{i}[1] << 8)) << 1

        command += "ASSERT("
        command += stpcommands.getStringAdd(
                                            rotl(x1_in,
                                                 rot_x1,
                                                 wordsize),
                                            x0_in,
                                            x0x1,
                                            wordsize)
        command += ");\n"

        command += "ASSERT({0} = {1});\n".format(x3_out, rotl(x0x1, rot_x0, wordsize))

        # X_{i+1}[2] = X_{i+1}[3]
        # X_{i+1}[1] = X_{i+1}[2]
        # X_{i+1}[0] = X_{i+1}[1]
        command += "ASSERT({0} = {1});\n".format(x2_out, x3_in)
        command += "ASSERT({0} = {1});\n".format(x1_out, x2_in)
        command += "ASSERT({0} = {1});\n".format(x0_out, x1_in)

        #For weight computation
        command += "ASSERT({0} = ~".format(w)
        command += stpcommands.getStringEq(x0_in,
                                           rotl(x1_in, rot_x1, wordsize),
                                           x0x1)
        command += ");\n"

        stp_file.write(command)
        return
Exemplo n.º 18
0
    def setupSimonRound(self, stp_file, x0_in, y0_in,  x0_out, y0_out,
                        and_out0, key, wordsize):
        """
        Returns a string representing one round of Simon in STP.
        y[i+1] = x[i]
        x[i+1] = (x[i] <<< 1) & (x[i] <<< 8) ^ y[i] ^ (x[i] << 2) ^ key
        """
        command = ""

        #Assert(y_out = x_in)
        command += "ASSERT({} = {});\n".format(y0_out, x0_in)

        #Assert AND Output
        command += "ASSERT({} = {} & {});\n".format(and_out0, 
            rotl(x0_in, self.rot_beta, wordsize), 
            rotl(x0_in, self.rot_alpha, wordsize))

        #Assert x_out
        command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR({}, {}))));\n".format(
            x0_out, y0_in, and_out0, key, rotl(x0_in, self.rot_gamma, wordsize))
        stp_file.write(command)
        return
Exemplo n.º 19
0
    def setupSimonRound(self, stp_file, x0_in, y0_in, x0_out, y0_out, and_out0,
                        key, wordsize):
        """
        Returns a string representing one round of Simon in STP.
        y[i+1] = x[i]
        x[i+1] = (x[i] <<< 1) & (x[i] <<< 8) ^ y[i] ^ (x[i] << 2) ^ key
        """
        command = ""

        #Assert(y_out = x_in)
        command += "ASSERT({} = {});\n".format(y0_out, x0_in)

        #Assert AND Output
        command += "ASSERT({} = {} & {});\n".format(
            and_out0, rotl(x0_in, self.rot_beta, wordsize),
            rotl(x0_in, self.rot_alpha, wordsize))

        #Assert x_out
        command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR({}, {}))));\n".format(
            x0_out, y0_in, and_out0, key, rotl(x0_in, self.rot_gamma,
                                               wordsize))
        stp_file.write(command)
        return
Exemplo n.º 20
0
    def setupRound(self, stp_file, x_in, y_in, x_out, y_out, in_G0, in_G1,
                   xor_G, perm_G, w, wordsize):
        """
        Model for differential behaviour of one round
        """
        command = ""

        # 1. y_out = x_in
        command += "ASSERT({} = {});\n".format(y_out, x_in)

        # 2. rotations
        x_in_rotalpha = rotl(x_in, self.rot_alpha, wordsize // 4)
        x_in_rotbeta = rotl(x_in, self.rot_beta, wordsize // 4)
        command += "ASSERT({} = {});\n".format(in_G0, x_in_rotalpha)
        command += "ASSERT({} = {});\n".format(in_G1, x_in_rotbeta)

        # 3. G0 ^ G1 = xor_G
        command += SatConstraints.PatternXorAssert(in_G0, in_G1, xor_G,
                                                   wordsize // 4)

        # 4. xor_G PERM to perm_G
        for i in range(wordsize // 4):
            command += "ASSERT({0}[{1}:{1}] = {2}[{3}:{3}]);\n".format(
                perm_G, self.PERM[i], xor_G, i)

        # 5. perm_G ^ y_in = x_out
        command += SatConstraints.PatternXorAssert(y_in, perm_G, x_out,
                                                   wordsize // 4)

        # 6. Weight computation
        sum_w_i = stpcommands.getWeightString([x_in], wordsize // 4, 0, w)
        sum_w_i += '\n'
        command += sum_w_i

        stp_file.write(command)
        return
Exemplo n.º 21
0
    def setupLBlockRound(self, stp_file, x_in, y_in, x_out, y_out, f_out, s_out, w, wordsize):
        """
        Model for differential behaviour of one round LBlock
        y[i+1] = x[i]
        x[i+1] = P(S(x[i])) xor y[i] <<< 8
        """
        command = ""

        #Assert(y[i+1] = x[i])
        command += "ASSERT({} = {});\n".format(y_out, x_in)

        y_in_rot = rotl(y_in, 8, wordsize)
        command += self.F(x_in, s_out, f_out, w)

        #Assert XOR
        command += "ASSERT({} = BVXOR({}, {}));\n".format(x_out, f_out, y_in_rot)

        stp_file.write(command)
        return
Exemplo n.º 22
0
    def L(self, x_in, y_in, x_out, y_out):
        """
        Model for the L function in SPARX. L is the Feistel function and
        is borrowed from NOEKEON.
        """
        command = ""

        # (x_in xor y_in)
        xor_x_y = "BVXOR(" + x_in + " , " + y_in + ")"
        #(x_in xor y_in) <<< 8)
        rot_x_y = rotl(xor_x_y, 8, 16)

        #Assert(x_out = x_in xor ((x_in xor y_in) <<< 8))
        command += "ASSERT(" + x_out + " = "
        command += "BVXOR(" + x_in + " , " + rot_x_y + "));\n"

        #Assert(y_out = y_in xor ((x_in xor y_in) <<< 8))
        command += "ASSERT(" + y_out + " = "
        command += "BVXOR(" + y_in + " , " + rot_x_y + "));\n"

        return command
Exemplo n.º 23
0
    def setupAsconRound(self, stp_file, rnd, s, a, b, c, wordsize, tmp,
                        w, xin, xout, andout):
        """
        Model for one round of Ascon.
        """
        command = ""
        weight_sum = ""

        # Linear part in S-box
        command += "ASSERT({} = BVXOR({}, {}));\n".format(a[0 + 5*rnd],
                                                          s[0 + 5*rnd],
                                                          s[4 + 5*rnd])
        command += "ASSERT({} = {});\n".format(a[1 + 5*rnd], s[1 + 5*rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(a[2 + 5*rnd],
                                                          s[2 + 5*rnd],
                                                          s[1 + 5*rnd])
        command += "ASSERT({} = {});\n".format(a[3 + 5*rnd], s[3 + 5*rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(a[4 + 5*rnd],
                                                          s[4 + 5*rnd],
                                                          s[3 + 5*rnd])


        # Model for the S-box

        for z in range(wordsize):
            # Construct S-box input
            command += "ASSERT({}={});\n".format(
                xin[z + 5*wordsize*rnd],
                a[0 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                a[1 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                a[2 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                a[3 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                a[4 + 5*rnd] + "[{0}:{0}]".format(z))

            # Construct S-box output
            command += "ASSERT({}={});\n".format(
                xout[z + 5*wordsize*rnd],
                b[0 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                b[1 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                b[2 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                b[3 + 5*rnd] + "[{0}:{0}]".format(z) + "@" +
                b[4 + 5*rnd] + "[{0}:{0}]".format(z))

            xin_rotalpha = rotl(xin[z + 5*wordsize*rnd], 2, 5)
            xin_rotbeta = rotl(xin[z + 5*wordsize*rnd], 1, 5)

            #Deal with dependent inputs
            varibits = "({0} | {1})".format(xin_rotalpha, xin_rotbeta)
            doublebits = self.getDoubleBits(xin[z + 5*wordsize*rnd])

            #Check for valid difference
            firstcheck = "({} & ~{})".format(andout[z + 5*wordsize*rnd], varibits)
            secondcheck = "(~BVXOR({}, {}) & {})".format(
            andout[z + 5*wordsize*rnd], rotl(andout[z + 5*wordsize*rnd], 2 - 1, 5), doublebits)
            thirdcheck = "(IF {0} = 0b{1} THEN BVMOD(5, {0}, 0b00010) ELSE 0b{2}ENDIF)".format(
                xin[z + 5*wordsize*rnd], "11111", "00000")
            command += "ASSERT(({} | {} | {}) = 0b{});\n".format(firstcheck,
            secondcheck, thirdcheck, "00000")

            #Assert XORs
            command += "ASSERT({} = BVXOR({},{}));\n".format(
                xout[z + 5*wordsize*rnd], 
                xin[z + 5*wordsize*rnd], 
                andout[z + 5*wordsize*rnd])

            #Weight computation
            command += ("ASSERT({0} = (IF {1} = 0b{4} THEN BVSUB({5},0b{4},0b{6}1)"
                        "ELSE BVXOR({2}, {3}) ENDIF));\n".format(
                            tmp[z + 5*wordsize*rnd], 
                            xin[z + 5*wordsize*rnd], 
                            varibits, doublebits, "1"*5,
                            5, "0"*4))

            weight_sum += ("0b{0}@(BVPLUS({1}, {2}[0:0], {2}[1:1], "
                "{2}[2:2],{2}[3:3], {2}[4:4])),".format("0"*11, 5, "0b0000@" +
                                                        tmp[z + 5*wordsize*rnd]))

        command += "ASSERT({}=BVPLUS({},{}));\n".format(w[rnd], 16, 
                                                        weight_sum[:-1])

        # Linear after S-box
        command += "ASSERT({} = BVXOR({}, {}));\n".format(c[0 + 5*rnd],
                                                          b[0 + 5*rnd],
                                                          b[4 + 5*rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(c[1 + 5*rnd],
                                                          b[0 + 5*rnd],
                                                          b[1 + 5*rnd])
        command += "ASSERT({} = {});\n".format(c[2 + 5*rnd], b[2 + 5*rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(c[3 + 5*rnd],
                                                          b[2 + 5*rnd],
                                                          b[3 + 5*rnd])
        command += "ASSERT({} = {});\n".format(c[4 + 5*rnd], b[4 + 5*rnd])


        # Linear functions
        rot_constants = [[19, 28], [61, 39], [1, 6], [10, 17], [7, 41]]
        for row in range(5):
            command += "ASSERT({} = BVXOR({}, BVXOR({}, {})));\n".format(
                s[row + 5 * (rnd + 1)],
                c[row + 5*rnd],
                rotr(c[row + 5*rnd], rot_constants[row][0], wordsize),
                rotr(c[row + 5*rnd], rot_constants[row][1], wordsize),
            )

        stp_file.write(command)
        return
Exemplo n.º 24
0
    def setupSimonRound(self, stp_file, x_in, y_in, x_out, y_out, and_out, b, c,
                        abits, w, tmpWeight, sbits, pbits, wordsize):
        """
        Model for linear behaviour of one round SIMON.
        y[i+1] = x[i]
        x[i+1] = (x[i] <<< 1) & (x[i] <<< 8) ^ y[i] ^ (x[i] << 2)

        This is a loop unrolled version of the model presented in
        http://eprint.iacr.org/2015/145
        """
        command = ""

        deltarot = self.rot_alpha - self.rot_beta
        lout = y_in
        lin = "BVXOR(BVXOR({}, {}), {})".format(x_in, rotr(lout, self.rot_gamma, wordsize), y_out)
        #lin = "BVXOR({}, {})".format(x_in, rotr(lout, self.rot_gamma, wordsize))

        #Assert(y_out = x_in)
        command += "ASSERT({} = {});\n".format(x_out, y_in)

        #Assert for AND linear approximation
        tmp = "BVXOR(({0} | {1}), {2}) & {2}".format(
            rotr(lout, self.rot_alpha, wordsize),
            rotr(lout, self.rot_beta, wordsize),
            lin)

        command += "ASSERT({} = 0x{});\n".format(tmp, "0"*(wordsize // 4))

        #Assert for y_out
        # command += "ASSERT({0} = BVXOR({1}, BVXOR({2}, BVXOR({3}, {4}))));\n".format(
        #     y_out, x_in, rotr(lout, self.rot_alpha, wordsize), rotr(lout, self.rot_beta, wordsize),
        #     rotr(x_out, self.rot_gamma, wordsize))
        command += "ASSERT({0} = BVXOR({1}, BVXOR({2}, {3})));\n".format(
            y_out, x_in, rotr(x_out, self.rot_gamma, wordsize), lin)

        #For weight computation
        #Compute abits
        loutRotated = rotr(lout, deltarot, wordsize)

        command += "ASSERT({} = ({} & {}));\n".format(tmpWeight[0], lout, loutRotated)

        for i in range(1, wordsize):
            command += "ASSERT({} = ({} & {}));\n".format(
                tmpWeight[i], lout, rotr(tmpWeight[i - 1], deltarot, wordsize))

        abits = "BVXOR({}, {})".format(lout, tmpWeight[0])
        for i in range(1, wordsize):
            abits = "BVXOR({}, {})".format(tmpWeight[i], abits)

        #abits = y_in #only use weight

        #Weight computation
        #command += "ASSERT({0} = (IF {1} = 0x{3} THEN BVSUB({4},0x{3},0x{5}1) \
        #          ELSE {2} ENDIF));\n".format(
        #            w, y_in, abits, "f"*(wordsize / 4),
        #            wordsize, "0"*((wordsize / 4) - 1))

        command += "ASSERT({} = {});\n".format(w, abits)

        #Parity Checks
        command += "ASSERT({} = {});\n".format(
            sbits[0], rotr("({} & ~{} & ~{})".format(
                rotr(lout, deltarot, wordsize), lout, rotr(abits, deltarot, wordsize)),
                1, wordsize))

        command += "ASSERT({} = {});\n".format(
            pbits[0], rotl("({} & {})".format(sbits[0], lin), 2*deltarot, wordsize))

        for i in range(1, wordsize):
            command += "ASSERT({} = {});\n".format(
                sbits[i], rotl("({} & {})".format(
                    rotl(sbits[i - 1], deltarot, wordsize),
                    rotr(sbits[i-1], self.rot_beta, wordsize)),
                    deltarot, wordsize)
                )
            command += "ASSERT({} = {});\n".format(
                pbits[i], rotl("BVXOR({}, {} & {})".format(
                    pbits[i - 1], sbits[i], lin), 2*deltarot, wordsize)
                )

        command += "ASSERT({} = 0x{});\n".format(pbits[wordsize - 1], "0"*(wordsize // 4))

        stp_file.write(command)
        return
Exemplo n.º 25
0
    def getStringForSipRound(self, v0_in, v1_in, v2_in, v3_in, a0, a1, a2, a3,
                             v0_out, v1_out, v2_out, v3_out, w0, w1, w2, w3,
                             wordsize):
        """
        Returns a string representing SipRound in STP.

        a0 = (v1 + v0) <<< 32
        a1 = (v1 + v0) ^ (v1 <<< 13)
        a2 = (v2 + v3)
        a3 = (v2 + v3) ^ (v3 <<< 16)

        v0_out = (a0 + a3)
        v1_out = (a2 + a1) ^ (a1 <<< 17)
        v2_out = (a2 + a1) <<< 32
        v3_out = (a0 + a3) ^ (a3 <<< 21)
        """
        command = ""

        #Assert intermediate values

        #Rotate right to get correct output value
        #a0
        command += "ASSERT("
        command += stpcommands.getStringAdd(
            v1_in, v0_in, rotr(a0, 32, wordsize), wordsize)
        command += ");\n"

        #a1
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            a1, rotl(v1_in, 13, wordsize), rotr(a0, 32, wordsize))

        #a2
        command += "ASSERT("
        command += stpcommands.getStringAdd(v2_in, v3_in, a2, wordsize)
        command += ");\n"

        #a3
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            a3, rotl(v3_in, 16, wordsize), a2)

        #v0_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(a0, a3, v0_out, wordsize)
        command += ");\n"

        #v1_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            v1_out, rotl(a1, 17, wordsize), rotr(v2_out, 32, wordsize))

        #v2_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(
            a2, a1, rotr(v2_out, 32, wordsize), wordsize)
        command += ");\n"

        #v3_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            v3_out, rotl(a3, 21, wordsize), v0_out)

        # Lipmaa and Moriai
        command += "ASSERT({0} = ~".format(w0)
        command += stpcommands.getStringEq(
            v1_in, v0_in, rotr(a0, 32, wordsize))
        command += ");\n"

        command += "ASSERT({0} = ~".format(w1)
        command += stpcommands.getStringEq(v2_in, v3_in, a2)
        command += ");\n"

        command += "ASSERT({0} = ~".format(w2)
        command += stpcommands.getStringEq(a0, a3, v0_out)
        command += ");\n"

        command += "ASSERT({0} = ~".format(w3)
        command += stpcommands.getStringEq(
            a2, a1, rotr(v2_out, 32, wordsize))
        command += ");\n"

        return command
Exemplo n.º 26
0
 def getDoubleBits(self, xin, rot_alpha, rot_beta):
     command = "({0} & ~{1} & {2})".format(
         rotl(xin, rot_beta, 5), rotl(xin, rot_alpha, 5),
         rotl(xin, 2*rot_alpha - rot_beta, 5))
     return command
Exemplo n.º 27
0
    def setupKeccakRound(self, stp_file, rnd, s, a, b, c, d, wordsize, tmp,
                         w, m, xin, xout, andOut):
        """
        Model for one round of Keccak.
        """
        command = ""

        #xor the state with the message for the first two words
        for x in range(5):
            for y in range(5):
                if(x == 0 and y == 0) or (x == 1 and y == 0):
                    command += "ASSERT({}=BVXOR({},{}));\n".format(
                    a[x + 5*y + 25*rnd], s[x + 5*y + 25*rnd], m[x + 2*rnd])
                else:
                    command += "ASSERT({}={});\n".format(
                    a[x + 5*y + 25*rnd], s[x + 5*y + 25*rnd])        

        # Linear functions
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR({}, BVXOR({}, {})))));\n".format(
                c[i + 5*rnd], a[i + 5*0 + 25*rnd], a[i + 5*1 + 25*rnd],
                a[i + 5*2 + 25*rnd], a[i + 5*3 + 25*rnd], a[i + 5*4 + 25*rnd])

        # Compute intermediate values
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, {}));\n".format(
                d[i + 5*rnd], c[(i - 1) % 5 + 5*rnd],
                rotl(c[(i + 1) % 5 + 5*rnd], 1, wordsize))

        # Rho and Pi
        for x in range(5):
            for y in range(5):
                new_b_index = y + 5*((2*x + 3*y) % 5) + 25*rnd
                tmp_xor = "BVXOR({}, {})".format(a[x + 5*y + 25*rnd], d[x + 5*rnd])
                command += "ASSERT({} = {});\n".format(
                    b[new_b_index], rotl(tmp_xor, self.RO[x][y], wordsize))

        # Chi
        rot_alpha = 2
        rot_beta = 1
        weight_sum = ""

        for y in range(5):
            for z in range(wordsize):
                # Construct S-box input
                command += "ASSERT({}={});\n".format(
                    xin[z + wordsize*y + 5*wordsize*rnd],
                    b[0 + 5*y + 25*rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[1 + 5*y + 25*rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[2 + 5*y + 25*rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[3 + 5*y + 25*rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[4 + 5*y + 25*rnd] + "[{0}:{0}]".format(z))

                # Construct S-box output
                command += "ASSERT({}={});\n".format(
                    xout[z + wordsize*y + 5*wordsize*rnd],
                    s[0 + 5*y + 25*(rnd+1)] + "[{0}:{0}]".format(z) + "@" +
                    s[1 + 5*y + 25*(rnd+1)] + "[{0}:{0}]".format(z) + "@" +
                    s[2 + 5*y + 25*(rnd+1)] + "[{0}:{0}]".format(z) + "@" +
                    s[3 + 5*y + 25*(rnd+1)] + "[{0}:{0}]".format(z) + "@" +
                    s[4 + 5*y + 25*(rnd+1)] + "[{0}:{0}]".format(z))

                xin_rotalpha = rotl(xin[z + wordsize*y + 5*wordsize*rnd], rot_alpha, 5)
                xin_rotbeta = rotl(xin[z + wordsize*y + 5*wordsize*rnd], rot_beta, 5)

                #Deal with dependent inputs
                varibits = "({0} | {1})".format(xin_rotalpha, xin_rotbeta)
                doublebits = self.getDoubleBits(xin[z + wordsize*y + 5*wordsize*rnd], rot_alpha, rot_beta)

                #Check for valid difference
                firstcheck = "({} & ~{})".format(andOut[z + wordsize*y + 5*wordsize*rnd], varibits)
                secondcheck = "(~BVXOR({}, {}) & {})".format(
                andOut[z + wordsize*y + 5*wordsize*rnd], rotl(andOut[z + wordsize*y + 5*wordsize*rnd], rot_alpha - rot_beta, 5), doublebits)
                thirdcheck = "(IF {0} = 0b{1} THEN BVMOD(5, {0}, 0b00010) ELSE 0b{2}ENDIF)".format(
                xin[z + wordsize*y + 5*wordsize*rnd], "11111", "00000")
                command += "ASSERT(({} | {} | {}) = 0b{});\n".format(firstcheck,
                secondcheck, thirdcheck, "00000")

                #Assert XORs
                command += "ASSERT({} = BVXOR({},{}));\n".format(
                    xout[z + wordsize*y + 5*wordsize*rnd], 
                    xin[z + wordsize*y + 5*wordsize*rnd], 
                    andOut[z + wordsize*y + 5*wordsize*rnd])

                #Weight computation
                command += ("ASSERT({0} = (IF {1} = 0b{4} THEN BVSUB({5},0b{4},0b{6}1)"
                            "ELSE BVXOR({2}, {3}) ENDIF));\n".format(
                                tmp[z + wordsize*y + 5*wordsize*rnd], 
                                xin[z + wordsize*y + 5*wordsize*rnd], 
                                varibits, doublebits, "1"*5,
                                5, "0"*4))

                weight_sum += ("0b{0}@(BVPLUS({1}, {2}[0:0], {2}[1:1], "
                               "{2}[2:2],{2}[3:3], {2}[4:4])),".format(
                                    "0"*11, 5, "0b0000@" + 
                                    tmp[z + wordsize*y + 5*wordsize*rnd]))

        command += "ASSERT({}=BVPLUS({},{}));\n".format(w[rnd], 16, weight_sum[:-1])

        stp_file.write(command)
        return
Exemplo n.º 28
0
    def setupAsconRound(self, stp_file, rnd, s, a, b, c, wordsize, tmp, w, xin,
                        xout, andout):
        """
        Model for one round of Ascon.
        """
        command = ""
        weight_sum = ""

        # Linear part in S-box
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            a[0 + 5 * rnd], s[0 + 5 * rnd], s[4 + 5 * rnd])
        command += "ASSERT({} = {});\n".format(a[1 + 5 * rnd], s[1 + 5 * rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            a[2 + 5 * rnd], s[2 + 5 * rnd], s[1 + 5 * rnd])
        command += "ASSERT({} = {});\n".format(a[3 + 5 * rnd], s[3 + 5 * rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            a[4 + 5 * rnd], s[4 + 5 * rnd], s[3 + 5 * rnd])

        # Model for the S-box

        for z in range(wordsize):
            # Construct S-box input
            command += "ASSERT({}={});\n".format(
                xin[z + 5 * wordsize * rnd],
                a[0 + 5 * rnd] + "[{0}:{0}]".format(z) + "@" + a[1 + 5 * rnd] +
                "[{0}:{0}]".format(z) + "@" + a[2 + 5 * rnd] +
                "[{0}:{0}]".format(z) + "@" + a[3 + 5 * rnd] +
                "[{0}:{0}]".format(z) + "@" + a[4 + 5 * rnd] +
                "[{0}:{0}]".format(z))

            # Construct S-box output
            command += "ASSERT({}={});\n".format(
                xout[z + 5 * wordsize * rnd],
                b[0 + 5 * rnd] + "[{0}:{0}]".format(z) + "@" + b[1 + 5 * rnd] +
                "[{0}:{0}]".format(z) + "@" + b[2 + 5 * rnd] +
                "[{0}:{0}]".format(z) + "@" + b[3 + 5 * rnd] +
                "[{0}:{0}]".format(z) + "@" + b[4 + 5 * rnd] +
                "[{0}:{0}]".format(z))

            xin_rotalpha = rotl(xin[z + 5 * wordsize * rnd], 2, 5)
            xin_rotbeta = rotl(xin[z + 5 * wordsize * rnd], 1, 5)

            #Deal with dependent inputs
            varibits = "({0} | {1})".format(xin_rotalpha, xin_rotbeta)
            doublebits = self.getDoubleBits(xin[z + 5 * wordsize * rnd])

            #Check for valid difference
            firstcheck = "({} & ~{})".format(andout[z + 5 * wordsize * rnd],
                                             varibits)
            secondcheck = "(~BVXOR({}, {}) & {})".format(
                andout[z + 5 * wordsize * rnd],
                rotl(andout[z + 5 * wordsize * rnd], 2 - 1, 5), doublebits)
            thirdcheck = "(IF {0} = 0b{1} THEN BVMOD(5, {0}, 0b00010) ELSE 0b{2}ENDIF)".format(
                xin[z + 5 * wordsize * rnd], "11111", "00000")
            command += "ASSERT(({} | {} | {}) = 0b{});\n".format(
                firstcheck, secondcheck, thirdcheck, "00000")

            #Assert XORs
            command += "ASSERT({} = BVXOR({},{}));\n".format(
                xout[z + 5 * wordsize * rnd], xin[z + 5 * wordsize * rnd],
                andout[z + 5 * wordsize * rnd])

            #Weight computation
            command += (
                "ASSERT({0} = (IF {1} = 0b{4} THEN BVSUB({5},0b{4},0b{6}1)"
                "ELSE BVXOR({2}, {3}) ENDIF));\n".format(
                    tmp[z + 5 * wordsize * rnd], xin[z + 5 * wordsize * rnd],
                    varibits, doublebits, "1" * 5, 5, "0" * 4))

            weight_sum += ("0b{0}@(BVPLUS({1}, {2}[0:0], {2}[1:1], "
                           "{2}[2:2],{2}[3:3], {2}[4:4])),".format(
                               "0" * 11, 5,
                               "0b0000@" + tmp[z + 5 * wordsize * rnd]))

        command += "ASSERT({}=BVPLUS({},{}));\n".format(
            w[rnd], 16, weight_sum[:-1])

        # Linear after S-box
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            c[0 + 5 * rnd], b[0 + 5 * rnd], b[4 + 5 * rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            c[1 + 5 * rnd], b[0 + 5 * rnd], b[1 + 5 * rnd])
        command += "ASSERT({} = {});\n".format(c[2 + 5 * rnd], b[2 + 5 * rnd])
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            c[3 + 5 * rnd], b[2 + 5 * rnd], b[3 + 5 * rnd])
        command += "ASSERT({} = {});\n".format(c[4 + 5 * rnd], b[4 + 5 * rnd])

        # Linear functions
        rot_constants = [[19, 28], [61, 39], [1, 6], [10, 17], [7, 41]]
        for row in range(5):
            command += "ASSERT({} = BVXOR({}, BVXOR({}, {})));\n".format(
                s[row + 5 * (rnd + 1)],
                c[row + 5 * rnd],
                rotr(c[row + 5 * rnd], rot_constants[row][0], wordsize),
                rotr(c[row + 5 * rnd], rot_constants[row][1], wordsize),
            )

        stp_file.write(command)
        return
Exemplo n.º 29
0
 def getDoubleBits(self, xin):
     command = "({0} & ~{1} & {2})".format(rotl(xin, 1, 5), rotl(xin, 2, 5),
                                           rotl(xin, 2 * 2 - 1, 5))
     return command
Exemplo n.º 30
0
 def getDoubleBits(self, xin, rot_alpha, rot_beta):
     command = "({0} & ~{1} & {2})".format(
         rotl(xin, rot_beta, 5), rotl(xin, rot_alpha, 5),
         rotl(xin, 2 * rot_alpha - rot_beta, 5))
     return command
Exemplo n.º 31
0
    def getStringForSipRound(self, v0_in, v1_in, v2_in, v3_in, a0, a1, a2, a3,
                             v0_out, v1_out, v2_out, v3_out, w0, w1, w2, w3,
                             wordsize):
        """
        Returns a string representing SipRound in STP.

        a0 = (v1 + v0) <<< 32
        a1 = (v1 + v0) ^ (v1 <<< 13)
        a2 = (v2 + v3)
        a3 = (v2 + v3) ^ (v3 <<< 16)

        v0_out = (a0 + a3)
        v1_out = (a2 + a1) ^ (a1 <<< 17)
        v2_out = (a2 + a1) <<< 32
        v3_out = (a0 + a3) ^ (a3 <<< 21)
        """
        command = ""

        #Assert intermediate values

        #Rotate right to get correct output value
        #a0
        command += "ASSERT("
        command += stpcommands.getStringAdd(v1_in, v0_in,
                                            rotr(a0, 32, wordsize), wordsize)
        command += ");\n"

        #a1
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            a1, rotl(v1_in, 13, wordsize), rotr(a0, 32, wordsize))

        #a2
        command += "ASSERT("
        command += stpcommands.getStringAdd(v2_in, v3_in, a2, wordsize)
        command += ");\n"

        #a3
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            a3, rotl(v3_in, 16, wordsize), a2)

        #v0_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(a0, a3, v0_out, wordsize)
        command += ");\n"

        #v1_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            v1_out, rotl(a1, 17, wordsize), rotr(v2_out, 32, wordsize))

        #v2_out
        command += "ASSERT("
        command += stpcommands.getStringAdd(a2, a1, rotr(v2_out, 32, wordsize),
                                            wordsize)
        command += ");\n"

        #v3_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            v3_out, rotl(a3, 21, wordsize), v0_out)

        # Lipmaa and Moriai
        command += "ASSERT({0} = ~".format(w0)
        command += stpcommands.getStringEq(v1_in, v0_in,
                                           rotr(a0, 32, wordsize))
        command += ");\n"

        command += "ASSERT({0} = ~".format(w1)
        command += stpcommands.getStringEq(v2_in, v3_in, a2)
        command += ");\n"

        command += "ASSERT({0} = ~".format(w2)
        command += stpcommands.getStringEq(a0, a3, v0_out)
        command += ");\n"

        command += "ASSERT({0} = ~".format(w3)
        command += stpcommands.getStringEq(a2, a1, rotr(v2_out, 32, wordsize))
        command += ");\n"

        return command
Exemplo n.º 32
0
    def setupKeccakRound(self, stp_file, rnd, s, b, c, d, wordsize, tmp, w,
                         xin, xout, andOut):
        """
        Model for one round of Keccak.
        """
        command = ""

        # Linear functions
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR({}, BVXOR({}, {})))));\n".format(
                c[i + 5 * rnd], s[i + 5 * 0 + 25 * rnd],
                s[i + 5 * 1 + 25 * rnd], s[i + 5 * 2 + 25 * rnd],
                s[i + 5 * 3 + 25 * rnd], s[i + 5 * 4 + 25 * rnd])

        # Compute intermediate values
        for i in range(5):
            command += "ASSERT({} = BVXOR({}, {}));\n".format(
                d[i + 5 * rnd], c[(i - 1) % 5 + 5 * rnd],
                rotl(c[(i + 1) % 5 + 5 * rnd], 1, wordsize))

        # Rho and Pi
        for x in range(5):
            for y in range(5):
                new_b_index = y + 5 * ((2 * x + 3 * y) % 5) + 25 * rnd
                tmp_xor = "BVXOR({}, {})".format(s[x + 5 * y + 25 * rnd],
                                                 d[x + 5 * rnd])
                command += "ASSERT({} = {});\n".format(
                    b[new_b_index], rotl(tmp_xor, self.RO[x][y], wordsize))

        # Chi
        rot_alpha = 2
        rot_beta = 1
        weight_sum = ""

        for y in range(5):
            for z in range(wordsize):
                # Construct S-box input
                command += "ASSERT({}={});\n".format(
                    xin[z + wordsize * y + 5 * wordsize * rnd],
                    b[0 + 5 * y + 25 * rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[1 + 5 * y + 25 * rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[2 + 5 * y + 25 * rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[3 + 5 * y + 25 * rnd] + "[{0}:{0}]".format(z) + "@" +
                    b[4 + 5 * y + 25 * rnd] + "[{0}:{0}]".format(z))

                # Construct S-box output
                command += "ASSERT({}={});\n".format(
                    xout[z + wordsize * y + 5 * wordsize * rnd],
                    s[0 + 5 * y + 25 * (rnd + 1)] + "[{0}:{0}]".format(z) +
                    "@" + s[1 + 5 * y + 25 *
                            (rnd + 1)] + "[{0}:{0}]".format(z) + "@" +
                    s[2 + 5 * y + 25 * (rnd + 1)] + "[{0}:{0}]".format(z) +
                    "@" + s[3 + 5 * y + 25 *
                            (rnd + 1)] + "[{0}:{0}]".format(z) + "@" +
                    s[4 + 5 * y + 25 * (rnd + 1)] + "[{0}:{0}]".format(z))

                xin_rotalpha = rotl(xin[z + wordsize * y + 5 * wordsize * rnd],
                                    rot_alpha, 5)
                xin_rotbeta = rotl(xin[z + wordsize * y + 5 * wordsize * rnd],
                                   rot_beta, 5)

                #Deal with dependent inputs
                varibits = "({0} | {1})".format(xin_rotalpha, xin_rotbeta)
                doublebits = self.getDoubleBits(
                    xin[z + wordsize * y + 5 * wordsize * rnd], rot_alpha,
                    rot_beta)

                #Check for valid difference
                firstcheck = "({} & ~{})".format(
                    andOut[z + wordsize * y + 5 * wordsize * rnd], varibits)
                secondcheck = "(~BVXOR({}, {}) & {})".format(
                    andOut[z + wordsize * y + 5 * wordsize * rnd],
                    rotl(andOut[z + wordsize * y + 5 * wordsize * rnd],
                         rot_alpha - rot_beta, 5), doublebits)
                thirdcheck = "(IF {0} = 0b{1} THEN BVMOD(5, {0}, 0b00010) ELSE 0b{2}ENDIF)".format(
                    xin[z + wordsize * y + 5 * wordsize * rnd], "11111",
                    "00000")
                command += "ASSERT(({} | {} | {}) = 0b{});\n".format(
                    firstcheck, secondcheck, thirdcheck, "00000")

                #Assert XORs
                command += "ASSERT({} = BVXOR({},{}));\n".format(
                    xout[z + wordsize * y + 5 * wordsize * rnd],
                    xin[z + wordsize * y + 5 * wordsize * rnd],
                    andOut[z + wordsize * y + 5 * wordsize * rnd])

                #Weight computation
                if rnd != 3:
                    command += (
                        "ASSERT({0} = (IF {1} = 0b{4} THEN BVSUB({5},0b{4},0b{6}1)"
                        "ELSE BVXOR({2}, {3}) ENDIF));\n".format(
                            tmp[z + wordsize * y + 5 * wordsize * rnd],
                            xin[z + wordsize * y + 5 * wordsize * rnd],
                            varibits, doublebits, "1" * 5, 5, "0" * 4))
                else:
                    command += ("ASSERT({0} = {1});\n".format(
                        tmp[z + wordsize * y + 5 * wordsize * rnd], "0b00000"))

                weight_sum += ("0b{0}@(BVPLUS({1}, {2}[0:0], {2}[1:1], "
                               "{2}[2:2],{2}[3:3], {2}[4:4])),".format(
                                   "0" * 11, 5, "0b0000@" +
                                   tmp[z + wordsize * y + 5 * wordsize * rnd]))

        command += "ASSERT({}=BVPLUS({},{}));\n".format(
            w[rnd], 16, weight_sum[:-1])

        stp_file.write(command)
        return
Exemplo n.º 33
0
 def getDoubleBits(self, xin):
     command = "({0} & ~{1} & {2})".format(
         rotl(xin, 1, 5), rotl(xin, 2, 5),
         rotl(xin, 2*2 - 1, 5))
     return command
Exemplo n.º 34
0
    def setupSimonRound(self, stp_file, x_in, y_in, x_out, y_out, and_out, b,
                        c, abits, w, tmpWeight, sbits, pbits, wordsize):
        """
        Model for linear behaviour of one round SIMON.
        y[i+1] = x[i]
        x[i+1] = (x[i] <<< 1) & (x[i] <<< 8) ^ y[i] ^ (x[i] << 2)

        This is a loop unrolled version of the model presented in
        http://eprint.iacr.org/2015/145
        """
        command = ""

        deltarot = self.rot_alpha - self.rot_beta
        lout = y_in
        lin = "BVXOR(BVXOR({}, {}), {})".format(
            x_in, rotr(lout, self.rot_gamma, wordsize), y_out)
        #lin = "BVXOR({}, {})".format(x_in, rotr(lout, self.rot_gamma, wordsize))

        #Assert(y_out = x_in)
        command += "ASSERT({} = {});\n".format(x_out, y_in)

        #Assert for AND linear approximation
        tmp = "BVXOR(({0} | {1}), {2}) & {2}".format(
            rotr(lout, self.rot_alpha, wordsize),
            rotr(lout, self.rot_beta, wordsize), lin)

        command += "ASSERT({} = 0x{});\n".format(tmp, "0" * (wordsize // 4))

        #Assert for y_out
        # command += "ASSERT({0} = BVXOR({1}, BVXOR({2}, BVXOR({3}, {4}))));\n".format(
        #     y_out, x_in, rotr(lout, self.rot_alpha, wordsize), rotr(lout, self.rot_beta, wordsize),
        #     rotr(x_out, self.rot_gamma, wordsize))
        command += "ASSERT({0} = BVXOR({1}, BVXOR({2}, {3})));\n".format(
            y_out, x_in, rotr(x_out, self.rot_gamma, wordsize), lin)

        #For weight computation
        #Compute abits
        loutRotated = rotr(lout, deltarot, wordsize)

        command += "ASSERT({} = ({} & {}));\n".format(tmpWeight[0], lout,
                                                      loutRotated)

        for i in range(1, wordsize):
            command += "ASSERT({} = ({} & {}));\n".format(
                tmpWeight[i], lout, rotr(tmpWeight[i - 1], deltarot, wordsize))

        abits = "BVXOR({}, {})".format(lout, tmpWeight[0])
        for i in range(1, wordsize):
            abits = "BVXOR({}, {})".format(tmpWeight[i], abits)

        #abits = y_in #only use weight

        #Weight computation
        #command += "ASSERT({0} = (IF {1} = 0x{3} THEN BVSUB({4},0x{3},0x{5}1) \
        #          ELSE {2} ENDIF));\n".format(
        #            w, y_in, abits, "f"*(wordsize / 4),
        #            wordsize, "0"*((wordsize / 4) - 1))

        command += "ASSERT({} = {});\n".format(w, abits)

        #Parity Checks
        command += "ASSERT({} = {});\n".format(
            sbits[0],
            rotr(
                "({} & ~{} & ~{})".format(rotr(lout, deltarot, wordsize), lout,
                                          rotr(abits, deltarot, wordsize)), 1,
                wordsize))

        command += "ASSERT({} = {});\n".format(
            pbits[0],
            rotl("({} & {})".format(sbits[0], lin), 2 * deltarot, wordsize))

        for i in range(1, wordsize):
            command += "ASSERT({} = {});\n".format(
                sbits[i],
                rotl(
                    "({} & {})".format(
                        rotl(sbits[i - 1], deltarot, wordsize),
                        rotr(sbits[i - 1], self.rot_beta, wordsize)), deltarot,
                    wordsize))
            command += "ASSERT({} = {});\n".format(
                pbits[i],
                rotl("BVXOR({}, {} & {})".format(pbits[i - 1], sbits[i], lin),
                     2 * deltarot, wordsize))

        command += "ASSERT({} = 0x{});\n".format(pbits[wordsize - 1],
                                                 "0" * (wordsize // 4))

        stp_file.write(command)
        return
Exemplo n.º 35
0
 def getDoubleBits(self, x_in, wordsize):
     command = "({0} & ~{1} & {2})".format(
         rotl(x_in, self.rot_beta, wordsize),
         rotl(x_in, self.rot_alpha, wordsize),
         rotl(x_in, 2 * self.rot_alpha - self.rot_beta, wordsize))
     return command
Exemplo n.º 36
0
    def setupRound(self, stp_file, x_in, y_in, x_out, y_out, out_G0, out_G1,
                   rot_G0, rot_G1, xor_G, perm_G, act_flag, w, wordsize):
        """
        Model for differential behaviour of one round
        """
        command = ""

        # 1. y_out = x_in
        command += "ASSERT({} = {});\n".format(y_out, x_in)

        # 2. pass SSb: x -> out_G0, out_G1
        for i in range(wordsize // 4):
            s_in_4_bit = "{0}[{1}:{1}]@{0}[{2}:{2}]@" \
                         "{0}[{3}:{3}]@{0}[{4}:{4}]".format(
                            x_in,
                            wordsize - 1 - 4 * i - 0,
                            wordsize - 1 - 4 * i - 1,
                            wordsize - 1 - 4 * i - 2,
                            wordsize - 1 - 4 * i - 3,
                            )
            s_out_4_bit_G0 = "{0}[{1}:{1}]@{0}[{2}:{2}]@" \
                             "{0}[{3}:{3}]@{0}[{4}:{4}]".format(
                            out_G0,
                            wordsize - 1 - 4 * i - 0,
                            wordsize - 1 - 4 * i - 1,
                            wordsize - 1 - 4 * i - 2,
                            wordsize - 1 - 4 * i - 3,
                            )
            s_out_4_bit_G1 = "{0}[{1}:{1}]@{0}[{2}:{2}]@" \
                             "{0}[{3}:{3}]@{0}[{4}:{4}]".format(
                            out_G1,
                            wordsize - 1 - 4 * i - 0,
                            wordsize - 1 - 4 * i - 1,
                            wordsize - 1 - 4 * i - 2,
                            wordsize - 1 - 4 * i - 3,
                            )
            command += "ASSERT(SBOX[{}@{}@{}] = 0bin1);\n".format(
                s_in_4_bit, s_out_4_bit_G0, s_out_4_bit_G1)
            command += "ASSERT({1} = (IF {0} = 0bin0000 " \
                                            "THEN 0bin0 " \
                                      "ELSE 0bin1 ENDIF));\n".format(
                        s_in_4_bit,
                        "{0}[{1}:{1}]".format(act_flag, wordsize // 4 - 1 - i))

        # 3. rot out_G0, out_G1
        out_G0_rotalpha = rotl(out_G0, self.rot_alpha, wordsize)
        out_G1_rotbeta = rotl(out_G1, self.rot_beta, wordsize)
        command += "ASSERT({} = {});\n".format(rot_G0, out_G0_rotalpha)
        command += "ASSERT({} = {});\n".format(rot_G1, out_G1_rotbeta)

        # 4. G0 ^ G1 = xor_G
        command += "ASSERT({} = BVXOR({}, {}));\n".format(
            xor_G, rot_G0, rot_G1)

        # 4. xor_G PERM to perm_G
        for i in range(wordsize):
            command += "ASSERT({0}[{1}:{1}] = {2}[{3}:{3}]);\n".format(
                perm_G, self.PERM[i], xor_G, i)

        # 5. perm_G ^ y_in = x_out
        command += "ASSERT({} = BVXOR({}, {}));\n".format(y_in, perm_G, x_out)

        # 6. Weight computation
        sum_w_i = stpcommands.getWeightString([act_flag], wordsize // 4, 0, w)
        sum_w_i += '\n'
        command += sum_w_i

        stp_file.write(command)
        return