-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathencryption.py
More file actions
110 lines (81 loc) · 3.05 KB
/
Copy pathencryption.py
File metadata and controls
110 lines (81 loc) · 3.05 KB
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
import random, os
import hashlib
import numpy as np
import time
from sympy import Matrix
from PIL import Image
def ACM(img, p, q, m):
counter = 0
if img.mode == "P":
img = img.convert("RGB")
assert img.size[0] == img.size[1]
while counter < m:
dim = width, height = img.size
with Image.new(img.mode, dim) as canvas:
for x in range(width):
for y in range(height):
nx = (x + y*p) % width
ny = (x*q + y*(p*q + 1)) % height
canvas.putpixel((nx, ny), img.getpixel((x, y)))
img = canvas
counter += 1
return canvas
def inv_ACM(img, p, q, m):
counter = 0
if img.mode == "P":
img = img.convert("RGB")
assert img.size[0] == img.size[1]
matrix = Matrix(np.array([[1, p], [q, p*q + 1]]))
inv_matrix = matrix.inv_mod(img.size[0])
while counter < m:
dim = width, height = img.size
with Image.new(img.mode, dim) as canvas:
for x in range(width):
for y in range(height):
nx = (x*inv_matrix[0] + y*inv_matrix[1]) % width
ny = (x*inv_matrix[2] + y*inv_matrix[3]) % height
canvas.putpixel((nx, ny), img.getpixel((x, y)))
img = canvas
counter += 1
return canvas
def logistic_map(init, r, length, prec=4):
x = [None] * (length+1)
x[0] = init
for i in range(1,length+1):
x[i] = r * x[i-1] * (1 - x[i-1])
keystream = [None] * length
for i in range(length):
if x[i] < 0:
keystream[i] = 0
else:
try:
float_point = int(str(x[i]).split(".")[1][:prec].replace("e","").replace("-",""))
keystream[i] = float_point & 0xF # 4 LSB bits
except IndexError:
keystream[i] = 0
return keystream
def selective_xor(m, k):
c = []
for i in range(len(m)):
bit_len = int(m[i]).bit_length()
if bit_len > 4:
msb = m[i] >> 4 & (2**(bit_len-4) - 1)
else:
msb = 0
# 4 bit MSB ^ 4 bit key + 4 bit LSB
xored = ((msb ^ k[i % len(k)]) << 4) | (m[i] & 0xF)
c.append(xored)
return bytes(c)
def encrypt(plain_image, p, q, m, init, r):
cipher_image = ACM(plain_image, p, q, m)
keystream = logistic_map(init, r, cipher_image.size[0]**2)
image_byte = np.array(cipher_image).flatten()
encrypted_byte = selective_xor(image_byte, keystream)
return Image.frombytes(cipher_image.mode, cipher_image.size, encrypted_byte)
def decrypt(cipher_image, p, q, m, init, r):
keystream = logistic_map(init, r, cipher_image.size[0]**2)
image_byte = np.array(cipher_image).flatten()
decrypted_byte = selective_xor(image_byte, keystream)
plain_image = Image.frombytes(cipher_image.mode, cipher_image.size, decrypted_byte)
plain_image = inv_ACM(plain_image, p, q, m)
return plain_image