ajout tp2

This commit is contained in:
2026-03-16 08:23:15 +01:00
parent 5f84465e1f
commit 126e99113f
9 changed files with 327 additions and 0 deletions

View File

@@ -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)

95
tp/tp2/README.md Normal file
View File

@@ -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
<div align="center">
<img src="./img/spn.png">
</div>
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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
tp/tp2/img/spn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

17
tp/tp2/src/Makefile Normal file
View File

@@ -0,0 +1,17 @@
all : spn-encrypt-file spn-decrypt-file
spn-encrypt-file.o : spn-encrypt-file.c
gcc -c spn-encrypt-file.c
spn-decrypt-file.o : spn-decrypt-file.c
gcc -c spn-decrypt-file.c
./lib/spn.o:./lib/spn.c
gcc -c ./lib/spn.c -o ./lib/spn.o
spn-encrypt-file : ./lib/spn.o spn-encrypt-file.o
gcc -o spn-encrypt-file ./lib/spn.o spn-encrypt-file.o
spn-decrypt-file : ./lib/spn.o spn-decrypt-file.o
gcc -o spn-decrypt-file ./lib/spn.o spn-decrypt-file.o

66
tp/tp2/src/lib/spn.c Normal file
View File

@@ -0,0 +1,66 @@
#include "spn.h"
void calc_inv_perm(unsigned char perm[8],unsigned char inv_perm[8])
{
// TODO
}
void calc_inv_subst(unsigned char subst[16],unsigned char inv_subst[16])
{
// TODO
}
unsigned char do_perm(unsigned char w,unsigned char perm[8])
{
unsigned char pw = 0; // permuted byte
int i;
unsigned char mask = 0x1;
unsigned char bit;
unsigned char place;
for(i=0;i<8;i++){
bit=w&mask;
place=perm[i];
pw |= bit<<place;
w>>=1;
}
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
}

24
tp/tp2/src/lib/spn.h Normal file
View File

@@ -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

View File

@@ -0,0 +1,65 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#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;
}

View File

@@ -0,0 +1,58 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#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;
}