Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 3712
1
#
2
# kryptering.sage
3
# Robert Nyqvist, 2015-2017
4
#
5
6
print "*** Pythonbibliotek för kryptering, version 2017 ***"
7
8
Asve = u'abcdefghijklmnopqrstuvxyz' + unichr(229) + unichr(228) + unichr(246)
9
10
Aeng = u'abcdefghijklmnopqrstuvwxyz'
11
12
def text_till_heltal(t, A = Asve) :
13
kodning = {A[i]: i for i in range(len(A))}
14
return map(lambda x : kodning[x], t)
15
16
def heltal_till_text(a, A = Asve) :
17
t = map(lambda x : A[x], a)
18
return u''.join(t)
19
20
def affint_krypto(t, a, b, A = Asve) :
21
c = text_till_heltal(t, A)
22
m = len(A)
23
c = map(lambda x : (a * x + b) % m, c)
24
return heltal_till_text(c, A)
25
26
def Caesarkrypto(t, s = 3, A = Asve) :
27
return affint_krypto(t, 1, s, A)
28
29
def substitutionskrypto(t, p, A = Asve) :
30
a = p.action(A)
31
nyckel = {A[i]:a[i] for i in range(len(A))}
32
c = map(lambda x : nyckel[x], t)
33
return ''.join(c)
34
35
def transpositionskrypto(t, n, metod = 'kryptera') :
36
if metod in ['kryptera', 'dekryptera'] :
37
m = len(t)
38
k = len(n)
39
if metod == 'kryptera' :
40
c = ''
41
else :
42
c = len(t) * [' ']
43
r = 0
44
for i in range(k) :
45
for j in range(n[i], m, k) :
46
if metod == 'kryptera' :
47
c += t[j]
48
else :
49
c[j] = t[r]
50
r += 1
51
if metod == 'dekryptera' :
52
c = ''.join(c)
53
return c
54
else :
55
return u'Okänd metod!'
56
57
def Playfair(t, n, x = 'x', metod = 'kryptera') :
58
if metod in ['kryptera', 'dekryptera'] :
59
if metod == 'kryptera' :
60
M = 1
61
else :
62
M = -1
63
s = t.replace('j', 'i')
64
t = ''
65
while s != '' :
66
if len(s) >= 2 :
67
if s[0] != s[1] :
68
t += s[:2]
69
s = s[2:]
70
else :
71
t += s[0] + x
72
s = s[1:]
73
else :
74
t += s + x
75
s = ''
76
c = ''
77
for i in range(0, len(t), 2) :
78
a = ZZ(n.index(t[i]))
79
q1, r1 = a.quo_rem(5)
80
b = ZZ(n.index(t[i+1]))
81
q2, r2 = b.quo_rem(5)
82
if q1 == q2 : # samma rad
83
x = 5 * q1 + ((r1 + M) % 5)
84
y = 5 * q2 + ((r2 + M) % 5)
85
elif r1 == r2 : # samma kolumn
86
x = 5 * ((q1 + M) % 5) + r1
87
y = 5 * ((q2 + M) % 5) + r2
88
else :
89
x = 5 * q1 + r2
90
y = 5 * q2 + r1
91
c += n[x] + n[y]
92
return c
93
else :
94
return u'Okänd metod!'
95
96
def ADFGVX(t, n, p, metod = 'kryptera') :
97
A = 'ADFGVX'
98
c = ''
99
if metod == 'kryptera' :
100
for i in range(len(t)) :
101
j = ZZ(n.index(t[i]))
102
q, r = j.quo_rem(6)
103
c += A[q] + A[r]
104
c = transpositionskrypto(c, p)
105
return c
106
elif metod == 'dekryptera' :
107
t = transpositionskrypto(t, p, metod = 'dekryptera')
108
for i in range(0, len(t), 2) :
109
q = A.index(t[i])
110
r = A.index(t[i+1])
111
j = 6 * q + r
112
c += n[j]
113
return c
114
else :
115
return u'Okänd metod!'
116
117
def Vigenerekrypto(t, k, A = Asve) :
118
c = text_till_heltal(t, A)
119
k = text_till_heltal(k, A)
120
m = len(A)
121
n = len(k)
122
for i in range(len(c)) :
123
j = i % n
124
c[i] = (c[i] + k[j]) % m
125
return heltal_till_text(c, A)
126
127
def Autokey(t, k, A = Asve, metod = 'kryptera') :
128
m = len(A)
129
k = text_till_heltal(k)[0]
130
if metod == 'kryptera' :
131
p = text_till_heltal(t)
132
c = []
133
for x in p :
134
c.append((x + k) % m)
135
k = x
136
return heltal_till_text(c, A)
137
elif metod == 'dekryptera' :
138
c = text_till_heltal(t)
139
p = []
140
for x in c :
141
p.append((x - k) % m)
142
k = p[-1]
143
return heltal_till_text(p, A)
144
else :
145
return u'Okänd metod!'
146
147
def Vernamchiffer(t, k, A = Asve, metod = 'kryptera') :
148
if len(t) <= len(k) :
149
if metod == 'dekryptera' :
150
m = len(A)
151
k = text_till_heltal(k, A)
152
k = heltal_till_text([-x % m for x in k])
153
c = Vigenerekrypto(t, k, A)
154
return c
155
else :
156
return u'För kort nyckel.'
157
158
def Enigma(t, k, r, s) :
159
A = '_ABCDEFGHIJKLMNOPQRSTUVWXYZ' # alfabet för Enigma
160
rotor = {'I':'EKMFLGDQVZNTOWYHXUSPAIBRCJ',
161
'II':'AJDKSIRUXBLHWTMCQGZNPYFVOE',
162
'III':'BDFHJLCPRTXVZNYEIWGAKMUSQO',
163
'IV':'ESOVPZJAYQUIRHXLNFTGKDCMWB',
164
'V':'VZBRGITYUPSDNHLXAWMJQOFECK'}
165
hack = {'I':'Q', 'II':'E', 'III':'V', 'IV':'J', 'V':'Z'}
166
# rotor 1
167
rho1 = Permutation([A.index(x) for x in rotor[r[0]]])
168
rho1inv = rho1.inverse()
169
h1 = A.index(hack[r[0]])
170
k1 = A.index(s[0])
171
# rotor 2
172
rho2 = Permutation([A.index(x) for x in rotor[r[1]]])
173
rho2inv = rho2.inverse()
174
h2 = A.index(hack[r[1]])
175
k2 = A.index(s[1])
176
# rotor 3
177
rho3 = Permutation([A.index(x) for x in rotor[r[2]]])
178
rho3inv = rho3.inverse()
179
# h3 = A.index(hack[r[2]])
180
k3 = A.index(s[2])
181
# reflektor
182
tau = Permutation([A.index(x) for x in 'YRUHQSLDPXNGOKMIEBFZCWVJAT'])
183
# permutation för kopplingstavla
184
p = ''.join(map(str, [(A.index(x), A.index(y)) for (x, y) in k]))
185
if p.find('26') < 0 :
186
p += '(26)'
187
beta = Permutation(p)
188
# rotationspermutation
189
def sigma(a, n) :
190
b = (a + n) % 26
191
if b == 0 :
192
b = 26
193
return b
194
# kryptering/dekryptering
195
c = ''
196
for m, x in enumerate(t) :
197
l1 = m
198
l2 = floor((h1 + k1 + l1)/26)
199
l3 = floor((h2 + k2 + l2)/26)
200
# koda klartext som heltal
201
y = A.index(x)
202
# kopplingstavla
203
y = beta(y)
204
# rotor 1
205
y = sigma(rho1(sigma(y, k1 + l1)), -k1 - l1)
206
# rotor 2
207
y = sigma(rho2(sigma(y, k2 + l2)), -k2 - l2)
208
# rotor 3
209
y = sigma(rho3(sigma(y, k3 + l3)), -k3 - l3)
210
# reflektor
211
y = tau(y)
212
# rotor 3
213
y = sigma(rho3inv(sigma(y, k3 + l3)), -k3 - l3)
214
# rotor 2
215
y = sigma(rho2inv(sigma(y, k2 + l2)), -k2 - l2)
216
# rotor 1
217
y = sigma(rho1inv(sigma(y, k1 + l1)), -k1 - l1)
218
# kopplingstavla
219
y = beta(y)
220
# koda heltal till kryptogram
221
c += A[y]
222
return c
223
224
def Hillkrypto(t, M, x = u'x', A = Asve, typ = 'V') :
225
m = len(A)
226
# antaf att matrisen M är kvadratisk
227
# konvertera klartexten/kryptogrammet til en matris
228
j = M.nrows() # blocklängd, d.v.s. antal kolonner
229
t = t + (-len(t) % j) * x # lägg till utfyllnadstecken
230
i = len(t) // j # antal rader
231
P = matrix(Zmod(m), i, j, text_till_heltal(t, A))
232
if typ == 'V' :
233
C = P * M
234
elif typ == 'H' :
235
C = (M * P.transpose()).transpose()
236
else :
237
return u'Felaktig typ!'
238
# konvertera från matris till text
239
c = flatten([list(r) for r in C])
240
return heltal_till_text(c, A)
241
242
def text_till_block64(text) :
243
n = -len(text) % 8
244
m = text + n * u' ' # utfyllnadstecken: mellanslag
245
b = flatten([ZZ(ord(t)).digits(base = 2, padto = 8) for t in m])
246
block = [b[i:i+64] for i in range(0, len(b), 64)]
247
return block
248
249
def block64_till_text(block, typ = 'text') :
250
def till_dec(b) :
251
return [ZZ(b[k:k+8], base = 2) for k in range(0, len(b), 8)]
252
if typ == 'text' :
253
d = flatten(map(till_dec, block))
254
t = map(unichr, d)
255
return ''.join(t)
256
elif typ == 'hex' :
257
d = map(till_dec, block)
258
h = [[''.join(a.digits(base = 16, digits = '0123456789ABCDEF', padto = 2)[::-1]) for a in b] for b in d]
259
return [''.join(b) for b in h]
260
elif typ == 'bin' :
261
return [''.join(map(str, b)) for b in block]
262
else :
263
return u'Okänd typ!'
264
265
IP_permutation = [58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
266
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
267
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
268
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7]
269
270
def IP(m) :
271
m0 = map(lambda i : m[i-1], IP_permutation)
272
return m0
273
274
def IPinv(m) :
275
c = 64 * [0]
276
for i in range(64) :
277
c[IP_permutation[i]-1] = m[i]
278
return c
279
280
def Sbox_DES(B, i) :
281
S = [# S-box 1
282
[[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
283
[ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
284
[ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
285
[15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]],
286
# S-box 2
287
[[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
288
[ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
289
[ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
290
[13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]],
291
# S-box 3
292
[[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
293
[13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
294
[13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
295
[ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]],
296
# S-box 4
297
[[ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
298
[13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
299
[10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
300
[ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]],
301
# S-box 5
302
[[ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
303
[14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
304
[ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
305
[11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]],
306
# S-box 6
307
[[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
308
[10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
309
[ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
310
[ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]],
311
# S-box 7
312
[[ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
313
[13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
314
[ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
315
[ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]],
316
# S-box 8
317
[[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
318
[ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
319
[ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
320
[ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]
321
]
322
r = ZZ([B[j] for j in [0, -1]], base = 2) # rad
323
k = ZZ(B[1:-1], base = 2) # kolumn
324
c = S[i][r][k]
325
C = c.digits(base = 2, padto = 4)
326
return C
327
328
def f_DES(R, K) :
329
def E(R) :
330
p = [32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
331
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
332
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
333
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1];
334
y = 48 * [0]
335
for i in range(48) :
336
y[i] = R[p[i]-1]
337
return y
338
p = [16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
339
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25];
340
B = map(lambda x, y : (x + y) % 2, E(R), K) # B = E(R) + K
341
Bi = [B[i:i+6] for i in range(0, 48, 6)]
342
Ci = map(lambda (j, Bj) : Sbox_DES(Bj, j), enumerate(Bi))
343
C = flatten(Ci)
344
y = [C[k-1] for k in p]
345
return y
346
347
def DES(m, K) :
348
# Initrial Permutation
349
m0 = IP(m)
350
# dela upp i vänster- oc högerblock
351
Li = m0[:32]
352
Ri = m0[32:]
353
# de sexton rundorna av Feistelsystemet
354
for i in range(16) :
355
S = map(lambda x, y : (x + y) % 2, Li, f_DES(Ri, K[i])) # L + f(R, K)
356
Li = Ri
357
Ri = S
358
# konkatenering
359
m = Ri + Li
360
# Inverse Initrial Permutation
361
c = IPinv(m)
362
return c
363
364
def rundnycklar_DES(K) :
365
def LS(L, k) :
366
return L[k:] + L[:k]
367
p1 = [57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
368
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
369
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
370
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4]
371
p2 = [14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
372
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
373
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
374
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32]
375
s = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
376
K0 = [K[i-1] for i in p1]
377
Ci = K0[:28] # C_0
378
Di = K0[28:] # D_0
379
Ki = []
380
for i in range(16) :
381
Ci = LS(Ci, s[i])
382
Di = LS(Di, s[i])
383
CD = Ci + Di
384
k = map(lambda j : CD[j-1], p2)
385
Ki += [k]
386
return Ki
387
388
def ECB_DES(block, K, metod = 'kryptering') :
389
Ki = rundnycklar_DES(K)
390
if metod == 'dekryptering' :
391
Ki = Ki[::-1]
392
c = map(lambda m : DES(m, Ki), block)
393
return c
394
395
def monogramanalys(t, A = Asve, typ = 'diagram') :
396
f = [t.count(x) for x in A]
397
if typ == 'diagram' :
398
fd = Graphics()
399
o = 0.05 * max(f)
400
for i in range(len(A)) :
401
fd += line([(i,0), (i,f[i])], thickness=10)
402
fd += text(A[i], (i,-o), fontsize='large', vertical_alignment='top')
403
fd.axes(False)
404
fd.show()
405
elif typ == 'tabell' :
406
for i in range(len(A)) :
407
print A[i], ' : ', f[i]
408
elif typ == 'lista' :
409
return {A[i]:f[i] for i in range(len(A))}
410
else :
411
print u'Okänd typ'
412
413
def bigramanalys(t, antal_bigram = 25) :
414
l = [t[i:i+2] for i in range(len(t)-1)]
415
u = list(set(l))
416
f = {x:l.count(x) for x in u}
417
b = sorted(f.items(), key = lambda x : x[1])
418
n = min(antal_bigram, len(b))
419
for i in range(len(b)-1, len(b)-n-1, -1) :
420
print b[i][0], ' : ', b[i][1]
421
422
def trigramanalys(t, antal_trigram = 25) :
423
l = [t[i:i+3] for i in range(lent(t)-2)]
424
u = list(set(l))
425
f = {x:l.count(x) for x in u}
426
b = sorted(f.items(), key = lambda x : x[1])
427
n = min(antal_trigram, len(b))
428
for i in range(len(b)-1, len(b)-n-1, -1) :
429
print b[i][0], ' : ', b[i][1]
430
431
def BabbageKasiski(t, d) :
432
p = []
433
k = t.find(d, 0)
434
while k != -1 :
435
p.append(k)
436
k = t.find(d, k + 1)
437
return p
438
439
def Friedman(t, s) :
440
t1 = t + s * u'-'
441
t2 = s * u'-' + t
442
n = sum([x == y for x, y in zip(t1, t2)])
443
return n
444
445
def splittra_text(t, n) :
446
s = []
447
for k in range(n) :
448
d = [t[i] for i in range(k, len(t), n)]
449
s.append(''.join(d))
450
return s
451
452
def heltal_till_block(m, n, s = 2, t = 23) :
453
m = m + (-len(m) % n) * [t]
454
m = [vector(m[i:i+n]) for i in range(0, len(m), n)]
455
b = 10^s
456
d = vector([b^(i-1) for i in range(n, 0, -1)])
457
m = map(lambda x : d.dot_product(x), m)
458
return m
459
460
def block_till_heltal(m, n, s = 2) :
461
t = []
462
b = 10^s
463
for i in range(len(m)) :
464
for j in range(n, 0, -1) :
465
t += [(m[i] % b^j) // b^(j-1)]
466
return t
467
468
def text_till_bitblock(t, n = 1024) :
469
b = map(ord, t)
470
b = [ZZ(x).digits(base = 2, padto = 8) for x in b]
471
b = flatten(b)
472
B = []
473
for i in range(0, len(b), n) :
474
B.append(ZZ(b[i:i+n], base = 2))
475
return B
476
477
def bitblock_till_text(b, n = 1024) :
478
t = map(lambda x : ZZ(x).digits(base = 2, padto = n), b)
479
t = flatten(t)
480
T = []
481
for i in range(0, len(t), 8) :
482
a = ZZ(t[i:i+8], base = 2)
483
if a != 0 :
484
T.append(a)
485
T = map(unichr, T)
486
T = ''.join(T)
487
return T
488
489
def RSA(m, n, e) :
490
return map(lambda x : power_mod(x, e, n), m)
491
492
def ElGamal(m, n, k = [], metod = 'kryptera') :
493
if metod == 'kryptera' :
494
p, g, b = n # publik nyckel
495
if len(k) == 0 :
496
k = [randint(1, p - 3) for i in range(len(m))]
497
c = []
498
for i in range(len(m)) :
499
r = power_mod(g, k[i], p)
500
t = (power_mod(b, k[i], p) * m[i]) % p
501
c.append((r, t))
502
elif metod == 'dekryptera' :
503
p, g, a = n # privat nyckel
504
c = [(t * power_mod(r, -a, p)) % p for (r, t) in m]
505
else :
506
c = u'Okänd metod'
507
return c
508
509
def BlumBlumShub(x0, m, n) :
510
x = Mod(x0, m)
511
b = []
512
for i in range(n) :
513
x = x^2
514
b.append(lift(x) % 2)
515
return b
516
517
518
def LFSR(x, f, n) :
519
m = len(x)
520
for i in range(n - m) :
521
b = f(x[-m:])
522
x.append(b)
523
return x
524
525
def Lehmer(x0, a, c, m, n) :
526
x = [x0]
527
for i in [2..n] :
528
x.append((a * x[-1] + c) % m)
529
return x
530