#include "spn.h" unsigned char do_subst(unsigned char w, unsigned char subst[16]) { return subst[w]; } unsigned char do_perm(unsigned char w, unsigned char perm[16]) { unsigned char result = 0; 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]); } return result; } 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)); } return result; } 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; }