예제 #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
예제 #2
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
예제 #3
0
파일: speck.py 프로젝트: jamella/cryptosmt
    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
예제 #4
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
예제 #5
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
예제 #6
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
예제 #7
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
예제 #8
0
 def setupSimonKey(self, stp_file, k, rounds, wordsize):
     command = ""
     for i in range(4, rounds):
         tmpZ = "BVXOR({}, {})".format(rotr(k[i - 1], 3, wordsize), k[i - 3])
         command += "ASSERT({} = ".format(k[i])
         command += "BVXOR({}, ".format(tmpZ)
         command += "BVXOR({}, ".format(rotr(tmpZ, 1, wordsize))
         command += "BVXOR({}, ~{}".format(k[i - 3], k[i - 4])
         command += "))));\n"
     stp_file.write(command)
     return
예제 #9
0
 def setupSimonKey(self, stp_file, k, rounds, wordsize):
     command = ""
     for i in range(4, rounds):
         tmpZ = "BVXOR({}, {})".format(rotr(k[i - 1], 3, wordsize),
                                       k[i - 3])
         command += "ASSERT({} = ".format(k[i])
         command += "BVXOR({}, ".format(tmpZ)
         command += "BVXOR({}, ".format(rotr(tmpZ, 1, wordsize))
         command += "BVXOR({}, ~{}".format(k[i - 3], k[i - 4])
         command += "))));\n"
     stp_file.write(command)
     return
예제 #10
0
 def setupKeySchedule(self, stp_file, key, tmp_key, rounds, wordsize):
     command = ""
     const3 = "0x{}3".format("0"*(wordsize // 4 - 1))
     if rounds > 4:
         for i in range(4, rounds):
             constz = "0x{}{}".format("0"*(wordsize // 4 - 1),
                                      self.CONST_Z[(i - 4) % 62])
             tmp = "BVXOR({}, {})".format(rotr(key[i-1], 3, wordsize), key[i-3])
             command += "ASSERT({} = BVXOR({}, {}));\n".format(
                 tmp_key[i], tmp, rotr(tmp, 1, wordsize))
             command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR(~{}, {}))));\n".format(
                 key[i], constz, const3, key[i-4], tmp_key[i])
     stp_file.write(command)
     return
예제 #11
0
 def setupKeySchedule(self, stp_file, key, tmp_key, rounds, wordsize):
     command = ""
     const3 = "0x{}3".format("0" * (wordsize // 4 - 1))
     if rounds > 4:
         for i in range(4, rounds):
             constz = "0x{}{}".format("0" * (wordsize // 4 - 1),
                                      self.CONST_Z[(i - 4) % 62])
             tmp = "BVXOR({}, {})".format(rotr(key[i - 1], 3, wordsize),
                                          key[i - 3])
             command += "ASSERT({} = BVXOR({}, {}));\n".format(
                 tmp_key[i], tmp, rotr(tmp, 1, wordsize))
             command += "ASSERT({} = BVXOR({}, BVXOR({}, BVXOR(~{}, {}))));\n".format(
                 key[i], constz, const3, key[i - 4], tmp_key[i])
     stp_file.write(command)
     return
예제 #12
0
    def pi2(self, in0, in1, in2, in3, out0, out1, out2, out3, wordsize):
        """
        Model for the Pi2 function in NOEKEON - which is the inverse of pi1
        """
        command = ""

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

        return command
예제 #13
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
예제 #14
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
예제 #15
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
예제 #16
0
파일: ascon.py 프로젝트: jamella/cryptosmt
    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
예제 #17
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
예제 #18
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