Ce TP a pour objectif d'implanter deux algorithmes résolvant le problème de décodage par syndrome.
Le premier, l'algorithme de Prange, est à le fondement d'algorithmes plus avancés dits de "décodage par ensemble d'information", et permet d'obtenir une solution au problème. Le second, dite méthode de Dumer, permet quant à lui d'obtenir un ensemble de solutions au problème, et s'avère donc avantageux lorsque le nombre de solutions à trouver est de grande taille.
Question 1. Écrire ou rappeler des fonctions qui permettent de :
def random_vector(n):
pass
def weight(x):
pass
def random_fixed_weight(n, w):
pass
def random_binary_matrix(k, n):
pass
def random_subset(n, k):
pass
def is_information_set(H, I):
pass
On considère l'algorithme de Prange, comme décrit ci-dessous :
Entrée : une matrice $\mathbf{H} \in \mathbb{F}_2^{(n-k) \times n}$ de rang plein, un entier $w$ et un vecteur $\mathbf{s}$ tel que $\mathbf{s} = \mathbf{H e}$ où $\mathbf{e}$ est de poids de Hamming $w$.
Sortie : un vecteur $\mathbf{x}$ de poids de Hamming $w$ tel que $\mathbf{H x} = \mathbf{s}$.
Question 2 : Implanter l'algorithme de Prange.
def prange(H, w, s):
pass
Question 3 : Tester votre algorithme à l'aide des fonctions écrites à la Question 1.
def TEST_PRANGE():
pass
Question 4 : Intégrer à votre algorithme de Prange un compteur permettant d'estimer son nombre d'itérations. Puis, donner la complexité expérimentale de l'algorithme de Prange pour les séries de valeurs suivantes :
Remarque importante : il y a une variance importante pour les complexités obtenues. Pour un certain triplet $(n, k, w)$, on considèrera donc la médiane de la complexité obtenue sur quelques dizaines d'échantillons.
La méthode de Dumer est un algorithme permettant de trouver un ensemble de solutions au problème de décodage par syndrome.
Dans l'exercice on suppose que $n$ est pair. Soit $J_1 \cup J_2$ une partition de $\{1, \dots, n\}$ en deux sous-ensembles de même taille. Étant donnée une matrice $\mathbf{H} \in \mathbf{F}_2^{(n-k) \times n}$, on note $\mathbf{H}_i = \mathbf{H}_{|J_i}$.
Enfin, pour $\mathbf{s} \in \mathbb{F}_2^{n-k}$, on définit : $$ \begin{array}{l} L_1 := \{ \mathbf{H_1 x_1} \mid \mathbf{x_1} \in \mathbb{F}_2^{n/2} \text{ et } |\mathbf{x_1}| = w/2 \} \subseteq \mathbf{F}_2^{n-k} \\ L_2 := \{ \mathbf{s} - \mathbf{H_2 x_2} \mid \mathbf{x_2} \in \mathbb{F}_2^{n/2} \text{ et } |\mathbf{x_2}| = w/2 \} \subseteq \mathbf{F}_2^{n-k} \end{array} $$ Ces listes peuvent être de taille importante, en moyenne $\binom{n/2}{w/2}$.
L'idée de la méthode de Dumer est de chercher une collision entre les listes $L_1$ et $L_2$ : si $\mathbf{H_1 x_1} = \mathbf{s} - \mathbf{H_2 x_2}$ et si $\mathbf{x_1}$ et $\mathbf{x_2}$ ont poids $w/2$, alors le vecteur $\mathbf{x} = (\mathbf{x_1}, \mathbf{x_2})$ est solution en poids $w$ du problème de décodage par syndrome.
Bien entendu, l'existence d'une collision entre les listes dépend du bon choix de $J_1$ et $J_2$ (qui, dans un sens, doivent partitionner équitablement l'erreur). Comme pour l'algotihme de Prange, on réitière donc des tirages aléatoires de $J_1$, $J_2$ jusqu'à obtenir une solution convenable.
Méthode de Dumer
Entrée : une matrice $\mathbf{H} \in \mathbb{F}_2^{n-k}$, un entier $w$ et un syndrome $\mathbf{s} = \mathbf{H e}$ où $\mathbf{e}$ est de poids $w$.
Sortie : un ensemble de vecteurs $\mathbf{x}$ de poids $w$ tels que $\mathbf{H x} = \mathbf{s}$.
Question 1. Implanter la méthode de Dumer. On pourra utiliser des fonctions déjà écrites dans l'exercice 1.
def dumer(H, w, s):
pass
Question 2. Tester votre implantation avec de petits exemples (par exemple $n = 20$, $k = 10$, $w = 8$).
def TEST_DUMER():
pass