# Path: parser/stpcommands.py
# def blockCharacteristic(stpfile, characteristic, wordsize):
# def setupQuery(stpfile):
# def setupVariables(stpfile, variables, wordsize):
# def assertVariableValue(stpfile, a, b):
# def getStringForVariables(variables, wordsize):
# def assertNonZero(stpfile, variables, wordsize):
# def getStringForNonZero(variables, wordsize):
# def limitWeight(stpfile, weight, p, wordsize, ignoreMSBs=0):
# def setupWeightComputationSum(stpfile, weight, p, wordsize, ignoreMSBs=0):
# def setupWeightComputation(stpfile, weight, p, wordsize, ignoreMSBs=0):
# def getWeightString(variables, wordsize, ignoreMSBs=0, weightVariable="weight"):
# def getStringEq(a, b, c):
# def getStringAdd(a, b, c, wordsize):
# def getStringForAndDifferential(a, b, c):
# def getStringLeftRotate(value, rotation, wordsize):
# def getStringRightRotate(value, rotation, wordsize):
# def add4bitSbox(sbox, variables):
#     DDT = [[0]*16 for i in range(16)]
# 
# Path: ciphers/cipher.py
# class AbstractCipher(object, metaclass=ABCMeta):
#     """
#     Abstract Class for Ciphers
#     """
# 
#     @abstractmethod
#     def createSTP(self, filename, cipherParameters):
#         """
#         Each cipher need to define how it creates an instance for the
#         SMT solver.
#         """
#         pass
# 
#     @abstractmethod
#     def getFormatString(self):
#         """
#         Each cipher needs to specify the format it should be printed.
#         """
#         pass
# 
# Path: parser/stpcommands.py
# def getStringRightRotate(value, rotation, wordsize):
#     if rotation % wordsize == 0:
#         return "{0}".format(value)
#     command = "((({0} >> {1})[{2}:0]) | (({0} << {3})[{2}:0]))".format(
#         value, (rotation % wordsize), wordsize - 1, (wordsize - rotation) % wordsize)
#     return command
# 
# Path: parser/stpcommands.py
# def getStringLeftRotate(value, rotation, wordsize):
#     if rotation % wordsize == 0:
#         return "{0}".format(value)
#     command = "((({0} << {1})[{2}:0]) | (({0} >> {3})[{2}:0]))".format(
#         value, (rotation % wordsize), wordsize - 1, (wordsize - rotation) % wordsize)
# 
#     return command


from parser import stpcommands
from ciphers.cipher import AbstractCipher
from parser.stpcommands import getStringRightRotate as rotr
from parser.stpcommands import getStringLeftRotate as rotl
                                         x0l_after_L[i], x0r_after_L[i],
                                         x1l_after_L[i], x1r_after_L[i],
                                         x0l[i+1], x0r[i+1],
                                         x1l[i+1], x1r[i+1],
                                         x2l[i+1], x2r[i+1],
                                         x3l[i+1], x3r[i+1])
                else:
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x0l[i], x0r[i], x0l[i+1], x0r[i+1],
                                           wx0[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x1l[i], x1r[i], x1l[i+1], x1r[i+1],
                                           wx1[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x2l[i], x2r[i], x2l[i+1], x2r[i+1],
                                           wx2[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x3l[i], x3r[i], x3l[i+1], x3r[i+1],
                                           wx3[i], wordsize)

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

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

# Path: parser/stpcommands.py
# def blockCharacteristic(stpfile, characteristic, wordsize):
# def setupQuery(stpfile):
# def setupVariables(stpfile, variables, wordsize):
# def assertVariableValue(stpfile, a, b):
# def getStringForVariables(variables, wordsize):
# def assertNonZero(stpfile, variables, wordsize):
# def getStringForNonZero(variables, wordsize):
# def limitWeight(stpfile, weight, p, wordsize, ignoreMSBs=0):
# def setupWeightComputationSum(stpfile, weight, p, wordsize, ignoreMSBs=0):
# def setupWeightComputation(stpfile, weight, p, wordsize, ignoreMSBs=0):
# def getWeightString(variables, wordsize, ignoreMSBs=0, weightVariable="weight"):
# def getStringEq(a, b, c):
# def getStringAdd(a, b, c, wordsize):
# def getStringForAndDifferential(a, b, c):
# def getStringLeftRotate(value, rotation, wordsize):
# def getStringRightRotate(value, rotation, wordsize):
# def add4bitSbox(sbox, variables):
#     DDT = [[0]*16 for i in range(16)]
# 
# Path: ciphers/cipher.py
# class AbstractCipher(object, metaclass=ABCMeta):
#     """
#     Abstract Class for Ciphers
#     """
# 
#     @abstractmethod
#     def createSTP(self, filename, cipherParameters):
#         """
#         Each cipher need to define how it creates an instance for the
#         SMT solver.
#         """
#         pass
# 
#     @abstractmethod
#     def getFormatString(self):
#         """
#         Each cipher needs to specify the format it should be printed.
#         """
#         pass
# 
# Path: parser/stpcommands.py
# def getStringRightRotate(value, rotation, wordsize):
#     if rotation % wordsize == 0:
#         return "{0}".format(value)
#     command = "((({0} >> {1})[{2}:0]) | (({0} << {3})[{2}:0]))".format(
#         value, (rotation % wordsize), wordsize - 1, (wordsize - rotation) % wordsize)
#     return command
# 
# Path: parser/stpcommands.py
# def getStringLeftRotate(value, rotation, wordsize):
#     if rotation % wordsize == 0:
#         return "{0}".format(value)
#     command = "((({0} << {1})[{2}:0]) | (({0} >> {3})[{2}:0]))".format(
#         value, (rotation % wordsize), wordsize - 1, (wordsize - rotation) % wordsize)
# 
#     return command


# Path: ciphers/sparxround128.py
from parser import stpcommands
from ciphers.cipher import AbstractCipher
from parser.stpcommands import getStringRightRotate as rotr
from parser.stpcommands import getStringLeftRotate as rotl

                                         x0l_after_L[i], x0r_after_L[i],
                                         x1l_after_L[i], x1r_after_L[i],
                                         x0l[i+1], x0r[i+1],
                                         x1l[i+1], x1r[i+1],
                                         x2l[i+1], x2r[i+1],
                                         x3l[i+1], x3r[i+1])
                else:
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x0l[i], x0r[i], x0l[i+1], x0r[i+1],
                                           wx0[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x1l[i], x1r[i], x1l[i+1], x1r[i+1],
                                           wx1[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x2l[i], x2r[i], x2l[i+1], x2r[i+1],
                                           wx2[i], wordsize)
                    #do round function (SPECKEY)
                    self.setupSPECKEYRound(stp_file, x3l[i], x3r[i], x3l[i+1], x3r[i+1],
                                           wx3[i], wordsize)

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

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

                stpcommands.assertVariableValue(stp_file, x2l[0], x2l[rounds])