In this encryption a matrix manipulation is used. A public key is needed to generate a matrix. Then for any input character, generated matrix is used as a lookup table. Here there is a simple implementation of this encryption method. This program encrypts/decrypts a binary file by the help of a public key. This method is really fast. A 107 MB file is encrypted in 98 seconds. Again this implementation is basic. Really much work is needed for robust encryption. Encrypted File Format File format size is 22 bytes. Order of first 22 bytes:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 P | L | A | Y | F | Encrypted file's name and extension (total 12 bytes) | | File size |
17'th byte = Input key's character size. Encrypted file is placed starting from 22'nd byte. Sample key: metal_money Repeated characters are truncated from input key.
ASCII representation of sample key is 109,101, 116, 97, 108, 95, 111, 110 and 121. These numbers are written in the starting elements of matrix. The rest unused ASCII numbers are written in sorted ascending order. A Playfair matrix for the key "metal_money" is at Table 2.
C Source Code
#include<stdio.h> #include<conio.h> #include<dos.h> #include<math.h> #include<time.h> #define info_size 5 struct plc { unsigned short i,j; } pl[256]; int num=0; long filesize(FILE *stream) { long curpos, length; curpos = ftell(stream); fseek(stream, 0L, SEEK_END); length = ftell(stream); fseek(stream, curpos, SEEK_SET); return length; } int make_matris(unsigned char len, unsigned char sifre[],unsigned char A[][16]) { unsigned char sif[50]; int i, j, k, L, n, ascii[256]; // array sifre[] is truncating. for(i=0;i<50;i++) sif[i] = 0; i = 1; n = 1; sif[0] = sifre[0]; while(i < len) { k = 0; for(j=0;j<i;j++) if (sifre[j] == sifre[i]) k = 1; if (k == 0) { // so character didn't used before sif[n] = sifre[i]; n++; } i++; } for(i=0;i<256;i++) ascii[i] = i; i = 0; j = 0; k = 0; while (k < n) { A[i][j] = sif[k]; ascii[sif[k]] = -1; if (j == 15) { i++; j = 0; } else j++; k++; } for(k=0;k<256;k++) if (ascii[k] != -1) { A[i][j] = ascii[k]; if (j == 15) { i++; j = 0; } else j++; } for(i=0;i<16;i++) for(j=0;j<16;j++) { pl[A[i][j]].i = i; pl[A[i][j]].j = j; } return 0; } int get_encrypted_data(unsigned char A[][16], unsigned char ch1, unsigned char ch2, unsigned char *ch3, unsigned char *ch4) { int i1, i2, j1, j2; i1 = pl[ch1].i; j1 = pl[ch1].j; i2 = pl[ch2].i; j2 = pl[ch2].j; if ((i1 != i2) && (j1 != j2)) { *ch3 = A[i1][j2]; *ch4 = A[i2][j1]; } else { if (i1 == i2) { j1++; j2++; if (j1 > 15) j1 = 0; if (j2 > 15) j2 = 0; } else if ( j1 == j2) { i1++; i2++; if (i1 > 15) i1 = 0; if (i2 > 15) i2 = 0; } *ch3 = A[i1][j1]; *ch4 = A[i2][j2]; } return 0; } int get_decrypted_data(unsigned char A[][16], unsigned char ch1, unsigned char ch2, unsigned char *ch3, unsigned char *ch4) { int i1, i2, j1, j2; i1 = pl[ch1].i; j1 = pl[ch1].j; i2 = pl[ch2].i; j2 = pl[ch2].j; if ((i1 != i2) && (j1 != j2)) { *ch3 = A[i1][j2]; *ch4 = A[i2][j1]; } else { if (i1 == i2) { j1--; j2--; if (j1 < 0) j1 = 15; if (j2 < 0) j2 = 15; } else if ( j1 == j2) { i1--; i2--; if (i1 < 0) i1 = 15; if (i2 < 0) i2 = 15; } *ch3 = A[i1][j1]; *ch4 = A[i2][j2]; } return 0; } void do_work() { unsigned char ch1, ch2, ch3, ch4; unsigned char sifre[50], src[13], dst[13], length, length_got, type[]={0,0,0,0,0,0,0,0,0,0,0,0}; // 12 byte char info[]="PLAYF"; // 5 byte char read_info[info_size], ch; int i, j, k, mode=0; long dst_data_size, den; FILE *src_file, *dst_file; unsigned char A[16][16]; time_t time_begin, time_end; for(i=0;i<49;i++) sifre[i] = 0; for(i=0;i<16;i++) for(j=0;j<16;j++) A[i][j] = 0; clrscr(); printf("Password: ");scanf("%s", sifre); printf("Mode(1:Encrypt 2:Decrypt): ");scanf("%d", &mode); if (mode == 1) { printf("Source File: ");scanf("%s", src); printf("Destination File: ");scanf("%s", dst); } else if (mode == 2) { printf("Source File: ");scanf("%s", src); } if ((src_file = fopen(src,"rb")) == NULL ) { clrscr(); printf("Couldn't open %s... ", src); sleep(1); return; } for(i=0;i<12;i++) type[i] = src[i]; length = 0; i = 0; while (( (sifre[i] != 0) || (sifre[i] != NULL) ) && ( i < 50 )) { i++; length++; } time_begin = time(NULL); if (mode == 1) { if ((dst_file = fopen(dst,"wb")) == NULL ) { clrscr(); printf("Couldn't create %s file... ", dst); sleep(1); return; } make_matris(length, sifre, A); dst_data_size = filesize(src_file); fwrite(&info, info_size, 1, dst_file); fwrite(&type, 12, 1, dst_file); fputc(length, dst_file); fwrite(&dst_data_size, 4, 1, dst_file); if ( fmod(dst_data_size, 2) == 0 ) { // file size is even number for(den=0;den<dst_data_size;den=den+2) { ch1 = fgetc(src_file); ch2 = fgetc(src_file); get_encrypted_data(A,ch1, ch2, &ch3, &ch4); fputc(ch3 ,dst_file); fputc(ch4 ,dst_file); } } else { // fil size is odd number for(den=0;den<dst_data_size-1;den=den+2) { ch1 = fgetc(src_file); ch2 = fgetc(src_file); get_encrypted_data(A,ch1, ch2, &ch3, &ch4); fputc(ch3 ,dst_file); fputc(ch4 ,dst_file); } fputc(fgetc(src_file), dst_file); } } else if (mode == 2) { // decrypt i = 0; if (fgetc(src_file) !='P') i++; if (fgetc(src_file) !='L') i++; if (fgetc(src_file) !='A') i++; if (fgetc(src_file) !='Y') i++; if (fgetc(src_file) !='F') i++; if (i != 0) { printf("\nIncorrect File..."); sleep(2); return; } fread(&type, 12, 1, src_file); if ((dst_file = fopen(type,"wb")) == NULL ) { clrscr(); printf("Couldn't create %s file... ", type); sleep(1); return; } length_got = fgetc(src_file); if (length == length_got) make_matris(length,sifre, A); else { printf("\nWrong Password %s... ", sifre); sleep(2); return; } fread(&dst_data_size, 4, 1, src_file); if ( fmod(dst_data_size, 2) == 0 ) { for(den=0;den<dst_data_size;den=den+2) { ch1 = fgetc(src_file); ch2 = fgetc(src_file); get_decrypted_data(A,ch1, ch2, &ch3, &ch4); fputc(ch3 ,dst_file); fputc(ch4 ,dst_file); } } else { // dosya boyutu tek rakamly for(den=0;den<dst_data_size-1;den=den+2) { ch1 = fgetc(src_file); ch2 = fgetc(src_file); get_decrypted_data(A,ch1, ch2, &ch3, &ch4); fputc(ch3 ,dst_file); fputc(ch4 ,dst_file); } fputc(fgetc(src_file), dst_file); } } time_end = time(NULL); printf("\n It took %f seconds to encrypt/decrypt file %s..\n", difftime(time_end,time_begin),src); fclose(src_file); fclose(dst_file); } void main() { do_work(); }
Example Execution Below there is the first 300 bytes of original file "Mpxinf.exe" File Pointer DATA: decimal DATA: ASCII
This is the first 300 bytes of Encrypted file "Mpxinf.exe". File Pointer DATA: decimal DATA: ASCII  Table 2.
Generated Playfair matrix using "metal_money" key | | i/j | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 0 | 109 101 116 97 108 95 111 110 121 0 1 2 3 4 5 6 | 1 | 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 2 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 3 | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 4 | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 5 | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 6 | 87 88 89 90 91 92 93 94 96 98 99 100 102 103 104 105 | 7 | 106 107 112 113 114 115 117 118 119 120 122 123 124 125 126 127 | 8 | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 9 | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | 10 | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | 11 | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | 12 | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | 13 | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | 14 | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | 15 | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
|