Skip to content

Commit 88410ab

Browse files
authored
Add files via upload
1 parent d29f826 commit 88410ab

File tree

1 file changed

+307
-0
lines changed

1 file changed

+307
-0
lines changed

Linear_MORUS_and_Mini.py

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Created on Wed Oct 10 15:22:29 2018
4+
5+
@author: LENOVO
6+
"""
7+
8+
from gurobipy import *
9+
from standard import *
10+
import time
11+
12+
class genVars_MORUS:
13+
14+
def __init__(self, length_register):
15+
self.len_Register = length_register
16+
17+
18+
def genVars_inputRegister(self, r, subr, index):
19+
return ['S' + str(index) + '_' + str(j) + '_sr' + str(subr) + '_r' + str(r) for j in range(self.len_Register)]
20+
21+
def genVars_keyStream(self, r):
22+
return ['C_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
23+
24+
def genVars_outputAnd(self, r, index):
25+
return ['OAnd' + str(index) + '_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
26+
27+
def genVars_inputAnd_first(self, r, index):
28+
return['IAnd_f' + str(index) + '_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
29+
30+
def genVars_inputAnd_second(self, r, index):
31+
return ['IAnd_s' + str(index) + '_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
32+
33+
def genVars_dummay(self, r, subr, index):
34+
return ['Dum_f' + str(index) + '_' + str(j) + '_sr' + str(subr) + '_r' + str(r) for j in range(self.len_Register)]
35+
36+
def genVars_outputAnd_additional(self, r):
37+
return ['OAnd_add' + '_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
38+
39+
def genVars_inputAnd_additional_first(self, r):
40+
return ['IAnd__add_f' + '_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
41+
42+
def genVars_inputAnd_additional_second(self, r):
43+
return ['IAnd__add_s' + '_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
44+
45+
def genVars_Message(self, r):
46+
return ['Mess_' + str(j) + '_r' + str(r) for j in range(self.len_Register)]
47+
48+
class BasicConstr_linear:
49+
def getConstraints_Branch(Input_Vars, Dummary_Var):
50+
'''
51+
>> BasicConstr_linear.getConstraints_Branch(['a','b'],'c')
52+
>> ['a + b - 2 c = 0']
53+
'''
54+
Constr = [' + '.join(Input_Vars) + ' - 2 ' + Dummary_Var + ' = 0']
55+
return Constr
56+
57+
def getConstraints_XOR(Input_Vars):
58+
'''
59+
>> BasicConstr_linear.getConstraints_XOR(['a','b','c'])
60+
>> ['a - b = 0', 'a - c = 0']
61+
'''
62+
n = len(Input_Vars)
63+
Constr = []
64+
for i in range(1, n):
65+
Constr = Constr + [Input_Vars[0] + ' - ' + Input_Vars[i] + ' = 0']
66+
return Constr
67+
68+
def getConstraints_AND(Input1, Input2, Output0):
69+
'''
70+
>> BasicConstr_linear.getConstraints_AND('a','b','c')
71+
>> ['c - a >= 0', 'c - b >= 0']
72+
'''
73+
Constr = []
74+
Constr = Constr + [Output0 + ' - ' + Input1 + ' >= 0']
75+
Constr = Constr + [Output0 + ' - ' + Input2 + ' >= 0']
76+
return Constr
77+
78+
def getConstraints_Rot_on_word(Input, Output, len_word, shiftbit):
79+
'''
80+
>> BasicConstr_linear.getConstraints_Rot_on_word(['a1','b1','c1','d1','e1','f1'],['a2','b2','c2','d2','e2','f2'], 3, 1)
81+
>>
82+
['b1 - a2 = 0',
83+
'c1 - b2 = 0',
84+
'a1 - c2 = 0',
85+
'e1 - d2 = 0',
86+
'f1 - e2 = 0',
87+
'd1 - f2 = 0']
88+
'''
89+
n = len(Input)//len_word
90+
Constr = []
91+
for j in range(n):
92+
In0 = Input[len_word*j : len_word*(j + 1)]
93+
Out0 = Output[len_word*j : len_word*(j + 1)]
94+
for h in range(len_word):
95+
Constr = Constr + [In0[(h + shiftbit) % len_word] + ' - ' + Out0[h] + ' = 0']
96+
return Constr
97+
98+
@staticmethod
99+
def getVariables_From_Constraints(C):
100+
V = set([])
101+
for s in C:
102+
temp = s.strip()
103+
temp = temp.replace('+', ' ')
104+
temp = temp.replace('-', ' ')
105+
temp = temp.replace('>=', ' ')
106+
temp = temp.replace('<=', ' ')
107+
temp = temp.replace('=', ' ')
108+
temp = temp.split()
109+
for v in temp:
110+
if not v.isdecimal():
111+
V.add(v)
112+
113+
return V
114+
115+
class LinearCryptanalysis_MORUS:
116+
117+
def __init__(self, length_register, length_word, shift_word, shift):
118+
self.len_Register = length_register
119+
self.len_Word = length_word
120+
self.b = shift_word
121+
self.w = shift
122+
123+
def getConstraints_subround(self, r, subr):
124+
Vars = genVars_MORUS(self.len_Register)
125+
KeyStream = Vars.genVars_keyStream(r)
126+
127+
if subr < 4:
128+
Input_S = []
129+
Output_S = []
130+
for j in range(5):
131+
Input_S.append(Vars.genVars_inputRegister(r, subr, j))
132+
Output_S.append(Vars.genVars_inputRegister(r, subr + 1, j))
133+
else:
134+
Input_S = []
135+
Output_S = []
136+
for j in range(5):
137+
Input_S.append(Vars.genVars_inputRegister(r, subr, j))
138+
Output_S.append(Vars.genVars_inputRegister(r + 1, 0, j))
139+
140+
141+
Output_And = Vars.genVars_outputAnd(r, subr)
142+
Input0_And= Vars.genVars_inputAnd_first(r, subr)
143+
Input1_And = Vars.genVars_inputAnd_second(r, subr)
144+
145+
Input0_And_additional = Vars.genVars_inputAnd_additional_first(r)
146+
Input1_And_additional = Vars.genVars_inputAnd_additional_second(r)
147+
148+
149+
Constr = []
150+
151+
#constrains for the branch
152+
if subr == 0:
153+
for index in [subr]:
154+
Dummary = Vars.genVars_dummay(r, subr, index)
155+
for j in range(self.len_Register):
156+
Constr = Constr + BasicConstr_linear.getConstraints_Branch([Input_S[index][j], KeyStream[j], Output_And[j]], Dummary[j])
157+
for index in [(subr + 1)%5]:
158+
Dummary = Vars.genVars_dummay(r, subr, index)
159+
for j in range(self.len_Register):
160+
Constr = Constr + BasicConstr_linear.getConstraints_Branch([KeyStream[(j - self.w[2])% self.len_Register], Input_S[index][j], Output_S[index][j], Input0_And[j]], Dummary[j])
161+
for index in [(subr + 2)%5]:
162+
Dummary = Vars.genVars_dummay(r, subr, index)
163+
for j in range(self.len_Register):
164+
Constr = Constr + BasicConstr_linear.getConstraints_Branch([Input0_And_additional[j], Input_S[index][j], Output_S[index][j], Input1_And[j]], Dummary[j])
165+
for index in [(subr + 3)%5]:
166+
Dummary = Vars.genVars_dummay(r, subr, index)
167+
for j in range(self.len_Register):
168+
Constr = Constr + BasicConstr_linear.getConstraints_Branch([Input1_And_additional[j], Input_S[index][j], Output_S[index][(j - self.w[subr])% self.len_Register], Output_And[j]], Dummary[j])
169+
else:
170+
for j in range(self.len_Register):
171+
Constr = Constr + [Input_S[subr][j] + ' - ' + Output_And[j] + ' = 0']
172+
for index in [(subr + 1)%5]:
173+
Dummary = Vars.genVars_dummay(r, subr, index)
174+
for j in range(self.len_Register):
175+
Constr = Constr + BasicConstr_linear.getConstraints_Branch([Input_S[index][j], Output_S[index][j], Input0_And[j]], Dummary[j])
176+
for index in [(subr + 2)%5]:
177+
Dummary = Vars.genVars_dummay(r, subr, index)
178+
for j in range(self.len_Register):
179+
Constr = Constr + BasicConstr_linear.getConstraints_Branch([Input_S[index][j], Output_S[index][j], Input1_And[j]], Dummary[j])
180+
for index in [(subr + 3)%5]:
181+
Dummary = Vars.genVars_dummay(r, subr, index)
182+
for j in range(self.len_Register):
183+
Constr = Constr + BasicConstr_linear.getConstraints_Branch([Input_S[index][j], Output_S[index][(j - self.w[subr])% self.len_Register], Output_And[j]], Dummary[j])
184+
185+
#Constraints for the AND
186+
for j in range(self.len_Register):
187+
Constr = Constr + BasicConstr_linear.getConstraints_AND(Input0_And[j], Input1_And[j], Output_And[j])
188+
#Constraints for rotation on each word
189+
for j in range(self.len_Register):
190+
Constr = Constr + BasicConstr_linear.getConstraints_Rot_on_word(Output_And, Output_S[subr], self.len_Word, self.b[subr])
191+
192+
#Constraints for the rest register
193+
for j in range(self.len_Register):
194+
Constr = Constr + [Input_S[(subr + 4) % 5][j] + ' - ' + Output_S[(subr + 4) % 5][j] + ' = 0']
195+
196+
return Constr
197+
198+
199+
def getConstraints_additional_AND_keystream(self, r):
200+
Vars = genVars_MORUS(self.len_Register)
201+
A0 = Vars.genVars_inputAnd_additional_first(r)
202+
A1 = Vars.genVars_inputAnd_additional_second(r)
203+
B = Vars.genVars_outputAnd_additional(r)
204+
Keystream = Vars.genVars_keyStream(r)
205+
206+
Constr = []
207+
#Constraints for the additional AND operation
208+
for j in range(self.len_Register):
209+
Constr = Constr + BasicConstr_linear.getConstraints_AND(A0[j], A1[j], B[j])
210+
211+
for j in range(self.len_Register):
212+
Constr = Constr + BasicConstr_linear.getConstraints_XOR([B[j], Keystream[j]])
213+
return Constr
214+
215+
def getConstraints_additional(self, TotalR):
216+
Constr = []
217+
Input_S = []
218+
Output_S = []
219+
Vars = genVars_MORUS(self.len_Register)
220+
for i in range(5):
221+
Input_S = Input_S + Vars.genVars_inputRegister(0, 0, i)
222+
Output_S = Output_S + Vars.genVars_inputRegister(TotalR, 0, i)
223+
224+
Constr = Constr + [' + '.join(Input_S) + ' = 0']
225+
Constr = Constr + [' + '.join(Output_S) + ' = 0']
226+
227+
Keystream = []
228+
for i in range(TotalR):
229+
Keystream = Keystream + Vars.genVars_keyStream(i)
230+
Constr = Constr + [' + '.join(Keystream) + ' >= 1']
231+
return Constr
232+
233+
234+
def genObjective(self, TotalR):
235+
Var_obj = []
236+
Vars = genVars_MORUS(self.len_Register)
237+
for i in range(TotalR):
238+
for j in range(5):
239+
Var_obj = Var_obj + Vars.genVars_outputAnd(i, j)
240+
Var_obj = Var_obj + Vars.genVars_outputAnd_additional(i)
241+
Obj = ' + '.join(Var_obj)
242+
return Obj
243+
244+
245+
def getConstraints_RoundFun(self, r):
246+
Constr = []
247+
for subr in range(5):
248+
Constr = Constr + self.getConstraints_subround(r, subr)
249+
Constr = Constr + self.getConstraints_additional_AND_keystream(r)
250+
return Constr
251+
252+
253+
254+
255+
def genModel(self, TotalR, Name):
256+
Constr = []
257+
for i in range(TotalR):
258+
Constr = Constr + self.getConstraints_RoundFun(i)
259+
Constr = Constr + self.getConstraints_additional(TotalR)
260+
261+
V = BasicConstr_linear.getVariables_From_Constraints(Constr)
262+
263+
fid=open('./Linear_' + Name + str(5*self.len_Register) + '_r' + str(TotalR) + '.lp','w')
264+
fid.write('Minimize')
265+
fid.write('\n')
266+
fid.write(self.genObjective(TotalR))
267+
fid.write('\n')
268+
fid.write('Subject To')
269+
fid.write('\n')
270+
for c in Constr:
271+
fid.write(c)
272+
fid.write('\n')
273+
274+
GV = []
275+
BV =[]
276+
for v in V:
277+
if v[0] == 'D':
278+
GV.append(v)
279+
else:
280+
BV.append(v)
281+
282+
283+
fid.write('Binary'+'\n')
284+
for bv in BV:
285+
fid.write(bv+'\n')
286+
287+
fid.write('Generals'+'\n')
288+
for gv in GV:
289+
fid.write(gv+'\n')
290+
291+
fid.close()
292+
293+
294+
def cmd(len_Register, len_Word, TotalR, Name):
295+
if len_Register == 128 or len_Register == 32:
296+
b = [5, 31, 7, 22, 13]
297+
w = [32, 64, 96, 64, 32]
298+
elif len_Register == 256 or len_Register == 64:
299+
b = [13, 46, 38, 7, 4]
300+
w = [64, 128, 192, 128, 64]
301+
302+
a = LinearCryptanalysis_MORUS(len_Register, len_Word, b, w)
303+
a.genModel(TotalR, Name)
304+
305+
modelname = 'Linear_' + Name + str(5*len_Register) + '_r' + str(TotalR)
306+
307+

0 commit comments

Comments
 (0)