112 lines
3.0 KiB
C
112 lines
3.0 KiB
C
#include "spn.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
// Applique la permutation définie par perm à l'octet w
|
|
unsigned char do_perm(unsigned char w, unsigned char perm[8]) {
|
|
unsigned char res = 0;
|
|
for (int i = 0; i < 8; i++) {
|
|
if (w & (1 << i)) {
|
|
res |= (1 << perm[i]);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// Applique la substitution définie par subst sur chaque moitié de w
|
|
unsigned char do_subst(unsigned char w, unsigned char subst[16]) {
|
|
unsigned char left = (w >> 4) & 0x0F; // 4 bits de poids fort
|
|
unsigned char right = w & 0x0F; // 4 bits de poids faible
|
|
return (subst[left] << 4) | subst[right];
|
|
}
|
|
|
|
// Chiffre un bloc de 8 bits avec une clé de 16 bits
|
|
unsigned char encrypt(
|
|
unsigned char w,
|
|
unsigned short key,
|
|
unsigned char perm[8],
|
|
unsigned char subst[16]
|
|
) {
|
|
unsigned char subkey1 = (key >> 8) & 0xFF;
|
|
unsigned char subkey2 = key & 0xFF;
|
|
|
|
// Tour 1 : XOR avec la clé, substitution, permutation
|
|
w ^= subkey1;
|
|
w = do_subst(w, subst);
|
|
w = do_perm(w, perm);
|
|
|
|
// Tour 2 : XOR avec la clé, substitution, XOR avec la sous-clé finale
|
|
w ^= subkey2;
|
|
w = do_subst(w, subst);
|
|
w ^= subkey1;
|
|
|
|
return w;
|
|
}
|
|
|
|
// Déchiffre un bloc de 8 bits avec une clé de 16 bits
|
|
unsigned char decrypt(
|
|
unsigned char w,
|
|
unsigned short key,
|
|
unsigned char perm[8],
|
|
unsigned char subst[16]
|
|
) {
|
|
unsigned char subkey1 = (key >> 8) & 0xFF;
|
|
unsigned char subkey2 = key & 0xFF;
|
|
|
|
// Table de substitution inverse
|
|
unsigned char inv_subst[16];
|
|
for (int i = 0; i < 16; i++) {
|
|
inv_subst[subst[i]] = i;
|
|
}
|
|
|
|
// Tour inverse 2 : XOR avec la clé, substitution inverse, XOR avec la sous-clé
|
|
w ^= subkey1;
|
|
w = do_subst(w, inv_subst);
|
|
w ^= subkey2;
|
|
|
|
// Tour inverse 1 : permutation inverse, substitution inverse, XOR avec la clé
|
|
unsigned char inv_perm[8];
|
|
for (int i = 0; i < 8; i++) {
|
|
inv_perm[perm[i]] = i;
|
|
}
|
|
w = do_perm(w, inv_perm);
|
|
w = do_subst(w, inv_subst);
|
|
w ^= subkey1;
|
|
|
|
return w;
|
|
}
|
|
|
|
void read_key(const char *filename, unsigned short *key) {
|
|
FILE *file = fopen(filename, "r");
|
|
if (!file) {
|
|
perror("Erreur ouverture fichier clé");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
fscanf(file, "%hx", key); // Lire un entier hexadécimal (16 bits)
|
|
fclose(file);
|
|
}
|
|
|
|
void read_subst(const char *filename, unsigned char subst[16]) {
|
|
FILE *file = fopen(filename, "r");
|
|
if (!file) {
|
|
perror("Erreur ouverture fichier substitution");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
for (int i = 0; i < 16; i++) {
|
|
fscanf(file, "%hhu", &subst[i]); // Lire un entier 8 bits
|
|
}
|
|
fclose(file);
|
|
}
|
|
|
|
void read_perm(const char *filename, unsigned char perm[8]) {
|
|
FILE *file = fopen(filename, "r");
|
|
if (!file) {
|
|
perror("Erreur ouverture fichier permutation");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
for (int i = 0; i < 8; i++) {
|
|
fscanf(file, "%hhu", &perm[i]); // Lire un entier 8 bits
|
|
}
|
|
fclose(file);
|
|
} |