HSG |
|
Eine Feistel-Chiffre ist eine Block-Chiffre. Im Beispiel soll ein Block aus 4 Bytes bestehen.
>>> block = bytes('ABCD','ascii') >>> block b'ABCD' >>> list(block) [65, 66, 67, 68] >>>
Für eine 'Feistel-Runde' benötigt man einen Rundenschlüssel.
>>> rs = bytes([42,170]) >>> rs b'*\xaa' >>>
Weiter wird eine 'möglichst nichtlineare' Funktion f benötigt, die mit Hilfe des Rundenschlüssels die Bytes eines halben Blocks verändert. Die Funktion f muss nicht umkehrbar sein. Im Beispiel werden die zwei 'Zahlen' im 256-System multipliziert und die ersten beiden 'Stellen' zurückgegeben.
>>> def f(hb,rs): return ntob(bton(hb)*bton(rs))[:2] >>>
Jetzt kann eine Feistel-Runde durchgeführt werden. Dazu wird der Block zunächst in eine linke und in eine rechte Hälfte geteilt.
>>> lh = block[:2] >>> rh = block[2:] >>> lh b'AB' >>> rh b'CD' >>>
Für die xor-Bildung zwischen byte-Listen benötigt man eine Funktion.
>>> def xor(a,b): return bytes([a[i]^b[i] for i in range(len(a))]) >>>
Jetzt kann der neue Block berechnet werden.
>>> lneu = rh >>> rneu = xor(f(rh,rs),lh) >>> lneu+rneu b'CDJw'
Jede Runde kann folgendermaßen rückgängig gemacht werden.
>>> ralt = lneu >>> lalt = xor(rneu,f(ralt,rs)) >>> lalt+ralt b'ABCD' >>>
Das funktioniert, weil rneu = xor(f(rh,rs),lh) und ralt = rh gilt und damit
lalt = xor(rneu,f(ralt,rs)) = xor(xor(lh,f(rh,rs)),f(rh,rs)) = lh
Vollziehe obige Rechnungen für einen selbstgewählten Block und einen selbstgewählten Rundenschlüssel nach. Als 'Kür' kann auch die Funktion f selbstgewählt werden.
Baue ein symmetrisches Kryptosystem mit einer Blocklänge von 16 Bytes auf, das aus vier Feistelrunden besteht. Der Schlüssel soll 8 Bytes lang sein, wobei je zwei Bytes die Rundenschlüssel bilden. Es muss also eine Funktion zum Verschlüsseln und eine zum Entschlüsseln geschrieben werden. Die Funktionen könnten z.B. Fencrypt und Fdecrypt heißen.