├── README.md ├── ciphers ├── __init__.py ├── gift.py ├── lblock.py ├── present.py ├── rectangle.py └── twine.py ├── function.py ├── main_feistel.py ├── main_sp.py ├── model.py ├── parameter.py └── txt ├── gift ├── AS │ └── 1th_sbox_reduce_ine_greedy.txt └── DC │ └── 1th_sbox_reduce_ine_greedy.txt ├── lblock ├── AS │ ├── 1th_sbox_reduce_ine_greedy.txt │ ├── 2th_sbox_reduce_ine_greedy.txt │ ├── 3th_sbox_reduce_ine_greedy.txt │ ├── 4th_sbox_reduce_ine_greedy.txt │ ├── 5th_sbox_reduce_ine_greedy.txt │ ├── 6th_sbox_reduce_ine_greedy.txt │ ├── 7th_sbox_reduce_ine_greedy.txt │ └── 8th_sbox_reduce_ine_greedy.txt └── DC │ ├── 1th_sbox_reduce_ine_greedy.txt │ ├── 2th_sbox_reduce_ine_greedy.txt │ ├── 3th_sbox_reduce_ine_greedy.txt │ ├── 4th_sbox_reduce_ine_greedy.txt │ ├── 5th_sbox_reduce_ine_greedy.txt │ ├── 6th_sbox_reduce_ine_greedy.txt │ ├── 7th_sbox_reduce_ine_greedy.txt │ └── 8th_sbox_reduce_ine_greedy.txt ├── present ├── AS │ └── 1th_sbox_reduce_ine_greedy.txt └── DC │ └── 1th_sbox_reduce_ine_greedy.txt ├── rectangle ├── AS │ └── 1th_sbox_reduce_ine_greedy.txt └── DC │ └── 1th_sbox_reduce_ine_greedy.txt └── twine ├── AS └── 1th_sbox_reduce_ine_greedy.txt └── DC └── 1th_sbox_reduce_ine_greedy.txt /README.md: -------------------------------------------------------------------------------- 1 | # MILPBasedSearchAlgorithmDiff 2 | Code for FSE 2020 - Improving the MILP-based Security Evaluation Algorithm against Differential-Linear Cryptanalysis Using A Divide-and-Conquer Approach 3 | -------------------------------------------------------------------------------- /ciphers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chunning-Zhou/MILPBasedSearchAlgorithmDiff/981bdfefbdacbf592181ae724daa9339fc0e9ecd/ciphers/__init__.py -------------------------------------------------------------------------------- /ciphers/gift.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | import numpy as np 3 | import function 4 | import copy 5 | from itertools import combinations 6 | class class_gift: 7 | def __init__(self): 8 | self.name = "gift" 9 | self.structure = "sp" 10 | self.oriented = "bit" 11 | self.block_size = 64 12 | self.sbox_size = 4 13 | self.num_of_sbox = 1 14 | self.nibble = 16 15 | self.sbox = [[0x1, 0xa, 0x4, 0xc, 0x6, 0xf, 0x3, 0x9, 0x2, 0xd, 0xb, 0x7, 0x5, 0x0, 0x8, 0xe]] 16 | self.pbox = [0, 17, 34, 51, 48, 1, 18, 35, 32, 49, 2, 19, 16, 33, 50, 3,\ 17 | 4, 21, 38, 55, 52, 5, 22, 39, 36, 53, 6, 23, 20, 37, 54, 7,\ 18 | 8, 25, 42, 59, 56, 9, 26, 43, 40, 57, 10, 27, 24, 41, 58, 11,\ 19 | 12, 29, 46, 63, 60, 13, 30, 47, 44, 61, 14, 31, 28, 45, 62, 15] 20 | self.branch_num_of_sbox = function.hamming_weight(self.name,self.sbox[0],self.sbox_size) 21 | self.var_and_num_LBAS = {"x":[0,self.block_size],"A":[self.nibble,0]} 22 | self.var_and_num_AS = {"x":[self.block_size,self.block_size],"A":[self.nibble,0]} 23 | self.var_and_num_DC = {"x":[self.block_size,self.block_size],"p":[self.nibble*3,0]} 24 | 25 | # searching 26 | self.diff_all = self.get_diff_all() 27 | self.num_of_diff_all = [240,27000] 28 | self.min_weight_of_sbox = 283 29 | self.round_of_first_region2 = 8 30 | 31 | def get_search_round(self,goal): 32 | if goal == "AS": 33 | return 16 34 | elif goal == "DC": 35 | return 15 36 | 37 | def get_max_num_of_round_to_solve(self,goal): 38 | if goal == "AS": 39 | max_num_of_round_to_solve = 4 40 | elif goal == "DC": 41 | max_num_of_round_to_solve = 5 42 | return 0,max_num_of_round_to_solve 43 | 44 | def get_diff_all(self): 45 | diff = [] 46 | position_1 = list(combinations(np.arange(1,self.nibble+1),1)) 47 | for i in position_1: 48 | diff_round_1 = [0 for l in range(self.nibble)] 49 | j = list(i)[0] 50 | for k in range(1,pow(2,self.sbox_size)): 51 | diff_round_1[j-1] = k 52 | diff.append(copy.deepcopy(diff_round_1)) 53 | 54 | position_2 = list(combinations(np.arange(1,self.nibble+1),2)) 55 | for i in position_2: 56 | diff_round_2 = [0 for l in range(self.nibble)] 57 | j1 = list(i)[0] 58 | j2 = list(i)[1] 59 | for k1 in range(1,pow(2,self.sbox_size)): 60 | for k2 in range(1,pow(2,self.sbox_size)): 61 | diff_round_2[j1-1] = k1 62 | diff_round_2[j2-1] = k2 63 | diff.append(copy.deepcopy(diff_round_2)) 64 | return diff 65 | 66 | def obj_fun(self,model_goal,model_filename,r1,r2): 67 | if model_goal == "LBAS" or model_goal == "AS": 68 | for i in range ((r1-1)*self.nibble+1,r2*self.nibble): 69 | with open(model_filename, "a") as f: 70 | f.write("A%d + "%(i)) 71 | with open(model_filename, "a") as f: 72 | f.write("A%d"%(r2*self.nibble)) 73 | elif model_goal == "DC": 74 | for i in range ((r1-1)*self.nibble*3+1,r2*self.nibble*3): 75 | if i%3 == 1: 76 | with open(model_filename, "a") as f: 77 | f.write("600 p%d + "%(i)) 78 | elif i%3 == 2: 79 | with open(model_filename, "a") as f: 80 | f.write("400 p%d + "%(i)) 81 | elif i%3 == 0: 82 | with open(model_filename, "a") as f: 83 | f.write("283 p%d + "%(i)) 84 | with open(model_filename, "a") as f: 85 | f.write("%d p%d"%(283,r2*self.nibble*3)) 86 | def gen_input_state(self): 87 | state = np.arange(1,self.block_size+1) 88 | return state 89 | def get_state_through_sbox(self,r): 90 | state = np.arange(self.block_size*r+1,self.block_size*(r+1)+1) 91 | return state 92 | def diff_propagation_of_sbox(self,model_goal,model_filename,r,state,state_through_sbox): 93 | var = {} 94 | for n in range(self.nibble): 95 | var["x"] = state[self.sbox_size*n:self.sbox_size*(n+1)] 96 | var["y"] = state_through_sbox[self.sbox_size*n:self.sbox_size*(n+1)] 97 | if model_goal == "AS": 98 | var["A"] = self.nibble*(r-1)+n+1 99 | ine = np.loadtxt("txt/"+self.name + "/AS/1th_sbox_reduce_ine_greedy.txt",int) 100 | function.diff_propagation_of_sbox_AS(self.sbox_size,model_filename,var,ine) 101 | elif model_goal == "DC": 102 | var["p"] = [(r-1)*3*self.nibble+3*n+1, (r-1)*3*self.nibble+3*n+2, (r-1)*3*self.nibble+3*n+3] 103 | ine = np.loadtxt("txt/"+self.name + "/DC/1th_sbox_reduce_ine_greedy.txt",int) 104 | function.diff_propagation_of_sbox_DC(self.sbox_size,self.var_and_num_DC["p"][0]/self.nibble,model_filename,var,ine) 105 | 106 | def get_state_through_per(self,state): 107 | state1 = np.arange(1,self.block_size+1) 108 | for i in range(self.block_size): 109 | state1[self.block_size-1-self.pbox[self.block_size-1-i]] = state[i] 110 | return state1 111 | 112 | def lowbound_of_sbox(self,model_goal,model_filename,r1,r2,lb): 113 | if model_goal == "AS": 114 | for r in range(r1,r2+1): 115 | for i in range(1,self.nibble): 116 | with open(model_filename, "a") as f: 117 | f.write("A%d + "%(self.nibble*(r-1)+i)) 118 | with open(model_filename, "a") as f: 119 | f.write("A%d >= %d \n"%(self.nibble*r,lb)) 120 | elif model_goal == "DC": 121 | for r in range(r1,r2+1): 122 | for i in range(1,self.nibble*3): 123 | with open(model_filename, "a") as f: 124 | f.write("p%d + "%(self.nibble*3*(r-1)+i)) 125 | with open(model_filename, "a") as f: 126 | f.write("p%d >= %d\n"%(self.nibble*r*3,lb)) 127 | 128 | def fix_diff(self,model_goal,model_filename,diff_type,r,diff_value): 129 | if diff_type == "input_diff": 130 | state = self.get_state_through_sbox(r-1) 131 | if r > 1: 132 | state = self.get_state_through_per(state) 133 | elif diff_type == "output_diff": 134 | state = self.get_state_through_per(self.get_state_through_sbox(r)) 135 | for i in range(self.nibble): 136 | value = diff_value[i] 137 | value_bin = bin(value).replace("0b","").zfill(self.sbox_size) 138 | for j in range(self.sbox_size): 139 | with open(model_filename, "a") as f: 140 | f.write("x%d = %d \n"%(state[self.sbox_size*i+j],int(value_bin[j]))) -------------------------------------------------------------------------------- /ciphers/lblock.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | import numpy as np 3 | import function 4 | import copy 5 | from itertools import combinations 6 | 7 | class class_lblock: 8 | def __init__(self): 9 | self.name = "lblock" 10 | self.structure = "feistel" 11 | self.oriented = "byte" 12 | self.block_size = 64 13 | self.sbox_size = 4 14 | self.num_of_sbox = 8 15 | self.nibble = 8 16 | self.sbox = [[13, 10, 15, 0, 14, 4, 9, 11, 2, 1, 8, 3, 7, 5, 12, 6],\ 17 | [11, 9, 4, 14, 0, 15, 10, 13, 6, 12, 5, 7, 3, 8, 1, 2],\ 18 | [2, 13, 11, 12, 15, 14, 0, 9, 7, 10, 6, 3, 1, 8, 4, 5],\ 19 | [14, 5, 15, 0, 7, 2, 12, 13, 1, 8, 4, 9, 11, 10, 6, 3],\ 20 | [7, 6, 8, 11, 0, 15, 3, 14, 9, 10, 12, 13, 5, 2, 4, 1],\ 21 | [1, 14, 7, 12, 15, 13, 0, 6, 11, 5, 9, 3, 2, 4, 8, 10],\ 22 | [4, 11, 14, 9, 15, 13, 0, 10, 7, 12, 5, 6, 2, 8, 1, 3],\ 23 | [14, 9, 15, 0, 13, 4, 10, 11, 1, 2, 8, 3, 7, 6, 12, 5]] 24 | self.pbox_left_DC = [8,9,10,11,0,1,2,3,12,13,14,15,4,5,6,7,\ 25 | 24,25,26,27,16,17,18,19,28,29,30,31,20,21,22,23] 26 | self.pbox_right_DC = [8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,\ 27 | 25,26,27,28,29,30,31,0,1,2,3,4,5,6,7] 28 | self.pbox_left_LBAS = [2,0,3,1,6,4,7,5] 29 | self.pbox_right_LBAS = [2,3,4,5,6,7,0,1] 30 | self.var_and_num_LBAS = {"A":[self.block_size/8,self.block_size/8],"d":[self.block_size/8,-self.block_size/8]} 31 | self.var_and_num_AS = {"x":[self.block_size,self.block_size/2],"A":[self.nibble,0],"d":[self.block_size/2,-self.block_size/2]} 32 | self.var_and_num_DC = {"x":[self.block_size,self.block_size/2],"p":[self.nibble*2,0],"d":[self.block_size/2,-self.block_size/2]} 33 | 34 | # searching 35 | self.diff_pattern_all = self.get_diff_pattern_all() 36 | self.num_of_diff_pattern_all = 255 37 | self.min_weight_of_sbox = 2 38 | 39 | def get_search_round(self,goal): 40 | if goal == "AS": 41 | return 20 42 | elif goal == "DC": 43 | return 16 44 | 45 | def get_max_num_of_round_to_solve(self,goal): 46 | return 16,0 47 | 48 | def get_diff_pattern_all(self): 49 | diff_pattern = [] 50 | for i in range(1,self.nibble+1): 51 | position = list(combinations(np.arange(1,self.nibble+1),i)) 52 | for j in position: 53 | diff_pattern_round = [0 for l in range(self.nibble)] 54 | for k in j: 55 | diff_pattern_round[k-1] = 1 56 | diff_pattern.append(copy.deepcopy(diff_pattern_round)) 57 | return diff_pattern 58 | 59 | def obj_fun(self,model_goal,model_filename,r1,r2): 60 | if model_goal == "LBAS": 61 | r1 = r1+1 62 | r2 = r2+1 63 | if model_goal == "LBAS" or model_goal == "AS": 64 | for i in range ((r1-1)*self.nibble+1,r2*self.nibble): 65 | with open(model_filename, "a") as f: 66 | f.write("A%d + "%(i)) 67 | with open(model_filename, "a") as f: 68 | f.write("A%d"%(r2*self.nibble)) 69 | elif model_goal == "DC": 70 | for i in range ((r1-1)*self.nibble*2+1,r2*self.nibble*2): 71 | if i%2 == 1: 72 | with open(model_filename, "a") as f: 73 | f.write("1 p%d + "%(i)) 74 | elif i%2 == 0: 75 | with open(model_filename, "a") as f: 76 | f.write("2 p%d + "%(i)) 77 | with open(model_filename, "a") as f: 78 | f.write("%d p%d"%(2, r2*self.nibble * 2)) 79 | def gen_input_state(self,model_goal): 80 | if model_goal == "LBAS": 81 | state = np.arange(1,self.nibble*2+1) 82 | elif model_goal == "AS" or model_goal == "DC": 83 | state = np.arange(1,self.block_size+1) 84 | return state 85 | def get_state_through_sbox(self,model_goal,r): 86 | if model_goal == "LBAS": 87 | state = np.arange(self.block_size*r+1,self.block_size*(r+1)+1) 88 | elif model_goal == "AS" or model_goal == "DC": 89 | state = np.arange(self.block_size*r+1,self.block_size*r+1+self.block_size/2) 90 | return state 91 | def diff_propagation_of_sbox(self,model_goal,model_filename,r,state,state_through_sbox): 92 | var = {} 93 | for n in range(self.nibble): 94 | var["x"] = state[self.sbox_size*n:self.sbox_size*(n+1)] 95 | var["y"] = state_through_sbox[self.sbox_size*n:self.sbox_size*(n+1)] 96 | if model_goal == "AS": 97 | var["A"] = self.nibble*(r-1)+n+1 98 | ine = np.loadtxt("txt/"+self.name + "/AS/"+str(n+1)+"th_sbox_reduce_ine_greedy.txt",int) 99 | function.diff_propagation_of_sbox_AS(self.sbox_size,model_filename,var,ine) 100 | elif model_goal == "DC": 101 | var["p"] = [2*n+(r-1)*2*self.nibble+1, 2*n+(r-1)*2*self.nibble+2] 102 | ine = np.loadtxt("txt/"+self.name + "/DC/"+str(n+1)+"th_sbox_reduce_ine_greedy.txt",int) 103 | function.diff_propagation_of_sbox_DC(self.sbox_size,self.var_and_num_DC["p"][0]/self.nibble,model_filename,var,ine) 104 | def get_state_through_per_right(self,model_goal,state): 105 | if model_goal == "LBAS": 106 | state1 = zeros(self.nibble, dtype = int16) 107 | for i in range(self.nibble): 108 | state1[self.nibble-1-self.pbox_right_LBAS[self.nibble-1-i]] = state[i] 109 | elif model_goal == "AS" or model_goal == "DC": 110 | state1 = zeros(self.block_size/2, dtype = int16) 111 | for i in range(self.block_size/2): 112 | state1[self.block_size/2-1-self.pbox_right_DC[self.block_size/2-1-i]] = state[i] 113 | return state1 114 | def get_state_through_per_left(self,model_goal,state): 115 | if model_goal == "LBAS": 116 | state1 = np.arange(1,self.nibble+1) 117 | for i in range(self.nibble): 118 | state1[self.nibble-1-self.pbox_left_LBAS[self.nibble-1-i]] = state[i] 119 | elif model_goal == "AS" or model_goal == "DC": 120 | state1 = np.arange(1,self.block_size/2+1) 121 | for i in range(self.block_size/2): 122 | state1[self.block_size/2-1-self.pbox_left_DC[self.block_size/2-1-i]] = state[i] 123 | return state1 124 | ########################### xor ############################### 125 | def get_state_through_xor(self,model_goal,r): 126 | if model_goal == "LBAS": 127 | state1 = np.arange((r+1)*self.block_size/8+1,(r+2)*self.block_size/8+1) 128 | elif model_goal == "AS" or model_goal == "DC": 129 | state1 = np.arange(r*self.block_size+self.block_size/2+1,r*self.block_size+self.block_size/2+1+self.block_size/2) 130 | return state1 131 | def diff_propagation_of_xor(self,model_goal,model_filename,r,state1,state2,state3): 132 | var = {} 133 | if model_goal == "LBAS": 134 | for i in range(self.nibble): 135 | var["x"] = state1[i] 136 | var["y"] = state2[i] 137 | var["z"] = state3[i] 138 | var["d"] = self.nibble*(r-1)+i+1 139 | function.diff_propagation_of_xor_word(model_filename,var) 140 | elif model_goal == "AS" or model_goal == "DC": 141 | for i in range(self.block_size/2): 142 | var["x"] = state1[i] 143 | var["y"] = state2[i] 144 | var["z"] = state3[i] 145 | var["d"] = self.block_size/2*(r-1)+i+1 146 | function.diff_propagation_of_xor_bit(model_filename,var) 147 | 148 | def lowbound_of_sbox(self,model_goal,model_filename,r1,r2,lb): 149 | if model_goal == "LBAS" or model_goal == "AS": 150 | if model_goal == "LBAS": 151 | r1 = r1+1 152 | r2 = r2+1 153 | for r in range(r1,r2+1): 154 | for i in range(1,self.nibble): 155 | with open(model_filename, "a") as f: 156 | f.write("A%d + "%(self.nibble*(r-1)+i)) 157 | with open(model_filename, "a") as f: 158 | f.write("A%d >= %d \n"%(self.nibble*r,lb)) 159 | elif model_goal == "DC": 160 | for r in range(r1,r2+1): 161 | for i in range(1,self.nibble): 162 | with open(model_filename, "a") as f: 163 | f.write("p%d + "%(self.nibble*2*(r-1)+2*i)) 164 | with open(model_filename, "a") as f: 165 | f.write("p%d >= %d\n"%(self.nibble*r*2,lb)) 166 | 167 | def fix_diff(self,model_goal,model_filename,diff_type,r,diff_pattern): 168 | diff_pattern_copy = copy.deepcopy(diff_pattern) 169 | if diff_type == "diff_pattern_front": 170 | r1 = r-1 171 | diff_pattern_copy[0:2] = copy.deepcopy(diff_pattern[6:8]) 172 | diff_pattern_copy[2:8] = copy.deepcopy(diff_pattern[0:6]) 173 | elif diff_type == "diff_pattern_next": 174 | r1 = r+1 175 | if model_goal == "LBAS" or model_goal == "AS": 176 | if model_goal == "LBAS": 177 | r = r+1 178 | r1 = r1+1 179 | for i in range(1,self.nibble+1): 180 | with open(model_filename, "a") as f: 181 | f.write("A%d = 0\n"%(self.nibble*(r-1)+i)) 182 | for i in range(1,self.nibble+1): 183 | if diff_pattern_copy[i-1] == 1: 184 | with open(model_filename, "a") as f: 185 | f.write("A%d = 1\n"%(self.nibble*(r1-1)+i)) 186 | else: 187 | with open(model_filename, "a") as f: 188 | f.write("A%d = 0\n"%(self.nibble*(r1-1)+i)) 189 | elif model_goal == "DC": 190 | for i in range(1,self.nibble+1): 191 | with open(model_filename, "a") as f: 192 | f.write("p%d = 0\n"%(self.nibble*(r-1)*2+i*2)) 193 | for i in range(1,self.nibble+1): 194 | if diff_pattern_copy[i-1] == 1: 195 | with open(model_filename, "a") as f: 196 | f.write("p%d = 1\n"%(self.nibble*(r1-1)*2+i*2)) 197 | else: 198 | with open(model_filename, "a") as f: 199 | f.write("p%d = 0\n"%(self.nibble*(r1-1)*2+i*2)) -------------------------------------------------------------------------------- /ciphers/present.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | import numpy as np 3 | import function 4 | import copy 5 | from itertools import combinations 6 | class class_present: 7 | def __init__(self): 8 | self.name = "present" 9 | self.structure = "sp" 10 | self.oriented = "bit" 11 | self.block_size = 64 12 | self.sbox_size = 4 13 | self.num_of_sbox = 1 14 | self.nibble = 16 15 | self.sbox = [[0xc, 0x5, 0x6, 0xb, 0x9, 0x0, 0xa, 0xd, 0x3, 0xe, 0xf, 0x8, 0x4, 0x7, 0x1, 0x2]] 16 | self.pbox = [0, 16, 32, 48, 1, 17, 33, 49, 2, 18, 34,50, 3, 19, 35, 51,\ 17 | 4, 20, 36, 52, 5, 21, 37, 53, 6, 22, 38, 54, 7, 23, 39, 55,\ 18 | 8, 24, 40, 56, 9, 25, 41, 57, 10, 26, 42, 58, 11, 27, 43, 59,\ 19 | 12, 28, 44, 60, 13, 29, 45, 61, 14, 30, 46, 62, 15, 31, 47, 63] 20 | self.branch_num_of_sbox = 3 21 | self.var_and_num_LBAS = {"x":[0,self.block_size],"d":[self.nibble,0],"A":[self.nibble,0]} 22 | self.var_and_num_AS = {"x":[self.block_size,self.block_size],"d":[self.nibble,0], "A":[self.nibble,0]} 23 | self.var_and_num_DC = {"x":[self.block_size,self.block_size],"d":[self.nibble,0], "p":[self.nibble*2,0]} #,"d":[self.nibble,0] 24 | 25 | # searching 26 | self.diff_all = self.get_diff_all() 27 | self.num_of_diff_all = [240,27000] 28 | self.min_weight_of_sbox = 2 29 | self.round_of_first_region2 = 6 30 | 31 | def get_search_round(self,goal): 32 | if goal == "AS": 33 | return 31 34 | elif goal == "DC": 35 | return 18 36 | 37 | def get_max_num_of_round_to_solve(self,goal): 38 | return 15,0 39 | 40 | 41 | def get_diff_all(self): 42 | diff = [] 43 | position_1 = list(combinations(np.arange(1,self.nibble+1),1)) 44 | for i in position_1: 45 | diff_round_1 = [0 for l in range(self.nibble)] 46 | j = list(i)[0] 47 | for k in range(1,pow(2,self.sbox_size)): 48 | diff_round_1[j-1] = k 49 | diff.append(copy.deepcopy(diff_round_1)) 50 | position_2 = list(combinations(np.arange(1,self.nibble+1),2)) 51 | for i in position_2: 52 | diff_round_2 = [0 for l in range(self.nibble)] 53 | j1 = list(i)[0] 54 | j2 = list(i)[1] 55 | for k1 in range(1,pow(2,self.sbox_size)): 56 | for k2 in range(1,pow(2,self.sbox_size)): 57 | diff_round_2[j1-1] = k1 58 | diff_round_2[j2-1] = k2 59 | diff.append(copy.deepcopy(diff_round_2)) 60 | return diff 61 | 62 | def obj_fun(self,model_goal,model_filename,r1,r2): 63 | if model_goal == "LBAS" or model_goal == "AS": 64 | for i in range ((r1-1)*self.nibble+1,r2*self.nibble): 65 | with open(model_filename, "a") as f: 66 | f.write("A%d + "%(i)) 67 | with open(model_filename, "a") as f: 68 | f.write("A%d"%(r2*self.nibble)) 69 | elif model_goal == "DC": 70 | for i in range ((r1-1)*self.nibble*2+1,r2*self.nibble*2): 71 | if i%2 == 1: 72 | with open(model_filename, "a") as f: 73 | f.write("1 p%d + "%(i)) 74 | elif i%2 == 0: 75 | with open(model_filename, "a") as f: 76 | f.write("2 p%d + "%(i)) 77 | with open(model_filename, "a") as f: 78 | f.write("%d p%d"%(2, r2*self.nibble * 2)) 79 | 80 | def gen_input_state(self): 81 | state = np.arange(1,self.block_size+1) 82 | return state 83 | def get_state_through_sbox(self,r): 84 | state = np.arange(self.block_size*r+1,self.block_size*(r+1)+1) 85 | return state 86 | def diff_propagation_of_sbox(self,model_goal,model_filename,r,state,state_through_sbox): 87 | var = {} 88 | for n in range(self.nibble): 89 | var["x"] = state[self.sbox_size*n:self.sbox_size*(n+1)] 90 | var["y"] = state_through_sbox[self.sbox_size*n:self.sbox_size*(n+1)] 91 | var["d"] = self.nibble*(r-1)+n+1 92 | if model_goal == "LBAS": 93 | var["A"] = self.nibble*(r-1)+n+1 94 | function.diff_propagation_of_sbox_LBAS_bit(self.sbox_size,self.branch_num_of_sbox,model_filename,var) 95 | else: 96 | for i in range(self.sbox_size): 97 | with open(model_filename, "a") as f: 98 | f.write("x%d + "%(var["x"][i])) 99 | for i in range(self.sbox_size-1): 100 | with open(model_filename, "a") as f: 101 | f.write("x%d + "%(var["y"][i])) 102 | with open(model_filename, "a") as f: 103 | f.write("x%d - %d d%d >= 0\n"%(var["y"][self.sbox_size-1],self.branch_num_of_sbox,var["d"])) 104 | for i in range(self.sbox_size): 105 | with open(model_filename, "a") as f: 106 | f.write("d%d - x%d >= 0\n"%(var["d"],var["x"][i])) 107 | for i in range(self.sbox_size): 108 | with open(model_filename, "a") as f: 109 | f.write("d%d - x%d >= 0\n"%(var["d"],var["y"][i])) 110 | if model_goal == "AS": 111 | var["A"] = self.nibble*(r-1)+n+1 112 | ine = np.loadtxt("txt/"+self.name + "/AS/1th_sbox_reduce_ine_greedy.txt",int) 113 | function.diff_propagation_of_sbox_AS(self.sbox_size,model_filename,var,ine) 114 | elif model_goal == "DC": 115 | var["p"] = [2*n+(r-1)*2*self.nibble+1, 2*n+(r-1)*2*self.nibble+2] 116 | ine = np.loadtxt("txt/"+self.name + "/DC/1th_sbox_reduce_ine_greedy.txt",int) 117 | function.diff_propagation_of_sbox_DC(self.sbox_size,self.var_and_num_DC["p"][0]/self.nibble,model_filename,var,ine) 118 | 119 | def get_state_through_per(self,state): 120 | state1 = np.arange(1,self.block_size+1) 121 | for i in range(self.block_size): 122 | state1[self.block_size-1-self.pbox[self.block_size-1-i]] = state[i] 123 | return state1 124 | 125 | def lowbound_of_sbox(self,model_goal,model_filename,r1,r2,lb): 126 | if model_goal == "LBAS" or model_goal == "AS": 127 | for r in range(r1,r2+1): 128 | for i in range(1,self.nibble): 129 | with open(model_filename, "a") as f: 130 | f.write("A%d + "%(self.nibble*(r-1)+i)) 131 | with open(model_filename, "a") as f: 132 | f.write("A%d >= %d \n"%(self.nibble*r,lb)) 133 | elif model_goal == "DC": 134 | for r in range(r1,r2+1): 135 | for i in range(1,self.nibble): 136 | with open(model_filename, "a") as f: 137 | f.write("p%d + "%(self.nibble*2*(r-1)+2*i)) 138 | with open(model_filename, "a") as f: 139 | f.write("p%d >= %d\n"%(self.nibble*r*2,lb)) 140 | 141 | def fix_diff(self,model_goal,model_filename,diff_type,r,diff_value): 142 | if diff_type == "input_diff": 143 | state = self.get_state_through_sbox(r-1) 144 | if r > 1: 145 | state = self.get_state_through_per(state) 146 | elif diff_type == "output_diff": 147 | state = self.get_state_through_per(self.get_state_through_sbox(r)) 148 | for i in range(self.nibble): 149 | value = diff_value[i] 150 | value_bin = bin(value).replace("0b","").zfill(self.sbox_size) 151 | for j in range(self.sbox_size): 152 | with open(model_filename, "a") as f: 153 | f.write("x%d = %d \n"%(state[self.sbox_size*i+j],int(value_bin[j]))) -------------------------------------------------------------------------------- /ciphers/rectangle.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | import numpy as np 3 | import function 4 | import copy 5 | class class_rectangle: 6 | def __init__(self): 7 | self.name = "rectangle" 8 | self.structure = "sp" 9 | self.oriented = "bit" 10 | self.block_size = 64 11 | self.sbox_size = 4 12 | self.num_of_sbox = 1 13 | self.nibble = 16 14 | self.sbox = [[0x6,0x5,0xc,0xa,0x1,0xe,0x7,0x9,0xb,0x0,0x3,0xd,0x8,0xf,0x4,0x2]] 15 | self.pbox = [13,14,15,0,1,2,3,4,5,6,7,8,9,10,11,12,\ 16 | 28,29,30,31,16,17,18,19,20,21,22,23,24,25,26,27,\ 17 | 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,32,\ 18 | 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63] 19 | self.branch_num_of_sbox = function.hamming_weight(self.name,self.sbox[0],self.sbox_size) #2 20 | self.var_and_num_LBAS = {"x":[0,self.block_size],"d":[self.nibble,0],"A":[self.nibble,0]} 21 | self.var_and_num_AS = {"x":[self.block_size,self.block_size],"A":[self.nibble,0]} 22 | self.var_and_num_DC = {"x":[self.block_size,self.block_size],"p":[self.nibble*2,0]} 23 | 24 | # searching 25 | self.diff_all = self.get_diff_all() 26 | self.num_of_diff_all = [15,3375] 27 | self.min_weight_of_sbox = 2 28 | self.max_round_of_solve_LBAS = 0 29 | self.round_of_first_region2 = 28 30 | 31 | def get_search_round(self,goal): 32 | if goal == "AS": 33 | return 17 34 | elif goal == "DC": 35 | return 16 36 | 37 | def get_max_num_of_round_to_solve(self,goal): 38 | if goal == "AS": 39 | max_num_of_round_to_solve = 6 40 | elif goal == "DC": 41 | max_num_of_round_to_solve = 5 42 | return 0,max_num_of_round_to_solve 43 | 44 | def get_diff_all(self): 45 | diff = [] 46 | diff_round_1 = [0 for i in range(self.nibble)] 47 | for k in range(1,pow(2,self.sbox_size)): 48 | diff_round_1[0] = k 49 | diff.append(copy.deepcopy(diff_round_1)) 50 | for i in range(2,self.nibble+1): 51 | diff_round_2 = [0 for j in range(self.nibble)] 52 | for k1 in range(1,pow(2,self.sbox_size)): 53 | for k2 in range(1,pow(2,self.sbox_size)): 54 | diff_round_2[0] = k1 55 | diff_round_2[i-1] = k2 56 | diff.append(copy.deepcopy(diff_round_2)) 57 | return diff 58 | 59 | def obj_fun(self,model_goal,model_filename,r1,r2): 60 | if model_goal == "LBAS" or model_goal == "AS": 61 | for i in range ((r1-1)*self.nibble+1,r2*self.nibble): 62 | with open(model_filename, "a") as f: 63 | f.write("A%d + "%(i)) 64 | with open(model_filename, "a") as f: 65 | f.write("A%d"%(r2*self.nibble)) 66 | elif model_goal == "DC": 67 | for i in range ((r1-1)*self.nibble*2+1,r2*self.nibble*2): 68 | if i%2 == 1: 69 | with open(model_filename, "a") as f: 70 | f.write("1 p%d + "%(i)) 71 | elif i%2 == 0: 72 | with open(model_filename, "a") as f: 73 | f.write("2 p%d + "%(i)) 74 | with open(model_filename, "a") as f: 75 | f.write("%d p%d"%(2, r2*self.nibble * 2)) 76 | 77 | def gen_input_state(self): 78 | state = np.arange(1,self.block_size+1) 79 | return state 80 | 81 | def get_state_through_sbox(self,r): 82 | state = np.arange(self.block_size*r+1,self.block_size*(r+1)+1) 83 | return state 84 | 85 | def diff_propagation_of_sbox(self,model_goal,model_filename,r,state,state_through_sbox): 86 | var = {} 87 | temp = [0 for i in range(self.sbox_size)] 88 | for n in range(self.nibble): 89 | var["x"] = [state[n],state[n+self.nibble*1],state[n+self.nibble*2],state[n+self.nibble*3]] 90 | var["y"] = [state_through_sbox[n],state_through_sbox[n+self.nibble*1],state_through_sbox[n+self.nibble*2],state_through_sbox[n+self.nibble*3]] 91 | if model_goal == "AS": 92 | var["A"] = self.nibble*(r-1)+n+1 93 | ine = np.loadtxt("txt/"+self.name + "/AS/1th_sbox_reduce_ine_greedy.txt",int) 94 | function.diff_propagation_of_sbox_AS(self.sbox_size,model_filename,var,ine) 95 | elif model_goal == "DC": 96 | var["p"] = [2*n+(r-1)*2*self.nibble+1, 2*n+(r-1)*2*self.nibble+2] 97 | ine = np.loadtxt("txt/"+self.name + "/DC/1th_sbox_reduce_ine_greedy.txt",int) 98 | function.diff_propagation_of_sbox_DC(self.sbox_size,self.var_and_num_DC["p"][0]/self.nibble,model_filename,var,ine) 99 | 100 | def get_state_through_per(self,state): 101 | state1 = np.arange(1,self.block_size+1) 102 | for i in range(self.block_size): 103 | state1[self.block_size-1-self.pbox[self.block_size-1-i]] = state[i] 104 | return state1 105 | 106 | def lowbound_of_sbox(self,model_goal,model_filename,r1,r2,lb): 107 | if model_goal == "LBAS" or model_goal == "AS": 108 | for r in range(r1,r2+1): 109 | for i in range(1,self.nibble): 110 | with open(model_filename, "a") as f: 111 | f.write("A%d + "%(self.nibble*(r-1)+i)) 112 | with open(model_filename, "a") as f: 113 | f.write("A%d >= %d \n"%(self.nibble*r,lb)) 114 | elif model_goal == "DC": 115 | for r in range(r1,r2+1): 116 | for i in range(1,self.nibble): 117 | with open(model_filename, "a") as f: 118 | f.write("p%d + "%(self.nibble*2*(r-1)+2*i)) 119 | with open(model_filename, "a") as f: 120 | f.write("p%d >= %d\n"%(self.nibble*r*2,lb)) 121 | 122 | def fix_diff(self,model_goal,model_filename,diff_type,r,diff_value): 123 | if diff_type == "input_diff": 124 | state = self.get_state_through_sbox(r-1) 125 | if r > 1: 126 | state = self.get_state_through_per(state) 127 | elif diff_type == "output_diff": 128 | state = self.get_state_through_per(self.get_state_through_sbox(r)) 129 | for i in range(self.nibble): 130 | value = diff_value[i] 131 | value_bin = bin(value).replace("0b","").zfill(self.sbox_size) 132 | for j in range(self.sbox_size): 133 | with open(model_filename, "a") as f: 134 | f.write("x%d = %d \n"%(state[self.nibble*j+i],int(value_bin[j]))) -------------------------------------------------------------------------------- /ciphers/twine.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | import numpy as np 3 | import function 4 | import copy 5 | from itertools import combinations 6 | class class_twine: 7 | def __init__(self): 8 | self.name = "twine" 9 | self.structure = "feistel" 10 | self.oriented = "byte" 11 | self.block_size = 64 12 | self.sbox_size = 4 13 | self.num_of_sbox = 1 14 | self.nibble = 8 15 | self.sbox = [[12, 0, 15, 10, 2, 11, 9, 5, 8, 3, 13, 7, 1, 14, 6, 4]] 16 | self.pbox_left_DC = [0,1,2,3,8,9,10,11,24,25,26,27,16,17,18,19,\ 17 | 12,13,14,15,4,5,6,7,20,21,22,23,28,29,30,31] 18 | self.pbox_right_DC = [8,9,10,11,0,1,2,3,12,13,14,15,4,5,6,7,\ 19 | 24,25,26,27,16,17,18,19,28,29,30,31,20,21,22,23] 20 | self.pbox_left_LBAS = [0,2,6,4,3,1,5,7] 21 | self.pbox_right_LBAS = [2,0,3,1,6,4,7,5] 22 | self.IN_pbox_left_LBAS = [0,5,1,4,3,6,2,7] 23 | self.IN_pbox_right_LBAS = [1,3,0,2,5,7,4,6] 24 | self.var_and_num_LBAS = {"A":[self.block_size/8,self.block_size/8],"d":[self.block_size/8,-self.block_size/8]} 25 | self.var_and_num_AS = {"x":[self.block_size,self.block_size/2],"A":[self.nibble,0],"d":[self.block_size/2,-self.block_size/2]} 26 | self.var_and_num_DC = {"x":[self.block_size,self.block_size/2],"p":[self.nibble*2,0],"d":[self.block_size/2,-self.block_size/2]} 27 | 28 | # searching 29 | self.diff_pattern_all = self.get_diff_pattern_all() 30 | self.num_of_diff_pattern_all = 255 31 | self.min_weight_of_sbox = 2 32 | self.max_round_of_solve_LBAS = 16 33 | self.max_round_of_solve_AS = 0 34 | self.max_round_of_solve_DC = 0 35 | 36 | def get_search_round(self,goal): 37 | if goal == "AS": 38 | return 20 39 | elif goal == "DC": 40 | return 16 41 | def get_max_num_of_round_to_solve(self,goal): 42 | return 16,0 43 | 44 | def get_diff_pattern_all(self): 45 | diff_pattern = [] 46 | for i in range(1,self.nibble+1): 47 | position = list(combinations(np.arange(1,self.nibble+1),i)) 48 | for j in position: 49 | diff_pattern_round = [0 for l in range(self.nibble)] 50 | for k in j: 51 | diff_pattern_round[k-1] = 1 52 | diff_pattern.append(copy.deepcopy(diff_pattern_round)) 53 | return diff_pattern 54 | def obj_fun(self,model_goal,model_filename,r1,r2): 55 | if model_goal == "LBAS": 56 | r1 = r1+1 57 | r2 = r2+1 58 | if model_goal == "LBAS" or model_goal == "AS": 59 | for i in range ((r1-1)*self.nibble+1,r2*self.nibble): 60 | with open(model_filename, "a") as f: 61 | f.write("A%d + "%(i)) 62 | with open(model_filename, "a") as f: 63 | f.write("A%d"%(r2*self.nibble)) 64 | elif model_goal == "DC": 65 | for i in range ((r1-1)*self.nibble*2+1,r2*self.nibble*2): 66 | if i%2 == 1: 67 | with open(model_filename, "a") as f: 68 | f.write("1 p%d + "%(i)) 69 | elif i%2 == 0: 70 | with open(model_filename, "a") as f: 71 | f.write("2 p%d + "%(i)) 72 | with open(model_filename, "a") as f: 73 | f.write("%d p%d"%(2, r2*self.nibble * 2)) 74 | def gen_input_state(self,model_goal): 75 | if model_goal == "LBAS": 76 | state = np.arange(1,self.nibble*2+1) 77 | else: 78 | state = np.arange(1,self.block_size+1) 79 | return state 80 | def get_state_through_sbox(self,model_goal,r): 81 | if model_goal == "LBAS": 82 | state = np.arange(self.block_size*r+1,self.block_size*(r+1)+1) 83 | elif model_goal == "AS" or model_goal == "DC": 84 | state = np.arange(self.block_size*r+1,self.block_size*r+1+self.block_size/2) 85 | 86 | return state 87 | def diff_propagation_of_sbox(self,model_goal,model_filename,r,state,state_through_sbox): 88 | var = {} 89 | for n in range(self.nibble): 90 | var["x"] = state[self.sbox_size*n:self.sbox_size*(n+1)] 91 | var["y"] = state_through_sbox[self.sbox_size*n:self.sbox_size*(n+1)] 92 | if model_goal == "AS": 93 | var["A"] = self.nibble*(r-1)+n+1 94 | ine = np.loadtxt("txt/"+self.name + "/AS/1th_sbox_reduce_ine_greedy.txt",int) 95 | function.diff_propagation_of_sbox_AS(self.sbox_size,model_filename,var,ine) 96 | elif model_goal == "DC": 97 | var["p"] = [2*n+(r-1)*2*self.nibble+1, 2*n+(r-1)*2*self.nibble+2] 98 | ine = np.loadtxt("txt/"+self.name + "/DC/1th_sbox_reduce_ine_greedy.txt",int) 99 | function.diff_propagation_of_sbox_DC(self.sbox_size,self.var_and_num_DC["p"][0]/self.nibble,model_filename,var,ine) 100 | def get_state_through_per_right(self,model_goal,state): 101 | if model_goal == "LBAS": 102 | state1 = zeros(self.nibble, dtype = int16) 103 | for i in range(self.nibble): 104 | state1[self.nibble-1-self.pbox_right_LBAS[self.nibble-1-i]] = state[i] 105 | elif model_goal == "AS" or model_goal == "DC": 106 | state1 = zeros(self.block_size/2, dtype = int16) 107 | for i in range(self.block_size/2): 108 | state1[self.block_size/2-1-self.pbox_right_DC[self.block_size/2-1-i]] = state[i] 109 | return state1 110 | def get_state_through_per_left(self,model_goal,state): 111 | if model_goal == "LBAS": 112 | state1 = np.arange(1,self.nibble+1) 113 | for i in range(self.nibble): 114 | state1[self.nibble-1-self.pbox_left_LBAS[self.nibble-1-i]] = state[i] 115 | elif model_goal == "AS" or model_goal == "DC": 116 | state1 = np.arange(1,self.block_size/2+1) 117 | for i in range(self.block_size/2): 118 | state1[self.block_size/2-1-self.pbox_left_DC[self.block_size/2-1-i]] = state[i] 119 | return state1 120 | ########################### xor ############################### 121 | def get_state_through_xor(self,model_goal,r): 122 | if model_goal == "LBAS": 123 | state1 = np.arange((r+1)*self.block_size/8+1,(r+2)*self.block_size/8+1) 124 | elif model_goal == "AS" or model_goal == "DC": 125 | state1 = np.arange(r*self.block_size+self.block_size/2+1,r*self.block_size+self.block_size/2+1+self.block_size/2) 126 | return state1 127 | def diff_propagation_of_xor(self,model_goal,model_filename,r,state1,state2,state3): 128 | var = {} 129 | if model_goal == "LBAS": 130 | for i in range(self.nibble): 131 | var["x"] = state1[i] 132 | var["y"] = state2[i] 133 | var["z"] = state3[i] 134 | var["d"] = self.nibble*(r-1)+i+1 135 | function.diff_propagation_of_xor_word(model_filename,var) 136 | elif model_goal == "AS" or model_goal == "DC": 137 | for i in range(self.block_size/2): 138 | var["x"] = state1[i] 139 | var["y"] = state2[i] 140 | var["z"] = state3[i] 141 | var["d"] = self.block_size/2*(r-1)+i+1 142 | function.diff_propagation_of_xor_bit(model_filename,var) 143 | def lowbound_of_sbox(self,model_goal,model_filename,r1,r2,lb): 144 | if model_goal == "LBAS" or model_goal == "AS": 145 | if model_goal == "LBAS": 146 | r1 = r1+1 147 | r2 = r2+1 148 | for r in range(r1,r2+1): 149 | for i in range(1,self.nibble): 150 | with open(model_filename, "a") as f: 151 | f.write("A%d + "%(self.nibble*(r-1)+i)) 152 | with open(model_filename, "a") as f: 153 | f.write("A%d >= %d \n"%(self.nibble*r,lb)) 154 | elif model_goal == "DC": 155 | for r in range(r1,r2+1): 156 | for i in range(1,self.nibble): 157 | with open(model_filename, "a") as f: 158 | f.write("p%d + "%(self.nibble*2*(r-1)+2*i)) 159 | with open(model_filename, "a") as f: 160 | f.write("p%d >= %d\n"%(self.nibble*r*2,lb)) 161 | def fix_diff(self,model_goal,model_filename,diff_type,r,diff_pattern): 162 | pattern = copy.deepcopy(diff_pattern) 163 | temp = copy.deepcopy(pattern) 164 | if diff_type == "diff_pattern_front": 165 | r1 = r-1 166 | for i in range(8): 167 | temp[self.IN_pbox_left_LBAS[i]] = pattern[i] 168 | pattern = copy.deepcopy(temp) 169 | temp_1 = copy.deepcopy(pattern) 170 | for i in range(8): 171 | temp_1[self.IN_pbox_right_LBAS[i]] = pattern[i] 172 | pattern = copy.deepcopy(temp_1) 173 | elif diff_type == "diff_pattern_next": 174 | r1 = r+1 175 | if model_goal == "LBAS" or model_goal == "AS": 176 | if model_goal == "LBAS": 177 | r = r+1 178 | r1 = r1+1 179 | if r1 > 2: 180 | for i in range(8): 181 | temp[self.IN_pbox_left_LBAS[i]] = pattern[i] 182 | pattern = copy.deepcopy(temp) 183 | for i in range(1,self.nibble+1): 184 | with open(model_filename, "a") as f: 185 | f.write("A%d = 0\n"%(self.nibble*(r-1)+i)) 186 | for i in range(1,self.nibble+1): 187 | if pattern[i-1] == 1: 188 | with open(model_filename, "a") as f: 189 | f.write("A%d = 1\n"%(self.nibble*(r1-1)+i)) 190 | else: 191 | with open(model_filename, "a") as f: 192 | f.write("A%d = 0\n"%(self.nibble*(r1-1)+i)) 193 | elif model_goal == "DC": 194 | for i in range(1,self.nibble+1): 195 | with open(model_filename, "a") as f: 196 | f.write("p%d = 0\n"%(self.nibble*(r-1)*2+i*2)) 197 | for i in range(1,self.nibble+1): 198 | if pattern[i-1] == 1: 199 | with open(model_filename, "a") as f: 200 | f.write("p%d = 1\n"%(self.nibble*(r1-1)*2+i*2)) 201 | else: 202 | with open(model_filename, "a") as f: 203 | f.write("p%d = 0\n"%(self.nibble*(r1-1)*2+i*2)) -------------------------------------------------------------------------------- /function.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | from numpy import * 4 | import numpy as np 5 | import math 6 | import copy 7 | import shutil 8 | 9 | def gen_filefolder(cipher_name,goal): 10 | filefolder = "model/"+cipher_name+"/LBAS/" 11 | if not os.path.isdir(filefolder): 12 | os.makedirs(filefolder) 13 | filefolder = "model/"+cipher_name+"/"+str(goal)+"/" 14 | if not os.path.isdir(filefolder): 15 | os.makedirs(filefolder) 16 | filefolder = "result/"+cipher_name+"/"+str(goal)+"/" 17 | if not os.path.isdir(filefolder): 18 | os.makedirs(filefolder) 19 | filefolder = "txt/"+cipher_name+"/"+goal+"/optimal_solution_of_submodel/" 20 | if not os.path.isdir(filefolder): 21 | os.makedirs(filefolder) 22 | 23 | def remove_file(filename): 24 | if os.path.exists(filename): 25 | os.remove(filename) 26 | 27 | def diff_propagation_of_sbox_LBAS_bit(sbox_size,branch_num_of_sbox,model_filename,var): 28 | for i in range(sbox_size-1): 29 | with open(model_filename, "a") as f: 30 | f.write("x%d + "%(var["x"][i])) 31 | # constraint 1 32 | with open(model_filename, "a") as f: 33 | f.write("x%d - A%d >= 0\n"%(var["x"][sbox_size-1],var["A"])) 34 | for i in range(sbox_size): 35 | with open(model_filename, "a") as f: 36 | f.write("A%d - x%d >= 0\n"%(var["A"],var["x"][i])) 37 | # constraint 2 38 | for i in range(sbox_size): 39 | with open(model_filename, "a") as f: 40 | f.write("x%d + "%(var["x"][i])) 41 | for i in range(sbox_size-1): 42 | with open(model_filename, "a") as f: 43 | f.write("x%d + "%(var["y"][i])) 44 | with open(model_filename, "a") as f: 45 | f.write("x%d - %d d%d >= 0\n"%(var["y"][sbox_size-1],branch_num_of_sbox,var["d"])) 46 | for i in range(sbox_size): 47 | with open(model_filename, "a") as f: 48 | f.write("d%d - x%d >= 0\n"%(var["d"],var["x"][i])) 49 | for i in range(sbox_size): 50 | with open(model_filename, "a") as f: 51 | f.write("d%d - x%d >= 0\n"%(var["d"],var["y"][i])) 52 | # constraint 3 53 | with open(model_filename, "a") as f: 54 | f.write("%d x%d + %d x%d + %d x%d + %d x%d - x%d - x%d - x%d - x%d >= 0\n"%(sbox_size,var["y"][0],sbox_size,var["y"][1],sbox_size,var["y"][2],sbox_size,var["y"][3],var["x"][0],var["x"][1],var["x"][2],var["x"][3])) 55 | f.write("%d x%d + %d x%d + %d x%d + %d x%d - x%d - x%d - x%d - x%d >= 0\n"%(sbox_size,var["x"][0],sbox_size,var["x"][1],sbox_size,var["x"][2],sbox_size,var["x"][3],var["y"][0],var["y"][1],var["y"][2],var["y"][3])) 56 | 57 | def diff_propagation_of_sbox_AS(sbox_size,model_filename,var,ine): 58 | vector_size = 2 * sbox_size 59 | symbal = [" " for i in range(vector_size+1)] 60 | for i in range(sbox_size-1): 61 | with open(model_filename, "a") as f: 62 | f.write("x%d + "%(var["x"][i])) 63 | with open(model_filename, "a") as f: 64 | f.write("x%d - A%d >= 0\n"%(var["x"][sbox_size-1],var["A"])) 65 | for i in range(sbox_size): 66 | with open(model_filename, "a") as f: 67 | f.write("A%d - x%d >= 0\n"%(var["A"],var["x"][i])) 68 | for i in range(len(ine)): 69 | for k in range (0,vector_size): 70 | if ine[i,k] < 0: 71 | symbal[k] = '-' 72 | elif ine[i,k] >= 0: 73 | symbal[k] = '+' 74 | for k1 in range(sbox_size): 75 | with open(model_filename, "a") as f: 76 | f.write("%s %d x%d "%(symbal[k1], abs(ine[i,k1]),var["x"][k1])) 77 | for k2 in range (sbox_size,sbox_size*2): 78 | with open(model_filename, "a") as f: 79 | f.write("%s %d x%d "%(symbal[k2], abs(ine[i,k2]),var["y"][k2-sbox_size])) 80 | if ine[i,vector_size] > 0: 81 | symbal[vector_size] = '-' 82 | elif ine[i,vector_size] <= 0: 83 | symbal[vector_size] = '+' 84 | with open(model_filename, "a") as f: 85 | f.write(" >= %s %d \n"%(symbal[vector_size], abs(ine[i,vector_size]))) 86 | 87 | def diff_propagation_of_sbox_DC(sbox_size,num_of_p_var,model_filename,var,ine): 88 | vector_size = 2 * sbox_size + num_of_p_var 89 | symbal = [" " for i in range(vector_size+1)] 90 | for i in range(len(ine)): 91 | for k in range (0,vector_size): 92 | if ine[i,k] < 0: 93 | symbal[k] = '-' 94 | elif ine[i,k] >= 0: 95 | symbal[k] = '+' 96 | for k1 in range(sbox_size): 97 | with open(model_filename, "a") as f: 98 | f.write("%s %d x%d "%(symbal[k1], abs(ine[i,k1]),var["x"][k1])) 99 | for k2 in range (sbox_size,sbox_size*2): 100 | with open(model_filename, "a") as f: 101 | f.write("%s %d x%d "%(symbal[k2], abs(ine[i,k2]),var["y"][k2-sbox_size])) 102 | for k3 in range(sbox_size*2,vector_size): 103 | with open(model_filename, "a") as f: 104 | f.write("%s %d p%d "%(symbal[k3], abs(ine[i,k3]),var["p"][k3-sbox_size*2])) 105 | if ine[i,vector_size] > 0: 106 | symbal[vector_size] = '-' 107 | elif ine[i,vector_size] <= 0: 108 | symbal[vector_size] = '+' 109 | with open(model_filename, "a") as f: 110 | f.write(" >= %s %d \n"%(symbal[vector_size], abs(ine[i,vector_size]))) 111 | 112 | def diff_propagation_of_xor_word(model_filename,var): 113 | with open(model_filename, "a") as f: 114 | f.write("A%d + A%d + A%d - 2 d%d >= 0\n"%(var["x"], var["y"], var["z"], var["d"])) 115 | f.write("d%d - A%d >= 0\n"%(var["d"],var["x"])) 116 | f.write("d%d - A%d >= 0\n"%(var["d"],var["y"])) 117 | f.write("d%d - A%d >= 0\n"%(var["d"],var["z"])) 118 | 119 | def diff_propagation_of_xor_bit(model_filename,var): 120 | with open(model_filename, "a") as f: 121 | f.write("x%d + x%d + x%d - 2 d%d >= 0\n"%(var["x"], var["y"], var["z"], var["d"])) 122 | f.write("d%d - x%d >= 0\n"%(var["d"],var["x"])) 123 | f.write("d%d - x%d >= 0\n"%(var["d"],var["y"])) 124 | f.write("d%d - x%d >= 0\n"%(var["d"],var["z"])) 125 | f.write("x%d + x%d + x%d <= 2\n"%(var["x"], var["y"], var["z"])) 126 | 127 | 128 | ################################################################################# 129 | # searching function 130 | def get_order_of_Na(cipher,r): 131 | if r < cipher.round_of_first_region2: 132 | temp = [1,2] 133 | elif r >= cipher.round_of_first_region2: 134 | temp = [2,1] 135 | return temp 136 | 137 | def get_value(r,value): 138 | if r == 0: 139 | return 0 140 | elif r >= 1: 141 | return value 142 | 143 | def get_search_round(r): 144 | middle = int((r+2)/2) 145 | array_1 = middle - np.arange(1,middle) 146 | array_2 = np.arange(middle+1,r+1) 147 | temp = [middle] 148 | if r%2 == 0: 149 | for i in range(max(len(array_1),len(array_2))): 150 | if i < len(array_1): 151 | temp.append(array_1[i]) 152 | if i < len(array_2): 153 | temp.append(array_2[i]) 154 | elif r%2 == 1: 155 | for i in range(max(len(array_1),len(array_2))): 156 | if i < len(array_2): 157 | temp.append(array_2[i]) 158 | if i < len(array_1): 159 | temp.append(array_1[i]) 160 | return array(temp) 161 | 162 | def trans_diff_pattern(cipher,Na): 163 | diff_pattern = [] 164 | position = list(combinations(np.arange(1,cipher.nibble+1),Na)) 165 | for i in range(len(position)): 166 | pattern = [0 for i in range(cipher.nibble)] 167 | for j in positoin[i]: 168 | pattern[j-1] = 1 169 | diff_pattern.append(copy.deepcopy(pattern)) 170 | return diff_pattern 171 | 172 | def read_txt(filename): 173 | line = [] 174 | with open(filename) as f: 175 | for j in f.readlines(): 176 | line.append(j) 177 | return line 178 | 179 | def get_var_from_two_submodels(cipher,goal,r,Na,i,diff): 180 | filename_1 = "txt/"+cipher.name+"/"+goal+"/optimal_solution_of_submodel/"+str(i-1)+"_round_"+str([[1,i-1,Na]])+str(["output_diff",i-1,diff])+"_optimal_solution.txt" 181 | filename_2 = "txt/"+cipher.name+"/"+goal+"/optimal_solution_of_submodel/"+str(r-i+1)+"_round_"+str([[2,r-i+1,Na]])+str(["input_diff",1,diff])+"_optimal_solution.txt" 182 | filename = "txt/"+cipher.name+"/"+goal+"/optimal_solution_of_submodel/"+"/"+str(r)+"_round_[][]_optimal_solution.txt" 183 | with open(filename,"w") as f: 184 | f.write("get variables from "+str(i-1)+"_round_"+str([[1,i-1,Na]])+str(diff)+"_and_"+str(r-i+1)+"_round_"+str([[2,r-i+1,Na]])+str(diff)+"_optimal_solutions\n") 185 | if goal == "AS": 186 | x_var = [0 for j in range (r*cipher.var_and_num_AS["x"][0]+cipher.var_and_num_AS["x"][1])] 187 | x_var_2 = [0 for j in range ((r-i+1)*cipher.var_and_num_AS["x"][0]+cipher.var_and_num_AS["x"][1])] 188 | A_var = [0 for j in range (r*cipher.var_and_num_AS["A"][0]+cipher.var_and_num_AS["A"][1])] 189 | elif goal == "DC": 190 | x_var = [0 for j in range (r*cipher.var_and_num_DC["x"][0]+cipher.var_and_num_DC["x"][1])] 191 | x_var_2 = [0 for j in range ((r-i+1)*cipher.var_and_num_DC["x"][0]+cipher.var_and_num_DC["x"][1])] 192 | p_var = [0 for j in range (r*cipher.var_and_num_DC["p"][0]+cipher.var_and_num_DC["p"][1])] 193 | if i > 1: 194 | var = read_txt(filename_1) 195 | for j in var: 196 | if j[0] == "x": 197 | x_index = int(re.findall(r'(-?[\d]+)',j)[0]) 198 | x_value = int(re.findall(r'(-?[\d]+)',j)[1]) 199 | x_var[x_index-1] = x_value 200 | elif j[0] == "A" and goal == "AS": 201 | A_index = int(re.findall(r'(-?[\d]+)',j)[0]) 202 | A_value = int(re.findall(r'(-?[\d]+)',j)[1]) 203 | A_var[A_index-1] = A_value 204 | elif j[0] == "p"and goal == "DC": 205 | p_index = int(re.findall(r'(-?[\d]+)',j)[0]) 206 | p_value = int(re.findall(r'(-?[\d]+)',j)[1]) 207 | p_var[p_index-1] = p_value 208 | var = read_txt(filename_2) 209 | for j in var: 210 | if j[0] == "x": 211 | x_index = int(re.findall(r'(-?[\d]+)',j)[0]) 212 | x_value = int(re.findall(r'(-?[\d]+)',j)[1]) 213 | x_var_2[x_index-1] = x_value 214 | if j[0] == "A" and goal == "AS": 215 | A_index = int(re.findall(r'(-?[\d]+)',j)[0]) 216 | A_value = int(re.findall(r'(-?[\d]+)',j)[1]) 217 | A_var[A_index+cipher.nibble*(i-1)-1] = A_value 218 | if j[0] == "p" and goal == "DC": 219 | p_index = int(re.findall(r'(-?[\d]+)',j)[0]) 220 | p_value = int(re.findall(r'(-?[\d]+)',j)[1]) 221 | p_var[p_index+(i-1)*cipher.var_and_num_DC["p"][0]-1] = p_value 222 | state1 = cipher.gen_input_state() 223 | state2 = cipher.gen_input_state() 224 | for j in range (1,r+2): 225 | if j >= i: 226 | for k in range(len(state2)): 227 | x_var[state1[k]-1] = x_var_2[state2[k]-1] 228 | Sstate2 = cipher.get_state_through_sbox(j-i+1) 229 | Pstate2 = cipher.get_state_through_per(Sstate2) 230 | state2 = Pstate2 231 | Sstate1 = cipher.get_state_through_sbox(j) 232 | Pstate1 = cipher.get_state_through_per(Sstate1) 233 | state1 = Pstate1 234 | with open(filename,"a") as f: 235 | for j in range(len(x_var)): 236 | f.write("x%d = %d\n"%(j+1,x_var[j])) 237 | if goal =="AS": 238 | for j in range(len(A_var)): 239 | f.write("A%d = %d\n"%(j+1,A_var[j])) 240 | elif goal =="DC": 241 | for j in range(len(p_var)): 242 | f.write("p%d = %d\n"%(j+1,p_var[j])) 243 | 244 | def get_trail_sp(cipher,goal,r): 245 | if goal == "AS": 246 | x_var = [0 for j in range (r*cipher.var_and_num_AS["x"][0]+cipher.var_and_num_AS["x"][1])] 247 | elif goal == "DC": 248 | x_var = [0 for j in range (r*cipher.var_and_num_DC["x"][0]+cipher.var_and_num_DC["x"][1])] 249 | shutil.copy("txt/"+cipher.name+"/"+goal+"/optimal_solution_of_submodel/"+str(r)+"_round_[][]_optimal_solution.txt", "result/"+cipher.name+"/"+goal+"/") 250 | 251 | var = read_txt("txt/"+cipher.name+"/"+goal+"/optimal_solution_of_submodel/"+str(r)+"_round_[][]_optimal_solution.txt") 252 | for i in var: 253 | if i[0] == "x": 254 | x_index = int(re.findall(r'(-?[\d]+)',i)[0]) 255 | x_value = int(re.findall(r'(-?[\d]+)',i)[1]) 256 | x_var[x_index-1] = x_value 257 | file_path = "result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_best_path.txt" 258 | with open(file_path,"w") as f: 259 | f.write("x_var list is " + str(x_var)+"\n") 260 | state = cipher.gen_input_state() 261 | for r in range (1,r+1): 262 | with open(file_path,"a") as f: 263 | f.write("\n%dth round input diff of Sbox: \n"%(r)) 264 | for i in range(len(state)): 265 | if i%4 == 0: 266 | with open(file_path,"a") as f: 267 | f.write(" ") 268 | with open(file_path,"a") as f: 269 | f.write(str(x_var[state[i]-1])) 270 | state_through_sbox = cipher.get_state_through_sbox(r) 271 | # print "state_through_sbox",state_through_sbox 272 | with open(file_path,"a") as f: 273 | f.write("\n%dth round output diff of Sbox: \n"%(r)) 274 | for i in range(len(state)): 275 | if i%4 == 0: 276 | with open(file_path,"a") as f: 277 | f.write(" ") 278 | with open(file_path,"a") as f: 279 | f.write(str(x_var[state_through_sbox[i]-1])) 280 | state_through_per = cipher.get_state_through_per(state_through_sbox) 281 | state = copy.deepcopy(state_through_per) 282 | # print "state_through_per",state 283 | 284 | 285 | def get_trail_feistel(cipher,goal,r): 286 | if goal == "AS": 287 | x_var = [0 for j in range (r*cipher.var_and_num_AS["x"][0]+cipher.var_and_num_AS["x"][1])] 288 | elif goal == "DC": 289 | x_var = [0 for j in range (r*cipher.var_and_num_DC["x"][0]+cipher.var_and_num_DC["x"][1])] 290 | shutil.copy("txt/"+cipher.name+"/"+goal+"/optimal_solution_of_submodel/"+"/"+str(r)+"_round_[][]_optimal_solution.txt", "result/"+cipher.name+"/"+goal+"/") 291 | var = read_txt("txt/"+cipher.name+"/"+goal+"/optimal_solution_of_submodel/"+"/"+str(r)+"_round_[][]_optimal_solution.txt") 292 | 293 | for i in var: 294 | if i[0] == "x": 295 | x_index = int(re.findall(r'(-?[\d]+)',i)[0]) 296 | x_value = int(re.findall(r'(-?[\d]+)',i)[1]) 297 | x_var[x_index-1] = x_value 298 | file_path = "result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_best_path.txt" 299 | with open(file_path,"w") as f: 300 | f.write("x_var list is " + str(x_var)+"\n") 301 | state = cipher.gen_input_state(goal) 302 | state_l = state[0:len(state)/2] 303 | state_r = state[len(state)/2:len(state)] 304 | for r in range(1,r+1): 305 | with open(file_path,"a") as f: 306 | f.write("\n%dth round left: input diff of Sbox: \n"%(r)) 307 | for i in range(len(state_l)): 308 | if i%4 == 0: 309 | with open(file_path,"a") as f: 310 | f.write(" ") 311 | with open(file_path,"a") as f: 312 | f.write(str(x_var[state_l[i]-1])) 313 | sc_state_l = cipher.get_state_through_sbox(goal,r) 314 | with open(file_path,"a") as f: 315 | f.write("\n%dth round left: output diff of Sbox: \n"%(r)) 316 | for i in range(len(sc_state_l)): 317 | if i%4 == 0: 318 | with open(file_path,"a") as f: 319 | f.write(" ") 320 | with open(file_path,"a") as f: 321 | f.write(str(x_var[sc_state_l[i]-1])) 322 | with open(file_path,"a") as f: 323 | f.write("\n%dth round right: \n"%(r)) 324 | for i in range(len(state_r)): 325 | if i%4 == 0: 326 | with open(file_path,"a") as f: 327 | f.write(" ") 328 | with open(file_path,"a") as f: 329 | f.write(str(x_var[state_r[i]-1])) 330 | if cipher.name == "lblock": 331 | state_r = state_l 332 | xor_state = cipher.get_state_through_xor(goal,r) 333 | state_l = xor_state 334 | elif cipher.name == "twine": 335 | xor_state = cipher.get_state_through_xor(goal,r) 336 | state_r = cipher.get_state_through_per_right(goal,state_l) 337 | state_l = cipher.get_state_through_per_left(goal,xor_state) -------------------------------------------------------------------------------- /main_feistel.py: -------------------------------------------------------------------------------- 1 | import function 2 | import parameter 3 | from model import class_model 4 | from numpy import * 5 | import numpy as np 6 | import time 7 | import copy 8 | 9 | global cipher 10 | global goal 11 | global search_round 12 | global bestobj 13 | global LB 14 | global flag 15 | global flag_lbas 16 | global upperbound 17 | global order_of_round 18 | global R_front 19 | 20 | def initArray(): 21 | global cipher 22 | global search_round 23 | global bestobj 24 | global LB 25 | global flag 26 | global flag_lbas 27 | 28 | bestobj = np.zeros((search_round), dtype=int) 29 | LB = np.zeros((search_round,2,1+search_round,1+cipher.num_of_diff_pattern_all), dtype=int32) 30 | flag = np.zeros((search_round,2,1+search_round,1+cipher.num_of_diff_pattern_all), dtype=int32) 31 | flag_lbas = np.zeros((search_round,2,1+search_round,cipher.num_of_diff_pattern_all), dtype=int32) 32 | 33 | # methods 1 to 3 34 | 35 | def Method_1(r,Na,i,DP): 36 | # split r rounds into the first r1 rounds and the last r-r1 rounds, r1 = 1,2,..,r-1. 37 | global LB 38 | 39 | temp = 0 40 | if i == 0 and DP == 0: 41 | for r1 in range(1,r): 42 | temp = max(temp, LB[r1-1,Na-1,-1,-1]+LB[r-r1-1,Na-1,-1,-1]) 43 | elif 1 <= i < r : 44 | if 1 < i < r: 45 | temp = LB[i-1,Na-1,i-1,DP-1] + LB[r-i+1-1,Na-1,0,DP-1] 46 | for r1 in range(1,i): 47 | temp = max(temp, LB[r1-1,Na-1,-1,-1] + LB[r-r1-1,Na-1,i-r1-1,DP-1]) 48 | for r1 in range(i+1,r): 49 | temp = max(temp, LB[r1-1,Na-1,i-1,DP-1]+LB[r-r1-1,Na-1,-1,-1]) 50 | elif i == r: 51 | for r1 in range(1,r-1): 52 | temp = max(temp, LB[r1-1,Na-1,-1,-1]+LB[r-r1-1,Na-1,r-r1-1,DP-1]) 53 | 54 | LB[r-1,Na-1,i-1,DP-1] = max(LB[r-1,Na-1,i-1,DP-1],temp) 55 | 56 | def Method_2(r,Na,i,DP): 57 | global LB 58 | global upperbound 59 | global order_of_round 60 | global R_front 61 | 62 | temp = 0 63 | R_front = order_of_round[np.where(order_of_round==i)[0][0]-1] 64 | 65 | if i < order_of_round[0]: 66 | # split 1: split r rounds into: (1) round 1 to i; (2) round (i+1) to R_front; (3) round (R_front+1) to r 67 | temp = function.get_value(i,LB[i-1,Na-1,-1,-1]) + LB[R_front-i-1,Na,-1,-1] + function.get_value(r-R_front,LB[r-R_front-1,Na-1,-1,-1]) 68 | 69 | # split 2: split r rounds into: (1) round 1 to i; (2) round i to R_front; (3) round R_front+1 to r rounds. 70 | temp = max(temp, function.get_value(i,LB[i-1,Na-1,i-1,DP-1]) + LB[R_front-i+1-1,Na,0,DP-1] + function.get_value(r-R_front,LB[r-R_front-1,Na-1,-1,-1])) 71 | 72 | elif i > order_of_round[0]: 73 | # split 1: split r rounds into: (1) round 1 to (R_front-1); (2) round R_front to (i-1); (3) round i to r 74 | temp = function.get_value(R_front-1,LB[R_front-2,Na-1,-1,-1]) + LB[i-1-R_front,Na,-1,-1] + function.get_value(r-i+1,LB[r-i+1-1,Na-1,-1,-1]) 75 | 76 | # split 2: split r rounds into: (1) round 1 to R_front-1; (2) round R_front to i; (3) round i to r rounds. 77 | temp = max(temp, function.get_value(R_front-1,LB[R_front-1-1,Na-1,-1,-1]) + LB[i-R_front,Na,i-R_front,DP-1] + function.get_value(r-i+1,LB[r-i+1-1,Na-1,0,DP-1])) 78 | 79 | if temp >= upperbound: 80 | LB[r-1,Na-1,i-1,DP-1] = max(LB[r-1,Na-1,i-1,DP-1],upperbound) 81 | 82 | def Method_3(r,Na,i,DP,Strategy,obj_compare): 83 | global cipher 84 | global goal 85 | global search_round 86 | global LB 87 | global flag 88 | global flag_lbas 89 | 90 | 91 | if Strategy == 'Rough': 92 | if cipher.oriented == "bit" and cipher.branch_num_of_sbox == 2: 93 | return 0 94 | else: 95 | # check if the model has been solved 96 | if flag_lbas[r-1,Na-1,i-1,DP-1] == 0: 97 | if i == r: 98 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":["diff_pattern_front",r,cipher.diff_pattern_all[DP-1]],"const_sbox":[[1,r-1,Na]],"obj_compare":0} 99 | elif 1<=i 0: 199 | Method_3(r,Na,0,0,'Tightest',0) 200 | 201 | def genUpperBound(r): 202 | global cipher 203 | global goal 204 | 205 | const_param_1 = {"model_goal":goal,"model_round":r,"const_diff":[],"const_sbox":"get_upperbound_1","obj_compare":25600} 206 | model_1 = class_model(cipher,const_param_1) 207 | upperbound_1 = model_1.model_obj 208 | const_param_2 = {"model_goal":goal,"model_round":r,"const_diff":[],"const_sbox":"get_upperbound_2","obj_compare":upperbound_1} 209 | model_2 = class_model(cipher,const_param_2) 210 | upperbound_2 = model_2.model_obj 211 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt","a") as f: 212 | f.write("initialized upperbound = min(%d,%d)=%d.\n"%(upperbound_1,upperbound_2,min(upperbound_1,upperbound_2))) 213 | return min(upperbound_1,upperbound_2) 214 | 215 | def searchSubset0(r): 216 | global cipher 217 | global goal 218 | global LB 219 | global upperbound 220 | global order_of_round 221 | order_of_round = function.get_search_round(r) 222 | Na = 0 223 | for i in order_of_round: 224 | for DP in range(1,1+cipher.num_of_diff_pattern_all): 225 | LB[r-1,Na-1,i-1,DP-1] = max(LB[r-1,Na-1,i-1,DP-1],LB[r-1,Na-1,-1,-1]) 226 | Method_1(r,Na,i,DP) 227 | Method_2(r,Na,i,DP) 228 | if LB[r-1,0-1,i-1,DP-1] < upperbound: 229 | UpdateLBSubset0(r,Na,i,DP) 230 | if LB[r-1,0-1,i-1,DP-1] < upperbound: 231 | upperbound = LB[r-1,-1,i-1,DP-1] 232 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt", "a") as f: 233 | f.write("*****************************************************************\n") 234 | f.write("(*_*) We update upperbound = LB[%d,%d,%d,%d] = %d. \n"%(r,0,i,DP,LB[r-1,-1,i-1,DP-1])) 235 | f.write("*****************************************************************\n") 236 | 237 | def UpdateLBSubset0(r,Na,i,DP): 238 | global cipher 239 | global goal 240 | global search_round 241 | global LB 242 | global upperbound 243 | global order_of_round 244 | global R_front 245 | 246 | 247 | for Strategy in ['Rough', 'Tightest']: 248 | r1 = 2 249 | while r1 <= max(i,r-i+1) and LB[r-1,Na-1,i-1,DP-1] < upperbound: 250 | # case1: i = order_of_round[0] 251 | if i == order_of_round[0]: 252 | if r1 <= r-i+1: 253 | Method_3(r1,Na,1,DP,Strategy,0) 254 | Method_1(r,Na,i,DP) 255 | if r1 <= i and LB[r-1,Na-1,i-1,DP-1] < upperbound: 256 | Method_3(r1,Na,r1,DP,Strategy,0) 257 | Method_1(r,Na,i,DP) 258 | 259 | 260 | # case2: i < order_of_round[0] 261 | elif i < order_of_round[0]: 262 | if r1 <= i and LB[r-1,Na-1,i-1,DP-1] < upperbound: 263 | Method_3(r1,Na,r1,DP,Strategy,0) 264 | Method_1(r,Na,i,DP) 265 | Method_2(r,Na,i,DP) 266 | if r1 <= R_front-i+1 and LB[r-1,Na-1,i-1,DP-1] < upperbound: 267 | Method_3(r1,Na+1,1,DP,Strategy,0) 268 | Method_2(r,Na,i,DP) 269 | if r1 <= r-i+1 and LB[r-1,Na-1,i-1,DP-1] < upperbound: 270 | Method_3(r1,Na,1,DP,Strategy,0) 271 | Method_1(r,Na,i,DP) 272 | 273 | 274 | # case3: i > order_of_round[0] 275 | elif i > order_of_round[0]: 276 | if r1 <= r-i+1: 277 | Method_3(r1,Na,1,DP,Strategy,0) 278 | Method_1(r,Na,i,DP) 279 | Method_2(r,Na,i,DP) 280 | if r1 <= i-R_front+1 and LB[r-1,Na-1,i-1,DP-1] < upperbound: 281 | Method_3(r1,Na+1,r1,DP,Strategy,0) 282 | Method_2(r,Na,i,DP) 283 | if r1 <= i and LB[r-1,Na-1,i-1,DP-1] < upperbound: 284 | Method_3(r1,Na,r1,DP,Strategy,0) 285 | Method_1(r,Na,i,DP) 286 | 287 | r1 = r1 + 1 288 | 289 | if LB[r-1,Na-1,i-1,DP-1] < upperbound: 290 | Method_3(r,Na,i,DP,Strategy,upperbound) 291 | 292 | if Strategy == 'Rough' and i != order_of_round[0] and LB[r-1,Na-1,i-1,DP-1] < upperbound: 293 | estimateAddition1(r,Na,i,DP) 294 | 295 | 296 | def estimateAddition1(r,Na,i,DP): 297 | global cipher 298 | global goal 299 | global LB 300 | global upperbound 301 | global order_of_round 302 | global R_front 303 | 304 | if cipher.oriented == 'bit' and cipher.branch_num_of_sbox == 2: 305 | return 0 306 | else: 307 | if i < order_of_round[0]: 308 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":["diff_pattern_next",i,cipher.diff_pattern_all[DP-1]],"const_sbox":[[1,i,Na],[i+1,R_front,Na+1],[R_front+1,r,Na]],"obj_compare":0} 309 | elif i > order_of_round[0]: 310 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":["diff_pattern_next",i,cipher.diff_pattern_all[DP-1]],"const_sbox":[[1,R_front-1,Na],[R_front,i-1,Na+1],[i,r,Na]],"obj_compare":0} 311 | 312 | model = class_model(cipher,const_param) 313 | with open("result/"+cipher.name+"/"+goal+"/solved_LBAS_model.txt", "a") as f: 314 | f.write("%s: %d\n"%(const_param,model.model_obj)) 315 | if goal == "AS": 316 | result = model.model_obj 317 | elif goal == "DC": 318 | result = model.model_obj*cipher.min_weight_of_sbox 319 | if result >= upperbound: 320 | LB[r-1,Na-1,i-1,DP-1] = max(LB[r-1,Na-1,i-1,DP-1],upperbound) 321 | 322 | def searchSubset1(r): 323 | global search_round 324 | global upperbound 325 | 326 | Na = 1 327 | 328 | if LB[r-1,Na-1,-1,-1] < upperbound: 329 | for Strategy in ['Rough', 'Tightest']: 330 | r1 = 1 331 | while r1 <= r and LB[r-1,Na-1,-1,-1] < upperbound: 332 | Method_3(r1,Na,0,0,Strategy) 333 | for r2 in range(r1 + 1, search_round+1): 334 | Method_1(r2,Na,0,0) 335 | r1 = r1 + 1 336 | upperbound = min(upperbound,LB[r-1,Na-1,-1,-1]) 337 | 338 | 339 | 340 | if __name__ == "__main__": 341 | global cipher 342 | global goal 343 | global search_round 344 | global bestobj 345 | 346 | cipher = parameter.cipher 347 | goal = parameter.goal 348 | search_round = cipher.get_search_round(goal) 349 | time_all = [] 350 | 351 | function.gen_filefolder(cipher.name,goal) 352 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_LBAS_model.txt", "w") as f: 353 | f.write("models we solved:\n") 354 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_model.txt", "w") as f: 355 | f.write("models we solved:\n") 356 | 357 | 358 | initArray() 359 | # search process from 1 to search_round rounds basing on Algorithm 1 360 | for r in range(1,search_round+1): 361 | time_start = time.time() 362 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt", "w") as f: 363 | f.write("search process:\n") 364 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_LBAS_model.txt", "a") as f: 365 | f.write("\n*****************************************************************************\nwhen searching the %d-round cipher, models we solved:\n"%(r)) 366 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_model.txt", "a") as f: 367 | f.write("\n*****************************************************************************\nwhen searching the %d-round cipher, models we solved:\n"%(r)) 368 | search(r) 369 | function.get_trail_feistel(cipher,goal,r) 370 | time_end = time.time() 371 | timespend = time_end - time_start 372 | time_all.append(timespend) 373 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt", "a") as f: 374 | f.write("time is %d s.\n"%(timespend)) 375 | 376 | with open("result/"+cipher.name+"/"+goal+"/"+"bestobj.txt","w") as f: 377 | f.write("bestobj = %s\n"%(str(bestobj))) 378 | f.write("time_all = %s\n"%(str(time_all))) 379 | -------------------------------------------------------------------------------- /main_sp.py: -------------------------------------------------------------------------------- 1 | import function 2 | import parameter 3 | from model import class_model 4 | from numpy import * 5 | import numpy as np 6 | import time 7 | import copy 8 | 9 | global cipher 10 | global goal 11 | global search_round 12 | global bestobj 13 | global LB 14 | global flag 15 | global flag_lbas 16 | global upperbound 17 | global order_of_round 18 | global R_front 19 | 20 | 21 | # initialize arrays which are used during the search 22 | def initArray(): 23 | global cipher 24 | global search_round 25 | global bestobj 26 | global LB 27 | global flag 28 | global flag_lbas 29 | 30 | bestobj = np.zeros((search_round), dtype=int) 31 | LB = np.zeros((search_round,3,2+search_round,1+cipher.num_of_diff_all[0]+cipher.num_of_diff_all[1]), dtype=int32) 32 | flag = np.zeros((search_round,3,2+search_round,cipher.num_of_diff_all[0]+cipher.num_of_diff_all[1]), dtype=int32) 33 | flag_lbas = np.zeros((search_round,3,search_round,cipher.num_of_diff_all[0]+cipher.num_of_diff_all[1]), dtype=int32) 34 | 35 | def Method_1(r,Na,i,D): 36 | # split r rounds into the first r1 rounds and the last r-r1 rounds, r1 = 1,2,..,r-1. 37 | global LB 38 | 39 | temp = 0 40 | if i == 0 and D == 0: 41 | for r1 in range(1,r): 42 | temp = max(temp, LB[r1-1,Na-1,-1,-1]+LB[r-r1-1,Na-1,-1,-1]) 43 | elif 1 <= i <= r : 44 | if i > 1: 45 | temp = LB[i-2,Na-1,i-1,D-1] + LB[r-i,Na-1,0,D-1] 46 | for r1 in range(1,i): 47 | temp = max(temp, LB[r1-1,Na-1,-1,-1] + LB[r-r1-1,Na-1,i-r1-1,D-1]) 48 | for r1 in range(i,r): 49 | temp = max(temp, LB[r1-1,Na-1,i-1,D-1]+LB[r-r1-1,Na-1,-1,-1]) 50 | elif i == r+1: 51 | for r1 in range(1,r): 52 | temp = max(temp, LB[r1-1,Na-1,-1,-1]+LB[r-r1-1,Na-1,r-r1,D-1]) 53 | LB[r-1,Na-1,i-1,D-1] = max(LB[r-1,Na-1,i-1,D-1],temp) 54 | 55 | def Method_2(r,Na,i,D): 56 | global LB 57 | global upperbound 58 | global order_of_round 59 | global R_front 60 | 61 | temp = 0 62 | R_front = order_of_round[np.where(order_of_round==i)[0][0]-1] 63 | 64 | if i < order_of_round[0]: 65 | # split 1: split r rounds into: (1) round 1 to i; (2) round (i+1) to R_front; (3) round (R_front+1) to r 66 | temp = function.get_value(i,LB[i-1,Na-1,-1,-1]) + LB[R_front-i-1,Na,-1,-1] + function.get_value(r-R_front,LB[r-R_front-1,Na-1,-1,-1]) 67 | # split 2: split r rounds into (1) 1 to i-1; (2)i to R_front; (3) (R_front+1) to r 68 | temp = max(temp, function.get_value(i-1,LB[i-1-1,Na-1,i-1,D-1]) + LB[R_front-i+1-1,Na,0,D-1] + function.get_value(r-R_front,LB[r-R_front-1,Na-1,-1,-1])) 69 | 70 | elif i > order_of_round[0]: 71 | # split 1: split r rounds into: (1) round 1 to (R_front-1); (2) round R_front to (i-1); (3) round i to r 72 | temp = function.get_value(R_front-1,LB[R_front-1-1,Na-1,-1,-1]) + LB[i-1-R_front+1-1,Na,-1,-1] + function.get_value(r-i+1,LB[r-i+1-1,Na-1,-1,-1]) 73 | # split 2: split r rounds into: (1) 1 to (R_front-1); (2)R_front to i-1; (3) i to r 74 | temp = max(temp, function.get_value(R_front-1,LB[R_front-1-1,Na-1,-1,-1]) + LB[i-1-R_front,Na,i-1-R_front+1,D-1] + function.get_value(r-i+1,LB[r-i+1-1,Na-1,0,D-1])) 75 | 76 | if temp >= upperbound: 77 | LB[r-1,Na-1,i-1,D-1] = max(LB[r-1,Na-1,i-1,D-1],upperbound) 78 | 79 | def Method_3(r,Na,i,D,Strategy,obj_compare): 80 | global cipher 81 | global goal 82 | global search_round 83 | global LB 84 | global flag 85 | global flag_lbas 86 | 87 | 88 | if Strategy == 'Rough': 89 | if cipher.oriented == "bit" and cipher.branch_num_of_sbox == 2: 90 | return 0 91 | else: 92 | # check if the model has been solved 93 | if flag_lbas[r-1,Na-1,i-1,D-1] == 0: 94 | 95 | # add constraints into the model 96 | if i == r + 1: 97 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":["output_diff",r,cipher.diff_all[D-1]],"const_sbox":[[1,r,Na]],"obj_compare":0} 98 | elif i == 1: 99 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":["input_diff",i,cipher.diff_all[D-1]],"const_sbox":[[2,r,Na]],"obj_compare":0} 100 | elif i == 0 and D == 0: 101 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":[],"const_sbox":[[1,r,Na]],"obj_compare":0} 102 | model = class_model(cipher,const_param) 103 | 104 | # assign a value to the lower bound array by the optimal objective value of the model 105 | if goal == "AS": 106 | LB[r-1,Na-1,i-1,D-1] = max(LB[r-1,Na-1,i-1,D-1], model.model_obj) 107 | elif goal == "DC": 108 | LB[r-1,Na-1,i-1,D-1] = max(LB[r-1,Na-1,i-1,D-1], model.model_obj * cipher.min_weight_of_sbox) 109 | 110 | # flag the model has been solved 111 | flag_lbas[r-1,Na-1,i-1,D-1] = 1 112 | 113 | # uptaing LB aray by using Method_1 114 | for r2 in range(r+1,search_round+1): 115 | if i == r+1: 116 | Method_1(r2,Na,r2+1,D) 117 | elif 1<=i<=r: 118 | Method_1(r2,Na,i,D) 119 | 120 | with open("result/"+cipher.name+"/"+goal+"/solved_LBAS_model.txt", "a") as f: 121 | f.write("%s: %d\n"%(const_param,model.model_obj)) 122 | 123 | 124 | elif Strategy == 'Tightest': 125 | # check if the model has been solved 126 | if flag[r-1,Na-1,i-1,D-1] == 0: 127 | if i == r + 1: 128 | const_param = {"model_goal":goal,"model_round":r,"const_diff":["output_diff",r,cipher.diff_all[D-1]],"const_sbox":[[1,r,Na]],"obj_compare":obj_compare} 129 | elif i == 1: 130 | const_param = {"model_goal":goal,"model_round":r,"const_diff":["input_diff",i,cipher.diff_all[D-1]],"const_sbox":[[i+1,r,Na]],"obj_compare":obj_compare} 131 | elif i == 0 and D == 0 and Na == 1: 132 | const_param = {"model_goal":goal,"model_round":r,"const_diff":[],"const_sbox":[],"obj_compare":25600} 133 | elif i == 0 and D == 0 and Na > 1: 134 | const_param = {"model_goal":goal,"model_round":r,"const_diff":[],"const_sbox":[[1,r,Na]],"obj_compare":0} 135 | model = class_model(cipher,const_param) 136 | 137 | # assign a value to the lower bound array by the optimal objective value of the model 138 | LB[r-1,Na-1,i-1,D-1] = model.model_obj 139 | 140 | # flag the model has been solved 141 | flag[r-1,Na-1,i-1,D-1] = 1 142 | 143 | # uptaing LB aray by using Method_1 144 | for r2 in range(r+1,search_round+1): 145 | if i == r+1: 146 | Method_1(r2,Na,r2+1,D) 147 | elif 1<=i<=r: 148 | Method_1(r2,Na,i,D) 149 | with open("result/"+cipher.name+"/"+goal+"/solved_model.txt", "a") as f: 150 | f.write("%s: %d\n"%(const_param,model.model_obj)) 151 | 152 | 153 | 154 | def search(r): 155 | global cipher 156 | global goal 157 | global bestobj 158 | global LB 159 | global upperbound 160 | global order_of_round 161 | 162 | if r == 1: 163 | # when searching the simplest 1 round, we don't use the split-Method and directly solve the model 164 | initLBArray(r) 165 | Method_3(r,1,0,0,'Tightest',25600) 166 | bestobj[r-1] = LB[r-1,0,-1,-1] 167 | else: 168 | # Step 1. Generating the currently best r-round differential characteristic and an upper bound of the minimum weight UpperBound by using Technique 1; 169 | upperbound = genUpperBound(r) 170 | 171 | # Step 2. initializing the lower bound array LB 172 | initLBArray(r) 173 | 174 | # Step 3. search Subset1 and Subset2 175 | searchSubset12(r) 176 | 177 | # Step 4. search Subset3 178 | searchSubset3(r) 179 | 180 | # Step 5. storing the final upper bound, namely, the mimimum weight into the array 'bestobj' 181 | bestobj[r-1] = upperbound 182 | 183 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt", "a") as f: 184 | f.write("From all of above, we obtain an optimal objective value:%d.\n"%(bestobj[r-1])) 185 | LB[r-1] = np.maximum(LB[r-1],bestobj[r-1]) 186 | 187 | def initLBArray(r): 188 | global cipher 189 | global goal 190 | global search_round 191 | global LB 192 | 193 | for Na in [1,2,3]: 194 | # (1) assigning a value by Method 1 195 | Method_1(r,Na,0,0) 196 | 197 | # (2) assigning a value by Method 3 and 2 198 | max_num_of_round_to_solve_LBAS, max_num_of_round_to_solve_AS_or_DC = cipher.get_max_num_of_round_to_solve(goal) 199 | if r <= max_num_of_round_to_solve_LBAS: 200 | Method_3(r,Na,0,0,'Rough',0) 201 | if r <= max_num_of_round_to_solve_AS_or_DC and Na > 1: 202 | Method_3(r,Na,0,0,'Tightest',0) 203 | 204 | 205 | def genUpperBound(r): 206 | global cipher 207 | global goal 208 | 209 | const_param_1 = {"model_goal":goal,"model_round":r,"const_diff":[],"const_sbox":"get_upperbound_1","obj_compare":25600} 210 | model = class_model(cipher,const_param_1) 211 | upperbound_1 = model.model_obj 212 | const_param_2 = {"model_goal":goal,"model_round":r,"const_diff":[],"const_sbox":"get_upperbound_2","obj_compare":upperbound_1} 213 | model = class_model(cipher,const_param_2) 214 | upperbound_2 = model.model_obj 215 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt","a") as f: 216 | f.write("initialized upperbound = min(%d,%d)=%d.\n"%(upperbound_1,upperbound_2,min(upperbound_1,upperbound_2))) 217 | 218 | return min(upperbound_1,upperbound_2) 219 | 220 | 221 | def searchSubset12(r): 222 | global cipher 223 | global goal 224 | global LB 225 | global upperbound 226 | global order_of_round 227 | 228 | order_of_Na = function.get_order_of_Na(cipher,r) 229 | order_of_round = function.get_search_round(r) 230 | for Na in order_of_Na: 231 | for i in order_of_round: 232 | for D in range(1+cipher.num_of_diff_all[0]*(Na-1),1+cipher.num_of_diff_all[0]*(Na-1)+cipher.num_of_diff_all[Na-1]): 233 | LB[r-1,Na-1,i-1,D-1] = max(LB[r-1,Na-1,i-1,D-1],LB[r-1,Na-1,-1,-1]) 234 | Method_1(r,Na,i,D) 235 | Method_2(r,Na,i,D) 236 | if LB[r-1,Na-1,i-1,D-1] < upperbound: 237 | UpdateLBSubset12(r,Na,i,D) 238 | if LB[r-1,Na-1,i-1,D-1] < upperbound: 239 | upperbound = LB[r-1,Na-1,i-1,D-1] 240 | function.get_var_from_two_submodels(cipher,goal,r,Na,i,cipher.diff_all[D-1]) 241 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt", "a") as f: 242 | f.write("*****************************************************************\n") 243 | f.write("(*_*) We update upperbound = LB[%d,%d,%d,%d] = %d. \n"%(r,Na,i,D,LB[r-1,Na-1,i-1,D-1])) 244 | f.write("*****************************************************************\n") 245 | 246 | def UpdateLBSubset12(r,Na,i,D): 247 | global cipher 248 | global goal 249 | global search_round 250 | global LB 251 | global upperbound 252 | global order_of_round 253 | global R_front 254 | 255 | 256 | for Strategy in ['Rough', 'Tightest']: 257 | r1 = 1 258 | while r1 <= max(i-1,r-i+1) and LB[r-1,Na-1,i-1,D-1] < upperbound: 259 | # case1: i = order_of_round[0] 260 | if i == order_of_round[0]: 261 | if r1 <= r-i+1: 262 | Method_3(r1,Na,1,D,Strategy,25600) 263 | Method_1(r,Na,i,D) 264 | if r1 <= i-1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 265 | Method_3(r1,Na,r1+1,D,Strategy,25600) 266 | Method_1(r,Na,i,D) 267 | 268 | # case2: i < order_of_round[0] 269 | elif i < order_of_round[0]: 270 | if r1 <= i-1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 271 | Method_3(r1,Na,r1+1,D,Strategy,25600) 272 | Method_1(r,Na,i,D) 273 | Method_2(r,Na,i,D) 274 | if r1 <= R_front-i+1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 275 | Method_3(r1,Na+1,1,D,Strategy,0) 276 | Method_2(r,Na,i,D) 277 | if Strategy == 'Tightest' and r1 == R_front-i+1 and r-i+1 >= 8 and Na == 1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 278 | estimateAddition2(r,Na,i,D) 279 | if r1 <= r-i+1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 280 | Method_3(r1,Na,1,D,Strategy,25600) 281 | Method_1(r,Na,i,D) 282 | 283 | 284 | # case3: i > order_of_round[0] 285 | elif i > order_of_round[0]: 286 | if r1 <= r-i+1: 287 | Method_3(r1,Na,1,D,Strategy,25600) 288 | Method_1(r,Na,i,D) 289 | Method_2(r,Na,i,D) 290 | if r1 <= i-1-R_front+1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 291 | Method_3(r1,Na+1,r1+1,D,Strategy,0) 292 | Method_2(r,Na,i,D) 293 | if Strategy == 'Tightest' and r1 == i-1-R_front+1 and i-1 >= 8 and Na == 1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 294 | estimateAddition2(r,Na,i,D) 295 | if r1 <= i-1 and LB[r-1,Na-1,i-1,D-1] < upperbound: 296 | Method_3(r1,Na,r1+1,D,Strategy,25600) 297 | Method_1(r,Na,i,D) 298 | r1 = r1 + 1 299 | 300 | if Strategy == 'Rough' and i != order_of_round[0] and LB[r-1,Na-1,i-1,D-1] < upperbound: 301 | estimateAddition1(r,Na,i,D) 302 | 303 | def estimateAddition1(r,Na,i,D): 304 | global cipher 305 | global goal 306 | global LB 307 | global upperbound 308 | global order_of_round 309 | global R_front 310 | 311 | if cipher.oriented == 'bit' and cipher.branch_num_of_sbox == 2: 312 | return 0 313 | else: 314 | if i < order_of_round[0]: 315 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":["input_diff",i,cipher.diff_all[D-1]],"const_sbox":[[1,i,Na],[i+1,R_front,Na+1],[R_front+1,r,Na]],"obj_compare":0} 316 | elif i > order_of_round[0]: 317 | const_param = {"model_goal":"LBAS","model_round":r,"const_diff":["input_diff",i,cipher.diff_all[D-1]],"const_sbox":[[1,R_front-1,Na],[R_front,i-1,Na+1],[i,r,Na]],"obj_compare":0} 318 | model = class_model(cipher,const_param) 319 | with open("result/"+cipher.name+"/"+goal+"/solved_LBAS_model.txt", "a") as f: 320 | f.write("%s: %d\n"%(const_param,model.model_obj)) 321 | if goal == "AS": 322 | result = model.model_obj 323 | elif goal == "DC": 324 | result = model.model_obj*cipher.min_weight_of_sbox 325 | if result >= upperbound: 326 | LB[r-1,Na-1,i-1,D-1] = max(LB[r-1,Na-1,i-1,D-1],upperbound) 327 | 328 | def estimateAddition2(r,Na,i,D): 329 | global LB 330 | global upperbound 331 | global order_of_round 332 | global R_front 333 | 334 | 335 | if i < order_of_round[0] and R_front < r: 336 | # consider two cases of the number of active S-boxes at round (R_front+1) 337 | i2 = R_front+1 338 | 339 | # consider case 1: round (R_front+1) has exactly Na active s-boxes 340 | for D2 in range(1+cipher.num_of_diff_all[0]*(Na-1),1+cipher.num_of_diff_all[0]*(Na-1)+cipher.num_of_diff_all[Na-1]): 341 | Method_1(r,Na,i2,D2) 342 | case1_obj = LB[r-1,Na-1,i2-1,D2-1] 343 | r1 = 1 344 | while r1 <= max(i2-i-1,r-i2+1) and case1_obj < upperbound: 345 | if r1 <= i2-i-1: 346 | Method_3(r1,Na+1,r1+1,D2,'Tightest',0) 347 | case1_obj = max(case1_obj,get_case1_obj(r,Na,i,D,i2,D2)) 348 | if r1 <= r-i2+1: 349 | Method_3(r1,Na,1,D2,'Tightest',25600) 350 | case1_obj = max(case1_obj,get_case1_obj(r,Na,i,D,i2,D2)) 351 | r1 = r1 + 1 352 | if case1_obj < upperbound: 353 | break 354 | # consider case 2: round (R_front+1) has greater than or equal to (Na+1) active s-boxes. 355 | if case1_obj >= upperbound: 356 | Method_3(i2-i+1,Na+1,1,D,'Tightest',0) 357 | case2_obj = function.get_value(i-1,LB[i-1-1,Na-1,i-1,D-1]) + LB[i2-i,Na,0,D-1] + function.get_value(r-i2,LB[r-i2-1,Na-1,-1,-1]) 358 | if case2_obj >= upperbound: 359 | LB[r-1,Na-1,i-1,D-1] = upperbound 360 | 361 | elif i > order_of_round[0]: 362 | # consider two cases of the number of active S-boxes at round (R_front-1) 363 | i2 = R_front-1 364 | 365 | # consider case 1: round (R_front-1) has exactly Na active s-boxes 366 | for D2 in range(1+cipher.num_of_diff_all[0]*(Na-1),1+cipher.num_of_diff_all[0]*(Na-1)+cipher.num_of_diff_all[Na-1]): 367 | Method_1(r,Na,i2,D2) 368 | case1_obj = LB[r-1,Na-1,i2-1,D2-1] 369 | r1 = 1 370 | while r1 <= max(i2-1,i-1-i2+1) and case1_obj < upperbound: 371 | if r1 <= i2-1: 372 | Method_3(r1,Na,r1+1,D2,'Tightest',25600) 373 | case1_obj = max(case1_obj,get_case1_obj(r,Na,i2,D2,i,D)) 374 | if r1 <= i-i2: 375 | Method_3(r1,Na+1,1,D2,'Tightest',0) 376 | case1_obj = max(case1_obj,get_case1_obj(r,Na,i2,D2,i,D)) 377 | r1 = r1 + 1 378 | if case1_obj < upperbound: 379 | break 380 | 381 | # consider case 2: round (R_front+1) has greater than or equal to (Na+1) active s-boxes. 382 | if case1_obj >= upperbound: 383 | Method_3(i-i2,Na+1,i-i2+1,D,'Tightest',0) 384 | case2_obj = function.get_value(i2-1,LB[i2-2,Na-1,-1,-1]) + LB[i-i2-1,Na,i-i2,D-1] + LB[r-i,Na-1,0,D-1] 385 | if case2_obj >= upperbound: 386 | LB[r-1,Na-1,i-1,D-1] = upperbound 387 | 388 | def get_case1_obj(r,Na,r1,D1,r2,D2): 389 | obj_list = [] 390 | for k in range(r1,r2): 391 | obj_list.append(LB[k-r1,Na,0,D1-1]+function.get_value(r2-1-k,LB[r2-1-k-1,Na,r2-1-k,D2-1])) 392 | temp = function.get_value(r1-1,LB[r1-2,Na-1,r1-1,D1-1]) + max(obj_list) + LB[r-r2,Na-1,0,D2-1] 393 | return temp 394 | 395 | 396 | def searchSubset3(r): 397 | global search_round 398 | global upperbound 399 | 400 | if LB[r-1,2,-1,-1] < upperbound: 401 | for Strategy in ['Rough', 'Tightest']: 402 | r1 = 1 403 | while r1 <= r and LB[r-1,2,-1,-1] < upperbound: 404 | Method_3(r1,3,0,0,Strategy) 405 | for r2 in range(r1 + 1, search_round+1): 406 | Method_1(r2,3,0,0) 407 | r1 = r1 + 1 408 | upperbound = min(upperbound,LB[r-1,2,-1,-1]) 409 | 410 | 411 | if __name__ == "__main__": 412 | global cipher 413 | global goal 414 | global search_round 415 | global bestobj 416 | 417 | cipher = parameter.cipher 418 | goal = parameter.goal 419 | search_round = cipher.get_search_round(goal) 420 | time_all = [] 421 | 422 | function.gen_filefolder(cipher.name,goal) 423 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_LBAS_model.txt", "w") as f: 424 | f.write("models we solved:\n") 425 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_model.txt", "w") as f: 426 | f.write("models we solved:\n") 427 | 428 | 429 | initArray() 430 | 431 | # search process from 1 to search_round rounds basing on Algorithm 1 432 | for r in range(1,search_round+1): 433 | time_start = time.time() 434 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt", "w") as f: 435 | f.write("search process:\n") 436 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_LBAS_model.txt", "a") as f: 437 | f.write("\n*****************************************************************************\nwhen searching the %d-round cipher, models we solved:\n"%(r)) 438 | with open("result/"+cipher.name+"/"+goal+"/"+"solved_model.txt", "a") as f: 439 | f.write("\n*****************************************************************************\nwhen searching the %d-round cipher, models we solved:\n"%(r)) 440 | search(r) 441 | function.get_trail_sp(cipher,goal,r) 442 | time_end = time.time() 443 | timespend = time_end - time_start 444 | time_all.append(timespend) 445 | with open("result/"+cipher.name+"/"+goal+"/"+str(r)+"_round_search_result.txt", "a") as f: 446 | f.write("time is %d s.\n"%(timespend)) 447 | 448 | with open("result/"+cipher.name+"/"+goal+"/"+"bestobj.txt","w") as f: 449 | f.write("bestobj = %s\n"%(str(bestobj))) 450 | f.write("time_all = %s\n"%(str(time_all))) 451 | 452 | -------------------------------------------------------------------------------- /model.py: -------------------------------------------------------------------------------- 1 | from gurobipy import * 2 | import time 3 | import copy 4 | import function 5 | import math 6 | import re 7 | 8 | class class_model: 9 | def __init__(self,cipher,model_param): 10 | self.cipher = cipher 11 | self.model_goal = model_param["model_goal"] 12 | self.model_round = model_param["model_round"] 13 | self.const_sbox = model_param["const_sbox"] 14 | self.const_diff = model_param["const_diff"] 15 | self.obj_compare = model_param["obj_compare"] 16 | self.model_filename = "model/"+self.cipher.name+"/"+self.model_goal+"/"+str(self.model_round)+"_round_"+str(self.const_sbox)+str(self.const_diff)+"_model.lp" 17 | 18 | self.build_model = self.build_model() 19 | self.model_obj = self.solve_model() 20 | 21 | def build_model(self): 22 | self.obj_fun = self.obj_fun() 23 | self.constraint = self.constraint() 24 | self.binary = self.binary() 25 | 26 | def obj_fun(self): 27 | with open(self.model_filename, "w") as f: 28 | f.write("Minimize\n") 29 | self.cipher.obj_fun(self.model_goal,self.model_filename,1,self.model_round) 30 | with open(self.model_filename, "a") as f: 31 | f.write("\n") 32 | 33 | def constraint(self): 34 | with open(self.model_filename, "a") as f: 35 | f.write("Subject To\n") 36 | if self.const_sbox != []: 37 | if self.const_sbox == "get_upperbound_1": 38 | self.constraint_upperbound(1) 39 | self.const_sbox = [] 40 | elif self.const_sbox == "get_upperbound_2": 41 | self.constraint_upperbound(2) 42 | self.const_sbox = [] 43 | else: 44 | for i in range(len(self.const_sbox)): 45 | r1 = self.const_sbox[i][0] 46 | r2 = self.const_sbox[i][1] 47 | Na = self.const_sbox[i][2] 48 | if self.cipher.structure == "sp" and Na >= 2: 49 | self.cipher.lowbound_of_sbox(self.model_goal,self.model_filename,r1,r2,Na) 50 | elif self.cipher.structure == "feistel" and Na >= 1: 51 | self.cipher.lowbound_of_sbox(self.model_goal,self.model_filename,r1,r2,Na) 52 | if self.const_diff != []: 53 | diff_type = self.const_diff[0] 54 | diff_round = self.const_diff[1] 55 | diff_value = self.const_diff[2] 56 | self.cipher.fix_diff(self.model_goal,self.model_filename,diff_type,diff_round,diff_value) 57 | 58 | if self.cipher.structure == "sp": 59 | self.constraints_state_sp() 60 | elif self.cipher.structure == "feistel": 61 | self.constraints_state_feistel() 62 | self.input_non_zero() #at least one sbox must be active 63 | 64 | def constraints_state_sp(self): 65 | state = self.cipher.gen_input_state() 66 | for r in range (1,self.model_round+1): 67 | state_through_sbox = self.cipher.get_state_through_sbox(r) 68 | self.cipher.diff_propagation_of_sbox(self.model_goal,self.model_filename,r,state,state_through_sbox) 69 | state_through_per = self.cipher.get_state_through_per(state_through_sbox) 70 | state = copy.deepcopy(state_through_per) 71 | 72 | def constraints_state_feistel(self): 73 | state = self.cipher.gen_input_state(self.model_goal) 74 | if self.model_goal == "LBAS" and self.cipher.oriented == "byte": 75 | state_r = state[0:len(state)/2] 76 | state_l = state[len(state)/2:len(state)] 77 | else: 78 | state_l = state[0:len(state)/2] 79 | state_r = state[len(state)/2:len(state)] 80 | for r in range (1,self.model_round+1): 81 | if self.model_goal == "LBAS" and self.cipher.oriented == "byte": 82 | sc_state_l = copy.deepcopy(state_l) 83 | else: 84 | sc_state_l = self.cipher.get_state_through_sbox(self.model_goal,r) 85 | if self.cipher.name == "lblock": 86 | ls_state_r = self.cipher.get_state_through_per_right(self.model_goal,state_r) 87 | p_state_l = self.cipher.get_state_through_per_left(self.model_goal,sc_state_l) 88 | self.cipher.diff_propagation_of_sbox(self.model_goal,self.model_filename,r,state_l,sc_state_l) 89 | if r < self.model_round: 90 | state_r = state_l 91 | xor_state = self.cipher.get_state_through_xor(self.model_goal,r) 92 | self.cipher.diff_propagation_of_xor(self.model_goal,self.model_filename,r,p_state_l,ls_state_r,xor_state) 93 | state_l = xor_state 94 | elif self.cipher.name == "twine": 95 | self.cipher.diff_propagation_of_sbox(self.model_goal,self.model_filename,r,state_l,sc_state_l) 96 | if r < self.model_round: 97 | xor_state = self.cipher.get_state_through_xor(self.model_goal,r) 98 | self.cipher.diff_propagation_of_xor(self.model_goal,self.model_filename,r,sc_state_l,state_r,xor_state) 99 | state_r = self.cipher.get_state_through_per_right(self.model_goal,state_l) 100 | state_l = self.cipher.get_state_through_per_left(self.model_goal,xor_state) 101 | 102 | 103 | def constraint_upperbound(self,order): 104 | filename = "result/"+self.cipher.name+"/"+self.model_goal+"/" + str(self.model_round-1) +"_round_[][]_optimal_solution.txt" 105 | if order == 1: 106 | add_num = 0 107 | elif order == 2: 108 | add_num = self.cipher.nibble 109 | if self.model_goal == "AS": 110 | fr = open (filename,"r") 111 | for v in fr: 112 | if v[0] == "A": 113 | var_index,var_value = int(re.findall(r'(-?[\d]+)',v)[0]),int(re.findall(r'(-?[\d]+)',v)[1]) 114 | with open(self.model_filename, "a") as f: 115 | f.write("A%d = %d\n"%(var_index+add_num,var_value)) 116 | elif self.model_goal == "DC": 117 | if self.cipher.name == "present" or self.cipher.name == "rectangle" or self.cipher.name == "lblock" or self.cipher.name == "twine": 118 | fr = open (filename,"r") 119 | for v in fr: 120 | if v[0] == "p": #<= (self.model_round-1)*self.cipher.nibble*self.cipher.num_of_p_var: 121 | var_index,var_value = int(re.findall(r'(-?[\d]+)',v)[0]),int(re.findall(r'(-?[\d]+)',v)[1]) 122 | if var_index%2 == 0: 123 | with open(self.model_filename, "a") as f: 124 | f.write("p%d = %d\n"%(var_index+add_num*2,var_value)) 125 | elif self.cipher.name == "gift": 126 | var = [0 for i in range(self.cipher.nibble*3*(self.model_round-1))] 127 | fr = open (filename,"r") 128 | for v in fr: 129 | if v[0] == "p": #<= (self.model_round-1)*self.cipher.nibble*self.cipher.num_of_p_var: 130 | var_index,var_value = int(re.findall(r'(-?[\d]+)',v)[0]),int(re.findall(r'(-?[\d]+)',v)[1]) 131 | var[var_index-1] = var_value 132 | for i in range(self.cipher.nibble*3*(self.model_round-1)): 133 | if i%3 == 0: 134 | with open(self.model_filename, "a") as f: 135 | f.write("p%d + p%d + p%d = %d\n"%(i+1+add_num*3,i+2+add_num*3,i+3+add_num*3,max(var[i:i+3]))) 136 | 137 | def input_non_zero(self): 138 | if self.model_goal == "LBAS" and self.cipher.oriented == "byte": 139 | for i in range (1,self.cipher.nibble*2): 140 | with open(self.model_filename, "a") as f: 141 | f.write("A%d + "%(i)) 142 | with open(self.model_filename, "a") as f: 143 | f.write("A%d >= 1\n"%(self.cipher.nibble*2)) 144 | else: 145 | for i in range (1,self.cipher.block_size): 146 | with open(self.model_filename, "a") as f: 147 | f.write("x%d + "%(i)) 148 | with open(self.model_filename, "a") as f: 149 | f.write("x%d >= 1\n"%(self.cipher.block_size)) 150 | def binary(self): 151 | with open(self.model_filename, "a") as f: 152 | f.write("Binary\n") 153 | if self.model_goal == "LBAS": 154 | var_dict = self.cipher.var_and_num_LBAS.copy() 155 | var_key = self.cipher.var_and_num_LBAS.keys() 156 | elif self.model_goal == "AS": 157 | var_dict = self.cipher.var_and_num_AS.copy() 158 | var_key = self.cipher.var_and_num_AS.keys() 159 | elif self.model_goal == "DC": 160 | var_dict = self.cipher.var_and_num_DC.copy() 161 | var_key = self.cipher.var_and_num_DC.keys() 162 | for i in var_key: 163 | for j in range(1,self.model_round*var_dict[i][0]+var_dict[i][1]+1): 164 | with open(self.model_filename, "a") as f: 165 | f.write(i+"%d\n"%(j)) 166 | with open(self.model_filename, "a") as f: 167 | f.write("End") 168 | 169 | def solve_model(self): 170 | time_start = time.time() 171 | m = read(self.model_filename) 172 | m.Params.MIPFocus = 2 # MIPFocus 173 | m.optimize() 174 | time_end = time.time() 175 | timespend = time_end - time_start 176 | if m.Status == 2: 177 | temp = int(round(m.objVal)) 178 | elif m.Status == 3: 179 | temp = 25600 180 | if temp < self.obj_compare: 181 | if self.cipher.structure == "sp": 182 | optimal_solution_file = "txt/"+self.cipher.name+"/"+self.model_goal+"/optimal_solution_of_submodel/"+str(self.model_round)+"_round_"+str(self.const_sbox)+str(self.const_diff)+"_optimal_solution.txt" 183 | elif self.cipher.structure == "feistel": 184 | optimal_solution_file = "txt/"+self.cipher.name+"/"+self.model_goal+"/optimal_solution_of_submodel/"+str(self.model_round)+"_round_[][]_optimal_solution.txt" 185 | f = open (optimal_solution_file,"w") 186 | f.write("solving the model " + str(self.model_filename) +"\n") 187 | f.write('obj is: %d\n'%(m.objVal)) 188 | f.write('time is %d s.\n'%(timespend)) 189 | for v in m.getVars(): 190 | f.write("%s = %d\n"%(v.varName,int(round(v.x)))) 191 | f.close() 192 | function.remove_file(self.model_filename) 193 | return temp -------------------------------------------------------------------------------- /parameter.py: -------------------------------------------------------------------------------- 1 | from ciphers.present import class_present 2 | from ciphers.gift import class_gift 3 | from ciphers.rectangle import class_rectangle 4 | from ciphers.lblock import class_lblock 5 | from ciphers.twine import class_twine 6 | '''' 7 | param cipher: a bloch cipher class 8 | ''' 9 | 10 | # cipher = class_present() 11 | # cipher = class_gift() 12 | # cipher = class_rectangle() 13 | cipher = class_lblock() 14 | # cipher = class_twine() 15 | 16 | ''' 17 | param goal: 18 | goal = AS: calculate the minimum number of act 19 | goal = DC: search for the best differential characteriatic 20 | ''' 21 | goal = "DC" 22 | 23 | 24 | -------------------------------------------------------------------------------- /txt/gift/AS/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 3 1 4 4 -2 0 -2 1 0 0 2 | 1 1 0 -3 3 1 2 2 0 0 3 | -2 -2 0 0 2 -1 -1 -1 5 0 4 | 3 -2 -2 3 1 1 4 1 0 0 5 | -1 1 -3 2 -1 0 -3 -3 8 0 6 | -2 2 1 2 0 0 1 1 0 0 7 | 3 2 0 -1 3 2 -1 -1 0 0 8 | -2 -1 -1 2 0 0 -2 -1 5 0 9 | -1 -1 2 -1 -2 2 2 -1 4 0 10 | 1 -2 -1 -1 1 -2 -1 1 5 0 11 | -2 4 1 1 3 -2 3 1 0 0 12 | 0 3 -1 -1 2 3 -1 3 0 0 13 | -1 1 2 -1 -2 -2 -2 1 6 0 14 | -1 -1 -2 -2 -1 -2 2 -1 8 0 15 | 3 1 -1 -1 2 3 1 -1 0 0 16 | -2 -2 -1 -2 -1 1 1 2 6 0 17 | -1 1 2 2 0 0 2 -1 0 0 18 | 1 -1 1 0 -1 1 -1 0 2 0 19 | 1 -1 -1 -2 1 -1 -2 -1 6 0 20 | -1 1 0 -1 -1 0 -1 -1 4 0 21 | -2 1 -1 1 2 2 1 3 0 0 22 | -2 -1 2 -2 -1 -2 -1 2 7 0 23 | 0 1 0 1 -1 0 1 1 0 0 24 | 2 3 3 2 -1 -1 1 -1 0 0 25 | -------------------------------------------------------------------------------- /txt/gift/DC/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 1 3 2 4 4 2 2 3 -8 -6 -10 0 0 2 | -2 -1 -1 -1 -4 -1 1 0 9 6 1 0 0 3 | 4 3 3 -2 0 4 3 2 2 -9 -11 0 0 4 | 0 0 0 0 0 0 0 0 -1 -1 -1 1 0 5 | -2 -4 0 -2 4 -1 -3 -3 11 9 11 0 0 6 | 1 -1 -1 3 -4 0 -3 -4 9 10 9 0 0 7 | 1 1 -1 3 4 1 2 2 -5 -2 -4 0 0 8 | 5 1 7 5 -1 -1 -3 3 -1 -3 0 0 0 9 | -3 3 -3 -2 -1 -3 1 -2 12 8 1 0 0 10 | 0 2 1 3 2 0 1 1 -4 -2 -4 0 0 11 | -4 1 -2 -3 -1 2 -2 1 10 6 2 0 0 12 | 4 -4 -1 -1 2 -4 -1 2 8 6 7 0 0 13 | 1 -1 0 -2 1 0 -2 -2 5 6 5 0 0 14 | -1 -1 0 -1 0 0 1 1 2 3 -1 0 0 15 | -2 -2 3 -2 -3 3 3 -1 7 3 -3 0 0 16 | -1 -1 -1 1 -1 0 -1 0 4 3 3 0 0 17 | -1 1 2 -1 -2 -2 -2 1 6 6 2 0 0 18 | 3 1 -1 -1 2 3 1 -1 0 -1 0 0 0 19 | 2 -2 -5 -1 -1 -5 -1 -1 14 11 9 0 0 20 | -1 1 2 2 -1 0 -1 -2 2 5 2 0 0 21 | -1 0 0 0 1 -1 1 -1 2 2 1 0 0 22 | 1 0 0 1 1 0 1 1 -2 -1 -2 0 0 23 | 4 -1 4 2 -1 1 -1 2 0 -2 -1 0 0 24 | 1 1 1 0 -1 -1 1 -1 2 1 0 0 0 25 | -1 1 -2 -2 -1 2 -2 1 6 5 2 0 0 26 | -------------------------------------------------------------------------------- /txt/lblock/AS/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 2 1 1 1 -3 0 2 1 0 0 2 | -1 0 0 -1 2 1 2 1 0 0 3 | -1 2 -2 -1 0 0 -1 -2 5 0 4 | 1 3 2 1 0 -2 -1 2 0 0 5 | 3 -1 -1 -1 0 3 1 2 0 0 6 | 1 2 3 -2 1 0 3 -1 0 0 7 | 1 2 -2 1 0 0 2 1 0 0 8 | 0 -1 0 1 -1 0 1 -1 2 0 9 | 1 1 2 2 0 1 -2 1 0 0 10 | -1 -1 -1 0 -1 -1 -1 0 5 0 11 | -1 -1 -1 0 1 1 -1 0 3 0 12 | -1 -1 1 -3 3 -1 2 -2 5 0 13 | 1 1 -2 -2 0 -1 -2 -1 6 0 14 | -1 0 1 0 1 1 0 1 0 0 15 | -1 1 0 1 1 -1 1 2 0 0 16 | -1 1 2 0 -1 -1 -2 2 3 0 17 | 0 -1 1 -1 -1 1 -1 -1 4 0 18 | -1 1 -1 0 -1 1 -1 0 3 0 19 | 1 -1 -1 1 0 1 -1 0 2 0 20 | 0 -1 1 1 1 -1 -1 -1 3 0 21 | 6 2 3 3 -4 -1 3 -1 0 0 22 | 1 -2 1 -1 2 3 1 1 0 0 23 | 1 0 0 0 -1 0 1 1 0 0 24 | -1 -1 1 0 -1 1 -1 -1 4 0 25 | 0 1 -1 -1 1 -1 -1 0 3 0 26 | 1 0 -1 1 0 -1 1 -1 2 0 27 | -------------------------------------------------------------------------------- /txt/lblock/AS/2th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 2 1 1 1 -3 0 2 1 0 0 2 | -1 0 0 -1 2 1 2 1 0 0 3 | -1 2 -2 -1 0 0 -1 -2 5 0 4 | 1 3 2 1 0 -2 -1 2 0 0 5 | 3 -1 -1 -1 0 3 1 2 0 0 6 | 1 2 3 -2 1 0 3 -1 0 0 7 | 1 2 -2 1 0 0 2 1 0 0 8 | 0 -1 0 1 -1 0 1 -1 2 0 9 | 1 1 2 2 0 1 -2 1 0 0 10 | -1 -1 -1 0 -1 -1 -1 0 5 0 11 | -1 -1 -1 0 1 1 -1 0 3 0 12 | -1 -1 1 -3 3 -1 2 -2 5 0 13 | 1 1 -2 -2 0 -1 -2 -1 6 0 14 | -1 0 1 0 1 1 0 1 0 0 15 | -1 1 0 1 1 -1 1 2 0 0 16 | -1 1 2 0 -1 -1 -2 2 3 0 17 | 0 -1 1 -1 -1 1 -1 -1 4 0 18 | -1 1 -1 0 -1 1 -1 0 3 0 19 | 1 -1 -1 1 0 1 -1 0 2 0 20 | 0 -1 1 1 1 -1 -1 -1 3 0 21 | 6 2 3 3 -4 -1 3 -1 0 0 22 | 1 -2 1 -1 2 3 1 1 0 0 23 | 1 0 0 0 -1 0 1 1 0 0 24 | -1 -1 1 0 -1 1 -1 -1 4 0 25 | 0 1 -1 -1 1 -1 -1 0 3 0 26 | 1 0 -1 1 0 -1 1 -1 2 0 27 | -------------------------------------------------------------------------------- /txt/lblock/AS/3th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 6 2 3 3 -4 -1 -1 3 0 0 2 | 3 -1 -1 -1 0 2 3 1 0 0 3 | -1 2 1 -2 3 1 0 2 0 0 4 | -1 2 -2 -1 0 -2 0 -1 5 0 5 | -1 4 5 3 -1 5 -1 -2 0 0 6 | -1 0 0 0 1 1 0 1 0 0 7 | -1 -1 1 -3 3 -2 -1 2 5 0 8 | 1 1 0 0 0 1 -1 0 0 0 9 | 0 -1 0 1 -1 -1 0 1 2 0 10 | 0 -1 0 0 1 1 1 0 0 0 11 | -1 -1 -1 0 -1 0 -1 -1 5 0 12 | 1 2 -2 1 0 1 0 2 0 0 13 | 3 2 3 3 0 -1 -1 -1 0 0 14 | 1 0 0 0 -1 1 0 1 0 0 15 | -1 1 0 -1 0 -1 0 1 2 0 16 | -1 1 -1 0 -1 0 1 -1 3 0 17 | -1 -1 -1 0 1 0 1 -1 3 0 18 | 0 -1 1 -1 -1 -1 1 -1 4 0 19 | 1 2 -3 -3 1 -1 -1 -3 8 0 20 | 1 -1 -1 1 0 0 1 -1 2 0 21 | 1 -2 1 -1 2 1 3 1 0 0 22 | 0 0 -1 -1 -1 -1 -1 -1 5 0 23 | -1 -1 1 0 -1 -1 1 -1 4 0 24 | 1 -1 0 0 0 1 1 0 0 0 25 | -1 -1 0 0 -1 1 -1 -1 4 0 26 | -1 1 -1 0 1 0 -1 -1 3 0 27 | 1 -1 -1 2 -1 -1 -1 2 3 0 28 | 0 -1 1 1 1 -1 -1 -1 3 0 29 | -------------------------------------------------------------------------------- /txt/lblock/AS/4th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 6 2 3 3 -1 -4 -1 3 0 0 2 | 3 -1 -1 -1 2 0 3 1 0 0 3 | -1 2 1 -2 1 3 0 2 0 0 4 | -1 2 -2 -1 -2 0 0 -1 5 0 5 | -1 4 5 3 5 -1 -1 -2 0 0 6 | 1 -2 1 -1 1 2 3 1 0 0 7 | 1 2 -2 1 1 0 0 2 0 0 8 | -1 -1 1 -3 -2 3 -1 2 5 0 9 | 0 -1 0 1 -1 -1 0 1 2 0 10 | 0 1 0 0 1 1 -1 0 0 0 11 | -1 -1 -1 0 0 -1 -1 -1 5 0 12 | -1 -1 -1 0 0 1 1 -1 3 0 13 | -1 0 0 0 1 1 0 1 0 0 14 | 1 0 0 0 1 -1 0 1 0 0 15 | 3 2 3 3 -1 0 -1 -1 0 0 16 | 1 1 -2 -2 -1 0 -1 -2 6 0 17 | -1 1 0 -1 -1 0 0 1 2 0 18 | -1 -1 1 0 -1 -1 1 -1 4 0 19 | -1 1 -1 0 0 -1 1 -1 3 0 20 | 1 -1 -1 1 0 0 1 -1 2 0 21 | 0 -1 1 -1 -1 -1 1 -1 4 0 22 | -1 0 1 0 1 1 1 0 0 0 23 | 1 -1 -1 2 -1 -1 -1 2 3 0 24 | -1 0 1 0 1 -1 -1 -1 3 0 25 | 2 2 1 1 1 -1 -2 1 0 0 26 | 3 1 2 2 1 -4 1 2 0 0 27 | 0 -1 1 1 -1 1 -1 -1 3 0 28 | -------------------------------------------------------------------------------- /txt/lblock/AS/5th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 6 2 3 3 -1 -1 -4 3 0 0 2 | 1 -2 1 -2 4 1 3 2 0 0 3 | -1 2 -2 -1 0 -2 0 -1 5 0 4 | 0 1 0 0 -1 1 1 0 0 0 5 | -1 4 5 3 -1 5 -1 -2 0 0 6 | 3 -1 -1 -1 3 2 0 1 0 0 7 | -1 -1 1 -3 -1 -2 3 2 5 0 8 | -1 0 0 0 0 1 1 1 0 0 9 | 0 -1 0 1 0 -1 -1 1 2 0 10 | 1 2 -2 1 0 1 0 2 0 0 11 | -1 -1 -1 0 -1 0 -1 -1 5 0 12 | 0 -1 0 0 1 1 1 0 0 0 13 | 3 2 3 3 -1 -1 0 -1 0 0 14 | 1 0 0 0 0 1 -1 1 0 0 15 | 1 1 -2 -2 -1 -1 0 -2 6 0 16 | -1 1 0 -1 0 -1 0 1 2 0 17 | -1 1 -1 0 1 0 -1 -1 3 0 18 | -1 0 -1 0 1 -1 1 -1 3 0 19 | 0 -1 1 -1 1 -1 -1 -1 4 0 20 | 1 -1 -1 1 1 0 0 -1 2 0 21 | -1 -1 1 0 -1 -1 1 -1 4 0 22 | 1 -2 -1 -1 -1 -2 2 1 5 0 23 | 1 1 2 2 1 1 0 -2 0 0 24 | -1 -1 0 0 -1 1 -1 -1 4 0 25 | 1 2 -1 1 -1 1 0 1 0 0 26 | -1 2 1 -2 0 1 3 2 0 0 27 | -1 -1 1 1 1 -1 -1 0 3 0 28 | -------------------------------------------------------------------------------- /txt/lblock/AS/6th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 2 1 1 1 1 -3 2 0 0 0 2 | -1 0 1 -2 1 3 2 2 0 0 3 | -1 2 -2 -1 -2 0 -1 0 5 0 4 | 0 1 0 0 1 1 0 -1 0 0 5 | 3 -1 -1 -1 2 0 1 3 0 0 6 | 3 2 3 3 -1 0 -1 -1 0 0 7 | -1 1 2 0 2 -1 -2 -1 3 0 8 | -1 -1 1 -3 -2 3 2 -1 5 0 9 | 0 -1 0 1 -1 -1 1 0 2 0 10 | -1 0 0 0 1 1 1 0 0 0 11 | -1 -1 -1 0 0 -1 -1 -1 5 0 12 | -1 -1 -1 0 0 1 -1 1 3 0 13 | 1 2 -2 1 1 0 2 0 0 0 14 | 1 1 -2 -2 -1 0 -2 -1 6 0 15 | 1 -2 1 -1 1 2 1 3 0 0 16 | 0 -1 1 -1 -1 -1 -1 1 4 0 17 | -1 1 -1 0 0 -1 -1 1 3 0 18 | -1 1 0 -1 -1 0 1 0 2 0 19 | -1 0 1 0 1 1 0 1 0 0 20 | 1 -1 -1 1 0 0 -1 1 2 0 21 | -1 -1 1 0 -1 -1 -1 1 4 0 22 | 3 -1 -1 0 2 -1 2 2 0 0 23 | 1 -1 -1 2 -1 -1 2 -1 3 0 24 | 1 -1 0 0 1 0 0 1 0 0 25 | 1 2 1 1 1 -1 0 -1 0 0 26 | 3 1 2 1 1 -3 3 -1 0 0 27 | 0 -1 1 1 -1 1 -1 -1 3 0 28 | -------------------------------------------------------------------------------- /txt/lblock/AS/7th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 2 1 1 1 -3 0 2 1 0 0 2 | -1 0 0 -1 2 1 2 1 0 0 3 | -1 2 -2 -1 0 0 -1 -2 5 0 4 | 1 3 2 1 0 -2 -1 2 0 0 5 | 3 -1 -1 -1 0 3 1 2 0 0 6 | 1 2 3 -2 1 0 3 -1 0 0 7 | 1 2 -2 1 0 0 2 1 0 0 8 | 0 -1 0 1 -1 0 1 -1 2 0 9 | 1 1 2 2 0 1 -2 1 0 0 10 | -1 -1 -1 0 -1 -1 -1 0 5 0 11 | -1 -1 -1 0 1 1 -1 0 3 0 12 | -1 -1 1 -3 3 -1 2 -2 5 0 13 | 1 1 -2 -2 0 -1 -2 -1 6 0 14 | -1 0 1 0 1 1 0 1 0 0 15 | -1 1 0 1 1 -1 1 2 0 0 16 | -1 1 2 0 -1 -1 -2 2 3 0 17 | 0 -1 1 -1 -1 1 -1 -1 4 0 18 | -1 1 -1 0 -1 1 -1 0 3 0 19 | 1 -1 -1 1 0 1 -1 0 2 0 20 | 0 -1 1 1 1 -1 -1 -1 3 0 21 | 6 2 3 3 -4 -1 3 -1 0 0 22 | 1 -2 1 -1 2 3 1 1 0 0 23 | 1 0 0 0 -1 0 1 1 0 0 24 | -1 -1 1 0 -1 1 -1 -1 4 0 25 | 0 1 -1 -1 1 -1 -1 0 3 0 26 | 1 0 -1 1 0 -1 1 -1 2 0 27 | -------------------------------------------------------------------------------- /txt/lblock/AS/8th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 6 2 3 3 -4 -1 -1 3 0 0 2 | 3 -1 -1 -1 0 3 2 1 0 0 3 | -1 2 1 -2 3 0 1 2 0 0 4 | -1 2 -2 -1 0 0 -2 -1 5 0 5 | -1 4 5 3 -1 -1 5 -2 0 0 6 | -1 0 0 0 1 0 1 1 0 0 7 | -1 -1 1 -3 3 -1 -2 2 5 0 8 | 2 3 1 1 0 -3 1 1 0 0 9 | 0 -1 0 1 -1 0 -1 1 2 0 10 | 0 -1 0 0 1 1 1 0 0 0 11 | -1 -1 -1 0 -1 -1 0 -1 5 0 12 | 1 2 -3 -3 1 -1 -1 -3 8 0 13 | -1 2 0 2 -1 1 2 1 0 0 14 | 1 0 0 0 -1 0 1 1 0 0 15 | 2 1 1 1 0 1 -2 1 0 0 16 | -1 1 0 -1 0 0 -1 1 2 0 17 | 0 -1 1 -1 -1 1 -1 -1 4 0 18 | -1 0 -1 0 1 1 -1 -1 3 0 19 | 1 -1 -1 1 0 1 0 -1 2 0 20 | 0 -1 1 1 1 -1 -1 -1 3 0 21 | 0 0 -1 -1 -1 -1 -1 -1 5 0 22 | -1 -1 1 0 -1 1 -1 -1 4 0 23 | -1 2 -2 -1 -1 1 -1 -1 5 0 24 | -1 1 -1 0 1 -1 0 -1 3 0 25 | -1 1 2 0 -1 -1 2 -2 3 0 26 | 1 -1 -1 2 -1 -1 -1 2 3 0 27 | 1 1 2 2 -2 1 1 0 0 0 28 | 1 -2 1 -1 2 3 1 1 0 0 29 | -------------------------------------------------------------------------------- /txt/lblock/DC/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -1 0 -1 0 -1 -1 -1 0 -1 5 0 0 2 | -3 -1 3 0 1 -1 -3 -1 5 3 0 0 3 | 1 1 0 0 0 0 1 1 -1 -1 0 0 4 | -1 -3 -1 0 -1 1 -1 1 4 3 0 0 5 | -1 2 2 2 -1 1 -1 -3 6 0 0 0 6 | 1 0 -1 -1 4 3 2 3 -2 -1 0 0 7 | 2 0 -1 -1 0 -1 -3 -1 2 4 0 0 8 | -4 -1 1 -2 3 -1 1 -2 4 4 0 0 9 | 1 0 0 0 0 0 1 0 -1 0 0 0 10 | 0 1 0 0 0 0 0 1 -1 0 0 0 11 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 12 | 0 -1 0 3 -3 0 1 -1 2 2 0 0 13 | 2 -1 -1 1 0 2 0 1 -1 1 0 0 14 | 2 2 1 1 0 0 1 0 0 -2 0 0 15 | 0 1 0 0 1 0 1 2 -1 -1 0 0 16 | -1 -3 2 0 -2 -1 -2 1 4 4 0 0 17 | 1 -4 1 -1 2 4 0 2 1 1 0 0 18 | 0 1 0 -1 0 0 1 0 -1 1 0 0 19 | -1 1 -1 0 0 0 -1 -2 1 3 0 0 20 | -1 -1 1 0 -1 1 -2 -1 2 3 0 0 21 | -1 0 -1 0 1 1 -1 -2 1 3 0 0 22 | 1 0 1 1 0 -1 -3 -1 2 2 0 0 23 | 1 -1 1 -1 0 1 0 0 -1 2 0 0 24 | 1 -2 -1 -1 2 -1 1 -2 0 5 0 0 25 | -------------------------------------------------------------------------------- /txt/lblock/DC/2th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -1 0 -1 0 -1 -1 -1 0 -1 5 0 0 2 | -3 -1 3 0 1 -1 -3 -1 5 3 0 0 3 | 1 1 0 0 0 0 1 1 -1 -1 0 0 4 | -1 -3 -1 0 -1 1 -1 1 4 3 0 0 5 | -1 2 2 2 -1 1 -1 -3 6 0 0 0 6 | 1 0 -1 -1 4 3 2 3 -2 -1 0 0 7 | 2 0 -1 -1 0 -1 -3 -1 2 4 0 0 8 | -4 -1 1 -2 3 -1 1 -2 4 4 0 0 9 | 1 0 0 0 0 0 1 0 -1 0 0 0 10 | 0 1 0 0 0 0 0 1 -1 0 0 0 11 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 12 | 0 -1 0 3 -3 0 1 -1 2 2 0 0 13 | 2 -1 -1 1 0 2 0 1 -1 1 0 0 14 | 2 2 1 1 0 0 1 0 0 -2 0 0 15 | 0 1 0 0 1 0 1 2 -1 -1 0 0 16 | -1 -3 2 0 -2 -1 -2 1 4 4 0 0 17 | 1 -4 1 -1 2 4 0 2 1 1 0 0 18 | 0 1 0 -1 0 0 1 0 -1 1 0 0 19 | -1 1 -1 0 0 0 -1 -2 1 3 0 0 20 | -1 -1 1 0 -1 1 -2 -1 2 3 0 0 21 | -1 0 -1 0 1 1 -1 -2 1 3 0 0 22 | 1 0 1 1 0 -1 -3 -1 2 2 0 0 23 | 1 -1 1 -1 0 1 0 0 -1 2 0 0 24 | 1 -2 -1 -1 2 -1 1 -2 0 5 0 0 25 | -------------------------------------------------------------------------------- /txt/lblock/DC/3th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -1 -2 -1 0 -1 0 -1 -1 1 5 0 0 2 | 1 1 0 0 0 1 0 1 -1 -1 0 0 3 | -1 1 1 0 0 -2 0 -1 3 1 0 0 4 | -1 -3 0 0 -1 2 1 -1 4 2 0 0 5 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 6 | 0 0 0 0 2 2 1 1 -1 -1 0 0 7 | 0 -1 0 3 -3 -1 0 1 2 2 0 0 8 | 1 -2 -1 -1 2 -2 -2 -5 6 6 0 0 9 | 1 -1 1 -2 2 -1 1 2 -1 2 0 0 10 | 1 2 1 1 0 1 -1 0 0 -1 0 0 11 | -4 -1 1 -2 3 -2 -1 1 4 4 0 0 12 | -1 1 -1 0 0 0 0 -1 -1 3 0 0 13 | 1 0 0 0 0 0 0 1 -1 0 0 0 14 | 2 -1 -1 1 0 1 2 0 -1 1 0 0 15 | 1 2 1 1 0 -1 0 0 1 -1 0 0 16 | 0 1 0 0 0 1 0 0 -1 0 0 0 17 | -1 -3 1 0 -2 1 -1 -1 3 4 0 0 18 | 0 1 0 -1 0 0 0 1 -1 1 0 0 19 | 0 -2 -2 -1 -1 0 2 -1 3 4 0 0 20 | 0 -1 1 -1 -1 -1 1 -1 0 4 0 0 21 | -1 0 -1 0 1 0 1 -1 -1 3 0 0 22 | -2 -1 1 3 -2 -1 2 0 4 1 0 0 23 | 1 0 1 1 0 -1 -1 0 -1 2 0 0 24 | 0 0 -1 -1 -1 -1 -1 -1 0 5 0 0 25 | -1 1 -3 4 3 -3 -3 -1 5 5 0 0 26 | 1 -1 1 -1 0 0 1 0 -1 2 0 0 27 | -1 -1 1 0 1 -1 -1 -1 1 3 0 0 28 | -------------------------------------------------------------------------------- /txt/lblock/DC/4th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 0 0 -1 -1 -1 -1 -1 -1 0 5 0 0 2 | -3 -1 3 0 -1 1 -1 -3 5 3 0 0 3 | 1 1 0 0 1 0 0 1 -1 -1 0 0 4 | -1 -3 -1 0 1 -1 1 -1 4 3 0 0 5 | -1 2 2 2 -3 -1 1 -1 6 0 0 0 6 | 1 0 -1 -1 3 4 3 2 -2 -1 0 0 7 | -4 -1 1 -2 -2 3 -1 1 4 4 0 0 8 | 1 0 0 0 0 0 0 1 -1 0 0 0 9 | -1 1 -1 0 0 0 0 -1 -1 3 0 0 10 | 2 0 -1 -1 -1 0 -1 -3 2 4 0 0 11 | 0 2 0 1 3 1 -1 1 -1 -1 0 0 12 | 0 -1 0 3 -1 -3 0 1 2 2 0 0 13 | 0 1 0 -1 0 0 0 1 -1 1 0 0 14 | -1 0 0 0 1 -1 -1 -1 -1 4 0 0 15 | 1 2 1 1 -1 0 0 0 1 -1 0 0 16 | 2 -1 1 -1 1 0 2 0 -1 1 0 0 17 | 1 0 2 1 -1 -3 -2 0 2 3 0 0 18 | 1 -1 -1 1 0 0 1 0 -1 2 0 0 19 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 20 | -1 -1 1 0 -1 -1 1 -1 1 3 0 0 21 | -1 -2 -1 -2 -1 1 1 0 2 4 0 0 22 | 0 0 0 0 2 2 1 1 -1 -1 0 0 23 | -1 -1 -1 2 -2 -1 -1 0 2 4 0 0 24 | 0 1 0 0 1 0 0 0 -1 0 0 0 25 | -1 0 -1 0 -2 1 1 -1 1 3 0 0 26 | 0 -1 1 1 -1 1 -1 -1 0 3 0 0 27 | -------------------------------------------------------------------------------- /txt/lblock/DC/5th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -1 0 -1 0 -1 0 -1 -1 -1 5 0 0 2 | -3 -1 3 0 -1 -1 1 -3 5 3 0 0 3 | 1 1 0 0 0 1 0 1 -1 -1 0 0 4 | -1 -3 -1 0 1 1 -1 -1 4 3 0 0 5 | -1 2 2 2 1 -3 -1 -1 6 0 0 0 6 | 1 0 -1 -1 3 3 4 2 -2 -1 0 0 7 | 2 0 -1 -1 -1 -1 0 -3 2 4 0 0 8 | -3 -1 1 -2 -1 -2 2 1 3 4 0 0 9 | 1 0 0 0 0 0 0 1 -1 0 0 0 10 | 0 1 0 0 0 1 0 0 -1 0 0 0 11 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 12 | 0 -1 0 3 0 -1 -3 1 2 2 0 0 13 | 2 -1 1 -1 2 1 0 0 -1 1 0 0 14 | 2 2 1 1 0 0 0 1 0 -2 0 0 15 | 0 1 0 0 0 2 1 1 -1 -1 0 0 16 | -1 -3 2 0 -1 1 -2 -2 4 4 0 0 17 | 0 1 0 -1 0 0 0 1 -1 1 0 0 18 | -1 1 -1 0 0 -2 0 -1 1 3 0 0 19 | 1 -1 -1 1 1 0 0 0 -1 2 0 0 20 | -1 -1 -1 -2 1 0 2 1 0 3 0 0 21 | -2 -1 1 0 1 -1 -1 -2 3 3 0 0 22 | 1 0 1 1 -1 -1 0 0 -1 2 0 0 23 | -2 -1 -1 0 -1 -1 1 0 3 3 0 0 24 | -1 0 -1 0 1 -2 1 -1 1 3 0 0 25 | 0 0 0 0 1 1 1 0 -1 0 0 0 26 | -------------------------------------------------------------------------------- /txt/lblock/DC/6th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 0 0 -1 -1 -1 -1 -1 -1 0 5 0 0 2 | -3 -1 3 0 -1 1 -3 -1 5 3 0 0 3 | 1 1 0 0 1 0 1 0 -1 -1 0 0 4 | -1 -3 -1 0 1 -1 -1 1 4 3 0 0 5 | -1 2 2 2 -3 -1 -1 1 6 0 0 0 6 | 1 0 -1 -1 3 4 2 3 -2 -1 0 0 7 | -4 -1 1 -2 -2 3 1 -1 4 4 0 0 8 | -1 1 -1 0 0 0 -1 0 -1 3 0 0 9 | 1 0 0 0 0 0 1 0 -1 0 0 0 10 | 2 0 -1 -1 -1 0 -3 -1 2 4 0 0 11 | 0 -1 0 3 -1 -3 1 0 2 2 0 0 12 | 0 1 0 0 1 0 0 0 -1 0 0 0 13 | 0 1 0 -1 0 0 1 0 -1 1 0 0 14 | 2 2 1 1 0 0 1 0 0 -2 0 0 15 | 2 -1 -1 1 1 0 0 2 -1 1 0 0 16 | -1 -3 0 0 1 -1 -1 -1 2 4 0 0 17 | 0 0 0 0 2 2 1 1 -1 -1 0 0 18 | 2 -2 2 -2 1 1 0 3 -1 2 0 0 19 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 20 | -1 -3 -1 -2 0 1 0 2 2 4 0 0 21 | -1 -1 1 0 -1 -1 -2 1 2 3 0 0 22 | -1 1 -1 2 -1 3 -1 -3 3 3 0 0 23 | 2 1 2 2 -1 -3 0 -1 2 1 0 0 24 | -1 0 -1 0 -2 -1 -1 -1 1 5 0 0 25 | -1 0 -1 0 0 1 -1 1 -1 3 0 0 26 | 0 -1 1 1 -1 1 -4 -1 3 3 0 0 27 | -------------------------------------------------------------------------------- /txt/lblock/DC/7th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -1 0 -1 0 -1 -1 -1 0 -1 5 0 0 2 | -3 -1 3 0 1 -1 -3 -1 5 3 0 0 3 | 1 1 0 0 0 0 1 1 -1 -1 0 0 4 | -1 -3 -1 0 -1 1 -1 1 4 3 0 0 5 | -1 2 2 2 -1 1 -1 -3 6 0 0 0 6 | 1 0 -1 -1 4 3 2 3 -2 -1 0 0 7 | 2 0 -1 -1 0 -1 -3 -1 2 4 0 0 8 | -4 -1 1 -2 3 -1 1 -2 4 4 0 0 9 | 1 0 0 0 0 0 1 0 -1 0 0 0 10 | 0 1 0 0 0 0 0 1 -1 0 0 0 11 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 12 | 0 -1 0 3 -3 0 1 -1 2 2 0 0 13 | 2 -1 -1 1 0 2 0 1 -1 1 0 0 14 | 2 2 1 1 0 0 1 0 0 -2 0 0 15 | 0 1 0 0 1 0 1 2 -1 -1 0 0 16 | -1 -3 2 0 -2 -1 -2 1 4 4 0 0 17 | 1 -4 1 -1 2 4 0 2 1 1 0 0 18 | 0 1 0 -1 0 0 1 0 -1 1 0 0 19 | -1 1 -1 0 0 0 -1 -2 1 3 0 0 20 | -1 -1 1 0 -1 1 -2 -1 2 3 0 0 21 | -1 0 -1 0 1 1 -1 -2 1 3 0 0 22 | 1 0 1 1 0 -1 -3 -1 2 2 0 0 23 | 1 -1 1 -1 0 1 0 0 -1 2 0 0 24 | 1 -2 -1 -1 2 -1 1 -2 0 5 0 0 25 | -------------------------------------------------------------------------------- /txt/lblock/DC/8th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -1 0 -1 0 -1 -1 0 -1 -1 5 0 0 2 | -3 -1 3 0 1 -1 -1 -3 5 3 0 0 3 | 1 1 0 0 0 0 1 1 -1 -1 0 0 4 | -1 -3 -1 0 -1 1 1 -1 4 3 0 0 5 | -1 2 2 2 -1 1 -3 -1 6 0 0 0 6 | 1 0 -1 -1 4 3 3 2 -2 -1 0 0 7 | 2 0 -1 -1 0 -1 -1 -3 2 4 0 0 8 | -3 -1 1 -2 2 -1 -2 1 3 4 0 0 9 | 1 0 0 0 0 0 0 1 -1 0 0 0 10 | 0 1 0 0 0 0 1 0 -1 0 0 0 11 | 0 1 -1 -1 0 0 0 0 -1 2 0 0 12 | 0 -1 0 3 -3 0 -1 1 2 2 0 0 13 | 2 -1 1 -1 0 2 1 0 -1 1 0 0 14 | 2 2 1 1 0 0 0 1 0 -2 0 0 15 | -1 0 0 0 1 0 1 1 0 0 0 0 16 | -1 -3 1 0 -2 -1 1 -1 3 4 0 0 17 | 0 1 0 -1 0 0 0 1 -1 1 0 0 18 | -1 0 -1 0 1 1 0 -1 -1 3 0 0 19 | 1 -1 -1 1 0 1 0 0 -1 2 0 0 20 | -1 -1 1 0 -1 1 -1 -2 2 3 0 0 21 | -1 1 -1 0 0 0 -2 -1 1 3 0 0 22 | 1 -2 -1 -1 2 -1 -2 1 0 5 0 0 23 | 1 0 1 1 0 -1 -1 0 -1 2 0 0 24 | -1 0 1 0 2 1 2 1 0 -1 0 0 25 | -------------------------------------------------------------------------------- /txt/present/AS/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 3 4 4 1 -2 0 -2 1 0 0 2 | 0 -2 -2 3 4 1 4 1 0 0 3 | -2 1 1 3 1 -1 1 2 0 0 4 | 1 -3 -2 -2 3 -4 1 -3 10 0 5 | -1 -2 -2 -1 -1 2 -1 0 6 0 6 | 2 1 1 -3 1 2 1 2 0 0 7 | -2 -2 1 -1 -2 -1 1 0 6 0 8 | -1 2 -3 1 -1 -2 -3 -3 10 0 9 | -1 1 1 -1 0 0 0 -1 2 0 10 | 2 -1 2 2 2 3 -1 -1 0 0 11 | 2 3 -2 -4 -4 -4 -1 1 11 0 12 | 2 2 -1 2 -1 3 2 -1 0 0 13 | -1 -3 2 1 -3 -2 -1 -3 10 0 14 | -1 0 -1 -1 1 0 -1 0 3 0 15 | 0 -1 -1 1 -1 0 -1 1 3 0 16 | 0 -1 1 -1 0 -1 -1 1 3 0 17 | -2 0 0 1 2 1 2 1 0 0 18 | 0 -2 -2 -2 -1 2 -1 -1 7 0 19 | 2 3 3 2 1 -4 1 1 0 0 20 | 1 -2 -3 -2 1 -4 3 -3 10 0 21 | 0 1 1 -1 -1 1 -1 0 2 0 22 | 1 1 1 1 1 1 -2 1 0 0 23 | 2 1 1 0 -2 1 1 2 0 0 24 | -------------------------------------------------------------------------------- /txt/present/DC/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 0 -1 -1 -1 -2 -2 -2 -1 -3 10 0 0 2 | 4 2 2 5 1 4 1 6 8 -12 0 0 3 | 3 4 4 2 2 0 2 1 -1 -5 0 0 4 | -1 -8 7 -3 -2 4 -2 -9 11 14 0 0 5 | -5 4 -2 -3 3 1 -3 -1 4 7 0 0 6 | 0 -1 -1 1 2 0 2 0 -1 1 0 0 7 | -1 1 -2 2 -5 -4 3 1 5 6 0 0 8 | 1 -5 2 -2 3 -5 -3 1 4 9 0 0 9 | 3 2 -5 -3 -2 -1 3 -1 2 7 0 0 10 | 1 2 2 0 -1 0 -1 0 -1 1 0 0 11 | -3 -2 1 -2 -2 -1 3 -1 1 7 0 0 12 | 1 -1 -1 1 -1 0 -1 -1 -2 5 0 0 13 | -2 -1 -1 -2 1 1 0 1 -1 5 0 0 14 | -8 -4 -4 6 -1 2 -1 0 7 10 0 0 15 | 0 1 1 -1 1 -1 1 -1 -1 2 0 0 16 | 3 2 1 0 2 4 2 4 1 -6 0 0 17 | 0 3 -3 1 -1 -1 -2 -2 1 6 0 0 18 | 1 -2 3 2 1 3 -2 -2 1 2 0 0 19 | 0 -3 -3 -2 -1 2 -1 -2 -1 10 0 0 20 | -1 2 2 5 1 -1 1 3 1 -3 0 0 21 | -1 0 -1 -1 -1 0 1 1 -1 4 0 0 22 | 0 2 -2 1 -1 1 0 -1 1 2 0 0 23 | 3 1 1 -3 -2 -3 -2 1 -1 7 0 0 24 | -3 -1 2 -2 -2 0 2 -1 2 5 0 0 25 | 0 -2 2 1 -2 -1 0 -1 1 4 0 0 26 | -------------------------------------------------------------------------------- /txt/rectangle/AS/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 7 -3 5 4 -1 -1 -2 7 0 0 2 | -2 3 3 -2 3 6 -2 4 0 0 3 | 3 4 -1 -1 3 -1 3 -1 0 0 4 | -1 -1 2 -1 0 0 -2 -2 5 0 5 | 0 -1 -2 0 -1 -1 -2 2 5 0 6 | 2 1 2 1 0 0 1 -2 0 0 7 | 0 -1 -1 0 1 2 2 2 0 0 8 | -1 1 2 -1 0 0 2 2 0 0 9 | 0 1 -1 1 0 1 0 -1 1 0 10 | -1 1 -1 -2 -1 -2 -1 -1 7 0 11 | -1 -2 1 2 -1 -1 1 -1 4 0 12 | 2 -2 -1 -1 2 1 -1 -2 5 0 13 | -1 -1 -1 0 -1 0 -1 0 4 0 14 | -1 -1 1 1 2 -1 -2 1 3 0 15 | 0 1 -2 0 2 1 1 2 0 0 16 | -1 1 -1 0 -1 0 1 -1 3 0 17 | 1 -1 -1 1 1 -1 0 -1 3 0 18 | -2 -1 -1 2 3 4 4 2 0 0 19 | -1 -1 -1 -1 -1 1 0 0 4 0 20 | -1 1 -2 -2 1 -2 1 -1 6 0 21 | 1 1 -1 -2 -1 -2 1 -2 6 0 22 | 4 -3 1 4 -1 3 2 2 0 0 23 | 0 1 1 1 -1 0 0 1 0 0 24 | -------------------------------------------------------------------------------- /txt/rectangle/DC/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -2 -1 -3 -1 -2 -1 -2 -3 4 9 0 0 2 | 1 -3 2 0 1 0 -3 2 -3 4 0 0 3 | 1 8 2 5 1 5 0 2 7 -10 0 0 4 | -1 -4 -2 -1 -1 -1 2 -2 6 6 0 0 5 | 2 1 2 1 0 0 1 0 0 -2 0 0 6 | 0 1 0 0 2 1 1 2 0 -2 0 0 7 | -1 3 -3 -4 -1 -4 -1 -3 2 11 0 0 8 | 0 1 -1 0 0 0 1 -1 -1 2 0 0 9 | 0 0 1 0 0 0 0 1 -1 0 0 0 10 | 0 0 -2 0 -1 -1 -1 1 1 3 0 0 11 | -1 0 1 -1 0 0 -1 -2 1 3 0 0 12 | 0 1 -1 1 0 1 -1 -1 1 1 0 0 13 | 0 -1 0 0 0 1 0 1 -1 1 0 0 14 | 0 -1 1 1 0 0 0 0 -1 1 0 0 15 | -3 -3 -5 2 -3 -2 -1 -2 4 12 0 0 16 | -7 1 -2 -2 -7 1 2 -2 5 13 0 0 17 | -1 1 -2 -4 1 -4 1 -1 2 8 0 0 18 | 1 1 -1 -1 -1 -1 1 -2 -1 5 0 0 19 | 1 -3 -1 -1 1 1 2 -2 3 3 0 0 20 | -1 0 -1 2 2 2 3 1 1 -1 0 0 21 | 3 -1 1 4 -3 3 5 -2 1 1 0 0 22 | 1 -3 -2 1 1 -1 2 -1 3 3 0 0 23 | -------------------------------------------------------------------------------- /txt/twine/AS/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | 2 3 4 4 -5 1 1 2 0 0 2 | 0 -1 -2 1 2 3 1 3 0 0 3 | -3 -3 1 2 3 -2 -1 -3 8 0 4 | 2 -4 -1 -3 -3 -2 -3 -1 13 0 5 | 1 3 -2 -3 2 4 1 -3 4 0 6 | 2 4 3 1 2 -3 -2 1 1 0 7 | -1 1 3 -3 3 -1 1 2 2 0 8 | 2 3 -1 1 -3 -1 2 -1 3 0 9 | -2 2 0 1 -1 -1 -1 2 3 0 10 | 2 -2 3 -1 1 -2 3 1 2 0 11 | 2 -1 -2 2 2 1 -1 2 1 0 12 | -2 -2 -2 1 -2 1 1 -1 7 0 13 | -1 2 -2 -1 -2 1 -1 2 5 0 14 | -1 1 1 0 -1 1 0 -1 2 0 15 | 2 1 1 1 1 1 1 -2 0 0 16 | -1 -1 -1 -1 0 -1 1 1 4 0 17 | -1 0 -1 0 1 1 -1 -1 3 0 18 | -1 1 -1 0 1 -1 1 -1 3 0 19 | -1 -2 -1 2 -1 2 -1 -2 6 0 20 | -1 -1 1 -1 -1 0 1 -1 4 0 21 | -1 0 -1 -1 -1 -1 -1 0 5 0 22 | -1 0 0 0 1 1 1 1 0 0 23 | 1 1 -2 -1 3 2 3 1 0 0 24 | 0 0 1 1 -1 -1 1 1 1 0 25 | -1 -1 1 -1 -1 1 -1 1 4 0 26 | 1 -1 1 0 0 0 1 1 0 0 27 | -------------------------------------------------------------------------------- /txt/twine/DC/1th_sbox_reduce_ine_greedy.txt: -------------------------------------------------------------------------------- 1 | -2 -6 1 -3 -2 -4 -3 -6 5 17 0 0 2 | 2 7 -4 -1 8 4 5 2 9 -9 0 0 3 | 1 3 5 11 -2 1 7 2 8 -10 0 0 4 | 1 -6 -10 2 -1 2 -8 -4 7 19 0 0 5 | 1 7 5 2 2 -6 -6 4 3 2 0 0 6 | 7 -1 5 2 2 3 6 7 -1 -7 0 0 7 | 1 2 -2 -1 -3 -1 1 -2 -2 8 0 0 8 | -2 -5 4 -10 -6 -2 -3 -1 10 18 0 0 9 | -3 -5 3 3 4 -3 -2 -4 2 9 0 0 10 | -1 2 1 -3 2 3 3 1 -2 2 0 0 11 | -1 -2 -4 2 4 5 -3 1 3 3 0 0 12 | -1 1 4 3 -2 4 -3 -3 -2 7 0 0 13 | -1 -1 -2 -3 -5 -2 -1 3 3 10 0 0 14 | 3 -3 -1 -3 -3 -1 -2 -2 -1 12 0 0 15 | 1 3 -2 -3 2 4 1 -3 1 3 0 0 16 | -1 -1 2 -3 3 -1 2 1 -1 4 0 0 17 | -2 -1 -2 3 2 -3 1 -2 -1 8 0 0 18 | 0 2 -1 1 -1 2 -2 2 -2 4 0 0 19 | -1 1 1 2 -2 -1 0 2 -1 3 0 0 20 | -3 -2 -2 1 -2 1 1 -1 2 6 0 0 21 | 1 -2 -3 1 2 2 -1 2 1 2 0 0 22 | 2 3 1 3 -1 1 2 0 0 -2 0 0 23 | -1 -1 -1 -1 0 -1 -1 0 -1 6 0 0 24 | -1 0 0 -1 -1 1 1 -1 0 3 0 0 25 | -1 1 -1 0 0 -1 1 -1 -1 4 0 0 26 | -2 -3 1 -1 -2 3 -1 1 3 5 0 0 27 | --------------------------------------------------------------------------------