diff --git a/tp2/spn-decrypt-file.c b/tp2/spn-decrypt-file.c new file mode 100644 index 0000000..46c1575 --- /dev/null +++ b/tp2/spn-decrypt-file.c @@ -0,0 +1,41 @@ +#include +#include +#include "spn.h" + +void read_array(const char* filename, unsigned char* array, int size) { + FILE* f = fopen(filename, "r"); + for (int i = 0; i < size; i++) { + fscanf(f, "%hhu", &array[i]); + } + fclose(f); +} + +int main(int argc, char* argv[]) { + if (argc != 6) { + printf("%s \n", argv[0]); + return 1; + } + + FILE* fkey = fopen(argv[1], "r"); + unsigned int key; + fscanf(fkey, "%u", &key); + fclose(fkey); + + unsigned char subst[16], perm[16]; + read_array(argv[2], subst, 16); + read_array(argv[3], perm, 16); + + FILE* fin = fopen(argv[4], "rb"); + FILE* fout = fopen(argv[5], "wb"); + + unsigned short block; + while (fread(&block, 2, 1, fin)) { + unsigned short dec = decrypt(block, key, perm, subst); + fputc(dec >> 8, fout); + fputc(dec & 0xFF, fout); + } + + fclose(fin); + fclose(fout); + return 0; +} \ No newline at end of file diff --git a/tp2/spn-encrypt-file.c b/tp2/spn-encrypt-file.c new file mode 100644 index 0000000..858a793 --- /dev/null +++ b/tp2/spn-encrypt-file.c @@ -0,0 +1,44 @@ +#include +#include +#include "spn.h" + +void read_array(const char* filename, unsigned char* array, int size) { + FILE* f = fopen(filename, "r"); + for (int i = 0; i < size; i++) { + fscanf(f, "%hhu", &array[i]); + } + fclose(f); +} + +int main(int argc, char* argv[]) { + if (argc != 6) { + printf("%s \n", argv[0]); + return 1; + } + + FILE* fkey = fopen(argv[1], "r"); + unsigned int key; + fscanf(fkey, "%u", &key); + fclose(fkey); + + unsigned char subst[16], perm[16]; + read_array(argv[2], subst, 16); + read_array(argv[3], perm, 16); + + FILE* fin = fopen(argv[4], "rb"); + FILE* fout = fopen(argv[5], "wb"); + + unsigned char b1, b2; + while (fread(&b1, 1, 1, fin)) { + if (fread(&b2, 1, 1, fin) != 1) { + b2 = 0; + } + unsigned short block = (b1 << 8) | b2; + unsigned short enc = encrypt(block, key, perm, subst); + fwrite(&enc, 2, 1, fout); + } + + fclose(fin); + fclose(fout); + return 0; +} \ No newline at end of file diff --git a/tp2/spn.c b/tp2/spn.c index 803aa79..c0c207f 100644 --- a/tp2/spn.c +++ b/tp2/spn.c @@ -6,81 +6,59 @@ unsigned char do_subst(unsigned char w, unsigned char subst[16]) { unsigned char do_perm(unsigned char w, unsigned char perm[16]) { unsigned char result = 0; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 8; i++) if ((w >> i) & 1) result |= (1 << perm[i]); - } return result; } -unsigned short apply_perm16(unsigned short w, unsigned char perm[16]) { - unsigned short result = 0; - for (int i = 0; i < 16; i++) { - if ((w >> i) & 1) - result |= (1 << perm[i]); +unsigned short encrypt(unsigned short w, unsigned int key, unsigned char perm[16], unsigned char subst[16]) { + for (int i = 0; i < 2; i++) { + unsigned char rk = (key >> (8 * (3 - i))) & 0xFF; + w ^= (rk << 8) | rk; + + unsigned short tmp = 0; + for (int j = 0; j < 4; ++j) { + unsigned char nib = (w >> (j * 4)) & 0xF; + tmp |= (subst[nib] << (j * 4)); + } + w = tmp; + + unsigned short permute = 0; + for (int j = 0; j < 16; ++j) + if ((w >> j) & 1) { + permute |= (1 << perm[j]); + } + w = permute; } - return result; + return w; } -unsigned short apply_subst16(unsigned short w, unsigned char subst[16]) { - unsigned short result = 0; - for (int i = 0; i < 4; i++) { - unsigned char nibble = (w >> (i * 4)) & 0xF; - result |= (do_subst(nibble, subst) << (i * 4)); +unsigned short decrypt(unsigned short w, unsigned int key, unsigned char perm[16], unsigned char subst[16]) { + unsigned char inverseSubst[16]; + unsigned char inversePerm[16]; + for (int i = 0; i < 16; ++i) { + inverseSubst[subst[i]] = i; + inversePerm[perm [i]] = i; } - return result; + + for (int i = 1; i >= 0; --i) { + unsigned short permInverse = 0; + for (int j = 0; j < 16; ++j) + if ((w >> j) & 1) { + permInverse |= (1 << inversePerm[j]); + } + w = permInverse; + + unsigned short tmp = 0; + for (int j = 0; j < 4; ++j) { + unsigned char sousBloc = (w >> (j * 4)) & 0xF; + tmp |= (inverseSubst[sousBloc] << (j * 4)); + } + w = tmp; + + unsigned char rk = (key >> (8 * (3 - i))) & 0xFF; + w ^= (rk << 8) | rk; + } + return w; } - -unsigned short encrypt( - unsigned short w, - unsigned int key, - unsigned char perm[16], - unsigned char subst[16] -) { - for (int round = 0; round < 2; round++) { - unsigned char round_key = (key >> (8 * (3 - round))) & 0xFF; - w ^= (round_key << 8) | round_key; - - w = apply_subst16(w, subst); - w = apply_perm16(w, perm); - } - - // Dernier round - pas de permutation - unsigned char round_key = (key & 0xFF); - w ^= (round_key << 8) | round_key; - w = apply_subst16(w, subst); - - return w; -} - -unsigned short decrypt( - unsigned short w, - unsigned int key, - unsigned char perm[16], - unsigned char subst[16] -) { - // Inverser la substitution - unsigned char inv_subst[16]; - for (int i = 0; i < 16; i++) - inv_subst[subst[i]] = i; - - // Inverser la permutation - unsigned char inv_perm[16]; - for (int i = 0; i < 16; i++) - inv_perm[perm[i]] = i; - - // Dernier tour - w = apply_subst16(w, inv_subst); - unsigned char round_key = (key & 0xFF); - w ^= (round_key << 8) | round_key; - - // 2 tours inverses - for (int round = 1; round >= 0; round--) { - w = apply_perm16(w, inv_perm); - w = apply_subst16(w, inv_subst); - round_key = (key >> (8 * (3 - round))) & 0xFF; - w ^= (round_key << 8) | round_key; - } - - return w; -} \ No newline at end of file