def createSTP(self, stp_filename, parameters): """ Creates an STP file for Ketje. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Ketje w={} rounds={}" "\n\n\n".format(wordsize, rounds)) # Setup variables # 5x5 lanes of wordsize s = ["s{}{}{}".format(x, y, i) for i in range(rounds + 1) for y in range(5) for x in range(5)] a = ["a{}{}{}".format(x, y, i) for i in range(rounds) for y in range(5) for x in range(5)] b = ["b{}{}{}".format(x, y, i) for i in range(rounds) for y in range(5) for x in range(5)] c = ["c{}{}".format(x, i) for i in range(rounds + 1) for x in range(5)] d = ["d{}{}".format(x, i) for i in range(rounds + 1) for x in range(5)] m = ["m{}{}".format(x, i) for i in range(rounds +1) for x in range(2)] xin = ["xin{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] xout = ["xout{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] andOut = ["andOut{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] # w = weight w = ["w{}".format(i) for i in range(rounds)] tmp = ["tmp{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] stpcommands.setupVariables(stp_file, s, wordsize) stpcommands.setupVariables(stp_file, a, wordsize) stpcommands.setupVariables(stp_file, b, wordsize) stpcommands.setupVariables(stp_file, c, wordsize) stpcommands.setupVariables(stp_file, d, wordsize) stpcommands.setupVariables(stp_file, w, 16) stpcommands.setupVariables(stp_file, tmp, 5) stpcommands.setupWeightComputationSum(stp_file, weight, w, wordsize) stpcommands.setupVariables(stp_file, xin, 5) stpcommands.setupVariables(stp_file, xout, 5) stpcommands.setupVariables(stp_file, andOut, 5) stpcommands.setupVariables(stp_file, m, wordsize) # No all zero characteristic stpcommands.assertNonZero(stp_file, a, wordsize) for rnd in range(rounds): self.setupKeccakRound(stp_file, rnd, s, a, b, c, d, wordsize, tmp, w, m, xin, xout, andOut) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a characteristic for SPECK with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] if wordsize == 16: self.rot_alpha = 7 self.rot_beta = 2 elif "rotationconstants" in parameters: self.rot_alpha = parameters["rotationconstants"][0] self.rot_beta = parameters["rotationconstants"][1] with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Speck w={} alpha={} beta={} " "rounds={}\n\n\n".format(wordsize, self.rot_alpha, self.rot_beta, rounds)) # Setup variable # x = left, y = right # w = weight x = ["x{}".format(i) for i in range(rounds + 1)] y = ["y{}".format(i) for i in range(rounds + 1)] w = ["w{}".format(i) for i in range(rounds)] stpcommands.setupVariables(stp_file, x, wordsize) stpcommands.setupVariables(stp_file, y, wordsize) stpcommands.setupVariables(stp_file, w, wordsize) # Ignore MSB stpcommands.setupWeightComputation(stp_file, weight, w, wordsize, 1) for i in range(rounds): self.setupSpeckRound(stp_file, x[i], y[i], x[i+1], y[i+1], w[i], wordsize) # No all zero characteristic stpcommands.assertNonZero(stp_file, x + y, wordsize) # Iterative characteristics only # Input difference = Output difference if parameters["iterative"]: stpcommands.assertVariableValue(stp_file, x[0], x[rounds]) stpcommands.assertVariableValue(stp_file, y[0], y[rounds]) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a characteristic for Salsa with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Salsa w={}" "rounds={}\n\n\n".format(wordsize, rounds)) # Setup variables a = ["a{}r{}".format(j, i) for i in range(rounds + 1) for j in range(16)] b = ["b{}r{}".format(j, i) for i in range(rounds) for j in range(16)] w = ["w{}r{}".format(j, i) for i in range(rounds) for j in range(16)] stpcommands.setupVariables(stp_file, a, wordsize) stpcommands.setupVariables(stp_file, b, wordsize) stpcommands.setupVariables(stp_file, w, wordsize) # Ignore MSB stpcommands.setupWeightComputation(stp_file, weight, w, wordsize, 1) for rnd in range(rounds): if rnd % 2 != 0: #Rowround for row in range(4): a_in = [a[(i + row) % 4 + 4 * row + 16 * rnd] for i in range(4)] a_out = [a[(i + row) % 4 + 4 * row + 16 * (rnd + 1)] for i in range(4)] tmp_b = [b[i + 4 * row + 16 * rnd] for i in range(4)] tmp_w = [w[i + 4 * row + 16 * rnd] for i in range(4)] self.setupQuarterRound(stp_file, a_in, tmp_b, a_out, tmp_w, wordsize) else: #Columnround for col in range(4): a_in = [a[(i * 4 + 4 * col + col) % 16 + 16 * rnd] for i in range(4)] a_out = [a[(i * 4 + 4 * col + col) % 16 + 16 * (rnd + 1)] for i in range(4)] tmp_b = [b[i * 4 + col + 16 * rnd] for i in range(4)] tmp_w = [w[i * 4 + col + 16 * rnd] for i in range(4)] self.setupQuarterRound(stp_file, a_in, tmp_b, a_out, tmp_w, wordsize) #stp_file.write("ASSERT(({}[31:31]) = 0b0);\n".format(a[0])) # No all zero characteristic stpcommands.assertNonZero(stp_file, a, wordsize) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a preimage for Keccak. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] # Default rate and capacity capacity = 160 rate = (wordsize * 25) - capacity if "rate" in parameters: rate = parameters["rate"] if "capacity" in parameters: capacity = parameters["capacity"] assert (rate + capacity) == wordsize * 25 with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Keccak w={} rate={} " "capacity={}\n\n\n".format(wordsize, rate, capacity, rounds)) # Setup variables # 5x5 lanes of wordsize s = ["s{}{}{}".format(x, y, i) for i in range(rounds + 1) for y in range(5) for x in range(5)] a = ["a{}{}{}".format(x, y, i) for i in range(rounds + 1) for y in range(5) for x in range(5)] b = ["b{}{}{}".format(x, y, i) for i in range(rounds + 1) for y in range(5) for x in range(5)] c = ["c{}{}".format(x, i) for i in range(rounds + 1) for x in range(5)] d = ["d{}{}".format(x, i) for i in range(rounds + 1) for x in range(5)] stpcommands.setupVariables(stp_file, s, wordsize) stpcommands.setupVariables(stp_file, a, wordsize) stpcommands.setupVariables(stp_file, b, wordsize) stpcommands.setupVariables(stp_file, c, wordsize) stpcommands.setupVariables(stp_file, d, wordsize) # Fix variables for capacity, only works if rate/capacity # is multiple of wordsize for i in range(rate // wordsize, (rate + capacity) // wordsize): stpcommands.assertVariableValue(stp_file, s[i], "0hex{}".format( "0" * (wordsize // 4))) for rnd in range(rounds): self.setupKeccakRound(stp_file, rnd, s, a, b, c, d, wordsize) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a differnetial trail for Skinny with the given parameters. """ blocksize = parameters["blocksize"] wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] if blocksize != 64: print("Only blocksize of 64-bit supported.") exit(1) with open(stp_filename, 'w') as stp_file: header = ("% Input File for STP\n% Skinny w={}" "rounds={}\n\n\n".format(blocksize, rounds)) stp_file.write(header) # Setup variables sc = ["SC{}".format(i) for i in range(rounds + 1)] sr = ["SR{}".format(i) for i in range(rounds)] mc = ["MC{}".format(i) for i in range(rounds)] # w = weight w = ["w{}".format(i) for i in range(rounds)] stpcommands.setupVariables(stp_file, sc, blocksize) stpcommands.setupVariables(stp_file, sr, blocksize) stpcommands.setupVariables(stp_file, mc, blocksize) stpcommands.setupVariables(stp_file, w, blocksize) stpcommands.setupWeightComputation(stp_file, weight, w, blocksize) for i in range(rounds): self.setupSkinnyRound(stp_file, sc[i], sr[i], mc[i], sc[i+1], w[i], blocksize) # No all zero characteristic stpcommands.assertNonZero(stp_file, sc, blocksize) # Iterative characteristics only # Input difference = Output difference if parameters["iterative"]: stpcommands.assertVariableValue(stp_file, sc[0], sc[rounds]) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, blocksize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a characteristic for PRESENT with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] if wordsize != 64: print("Only wordsize of 64-bit supported.") exit(1) with open(stp_filename, 'w') as stp_file: header = ("% Input File for STP\n% PRESENT w={}" "rounds={}\n\n\n".format(wordsize, rounds)) stp_file.write(header) # Setup variables s = ["S{}".format(i) for i in range(rounds + 1)] p = ["P{}".format(i) for i in range(rounds)] # w = weight w = ["w{}".format(i) for i in range(rounds)] stpcommands.setupVariables(stp_file, s, wordsize) stpcommands.setupVariables(stp_file, p, wordsize) stpcommands.setupVariables(stp_file, w, wordsize) stpcommands.setupWeightComputation(stp_file, weight, w, wordsize) for i in range(rounds): self.setupPresentRound(stp_file, s[i], p[i], s[i+1], w[i], wordsize) # No all zero characteristic stpcommands.assertNonZero(stp_file, s, wordsize) # Iterative characteristics only # Input difference = Output difference if parameters["iterative"]: stpcommands.assertVariableValue(stp_file, s[0], s[rounds]) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file for SIMON. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] # Replace with custom if set in parameters. if "rotationconstants" in parameters: self.rot_alpha = parameters["rotationconstants"][0] self.rot_beta = parameters["rotationconstants"][1] self.rot_gamma = parameters["rotationconstants"][2] self.num_messages = parameters["nummessages"] with open(stp_filename, 'w') as stp_file: header = ("% Input File for STP\n% Simon w={} alpha={} beta={}" " gamma={} rounds={}\n\n\n".format(wordsize, self.rot_alpha, self.rot_beta, self.rot_gamma, rounds)) stp_file.write(header) # Setup key key = ["key{}".format(i) for i in range(rounds + 1)] tmp_key = ["tmpkey{}".format(i) for i in range(rounds + 1)] stpcommands.setupVariables(stp_file, key, wordsize) stpcommands.setupVariables(stp_file, tmp_key, wordsize) #TODO Add constant addition self.setupKeySchedule(stp_file, key, tmp_key, rounds, wordsize) # Setup variables # x = left, y = right for msg in range(self.num_messages): x = ["x{}r{}".format(msg, i) for i in range(rounds + 1)] y = ["y{}r{}".format(msg, i) for i in range(rounds + 1)] and_out = ["andout{}r{}".format(msg, i) for i in range(rounds + 1)] stpcommands.setupVariables(stp_file, x, wordsize) stpcommands.setupVariables(stp_file, y, wordsize) stpcommands.setupVariables(stp_file, and_out, wordsize) #Setup Rounds for i in range(rounds): self.setupSimonRound(stp_file, x[i], y[i], x[i+1], y[i+1], and_out[i], key[i], wordsize) #Differences between x_0 and x_i for msg in range(1, self.num_messages): delta_x = ["dx{}r{}".format(msg, i) for i in range(rounds + 1)] delta_y = ["dy{}r{}".format(msg, i) for i in range(rounds + 1)] stpcommands.setupVariables(stp_file, delta_x, wordsize) stpcommands.setupVariables(stp_file, delta_y, wordsize) for i in range(rounds + 1): stp_file.write("ASSERT({} = BVXOR({}, {}));\n".format( delta_x[i], "x0r{}".format(i), "x{}r{}".format(msg, i))) stp_file.write("ASSERT({} = BVXOR({}, {}));\n".format( delta_y[i], "y0r{}".format(i), "y{}r{}".format(msg, i))) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a characteristic for CRAFT with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] if wordsize != 64: print("Only wordsize of 64-bit supported.") exit(1) with open(stp_filename, 'w') as stp_file: header = ("% Input File for STP\n% CRAFT w={} " "rounds={}\n\n\n".format(wordsize, rounds)) stp_file.write(header) # Setup variables """ x(roundNumber), other variables are like this one. x(r) is a variable modeling the 64-bit input difference to the (r+1)'th round y(r) is a variable modeling the 64-bit output difference from MixColumn of the (r+1)'th round z(r) is a variable modeling the 64-bit output difference from PermuteNibble of the (r+1)'th round x(r+1) is a variable modeling the 64-bit output differenece from the (r+1)'th round Example: x0 = x0[63, 62, ..., 0] x0[3:0]: nibble 0 x0[63:60]: nibble 15 It is supposed that the input difference is as bellow: [x[3:0], x[7:4], ..., x[63:60]] """ # note that the last integer index in the name of a variable \ # always shows the round's number in the CryptoSMT x = ["x%d" % i for i in range(rounds + 1)] y = ["y%d" % i for i in range(rounds)] z = ["z%d" % i for i in range(rounds)] # w = weight w = ["w%d" % i for i in range(rounds)] stpcommands.setupVariables(stp_file, x, wordsize) stpcommands.setupVariables(stp_file, y, wordsize) stpcommands.setupVariables(stp_file, z, wordsize) stpcommands.setupVariables(stp_file, w, wordsize) stpcommands.setupWeightComputation(stp_file, weight, w, wordsize) for i in range(rounds): self.setupCraftRound(stp_file, x[i], y[i], z[i], x[i+1], w[i], wordsize) # No all zero characteristic stpcommands.assertNonZero(stp_file, x, wordsize) # Iterative characteristics only # Input difference = Output difference if parameters["iterative"]: stpcommands.assertVariableValue(stp_file, x[0], x[rounds]) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a characteristic for SIMON with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] # Replace with custom if set in parameters. if "rotationconstants" in parameters: self.rot_alpha = parameters["rotationconstants"][0] self.rot_beta = parameters["rotationconstants"][1] self.rot_gamma = parameters["rotationconstants"][2] with open(stp_filename, 'w') as stp_file: header = ("% Input File for STP\n% Simon w={} alpha={} beta={}" " gamma={} rounds={}\n\n\n".format(wordsize, self.rot_alpha, self.rot_beta, self.rot_gamma, rounds)) stp_file.write(header) # Setup variables # x = left, y = right x = ["x{}".format(i) for i in range(rounds + 1)] y = ["y{}".format(i) for i in range(rounds + 1)] and_out = ["andout{}".format(i) for i in range(rounds + 1)] # w = weight w = ["w{}".format(i) for i in range(rounds)] stpcommands.setupVariables(stp_file, x, wordsize) stpcommands.setupVariables(stp_file, y, wordsize) stpcommands.setupVariables(stp_file, and_out, wordsize) stpcommands.setupVariables(stp_file, w, wordsize) stpcommands.setupWeightComputation(stp_file, weight, w, wordsize) for i in range(rounds): self.setupSimonRound(stp_file, x[i], y[i], x[i+1], y[i+1], and_out[i], w[i], wordsize) # No all zero characteristic stpcommands.assertNonZero(stp_file, x + y, wordsize) # Iterative characteristics only # Input difference = Output difference if parameters["iterative"]: stpcommands.assertVariableValue(stp_file, x[0], x[rounds]) stpcommands.assertVariableValue(stp_file, y[0], y[rounds]) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file for Ascon. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] sboxsize = 5 # TODO: support arbitrary sizes capacity = 0 rate = (wordsize * sboxsize) - capacity if "rate" in parameters: rate = parameters["rate"] if "capacity" in parameters: capacity = parameters["capacity"] assert (rate + capacity) == wordsize * sboxsize with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Ascon w={} rate={} " "capacity={} round={}\n\n\n".format(wordsize, rate, capacity, rounds)) # Setup variables # 5 x wordsize state s = ["s{}{}".format(x, i) for i in range(rounds+1) for x in range(sboxsize)] # Output after S-box Linear part 1 a = ["a{}{}".format(x, i) for i in range(rounds+1) for x in range(sboxsize)] # Output after S-box Non-Linear part b = ["b{}{}".format(x, i) for i in range(rounds+1) for x in range(sboxsize)] # Output after S-box Linear part 2 c = ["c{}{}".format(x, i) for i in range(rounds+1) for x in range(sboxsize)] # Inputs/Output to the S-box xin = ["inx{}{}{}".format(y, z, i) for i in range(rounds) for y in range(sboxsize) for z in range (wordsize)] xout = ["outx{}{}{}".format(y, z, i) for i in range(rounds) for y in range(sboxsize) for z in range (wordsize)] andout = ["andout{}{}{}".format(y, z, i) for i in range(rounds) for y in range(sboxsize) for z in range (wordsize)] # w = weight w = ["w{}".format(i) for i in range(rounds)] tmp = ["tmp{}{}{}".format(y, z, i) for i in range(rounds) for y in range(sboxsize) for z in range (wordsize)] stpcommands.setupVariables(stp_file, s, wordsize) stpcommands.setupVariables(stp_file, a, wordsize) stpcommands.setupVariables(stp_file, b, wordsize) stpcommands.setupVariables(stp_file, c, wordsize) stpcommands.setupVariables(stp_file, w, 16) stpcommands.setupVariables(stp_file, tmp, sboxsize) stpcommands.setupWeightComputationSum(stp_file, weight, w, wordsize) stpcommands.setupVariables(stp_file, xin, sboxsize) stpcommands.setupVariables(stp_file, xout, sboxsize) stpcommands.setupVariables(stp_file, andout, sboxsize) # No all zero characteristic stpcommands.assertNonZero(stp_file, s, wordsize) # Fix variables for capacity, only works if rate/capacity is # multiple of wordsize. for i in range(rate // wordsize, (rate + capacity) // wordsize): stpcommands.assertVariableValue(stp_file, s[i], "0hex{}".format("0"*(wordsize // 4))) for rnd in range(rounds): self.setupAsconRound(stp_file, rnd, s, a, b, c, wordsize, tmp, w, xin, xout, andout) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a characteristic for SipHash with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] self.num_messages = parameters["nummessages"] with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Siphash w={} " "rounds={}\n\n\n".format(wordsize, rounds)) # Setup variables # state = v0, v1, v2, v3 # intermediate values = a0, a1, a2, a3 v0 = ["v0{}".format(i) for i in range((rounds + 1) * self.num_messages)] v1 = ["v1{}".format(i) for i in range((rounds + 1) * self.num_messages)] v2 = ["v2{}".format(i) for i in range((rounds + 1) * self.num_messages)] v3 = ["v3{}".format(i) for i in range((rounds + 1) * self.num_messages)] a0 = ["a0{}".format(i) for i in range((rounds + 1) * self.num_messages)] a1 = ["a1{}".format(i) for i in range((rounds + 1) * self.num_messages)] a2 = ["a2{}".format(i) for i in range((rounds + 1) * self.num_messages)] a3 = ["a3{}".format(i) for i in range((rounds + 1) * self.num_messages)] m = ["m{}".format(i) for i in range(self.num_messages)] # w = weight of each modular addition w0 = ["w0{}".format(i) for i in range(rounds * self.num_messages)] w1 = ["w1{}".format(i) for i in range(rounds * self.num_messages)] w2 = ["w2{}".format(i) for i in range(rounds * self.num_messages)] w3 = ["w3{}".format(i) for i in range(rounds * self.num_messages)] stpcommands.setupVariables(stp_file, v0 + v1 + v2 + v3, wordsize) stpcommands.setupVariables(stp_file, a0 + a1 + a2 + a3, wordsize) stpcommands.setupVariables(stp_file, w0 + w1 + w2 + w3, wordsize) stpcommands.setupVariables(stp_file, m, wordsize) stpcommands.setupWeightComputation(stp_file, weight, w0 + w1 + w2 + w3, wordsize, 1) for block in range(self.num_messages): self.setupSipBlock(stp_file, block, rounds, m, v0, v1, v2, v3, a0, a1, a2, a3, w0, w1, w2, w3, wordsize) # TODO: There are many different attack scenarios interesting here, # but no interface exists at the moment to support this # without using different "ciphers". ## Uncomment to search for internal collision # zero_string = "0hex" + "0"*(wordsize / 4) # stpcommands.assertVariableValue(stp_file, v0[rounds], zero_string) # stpcommands.assertVariableValue(stp_file, v1[rounds], zero_string) # stpcommands.assertVariableValue(stp_file, v2[rounds], zero_string) # stpcommands.assertVariableValue(stp_file, v3[rounds], zero_string) # stpcommands.assertVariableValue(stp_file, v0[0], zero_string) # stpcommands.assertVariableValue(stp_file, v1[0], zero_string) # stpcommands.assertVariableValue(stp_file, v2[0], zero_string) # stpcommands.assertVariableValue(stp_file, v3[0], zero_string) # stpcommands.assertNonZero(stp_file, m, wordsize) # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds], # v2[rounds], v3[rounds], wordsize)) ## Uncomment to search for internal collision for a single block # zero_string = "0hex" + "0"*(wordsize / 4) # stpcommands.assertVariableValue(stp_file, v0[rounds], zero_string) # #stpcommands.assertVariableValue(stp_file, v1[rounds], zero_string) # stpcommands.assertVariableValue(stp_file, v2[rounds], zero_string) # stpcommands.assertVariableValue(stp_file, v3[rounds], zero_string) # stpcommands.assertVariableValue(stp_file, v0[0], zero_string) # stpcommands.assertVariableValue(stp_file, v1[0], zero_string) # stpcommands.assertVariableValue(stp_file, v2[0], zero_string) # stpcommands.assertVariableValue(stp_file, v3[0], v1[rounds]) # stpcommands.assertVariableValue(stp_file, m[0], zero_string) # stpcommands.assertVariableValue(stp_file, m[1], zero_string) # stpcommands.assertNonZero(stp_file, [v3[0]], wordsize) # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds], # v2[rounds], v3[rounds], wordsize)) ## Uncomment to search for Key Collisions # stpcommands.assertNonZero(stp_file, [v0[0], v1[0]], wordsize) # stpcommands.assertVariableValue(stp_file, v0[0], v3[0]) # stpcommands.assertVariableValue(stp_file, v1[0], v2[0]) # stp_file.write(self.getStringForCollision(v0[rounds], v1[rounds], # v2[rounds], v3[rounds], wordsize)) ## Uncomment to search for message collision stpcommands.assertNonZero(stp_file, m, wordsize) zero_string = "0hex" + "0"*(wordsize / 4) stpcommands.assertVariableValue(stp_file, v0[0], zero_string) stpcommands.assertVariableValue(stp_file, v1[0], zero_string) stpcommands.assertVariableValue(stp_file, v2[0], zero_string) stpcommands.assertVariableValue(stp_file, v3[0], zero_string) stp_file.write(self.getStringForCollision(v0[rounds*self.num_messages], v1[rounds*self.num_messages], v2[rounds*self.num_messages], v3[rounds*self.num_messages], wordsize)) ## Uncomment to search for characteristic / distinguisher # for i in m: # zero_string = "0hex" + "0"*(wordsize / 4) # stpcommands.assertVariableValue(stp_file, i, zero_string) # stpcommands.assertNonZero(stp_file, v0 + v1 + v2 + v3, wordsize) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a differential trail for Gimli with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] if "rotationconstants" in parameters: self.d = parameters["rotationconstants"][0] self.e = parameters["rotationconstants"][1] self.f = parameters["rotationconstants"][2] with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Gimli w={}" "rounds={}\n\n\n".format(wordsize, rounds)) # Setup variables x = ["x{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)] xsb = ["xsb{}r{}".format(j, i) for i in range(rounds) for j in range(4)] y = ["y{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)] ysb = ["ysb{}r{}".format(j, i) for i in range(rounds) for j in range(4)] z = ["z{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)] zsb = ["zsb{}r{}".format(j, i) for i in range(rounds + 1) for j in range(4)] w = ["rw{}".format(i) for i in range(rounds)] wp = ["rwp{}r{}".format(j, i) for i in range(rounds) for j in range(4)] xtmp = ["xtmp{}r{}".format(j, i) for i in range(rounds) for j in range(4)] ytmp = ["ytmp{}r{}".format(j, i) for i in range(rounds) for j in range(4)] ztmp = ["ztmp{}r{}".format(j, i) for i in range(rounds) for j in range(4)] stpcommands.setupVariables(stp_file, x, wordsize) stpcommands.setupVariables(stp_file, y, wordsize) stpcommands.setupVariables(stp_file, z, wordsize) stpcommands.setupVariables(stp_file, xtmp, wordsize) stpcommands.setupVariables(stp_file, ytmp, wordsize) stpcommands.setupVariables(stp_file, ztmp, wordsize) stpcommands.setupVariables(stp_file, xsb, wordsize) stpcommands.setupVariables(stp_file, ysb, wordsize) stpcommands.setupVariables(stp_file, zsb, wordsize) stpcommands.setupVariables(stp_file, wp, wordsize) stpcommands.setupVariables(stp_file, w, 16) for rnd in range(rounds): stp_file.write(stpcommands.getWeightString(wp[4*rnd:4*rnd + 4], wordsize, 0, w[rnd]) + "\n") stpcommands.setupWeightComputationSum(stp_file, weight, w, wordsize) # Rounds for rnd in range(rounds): if ((rnd) & 3) == 0: # Small Swap for perm in range(4): self.setupRound(stp_file, x[4*rnd + perm], y[4*rnd + perm], z[4*rnd + perm], xtmp[4*rnd + perm], ytmp[4*rnd + perm], ztmp[4*rnd + perm], xsb[4*rnd + perm], ysb[4*rnd + perm], zsb[4*rnd + perm], wp[4*rnd + perm], wordsize) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1)], xtmp[4*rnd + 1])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1)], ytmp[4*rnd])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1)], ztmp[4*rnd])) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 1], xtmp[4*rnd])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 1], ytmp[4*rnd + 1])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 1], ztmp[4*rnd + 1])) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 2], xtmp[4*rnd + 3])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 2], ytmp[4*rnd + 2])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 2], ztmp[4*rnd + 2])) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 3], xtmp[4*rnd + 2])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 3], ytmp[4*rnd + 3])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 3], ztmp[4*rnd + 3])) elif ((rnd) & 3) == 2: # Big Swap for perm in range(4): self.setupRound(stp_file, x[4*rnd + perm], y[4*rnd + perm], z[4*rnd + perm], xtmp[4*rnd + perm], ytmp[4*rnd + perm], ztmp[4*rnd + perm], xsb[4*rnd + perm], ysb[4*rnd + perm], zsb[4*rnd + perm], wp[4*rnd + perm], wordsize) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1)], xtmp[4*rnd + 2])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1)], ytmp[4*rnd])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1)], ztmp[4*rnd])) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 1], xtmp[4*rnd + 3])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 1], ytmp[4*rnd + 1])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 1], ztmp[4*rnd + 1])) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 2], xtmp[4*rnd])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 2], ytmp[4*rnd + 2])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 2], ztmp[4*rnd + 2])) stp_file.write("ASSERT({} = {});\n".format(x[4*(rnd + 1) + 3], xtmp[4*rnd + 1])) stp_file.write("ASSERT({} = {});\n".format(y[4*(rnd + 1) + 3], ytmp[4*rnd + 3])) stp_file.write("ASSERT({} = {});\n".format(z[4*(rnd + 1) + 3], ztmp[4*rnd + 3])) else: # No Swap for perm in range(4): self.setupRound(stp_file, x[4*rnd + perm], y[4*rnd + perm], z[4*rnd + perm], x[4*(rnd + 1) + perm], y[4*(rnd + 1) + perm], z[4*(rnd + 1) + perm], xsb[4*rnd + perm], ysb[4*rnd + perm], zsb[4*rnd + perm], wp[4*rnd + perm], wordsize) # No all zero characteristic stpcommands.assertNonZero(stp_file, x + y + z, wordsize) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file for Keccak. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] capacity = 160 rate = (wordsize * 25) - capacity if "rate" in parameters: rate = parameters["rate"] if "capacity" in parameters: capacity = parameters["capacity"] assert (rate + capacity) == wordsize * 25 with open(stp_filename, 'w') as stp_file: stp_file.write("% Input File for STP\n% Keccak w={} rate={} " "capacity={}\n\n\n".format(wordsize, rate, capacity, rounds)) # Setup variables # 5x5 lanes of wordsize s = ["s{}{}{}".format(x, y, i) for i in range(rounds+1) for y in range(5) for x in range(5)] b = ["b{}{}{}".format(x, y, i) for i in range(rounds) for y in range(5) for x in range(5)] c = ["c{}{}".format(x, i) for i in range(rounds) for x in range(5)] d = ["d{}{}".format(x, i) for i in range(rounds) for x in range(5)] xin = ["xin{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] xout = ["xout{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] andOut = ["andOut{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] # w = weight w = ["w{}".format(i) for i in range(rounds)] tmp = ["tmp{}{}{}".format(y, z, i) for i in range(rounds) for y in range(5) for z in range (wordsize)] stpcommands.setupVariables(stp_file, s, wordsize) stpcommands.setupVariables(stp_file, b, wordsize) stpcommands.setupVariables(stp_file, c, wordsize) stpcommands.setupVariables(stp_file, d, wordsize) stpcommands.setupVariables(stp_file, w, 16) stpcommands.setupVariables(stp_file, tmp, 5) stpcommands.setupWeightComputationSum(stp_file, weight, w, wordsize) stpcommands.setupVariables(stp_file, xin, 5) stpcommands.setupVariables(stp_file, xout, 5) stpcommands.setupVariables(stp_file, andOut, 5) # No all zero characteristic stpcommands.assertNonZero(stp_file, s, wordsize) # Fix variables for capacity, only works if rate/capacity is # multiple of wordsize. for i in range(rate // wordsize, (rate + capacity) // wordsize): stpcommands.assertVariableValue(stp_file, s[i], "0hex{}".format("0"*(wordsize // 4))) for rnd in range(rounds): self.setupKeccakRound(stp_file, rnd, s, b, c, d, wordsize, tmp, w, xin, xout, andOut) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) stpcommands.setupQuery(stp_file) return
def createSTP(self, stp_filename, parameters): """ Creates an STP file to find a characteristic for ChasKey with the given parameters. """ wordsize = parameters["wordsize"] rounds = parameters["rounds"] weight = parameters["sweight"] self.num_messages = parameters["nummessages"] with open(stp_filename, "w") as stp_file: stp_file.write("% Input File for STP\n% ChasKeyMac w={} rounds={}" "\n\n\n".format(wordsize, rounds)) # Setup variables # state = v0, v1, v2, v3 # intermediate values = a0, a1, a2, a3 v0 = ["v0{}".format(i) for i in range((rounds + 1) * self.num_messages)] v1 = ["v1{}".format(i) for i in range((rounds + 1) * self.num_messages)] v2 = ["v2{}".format(i) for i in range((rounds + 1) * self.num_messages)] v3 = ["v3{}".format(i) for i in range((rounds + 1) * self.num_messages)] # w = weight of each modular addition w0 = ["w0{}".format(i) for i in range(rounds * self.num_messages)] w1 = ["w1{}".format(i) for i in range(rounds * self.num_messages)] stpcommands.setupVariables(stp_file, v0, wordsize) stpcommands.setupVariables(stp_file, v1, wordsize) stpcommands.setupVariables(stp_file, v2, wordsize) stpcommands.setupVariables(stp_file, v3, wordsize) stpcommands.setupVariables(stp_file, w0, wordsize) stpcommands.setupVariables(stp_file, w1, wordsize) stpcommands.setupWeightComputation(stp_file, weight, w0 + w1, wordsize, 1) # Minimize Weight in middle rounds # stpcommands.limitWeight(stp_file, 10, w0[2:4] + w1[2:4], wordsize, 1) for i in range(rounds): self.setupChasKeyRound( stp_file, i, v0[i], v1[i], v2[i], v3[i], v0[i + 1], v1[i + 1], v2[i + 1], v3[i + 1], w0[i], w1[i], wordsize, ) # Message Collision stpcommands.assertNonZero(stp_file, v0 + v1 + v2 + v3, wordsize) # zeroString = "0hex" + "0"*(wordsize / 4) # stpcommands.assertVariableValue(stp_file, v0[rounds], zeroString) # stpcommands.assertVariableValue(stp_file, v1[rounds], zeroString) # stpcommands.assertVariableValue(stp_file, v2[rounds], zeroString) # stpcommands.assertVariableValue(stp_file, v3[rounds], zeroString) for key, value in parameters["fixedVariables"].items(): stpcommands.assertVariableValue(stp_file, key, value) for char in parameters["blockedCharacteristics"]: stpcommands.blockCharacteristic(stp_file, char, wordsize) stpcommands.setupQuery(stp_file) return