tentative 2eme exo
This commit is contained in:
41
tp2/spn-decrypt-file.c
Normal file
41
tp2/spn-decrypt-file.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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 <key_file> <subst_file> <perm_file> <input> <output>\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;
|
||||||
|
}
|
44
tp2/spn-encrypt-file.c
Normal file
44
tp2/spn-encrypt-file.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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 <key_file> <subst_file> <perm_file> <input> <output>\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;
|
||||||
|
}
|
102
tp2/spn.c
102
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 do_perm(unsigned char w, unsigned char perm[16]) {
|
||||||
unsigned char result = 0;
|
unsigned char result = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++)
|
||||||
if ((w >> i) & 1)
|
if ((w >> i) & 1)
|
||||||
result |= (1 << perm[i]);
|
result |= (1 << perm[i]);
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short apply_perm16(unsigned short w, unsigned char perm[16]) {
|
unsigned short encrypt(unsigned short w, unsigned int key, unsigned char perm[16], unsigned char subst[16]) {
|
||||||
unsigned short result = 0;
|
for (int i = 0; i < 2; i++) {
|
||||||
for (int i = 0; i < 16; i++) {
|
unsigned char rk = (key >> (8 * (3 - i))) & 0xFF;
|
||||||
if ((w >> i) & 1)
|
w ^= (rk << 8) | rk;
|
||||||
result |= (1 << perm[i]);
|
|
||||||
|
unsigned short tmp = 0;
|
||||||
|
for (int j = 0; j < 4; ++j) {
|
||||||
|
unsigned char nib = (w >> (j * 4)) & 0xF;
|
||||||
|
tmp |= (subst[nib] << (j * 4));
|
||||||
}
|
}
|
||||||
return result;
|
w = tmp;
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short apply_subst16(unsigned short w, unsigned char subst[16]) {
|
unsigned short permute = 0;
|
||||||
unsigned short result = 0;
|
for (int j = 0; j < 16; ++j)
|
||||||
for (int i = 0; i < 4; i++) {
|
if ((w >> j) & 1) {
|
||||||
unsigned char nibble = (w >> (i * 4)) & 0xF;
|
permute |= (1 << perm[j]);
|
||||||
result |= (do_subst(nibble, subst) << (i * 4));
|
|
||||||
}
|
}
|
||||||
return result;
|
w = permute;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short decrypt(
|
unsigned short decrypt(unsigned short w, unsigned int key, unsigned char perm[16], unsigned char subst[16]) {
|
||||||
unsigned short w,
|
unsigned char inverseSubst[16];
|
||||||
unsigned int key,
|
unsigned char inversePerm[16];
|
||||||
unsigned char perm[16],
|
for (int i = 0; i < 16; ++i) {
|
||||||
unsigned char subst[16]
|
inverseSubst[subst[i]] = i;
|
||||||
) {
|
inversePerm[perm [i]] = i;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return w;
|
||||||
}
|
}
|
Reference in New Issue
Block a user