From 126e99113fbde447a3180c037a9abd5400af3477 Mon Sep 17 00:00:00 2001 From: Denis Monnerat Date: Mon, 16 Mar 2026 08:23:15 +0100 Subject: [PATCH] ajout tp2 --- README.md | 2 + tp/tp2/README.md | 95 ++++++++++++++++++ .../img/SubstitutionPermutationNetwork2.png | Bin 0 -> 19879 bytes tp/tp2/img/spn.png | Bin 0 -> 42884 bytes tp/tp2/src/Makefile | 17 ++++ tp/tp2/src/lib/spn.c | 66 ++++++++++++ tp/tp2/src/lib/spn.h | 24 +++++ tp/tp2/src/spn-decrypt-file.c | 65 ++++++++++++ tp/tp2/src/spn-encrypt-file.c | 58 +++++++++++ 9 files changed, 327 insertions(+) create mode 100644 tp/tp2/README.md create mode 100644 tp/tp2/img/SubstitutionPermutationNetwork2.png create mode 100644 tp/tp2/img/spn.png create mode 100644 tp/tp2/src/Makefile create mode 100644 tp/tp2/src/lib/spn.c create mode 100644 tp/tp2/src/lib/spn.h create mode 100644 tp/tp2/src/spn-decrypt-file.c create mode 100644 tp/tp2/src/spn-encrypt-file.c diff --git a/README.md b/README.md index f635054..767d6b8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ Cryptographie - Outils et algorithmes - cm : [LFSR, Chiffrements par bloc, algorithmes à clefs symétriques](cours/crypto.pdf). - td : [Généralités, chiffrements par flot](td/td1.pdf) - tp : [Chiffrement ECB, lfsr, xtea](tp/tp1) + #### Semaine 2 - cm : [Algorithmes à clefs symétriques, Hachages](cours/crypto.pdf). - td : [Chiffrements symétriques par blocs et modes](td/td2.pdf) +- tp : [Substitution-Permutation-Network](tp/tp2) diff --git a/tp/tp2/README.md b/tp/tp2/README.md new file mode 100644 index 0000000..1ce7bfb --- /dev/null +++ b/tp/tp2/README.md @@ -0,0 +1,95 @@ +# TP2 + +> Dans ce tp, on implémente un algorithme de chiffrement par Blocs basé +> sur un réseau de permutation-substitution (SPN), en mode ECB. + + +### SPN + +
+ +
+ + + +Ces algorithmes utilisent en entrée une clé, et applique à chaque bloc +plusieurs tours constitués de boîtes de substitutions (S-Box) et de +boîtes de permutations (P-Box). + +- Une **S-Box** substitue à un ensemble de bits un autre ensembe de + bits (transormation bijective). +- Une **P-Box** est une permutation de bits. Elle prend la sortie + d'une S-Box, permutte les bits, et les transmet à une S-box au tour + d'après. +- A chaque tour, on combine le bloc avec la clé (ici un xor). + +#### implantation + + + +- la taille de bloc est 8 bits, +- le bloc est découpé en 2 sous-blocs de 4 bits chacun, +- la taille de la clef est 24 bits, +- la clef est décomposée en 3 sous-clefs de 8 bits chacun, +- le nombre de tours est égale à 2, +- les substitutions et les permutations sont les mêmes à chaque tour. + +Remarques + +On représentera dans le programme une substitution par un tableau +d'entiers (unsigned char) de taille 16. + +```c +unsigned char s[]={14,3,2,10,12,11,15,9,0,4,7,13,1,8,6,5} +``` + +Ainsi, le bloc binaire 0011, qui vaut 3, sera remplacé par 1010 car `s[3]=10` + +On représentera une permutation par un tableau d'entiers (`unisgned char`) de taille 16. + +``` +unsigned char perm[8]={5,0,4,6,7,1,2,3}; +``` + +Ainsi, le bit de poids faible (rang 0) est placé au rang 5. + +#### Votre travail + +1. Ecrivez les fonctions suivantes, qui implantent le spn décrit ci-dessus. + + ```c + #ifndef _SPN_H + #define _SPN_H + + unsigned char do_perm(unsigned char w,unsigned char perm[16]); + unsigned char do_subst(unsigned char w,unsigned char subst[16]); + + unsigned char encrypt( + unsigned short w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + + unsigned char decrypt( + unsigned short w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + + #endif + ``` + +2. Ecrivez des programmes spn-encrypt-file.c , spn-decrypt-file.c qui + implantent le SPN décrit ci-dessus. Les deux prennent sur la ligne de + commande : + + - "nom fichier codé" et "nom fichier décodé " + - la clef + + La permutation et la substitution seront codées en dur dans les programmes. + + Testez vos programmes sur un exemple à vous. + +3. Passez vos deux programmes en mode CBC. diff --git a/tp/tp2/img/SubstitutionPermutationNetwork2.png b/tp/tp2/img/SubstitutionPermutationNetwork2.png new file mode 100644 index 0000000000000000000000000000000000000000..078e4d240fcc1e4f079a323950a6f4ae937ea97b GIT binary patch literal 19879 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 S&g5R2$0b|2*-Hz#;|>7U^w?(r literal 0 HcmV?d00001 diff --git a/tp/tp2/img/spn.png b/tp/tp2/img/spn.png new file mode 100644 index 0000000000000000000000000000000000000000..571ac8966454f28d6897f3956d2a3d802d87e336 GIT binary patch literal 42884 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 + } + + return pw; +} + +unsigned char do_subst(unsigned char w,unsigned char subst[16]) +{ + unsigned char sw=0; + + // TODO + return sw; +} + +unsigned char encrypt( + unsigned char w, + unsigned key, + unsigned char perm[8], + unsigned char subst[16]) +{ + unsigned char k0=key&0xff; + unsigned char k1=(key>>8)&0xff; + unsigned char k2=(key>>16)&0xff; + + // TODO + + return w; +} +unsigned char decrypt( + unsigned char w, + unsigned short key, + unsigned char perm[8], + unsigned char subst[16]) +{ + unsigned char k0=key&0xff; + unsigned char k1=(key>>8)&0xff; + unsigned char k2=(key>>16)&0xff; + + // TODO + +} + diff --git a/tp/tp2/src/lib/spn.h b/tp/tp2/src/lib/spn.h new file mode 100644 index 0000000..ad0da20 --- /dev/null +++ b/tp/tp2/src/lib/spn.h @@ -0,0 +1,24 @@ +#ifndef _SPN_H +#define _SPN_H + +void calc_inv_perm(unsigned char perm[8],unsigned char inv_perm[8]); +void calc_inv_subst(unsigned char subst[16],unsigned char inv_subst[16]); + +unsigned char do_perm(unsigned char w,unsigned char perm[8]); +unsigned char do_subst(unsigned char w,unsigned char subst[16]); + +unsigned char encrypt( + unsigned char w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + +unsigned char decrypt( + unsigned char w, + unsigned int key, + unsigned char perm[8], + unsigned char subst[16] + ); + +#endif diff --git a/tp/tp2/src/spn-decrypt-file.c b/tp/tp2/src/spn-decrypt-file.c new file mode 100644 index 0000000..4de2be8 --- /dev/null +++ b/tp/tp2/src/spn-decrypt-file.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include "./lib/spn.h" + +void randomize (unsigned char arr[], int n) +{ + unsigned char tmp; + for (int i = n - 1; i > 0; i--) + { + // Pick a random index from 0 to i + int j = rand() % (i + 1); + + // Swap arr[i] with the element + // at random index + // swap(&arr[i], &arr[j]); + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +} + + +int main(int argc, char *argv[]) +{ + int fd_in,fd_out; + unsigned int key; + unsigned char perm[8] = {0,1,2,3,4,5,6,7}; + unsigned char subst[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + unsigned char inv_perm[8]; + unsigned char inv_subst[16]; + + unsigned char buf; + + assert(argc == 4); + + srand(0); + + randomize(perm,8); + randomize(subst,16); + calc_inv_perm(perm,inv_perm); + calc_inv_subst(subst,inv_subst); + + + + fd_in = open(argv[1],O_RDONLY); + fd_out = open(argv[2],O_WRONLY|O_TRUNC|O_CREAT,0600); + key = (unsigned int)strtol(argv[3],NULL,0); + + + while(1){ + ssize_t nb = read(fd_in, &buf, 1); + if (nb <=0) + break; + buf = decrypt(buf, key, inv_perm, inv_subst); + write(fd_out, &buf, 1); + } + close(fd_in); + close(fd_out); + + return 0; +} diff --git a/tp/tp2/src/spn-encrypt-file.c b/tp/tp2/src/spn-encrypt-file.c new file mode 100644 index 0000000..d3446af --- /dev/null +++ b/tp/tp2/src/spn-encrypt-file.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include "./lib/spn.h" + +void randomize (unsigned char arr[], int n) +{ + unsigned char tmp; + for (int i = n - 1; i > 0; i--) + { + // Pick a random index from 0 to i + int j = rand() % (i + 1); + + // Swap arr[i] with the element + // at random index + // swap(&arr[i], &arr[j]); + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +} + + +int main(int argc, char *argv[]) +{ + int fd_in,fd_out; + unsigned int key; + unsigned char perm[8] = {0,1,2,3,4,5,6,7}; + unsigned char subst[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + unsigned char buf; + + assert(argc == 4); + + srand(0); + randomize(perm,8); + randomize(subst,16); + + + fd_in = open(argv[1],O_RDONLY); + fd_out = open(argv[2],O_WRONLY|O_TRUNC|O_CREAT,0600); + + key = (unsigned int)strtol(argv[3],NULL,0); + + while(1){ + ssize_t nb = read(fd_in, &buf, 1); + if (nb <=0) + break; + + buf = encrypt(buf, key, perm, subst); + write(fd_out, &buf, 1); + } + close(fd_in); + close(fd_out); + + return 0; +}