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 0000000..078e4d2
Binary files /dev/null and b/tp/tp2/img/SubstitutionPermutationNetwork2.png differ
diff --git a/tp/tp2/img/spn.png b/tp/tp2/img/spn.png
new file mode 100644
index 0000000..571ac89
Binary files /dev/null and b/tp/tp2/img/spn.png differ
diff --git a/tp/tp2/src/Makefile b/tp/tp2/src/Makefile
new file mode 100644
index 0000000..dabbccf
--- /dev/null
+++ b/tp/tp2/src/Makefile
@@ -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
diff --git a/tp/tp2/src/lib/spn.c b/tp/tp2/src/lib/spn.c
new file mode 100644
index 0000000..4f5346e
--- /dev/null
+++ b/tp/tp2/src/lib/spn.c
@@ -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<>=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
+
+}
+
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;
+}