-
Notifications
You must be signed in to change notification settings - Fork 6
/
CFunc.spyx
338 lines (239 loc) · 9.31 KB
/
CFunc.spyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# distutils: language = c
# distutils: include_dirs = ./C/
# distutils: sources = ./C/AC.c ./C/CI.c ./C/SSI.c ./C/AlgebraicImmunity.c ./C/MLT.c ./C/MDT.c ./C/tools_functions.c ./C/matrix.c ./C/MinimumDegree.c ./C/PC.c
r"""
The interface for calling "c" functions
AUTHORS:
- Oleksandr Kazymyrov (2011-06-21): initial version
- Oleksandr Kazymyrov (2013-08-04): rewrote many functions
- Anna Maria Eilertsen, Oleksandr Kazymyrov (2013-08-14): updated description
"""
#*****************************************************************************
# Copyright (C) 2013 Oleksandr Kazymyrov <okazymyrov@gmail.com>
#
# Distributed under the terms of the GNU General Public License (GPL)
# as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
# http://www.gnu.org/licenses/
#*****************************************************************************
from sage.all import ZZ
from sage.all import log
from libc.stdlib cimport malloc
from libc.stdlib cimport free
cdef extern from *:
int AC(char *f, int FunctionsLength)
int CI(int m,char *f, int FunctionsLength)
int minimum_degree(char *f, int FunctionsLength)
int PC(int k,char *f, int FunctionsLength)
unsigned long long SumOfSquares(char *f, int FunctionsLength)
int algebraic_immunity(char **Functions, int deg, int FunctionsLength, int SboxBitIn, int SboxBitOut)
unsigned long long d_uniform_xor_xor(unsigned long long *Sbox, unsigned long long SboxLength, unsigned long long TableSize, unsigned long long delta)
unsigned long long d_uniform_add_xor(unsigned long long *Sbox, unsigned long long SboxLength, unsigned long long TableSize, unsigned long long n, unsigned long long m, unsigned long long delta)
unsigned long long d_uniform_xor_add(unsigned long long *Sbox, unsigned long long SboxLength, unsigned long long TableSize, unsigned long long n, unsigned long long m, unsigned long long delta)
unsigned long long d_uniform_add_add(unsigned long long *Sbox, unsigned long long SboxLength, unsigned long long TableSize, unsigned long long n, unsigned long long m, unsigned long long delta)
unsigned long long c_lambda(unsigned long long *sbox, long long InLength, long long OutLength)
def c_absolute_indicator(pSbox,length):
r"""
Return the maximum value of the autocorrelation spectrum
It is a convenience function and connects cr_autocorrelation() in CSbox with
AC() in AC.c
INPUT::
- ``pSbox`` -- array of integers
- ``length`` -- length of array
"""
cdef char *fSbox = <char *>malloc(length*sizeof(char))
ac=0
ret_ac=0
for j in range(1,length):
for i in range(length):
fSbox[i] = (ZZ(pSbox[i]&j).popcount())&1
ac=AC(fSbox, length)
if ac > ret_ac:
ret_ac=ac
free(fSbox)
return ZZ(ret_ac)
def c_algebraic_immunity_sbox(pSbox,length,SboxBitIn,SboxBitOut):
r"""
Return algebraic immunity, that is the maximum degree of a system of equations that describes the S-box
It is a convenience function and connects cr_algebraic_immunity_sbox() in CSbox
with alg_eq_Sbox() in AlgebraicImmunity.c
INPUT::
- ``pSbox`` -- array of integers
- ``length`` -- length of array
- ``SboxBitIn`` -- number of in-bits ('n')
- ``SboxBitOut`` -- number of out-bits ('m')
"""
cdef char **fSbox = <char **>malloc(SboxBitOut*sizeof(char*))
for j in range(SboxBitOut):
fSbox[j] = <char *>malloc(length*sizeof(char))
for j in range(SboxBitOut):
for i in range(length):
fSbox[j][i] = (ZZ(pSbox[i]&(1<<j)).popcount())&1
d=0
num_of_eq=0
for d in range(1,length):
num_of_eq = algebraic_immunity(fSbox,d,length,SboxBitIn,SboxBitOut)
if num_of_eq != 0:
break
for j in range(SboxBitOut):
free(fSbox[j])
free(fSbox)
return [d,num_of_eq]
def c_is_balanced(pSbox,length,SboxBitOut):
r"""
Check S-box on balancedness
INPUT::
- ``pSbox`` -- array of integers
- ``length`` -- length of array
- ``SboxBitOut`` -- number of out-bits ('m')
"""
for j in range(1,1<<SboxBitOut):
if [(ZZ(s&j).popcount())&1 for s in pSbox].count(1) != (length>>1):
return False
return True
def c_CI(pSbox,length):
r"""
Return the correlation immunity of the vectorial boolean function
It is a convenience function and connects cr_CI() in CSbox with
CI() in CI.c
INPUT::
- ``pSbox`` -- array of integers
- ``length`` - length of array
"""
cdef char *fSbox = <char *>malloc(length*sizeof(char))
ci=1
ret_ci=0
for m in range(1,length):
for j in range(1,length):
for i in range(length):
fSbox[i] = (ZZ(pSbox[i]&j).popcount())&1
ci&=CI(m, fSbox, length)
if ci == 0:
free(fSbox)
return m-1
free(fSbox)
return -1
def c_is_APN(pSbox,length,TableSize):
r"""
Return 0 if the substitution is APN (2-uniform)
It is a convenience function and connects cr_is_APN() in CSbox with
d_uniform() in MDT.c
INPUT::
- ``pSbox`` -- array of integers
- ``length`` -- lenght of array
- ``TableSize`` -- length of a differential table
"""
cdef unsigned long long *cSbox = <unsigned long long *>malloc(length*sizeof(unsigned long long))
for i in range(length):
cSbox[i] = pSbox[i]
ret_val = d_uniform_xor_xor(cSbox,length,TableSize,2)
free(cSbox)
return True if ret_val else False
def c_MDT(pSbox,n,m,difference):
r"""
Return the maximum value of differential table.
It is a convenience function that connects cr_MDT() in CSbox with
other functions in MDT.c
INPUT::
- ``pSbox`` -- array of integers
- ``n`` -- number of input bits
- ``m`` -- number of output bits
"""
length = 1<<n
TableSize = 1<<m
cdef unsigned long long *cSbox = <unsigned long long *>malloc(length*sizeof(unsigned long long))
for i in range(length):
cSbox[i] = pSbox[i]
if difference == 'XORXOR':
ret_val = d_uniform_xor_xor(cSbox,length,TableSize,length)
elif difference == 'ADDXOR':
ret_val = d_uniform_add_xor(cSbox,length,TableSize,n,m,length)
elif difference == 'XORADD':
ret_val = d_uniform_xor_add(cSbox,length,TableSize,n,m,length)
elif difference == 'ADDADD':
ret_val = d_uniform_add_add(cSbox,length,TableSize,n,m,length)
else:
raise NotImplementedError("'{0}'".format(difference))
free(cSbox)
return ZZ(ret_val)
def c_minimum_degree(pSbox,n,m):
r"""
Return the minimum degree of substitution
It is a convenience function and connects cr_minimum_degree() in CSbox with
minimum_degree() in MinimumDegree.c
INPUT::
- ``pSbox`` -- array of integers
- ``n`` -- number of input bits
- ``m`` -- number of output bits
"""
length_n = 1<<n
length_m = 1<<m
cdef char *fSbox = <char *>malloc(length_n*sizeof(char))
d=0
ret_deg = n
for j in range(1,length_m):
for i in range(length_n):
fSbox[i] = (ZZ(pSbox[i]&j).popcount())&1
d = minimum_degree(fSbox, length_n)
if d < ret_deg:
ret_deg=d
free(fSbox)
return ret_deg
def c_MLT(pSbox,SboxBitIn,SboxBitOut):
r"""
Return the maximum value of linear approximation table
It is a convenience function and connects cr_MLT() in CSbox with
c_lambda() in MLT.c
INPUT::
- ``pSbox`` -- array of integers
- ``SboxBitIn`` -- number of in-bits ('n')
- ``SboxBitOut`` -- number of out-bits ('m')
"""
cdef unsigned long long *cSbox = <unsigned long long *>malloc((1<<SboxBitIn)*sizeof(unsigned long long))
for i in range(1<<SboxBitIn):
cSbox[i] = pSbox[i]
ret_val=c_lambda(cSbox,SboxBitIn,SboxBitOut)
free(cSbox)
return ZZ(ret_val)
def c_PC(pSbox,length):
r"""
Return the value of propogation criterion
It is a convenience function and connects cr_PC() in CSbox with
PC() in PC.c
INPUT::
- ``pSbox`` -- array of integers
- ``length`` -- length of array
"""
cdef char *fSbox = <char *>malloc(length*sizeof(char))
pc=1
ret_pc=0
for k in range(1,length):
for j in range(1,length):
for i in range(length):
fSbox[i] = (ZZ(pSbox[i]&j).popcount())&1
pc&=PC(k, fSbox, length)
if pc == 0:
free(fSbox)
return ZZ(k-1)
free(fSbox)
return -1
def c_SSI(pSbox,length):
r"""
Return the sum-of-squares indicator
It is a convenience function and connects cr_SSI() in CSbox with
SumOfSquares() in SSI.c
INPUT::
- ``pSbox`` -- array of integers
- ``length`` -- length of array
"""
cdef char *fSbox = <char *>malloc(length*sizeof(char))
ssi=0
ret_ssi=0
for j in range(1,length):
for i in range(length):
fSbox[i] = (ZZ(pSbox[i]&j).popcount())&1
ssi=SumOfSquares(fSbox, length)
if ssi > ret_ssi:
ret_ssi=ssi
free(fSbox)
return ZZ(ret_ssi)