├── images ├── house.tiff ├── 4.1.04.tiff ├── 4.1.05.tiff ├── car.jpg └── ct-tesla-new-roadster-20171117.jpg ├── README.md └── encr.py /images/house.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tafseerahmed/image-Encryption-dna-encoding/HEAD/images/house.tiff -------------------------------------------------------------------------------- /images/4.1.04.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tafseerahmed/image-Encryption-dna-encoding/HEAD/images/4.1.04.tiff -------------------------------------------------------------------------------- /images/4.1.05.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tafseerahmed/image-Encryption-dna-encoding/HEAD/images/4.1.05.tiff -------------------------------------------------------------------------------- /images/car.jpg: -------------------------------------------------------------------------------- 1 | ![ct-tesla-new-roadster-20171117](https://user-images.githubusercontent.com/12884292/33086083-9d6fe5de-cf0c-11e7-9047-6c5b12515ab6.jpg) 2 | -------------------------------------------------------------------------------- /images/ct-tesla-new-roadster-20171117.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tafseerahmed/image-Encryption-dna-encoding/HEAD/images/ct-tesla-new-roadster-20171117.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # image-Encryption-dna-encoding 2 | Minor Project, create a image encryption program using Dna encoding and chaos map 3 | 4 | 5 | To run the program, type in console "python encr.py", select the image to encrpyt and thats it!. "enc.jpg" is encrypted image and the recovered image is "recovered.jpg" 6 | -------------------------------------------------------------------------------- /encr.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import tkinter as tk 3 | from tkinter import filedialog 4 | import hashlib 5 | import binascii 6 | import textwrap 7 | import cv2 8 | import numpy as np 9 | from scipy.integrate import odeint 10 | import matplotlib.pyplot as plt 11 | from mpl_toolkits.mplot3d import Axes3D 12 | import sys 13 | from importlib import reload 14 | from bisect import bisect_left as bsearch 15 | 16 | ''' 17 | GLOBAL Constants 18 | ''' 19 | # Lorenz paramters and initial conditions 20 | a, b, c = 10, 2.667, 28 21 | x0, y0, z0 = 0, 0, 0 22 | 23 | #DNA-Encoding RULE #1 A = 00, T=01, G=10, C=11 24 | dna={} 25 | dna["00"]="A" 26 | dna["01"]="T" 27 | dna["10"]="G" 28 | dna["11"]="C" 29 | dna["A"]=[0,0] 30 | dna["T"]=[0,1] 31 | dna["G"]=[1,0] 32 | dna["C"]=[1,1] 33 | #DNA xor 34 | dna["AA"]=dna["TT"]=dna["GG"]=dna["CC"]="A" 35 | dna["AG"]=dna["GA"]=dna["TC"]=dna["CT"]="G" 36 | dna["AC"]=dna["CA"]=dna["GT"]=dna["TG"]="C" 37 | dna["AT"]=dna["TA"]=dna["CG"]=dna["GC"]="T" 38 | # Maximum time point and total number of time points 39 | tmax, N = 100, 10000 40 | 41 | def lorenz(X, t, a, b, c): 42 | x, y, z = X 43 | x_dot = -a*(x - y) 44 | y_dot = c*x - y - x*z 45 | z_dot = -b*z + x*y 46 | return x_dot, y_dot, z_dot 47 | 48 | def image_selector(): #returns path to selected image 49 | path = "NULL" 50 | root = tk.Tk() 51 | root.withdraw() # we don't want a full GUI, so keep the root window from appearing 52 | path = filedialog.askopenfilename() # show an "Open" dialog box and return the path to the selected file 53 | if path!="NULL": 54 | print("Image loaded!") 55 | else: 56 | print("Error Image not loaded!") 57 | return path 58 | 59 | def split_into_rgb_channels(image): 60 | red = image[:,:,2] 61 | green = image[:,:,1] 62 | blue = image[:,:,0] 63 | return red, green, blue 64 | 65 | #Secure key generation 66 | def securekey (iname): 67 | img = Image.open(iname) 68 | m, n = img.size 69 | print("pixels: {0} width: {2} height: {1} ".format(m*n, m, n)) 70 | pix = img.load() 71 | plainimage = list() #_plainimage contains all the rgb values continuously 72 | for y in range(n): 73 | for x in range(m): 74 | for k in range(0,3): 75 | plainimage.append(pix[x,y][k]) 76 | key = hashlib.sha256() #key is made a hash.sha256 object 77 | key.update(bytearray(plainimage)) #image data is fed to generate digest 78 | return key.hexdigest() ,m ,n 79 | 80 | def update_lorentz (key): 81 | key_bin = bin(int(key, 16))[2:].zfill(256) #covert hex key digest to binary 82 | k={} #key dictionary 83 | key_32_parts=textwrap.wrap(key_bin, 8) #slicing key into 8 parts 84 | num=1 85 | for i in key_32_parts: 86 | k["k{0}".format(num)]=i 87 | num = num + 1 88 | t1 = t2 = t3 = 0 89 | for i in range (1,12): 90 | t1=t1^int(k["k{0}".format(i)],2) 91 | for i in range (12,23): 92 | t2=t2^int(k["k{0}".format(i)],2) 93 | for i in range (23,33): 94 | t3=t3^int(k["k{0}".format(i)],2) 95 | global x0 ,y0, z0 96 | x0=x0 + t1/256 97 | y0=y0 + t2/256 98 | z0=z0 + t3/256 99 | 100 | def decompose_matrix(iname): 101 | image = cv2.imread(iname) 102 | blue,green,red = split_into_rgb_channels(image) 103 | for values, channel in zip((red, green, blue), (2,1,0)): 104 | img = np.zeros((values.shape[0], values.shape[1]), dtype = np.uint8) 105 | img[:,:] = (values) 106 | if channel == 0: 107 | B = np.asmatrix(img) 108 | elif channel == 1: 109 | G = np.asmatrix(img) 110 | else: 111 | R = np.asmatrix(img) 112 | return B,G,R 113 | 114 | def dna_encode(b,g,r): 115 | 116 | b = np.unpackbits(b,axis=1) 117 | g = np.unpackbits(g,axis=1) 118 | r = np.unpackbits(r,axis=1) 119 | m,n = b.shape 120 | r_enc= np.chararray((m,int(n/2))) 121 | g_enc= np.chararray((m,int(n/2))) 122 | b_enc= np.chararray((m,int(n/2))) 123 | 124 | for color,enc in zip((b,g,r),(b_enc,g_enc,r_enc)): 125 | idx=0 126 | for j in range(0,m): 127 | for i in range(0,n,2): 128 | enc[j,idx]=dna["{0}{1}".format(color[j,i],color[j,i+1])] 129 | idx+=1 130 | if (i==n-2): 131 | idx=0 132 | break 133 | 134 | b_enc=b_enc.astype(str) 135 | g_enc=g_enc.astype(str) 136 | r_enc=r_enc.astype(str) 137 | return b_enc,g_enc,r_enc 138 | 139 | def key_matrix_encode(key,b): 140 | #encoded key matrix 141 | b = np.unpackbits(b,axis=1) 142 | m,n = b.shape 143 | key_bin = bin(int(key, 16))[2:].zfill(256) 144 | Mk = np.zeros((m,n),dtype=np.uint8) 145 | x=0 146 | for j in range(0,m): 147 | for i in range(0,n): 148 | Mk[j,i]=key_bin[x%256] 149 | x+=1 150 | 151 | Mk_enc=np.chararray((m,int(n/2))) 152 | idx=0 153 | for j in range(0,m): 154 | for i in range(0,n,2): 155 | if idx==(n/2): 156 | idx=0 157 | Mk_enc[j,idx]=dna["{0}{1}".format(Mk[j,i],Mk[j,i+1])] 158 | idx+=1 159 | Mk_enc=Mk_enc.astype(str) 160 | return Mk_enc 161 | 162 | def xor_operation(b,g,r,mk): 163 | m,n = b.shape 164 | bx=np.chararray((m,n)) 165 | gx=np.chararray((m,n)) 166 | rx=np.chararray((m,n)) 167 | b=b.astype(str) 168 | g=g.astype(str) 169 | r=r.astype(str) 170 | for i in range(0,m): 171 | for j in range (0,n): 172 | bx[i,j] = dna["{0}{1}".format(b[i,j],mk[i,j])] 173 | gx[i,j] = dna["{0}{1}".format(g[i,j],mk[i,j])] 174 | rx[i,j] = dna["{0}{1}".format(r[i,j],mk[i,j])] 175 | 176 | bx=bx.astype(str) 177 | gx=gx.astype(str) 178 | rx=rx.astype(str) 179 | return bx,gx,rx 180 | 181 | def gen_chaos_seq(m,n): 182 | global x0,y0,z0,a,b,c,N 183 | N=m*n*4 184 | x= np.array((m,n*4)) 185 | y= np.array((m,n*4)) 186 | z= np.array((m,n*4)) 187 | t = np.linspace(0, tmax, N) 188 | f = odeint(lorenz, (x0, y0, z0), t, args=(a, b, c)) 189 | x, y, z = f.T 190 | x=x[:(N)] 191 | y=y[:(N)] 192 | z=z[:(N)] 193 | return x,y,z 194 | 195 | def plot(x,y,z): 196 | fig = plt.figure() 197 | ax = fig.gca(projection='3d') 198 | s = 100 199 | c = np.linspace(0,1,N) 200 | for i in range(0,N-s,s): 201 | ax.plot(x[i:i+s+1], y[i:i+s+1], z[i:i+s+1], color=(1-c[i],c[i],1), alpha=0.4) 202 | ax.set_axis_off() 203 | plt.show() 204 | 205 | def sequence_indexing(x,y,z): 206 | n=len(x) 207 | fx=np.zeros((n),dtype=np.uint32) 208 | fy=np.zeros((n),dtype=np.uint32) 209 | fz=np.zeros((n),dtype=np.uint32) 210 | seq=sorted(x) 211 | for k1 in range(0,n): 212 | t = x[k1] 213 | k2 = bsearch(seq, t) 214 | fx[k1]=k2 215 | seq=sorted(y) 216 | for k1 in range(0,n): 217 | t = y[k1] 218 | k2 = bsearch(seq, t) 219 | fy[k1]=k2 220 | seq=sorted(z) 221 | for k1 in range(0,n): 222 | t = z[k1] 223 | k2 = bsearch(seq, t) 224 | fz[k1]=k2 225 | return fx,fy,fz 226 | 227 | def scramble(fx,fy,fz,b,r,g): 228 | p,q=b.shape 229 | size = p*q 230 | bx=b.reshape(size).astype(str) 231 | gx=g.reshape(size).astype(str) 232 | rx=r.reshape(size).astype(str) 233 | bx_s=np.chararray((size)) 234 | gx_s=np.chararray((size)) 235 | rx_s=np.chararray((size)) 236 | 237 | for i in range(size): 238 | idx = fz[i] 239 | bx_s[i] = bx[idx] 240 | for i in range(size): 241 | idx = fy[i] 242 | gx_s[i] = gx[idx] 243 | for i in range(size): 244 | idx = fx[i] 245 | rx_s[i] = rx[idx] 246 | bx_s=bx_s.astype(str) 247 | gx_s=gx_s.astype(str) 248 | rx_s=rx_s.astype(str) 249 | 250 | b_s=np.chararray((p,q)) 251 | g_s=np.chararray((p,q)) 252 | r_s=np.chararray((p,q)) 253 | 254 | b_s=bx_s.reshape(p,q) 255 | g_s=gx_s.reshape(p,q) 256 | r_s=rx_s.reshape(p,q) 257 | return b_s,g_s,r_s 258 | 259 | def scramble_new(fx,fy,fz,b,g,r): 260 | p,q=b.shape 261 | size = p*q 262 | bx=b.reshape(size) 263 | gx=g.reshape(size) 264 | rx=r.reshape(size) 265 | 266 | bx_s=b.reshape(size) 267 | gx_s=g.reshape(size) 268 | rx_s=r.reshape(size) 269 | 270 | bx=bx.astype(str) 271 | gx=gx.astype(str) 272 | rx=rx.astype(str) 273 | bx_s=bx_s.astype(str) 274 | gx_s=gx_s.astype(str) 275 | rx_s=rx_s.astype(str) 276 | 277 | for i in range(size): 278 | idx = fz[i] 279 | bx_s[idx] = bx[i] 280 | for i in range(size): 281 | idx = fy[i] 282 | gx_s[idx] = gx[i] 283 | for i in range(size): 284 | idx = fx[i] 285 | rx_s[idx] = rx[i] 286 | 287 | b_s=np.chararray((p,q)) 288 | g_s=np.chararray((p,q)) 289 | r_s=np.chararray((p,q)) 290 | 291 | b_s=bx_s.reshape(p,q) 292 | g_s=gx_s.reshape(p,q) 293 | r_s=rx_s.reshape(p,q) 294 | 295 | return b_s,g_s,r_s 296 | 297 | 298 | def dna_decode(b,g,r): 299 | m,n = b.shape 300 | r_dec= np.ndarray((m,int(n*2)),dtype=np.uint8) 301 | g_dec= np.ndarray((m,int(n*2)),dtype=np.uint8) 302 | b_dec= np.ndarray((m,int(n*2)),dtype=np.uint8) 303 | for color,dec in zip((b,g,r),(b_dec,g_dec,r_dec)): 304 | for j in range(0,m): 305 | for i in range(0,n): 306 | dec[j,2*i]=dna["{0}".format(color[j,i])][0] 307 | dec[j,2*i+1]=dna["{0}".format(color[j,i])][1] 308 | b_dec=(np.packbits(b_dec,axis=-1)) 309 | g_dec=(np.packbits(g_dec,axis=-1)) 310 | r_dec=(np.packbits(r_dec,axis=-1)) 311 | return b_dec,g_dec,r_dec 312 | 313 | def xor_operation_new(b,g,r,mk): 314 | m,n = b.shape 315 | bx=np.chararray((m,n)) 316 | gx=np.chararray((m,n)) 317 | rx=np.chararray((m,n)) 318 | b=b.astype(str) 319 | g=g.astype(str) 320 | r=r.astype(str) 321 | for i in range(0,m): 322 | for j in range (0,n): 323 | bx[i,j] = dna["{0}{1}".format(b[i,j],mk[i,j])] 324 | gx[i,j] = dna["{0}{1}".format(g[i,j],mk[i,j])] 325 | rx[i,j] = dna["{0}{1}".format(r[i,j],mk[i,j])] 326 | 327 | bx=bx.astype(str) 328 | gx=gx.astype(str) 329 | rx=rx.astype(str) 330 | return bx,gx,rx 331 | 332 | def recover_image(b,g,r,iname): 333 | img = cv2.imread(iname) 334 | img[:,:,2] = r 335 | img[:,:,1] = g 336 | img[:,:,0] = b 337 | cv2.imwrite(("enc.jpg"), img) 338 | print("saved ecrypted image as enc.jpg") 339 | return img 340 | 341 | def decrypt(image,fx,fy,fz,fp,Mk,bt,gt,rt): 342 | r,g,b=split_into_rgb_channels(image) 343 | p,q = rt.shape 344 | benc,genc,renc=dna_encode(b,g,r) 345 | bs,gs,rs=scramble_new(fx,fy,fz,benc,genc,renc) 346 | bx,rx,gx=xor_operation_new(bs,gs,rs,Mk) 347 | blue,green,red=dna_decode(bx,gx,rx) 348 | green,red = red, green 349 | img=np.zeros((p,q,3),dtype=np.uint8) 350 | img[:,:,0] = red 351 | img[:,:,1] = green 352 | img[:,:,2] = blue 353 | cv2.imwrite(("Recovered.jpg"), img) 354 | 355 | 356 | #program exec9 357 | if (__name__ == "__main__"): 358 | file_path = image_selector() 359 | print(file_path) 360 | key,m,n = securekey(file_path) 361 | update_lorentz(key) 362 | blue,green,red=decompose_matrix(file_path) 363 | blue_e,green_e,red_e=dna_encode(blue,green,red) 364 | Mk_e = key_matrix_encode(key,blue) 365 | blue_final, green_final, red_final = xor_operation(blue_e,green_e,red_e,Mk_e) 366 | x,y,z=gen_chaos_seq(m,n) 367 | fx,fy,fz=sequence_indexing(x,y,z) 368 | blue_scrambled,green_scrambled,red_scrambled = scramble(fx,fy,fz,blue_final,red_final,green_final) 369 | b,g,r=dna_decode(blue_scrambled,green_scrambled,red_scrambled) 370 | img=recover_image(b,g,r,file_path) 371 | 372 | print("decrypting...") 373 | decrypt(img,fx,fy,fz,file_path,Mk_e,blue,green,red) 374 | --------------------------------------------------------------------------------