├── ImageEncryptionSchemeAttacks ├── SKKAttack │ ├── decrypt_diffkey_adv.m │ ├── decrypt_diffkey_basic.m │ ├── decrypt_samekey.m │ ├── encrypt.m │ ├── helper_pic.m │ ├── imgs │ │ ├── bird.PNG │ │ └── horse.PNG │ └── shuffle_pic.m └── TanakaAttack │ ├── decrypt.m │ ├── encrypt.m │ ├── helper_pics.m │ └── imgs │ ├── bird.PNG │ └── horse.PNG ├── LICENSE └── README.md /ImageEncryptionSchemeAttacks/SKKAttack/decrypt_diffkey_adv.m: -------------------------------------------------------------------------------- 1 | % Decrypts input image for SKK different keys variant using advanced attack 2 | % Replace string in enc imread with encrypted input image 3 | % Replace RGB vector in initial decrypted pixel with starting value 4 | % Outputs: imgs/dec.png, input image decrypted; imgs/dec_gray.png, 5 | % grayscale version 6 | 7 | enc = imread('imgs/enc_shuffle.png'); 8 | size_x = size(enc, 1); 9 | size_y = size(enc, 2); 10 | 11 | dec = zeros(size_x, size_y, 3, 'uint8'); 12 | dec(1, 1, 1:3) = [141, 195, 241]; % initial decrypted pixel 13 | 14 | for j = 2:size_y 15 | compare = int16(dec(1, j - 1, 1:3)); 16 | 17 | perm = zeros(6, 8, 3, 'int16'); 18 | 19 | perm(1, 1, 1:3) = int16([enc(1, j, 1), enc(1, j, 2), enc(1, j, 3)]); 20 | perm(2, 1, 1:3) = int16([enc(1, j, 1), enc(1, j, 3), enc(1, j, 2)]); 21 | perm(3, 1, 1:3) = int16([enc(1, j, 2), enc(1, j, 1), enc(1, j, 3)]); 22 | perm(4, 1, 1:3) = int16([enc(1, j, 2), enc(1, j, 3), enc(1, j, 1)]); 23 | perm(5, 1, 1:3) = int16([enc(1, j, 3), enc(1, j, 1), enc(1, j, 2)]); 24 | perm(6, 1, 1:3) = int16([enc(1, j, 3), enc(1, j, 2), enc(1, j, 1)]); 25 | 26 | for row = 1:6 27 | for bitflip = 0:7 28 | bit3 = mod(bitflip, 2); 29 | bit2 = mod(idivide(int16(bitflip), 2), 2); 30 | bit1 = mod(idivide(int16(bitflip), 4), 2); 31 | 32 | if bit1 == 0 33 | perm(row, bitflip + 1, 1) = perm(row, 1, 1); 34 | else 35 | perm(row, bitflip + 1, 1) = bitxor(perm(row, 1, 1), 255); 36 | end 37 | 38 | if bit2 == 0 39 | perm(row, bitflip + 1, 2) = perm(row, 1, 2); 40 | else 41 | perm(row, bitflip + 1, 2) = bitxor(perm(row, 1, 2), 255); 42 | end 43 | 44 | if bit3 == 0 45 | perm(row, bitflip + 1, 3) = perm(row, 1, 3); 46 | else 47 | perm(row, bitflip + 1, 3) = bitxor(perm(row, 1, 3), 255); 48 | end 49 | end 50 | end 51 | 52 | diff = zeros(6, 8, 'int16'); 53 | 54 | for row = 1:6 55 | for col = 1:8 56 | diff(row, col) = sum(abs(compare - perm(row, col, 1:3))); 57 | end 58 | end 59 | 60 | min_diff = min(diff, [], 'all'); 61 | 62 | for row = 1:6 63 | for col = 1:8 64 | if diff(row, col) == min_diff 65 | dec(1, j, 1:3) = perm(row, col, 1:3); 66 | break 67 | end 68 | end 69 | end 70 | end 71 | 72 | for i = 2:size_x 73 | for j = 1:size_y 74 | compare = int16(dec(i - 1, j, 1:3)); 75 | 76 | perm = zeros(6, 8, 3, 'int16'); 77 | 78 | perm(1, 1, 1:3) = int16([enc(i, j, 1), enc(i, j, 2), enc(i, j, 3)]); 79 | perm(2, 1, 1:3) = int16([enc(i, j, 1), enc(i, j, 3), enc(i, j, 2)]); 80 | perm(3, 1, 1:3) = int16([enc(i, j, 2), enc(i, j, 1), enc(i, j, 3)]); 81 | perm(4, 1, 1:3) = int16([enc(i, j, 2), enc(i, j, 3), enc(i, j, 1)]); 82 | perm(5, 1, 1:3) = int16([enc(i, j, 3), enc(i, j, 1), enc(i, j, 2)]); 83 | perm(6, 1, 1:3) = int16([enc(i, j, 3), enc(i, j, 2), enc(i, j, 1)]); 84 | 85 | for row = 1:6 86 | for bitflip = 0:7 87 | bit3 = mod(bitflip, 2); 88 | bit2 = mod(idivide(int16(bitflip), 2), 2); 89 | bit1 = mod(idivide(int16(bitflip), 4), 2); 90 | 91 | if bit1 == 0 92 | perm(row, bitflip + 1, 1) = perm(row, 1, 1); 93 | else 94 | perm(row, bitflip + 1, 1) = bitxor(perm(row, 1, 1), 255); 95 | end 96 | 97 | if bit2 == 0 98 | perm(row, bitflip + 1, 2) = perm(row, 1, 2); 99 | else 100 | perm(row, bitflip + 1, 2) = bitxor(perm(row, 1, 2), 255); 101 | end 102 | 103 | if bit3 == 0 104 | perm(row, bitflip + 1, 3) = perm(row, 1, 3); 105 | else 106 | perm(row, bitflip + 1, 3) = bitxor(perm(row, 1, 3), 255); 107 | end 108 | end 109 | end 110 | 111 | diff = zeros(6, 8, 'int16'); 112 | 113 | for row = 1:6 114 | for col = 1:8 115 | diff(row, col) = sum(abs(compare - perm(row, col, 1:3))); 116 | end 117 | end 118 | 119 | min_diff = min(diff, [], 'all'); 120 | 121 | for row = 1:6 122 | for col = 1:8 123 | if diff(row, col) == min_diff 124 | dec(i, j, 1:3) = perm(row, col, 1:3); 125 | break 126 | end 127 | end 128 | end 129 | end 130 | end 131 | 132 | imwrite(dec, 'imgs/dec.png'); 133 | imwrite(rgb2gray(dec), 'imgs/dec_gray.png'); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/SKKAttack/decrypt_diffkey_basic.m: -------------------------------------------------------------------------------- 1 | % Decrypts input image for SKK different keys variant using basic attack 2 | % Replace string in enc imread with encrypted input image 3 | % Outputs: imgs/dec.png, input image decrypted; imgs/dec_gray.png, 4 | % grayscale version 5 | 6 | enc = imread('imgs/enc_shuffle.png'); 7 | size_x = size(enc, 1); 8 | size_y = size(enc, 2); 9 | 10 | dec = zeros(size_x, size_y, 3, 'uint8'); 11 | 12 | for i = 1:size_x 13 | for j = 1:size_y 14 | for rgb = 1:3 15 | val = enc(i, j, rgb); 16 | if val <= 127 17 | dec(i, j, rgb) = val; 18 | else 19 | dec(i, j, rgb) = bitxor(val, 255); 20 | end 21 | end 22 | end 23 | end 24 | 25 | imwrite(dec, 'imgs/dec.png'); 26 | imwrite(rgb2gray(dec), 'imgs/dec_gray.png'); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/SKKAttack/decrypt_samekey.m: -------------------------------------------------------------------------------- 1 | % Decrypts input image and helper image for SKK same key variant 2 | % Replace string in helper_enc imread with encrypted helper image 3 | % (e.g. run encrypt.m on helper.png, rename output enc_shuffle_helper.png) 4 | % Replace string in attack_enc imread with encrypted input image 5 | % Outputs: imgs/helper_dec.png, helper image decrypted; 6 | % imgs/attack_dec.png, input image decrypted 7 | 8 | helper_enc = imread('imgs/enc_shuffle_helper.png'); 9 | attack_enc = imread('imgs/enc_shuffle.png'); 10 | size_x = size(attack_enc, 1); 11 | size_y = size(attack_enc, 2); 12 | 13 | for i = 1:size_x 14 | for j = 1:size_y 15 | for rgb = 1:3 16 | if helper_enc(i, j, rgb) > 127 17 | helper_enc(i, j, rgb) = bitxor(helper_enc(i, j, rgb), 255); 18 | attack_enc(i, j, rgb) = bitxor(attack_enc(i, j, rgb), 255); 19 | end 20 | end 21 | helper_tmp = helper_enc(i, j, 1:3); 22 | attack_tmp = attack_enc(i, j, 1:3); 23 | for rgb_val = 1:3 24 | for rgb_ind = 1:3 25 | if helper_tmp(rgb_ind) == rgb_val 26 | helper_enc(i, j, rgb_val) = helper_tmp(rgb_ind); 27 | attack_enc(i, j, rgb_val) = attack_tmp(rgb_ind); 28 | break 29 | end 30 | end 31 | end 32 | end 33 | end 34 | 35 | imwrite(helper_enc, 'imgs/helper_dec.png'); 36 | imwrite(attack_enc, 'imgs/attack_dec.png'); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/SKKAttack/encrypt.m: -------------------------------------------------------------------------------- 1 | % Encrypts input image with specifications in SKK paper 2 | % Replace string in img imread with input image 3 | % Replace number in rng with seed for random number generator 4 | % Outputs: imgs/enc_negpos.png, image encrypted with negative-positive 5 | % transformation; imgs/enc_shuffle.png, image encrypted with optional 6 | % shuffle step 7 | 8 | img = imread('imgs/bird.png'); 9 | size_x = size(img, 1); 10 | size_y = size(img, 2); 11 | 12 | enc_negpos = zeros(size_x, size_y, 3, 'uint8'); 13 | 14 | rng(8888); 15 | 16 | for i = 1:size_x 17 | for j = 1:size_y 18 | for rgb = 1:3 19 | negpos = rand; 20 | if negpos < 0.5 21 | enc_negpos(i, j, rgb) = img(i, j, rgb); 22 | else 23 | enc_negpos(i, j, rgb) = bitxor(img(i, j, rgb), 255); 24 | end 25 | end 26 | end 27 | end 28 | 29 | imwrite(enc_negpos, 'imgs/enc_negpos.png'); 30 | 31 | enc_shuffle = enc_negpos; 32 | 33 | for i = 1:size_x 34 | for j = 1:size_y 35 | shuffle = randi(6); 36 | if shuffle == 1 37 | enc_shuffle(i, j, 1) = enc_negpos(i, j, 1); 38 | enc_shuffle(i, j, 2) = enc_negpos(i, j, 2); 39 | enc_shuffle(i, j, 3) = enc_negpos(i, j, 3); 40 | elseif shuffle == 2 41 | enc_shuffle(i, j, 1) = enc_negpos(i, j, 1); 42 | enc_shuffle(i, j, 2) = enc_negpos(i, j, 3); 43 | enc_shuffle(i, j, 3) = enc_negpos(i, j, 2); 44 | elseif shuffle == 3 45 | enc_shuffle(i, j, 1) = enc_negpos(i, j, 2); 46 | enc_shuffle(i, j, 2) = enc_negpos(i, j, 1); 47 | enc_shuffle(i, j, 3) = enc_negpos(i, j, 3); 48 | elseif shuffle == 4 49 | enc_shuffle(i, j, 1) = enc_negpos(i, j, 2); 50 | enc_shuffle(i, j, 2) = enc_negpos(i, j, 3); 51 | enc_shuffle(i, j, 3) = enc_negpos(i, j, 1); 52 | elseif shuffle == 5 53 | enc_shuffle(i, j, 1) = enc_negpos(i, j, 3); 54 | enc_shuffle(i, j, 2) = enc_negpos(i, j, 1); 55 | enc_shuffle(i, j, 3) = enc_negpos(i, j, 2); 56 | else 57 | enc_shuffle(i, j, 1) = enc_negpos(i, j, 3); 58 | enc_shuffle(i, j, 2) = enc_negpos(i, j, 2); 59 | enc_shuffle(i, j, 3) = enc_negpos(i, j, 1); 60 | end 61 | end 62 | end 63 | 64 | imwrite(enc_shuffle, 'imgs/enc_shuffle.png'); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/SKKAttack/helper_pic.m: -------------------------------------------------------------------------------- 1 | % Creates helper image for SKK same key variant attack 2 | % Replace size_x, size_y with x and y length respectively of input image 3 | % Outputs: imgs/helper.png, helper image 4 | 5 | size_x = 96; 6 | size_y = 96; 7 | helper = zeros(size_x, size_y, 3, 'uint8'); 8 | 9 | for i = 1:size_x 10 | for j = 1:size_y 11 | helper(i, j, 1) = 1; 12 | helper(i, j, 2) = 2; 13 | helper(i, j, 3) = 3; 14 | end 15 | end 16 | 17 | imwrite(helper, 'imgs/helper.png'); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/SKKAttack/imgs/bird.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahchang98/image-encryption-scheme-attacks/cd0f35baebe3a2a9b041aa97f003506868339388/ImageEncryptionSchemeAttacks/SKKAttack/imgs/bird.PNG -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/SKKAttack/imgs/horse.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahchang98/image-encryption-scheme-attacks/cd0f35baebe3a2a9b041aa97f003506868339388/ImageEncryptionSchemeAttacks/SKKAttack/imgs/horse.PNG -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/SKKAttack/shuffle_pic.m: -------------------------------------------------------------------------------- 1 | % Permutes the color components of each pixel in the input image 2 | % Replace string in img imread with input image 3 | % Replace number in rng with seed for random number generator 4 | % Outputs: imgs/shuffle.png, shuffled image 5 | 6 | img = imread('imgs/bird.png'); 7 | size_x = size(img, 1); 8 | size_y = size(img, 2); 9 | 10 | rng(8888); 11 | 12 | shuffle = zeros(size_x, size_y, 3, 'uint8'); 13 | 14 | for i = 1:size_x 15 | for j = 1:size_y 16 | shuffle_num = randi(6); 17 | if shuffle_num == 1 18 | shuffle(i, j, 1) = img(i, j, 1); 19 | shuffle(i, j, 2) = img(i, j, 2); 20 | shuffle(i, j, 3) = img(i, j, 3); 21 | elseif shuffle_num == 2 22 | shuffle(i, j, 1) = img(i, j, 1); 23 | shuffle(i, j, 2) = img(i, j, 3); 24 | shuffle(i, j, 3) = img(i, j, 2); 25 | elseif shuffle_num == 3 26 | shuffle(i, j, 1) = img(i, j, 2); 27 | shuffle(i, j, 2) = img(i, j, 1); 28 | shuffle(i, j, 3) = img(i, j, 3); 29 | elseif shuffle_num == 4 30 | shuffle(i, j, 1) = img(i, j, 2); 31 | shuffle(i, j, 2) = img(i, j, 3); 32 | shuffle(i, j, 3) = img(i, j, 1); 33 | elseif shuffle_num == 5 34 | shuffle(i, j, 1) = img(i, j, 3); 35 | shuffle(i, j, 2) = img(i, j, 1); 36 | shuffle(i, j, 3) = img(i, j, 2); 37 | else 38 | shuffle(i, j, 1) = img(i, j, 3); 39 | shuffle(i, j, 2) = img(i, j, 2); 40 | shuffle(i, j, 3) = img(i, j, 1); 41 | end 42 | end 43 | end 44 | 45 | imwrite(shuffle, 'imgs/shuffle.png'); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/TanakaAttack/decrypt.m: -------------------------------------------------------------------------------- 1 | % Decrypts input image with Tanaka scheme, block size 4x4 2 | % Replace string in helpers_enc imread with encrypted helper images 3 | % (e.g. run encrypt.m on output of helper_pics.m) 4 | % Replace string in attack_enc imread with encrypted input image 5 | % Outputs: imgs/helper_dec.png, helper image decrypted; 6 | % imgs/attack_dec.png, input image decrypted 7 | 8 | helpers_enc = zeros(16, 4, 4, 3, 'uint8'); 9 | for helper_ind = 1:16 10 | helpers_enc(helper_ind, 1:4, 1:4, 1:3) = imread(sprintf('imgs/ScrambleRandBlock_enc_helper%d.png', helper_ind)); 11 | end 12 | 13 | attack_enc = imread('imgs/ScrambleRandBlock_enc.png'); 14 | 15 | block_stop = size(attack_enc, 1)/4 - 1; 16 | 17 | for helper_ind = 1:16 18 | for i = 1:4 19 | for j = 1:4 20 | for rgb = 1:3 21 | if helpers_enc(helper_ind, i, j, rgb) > 127 && helpers_enc(helper_ind, i, j, rgb) ~= 255 22 | helpers_enc(helper_ind, i, j, rgb) = 255 - helpers_enc(helper_ind, i, j, rgb); 23 | for i_block = 0:block_stop 24 | for j_block = 0:block_stop 25 | attack_enc(4*i_block + i, 4*j_block + j, rgb) = 255 - attack_enc(4*i_block + i, 4*j_block + j, rgb); 26 | end 27 | end 28 | end 29 | end 30 | end 31 | end 32 | end 33 | 34 | attack_dec = attack_enc; 35 | helpers_dec = helpers_enc; 36 | 37 | for helper_ind = 1:16 38 | for value = 1:3 39 | i_match = 0; 40 | j_match = 0; 41 | rgb_match = 0; 42 | 43 | for i = 1:4 44 | for j = 1:4 45 | for rgb = 1:3 46 | if helpers_dec(helper_ind, i, j, rgb) == value 47 | i_match = i; 48 | j_match = j; 49 | rgb_match = rgb; 50 | end 51 | end 52 | end 53 | end 54 | 55 | if i_match ~= 0 56 | i_spot = idivide(helper_ind - 1, uint8(4)) + 1; 57 | j_spot = mod(helper_ind - 1, 4) + 1; 58 | rgb_spot = value; 59 | 60 | for i_block = 0:block_stop 61 | for j_block = 0:block_stop 62 | attack_dec(4*i_block + i_spot, 4*j_block + j_spot, rgb_spot) = attack_enc(4*i_block + i_match, 4*j_block + j_match, rgb_match); 63 | end 64 | end 65 | end 66 | end 67 | end 68 | 69 | imwrite(attack_dec, 'imgs/attack_dec.png'); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/TanakaAttack/encrypt.m: -------------------------------------------------------------------------------- 1 | % Encrypts input image and helper images with Tanaka scheme and optional 2 | % reversal step, block size 4x4 3 | % Replace number in key with seed for random number generator 4 | % Replace string in helper_img imread with helper images 5 | % (e.g. output of helper_pics.m) 6 | % Replace string in img imread with input image 7 | % Outputs: imgs/ScrambleRandBlock_enc_helper[1-16].png, helper images 8 | % encrypted; imgs/ScrambleRandBlock_enc.png, input image encrypted 9 | % Dependencies: Files found at link below should be in the same directory 10 | % https://www.mathworks.com/matlabcentral/fileexchange/66472-image-shuffle 11 | 12 | key = uint32(8888); 13 | 14 | for helper_ind = 1:16 15 | helper_img = imread(sprintf('imgs/helper%d.png', helper_ind)); 16 | helper_ims = imScrambleRandBlock(key, [4, 4]); 17 | helper_enc = helper_ims.enc(helper_img); 18 | 19 | imwrite(helper_enc, sprintf('imgs/ScrambleRandBlock_enc_helper%d.png', helper_ind)); 20 | end 21 | 22 | img = imread('imgs/horse.png'); 23 | ims = imScrambleRandBlock(key, [4, 4]); 24 | enc = ims.enc(img); 25 | 26 | imwrite(enc, sprintf('imgs/ScrambleRandBlock_enc.png', key ) ); -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/TanakaAttack/helper_pics.m: -------------------------------------------------------------------------------- 1 | % Creates helper images for Tanaka scheme attack, block size 4x4 2 | % Outputs: imgs/helper[1-16].png, helper images 1-16 3 | 4 | helpers = zeros(16, 4, 4, 3, 'uint8'); 5 | 6 | for helper_ind = 1:16 7 | x = idivide(helper_ind - 1, uint8(4)) + 1; 8 | y = mod(helper_ind - 1, 4) + 1; 9 | 10 | for i = 1:4 11 | for j = 1:4 12 | if i == x && j == y 13 | helpers(helper_ind, i, j, 1) = 1; 14 | helpers(helper_ind, i, j, 2) = 2; 15 | helpers(helper_ind, i, j, 3) = 3; 16 | else 17 | helpers(helper_ind, i, j, 1) = 0; 18 | helpers(helper_ind, i, j, 2) = 0; 19 | helpers(helper_ind, i, j, 3) = 0; 20 | end 21 | end 22 | end 23 | end 24 | 25 | for helper_ind = 1:16 26 | imwrite(reshape(helpers(helper_ind, 1:4, 1:4, 1:3), [4, 4, 3]), sprintf('imgs/helper%d.png', helper_ind)); 27 | end -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/TanakaAttack/imgs/bird.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahchang98/image-encryption-scheme-attacks/cd0f35baebe3a2a9b041aa97f003506868339388/ImageEncryptionSchemeAttacks/TanakaAttack/imgs/bird.PNG -------------------------------------------------------------------------------- /ImageEncryptionSchemeAttacks/TanakaAttack/imgs/horse.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahchang98/image-encryption-scheme-attacks/cd0f35baebe3a2a9b041aa97f003506868339388/ImageEncryptionSchemeAttacks/TanakaAttack/imgs/horse.PNG -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Habeen Chang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image Encryption Scheme Attacks 2 | Attacks against proposed image encryption schemes 3 | 4 | # Dependencies 5 | To run the Tanaka encryption, the files found at the link below should be in the same directory as encrypt.m 6 | https://www.mathworks.com/matlabcentral/fileexchange/66472-image-shuffle 7 | --------------------------------------------------------------------------------