diff --git a/school/intro-crypto/uebung/06/06.tex b/school/intro-crypto/uebung/06/06.tex new file mode 100644 index 0000000..f892cfb --- /dev/null +++ b/school/intro-crypto/uebung/06/06.tex @@ -0,0 +1,164 @@ +\documentclass[12pt,a4paper,german]{article} +\usepackage{url} +%\usepackage{graphics} +\usepackage{times} +\usepackage[T1]{fontenc} +\usepackage{pifont} +\usepackage{ngerman} +\usepackage{float} +\usepackage{diagbox} +\usepackage[latin1]{inputenc} +\usepackage{geometry} +\usepackage{amsfonts} +\usepackage{amsmath} +\usepackage{delarray} +% \usepackage{minted} +\usepackage{csquotes} +\usepackage{graphicx} +\usepackage{epsfig} +\usepackage{longtable} +\usepackage{paralist} +\geometry{left=2.0cm,textwidth=17cm,top=3.5cm,textheight=23cm} + +\graphicspath{.} + +%%%%%%%%%% Fill out the the definitions %%%%%%%%% +\def \name {Valentin Brandl} % +\def \matrikel {108018274494} % +% \def \pname {Vorname2 Nachname2} % +% \def \pmatrikel {Matrikelnummer2} % +\def \gruppe {Gruppe 193} % +\def \uebung {6} % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % DO NOT MODIFY THIS HEADER +\newcommand{\hwsol}{ +\vspace*{-2cm} +\noindent \matrikel \quad \name \hfill Gruppe:\gruppe \\ +% \noindent \pmatrikel \quad \pname \\ +\begin{center}{\Large \bf L\"osung f\"ur \"Ubung \# \uebung}\end{center} +} + +\newcommand{\cmark}{\ding{51}}% +\newcommand{\xmark}{\ding{55}}% +\newcommand{\csquare}{\text{\rlap{$\checkmark$}}\square}% + +\begin{document} +%Import header +\hwsol + + +\section*{Aufgabe 1} + +\begin{enumerate}[a)] + + \item Ein einzelner der im Paper beschriebenen FPGAs kann 400.000.000 (400 Millionen) Schlüssel pro Sekunde testen. + + \item Der Average Case einer Schlüsselsuche eines $n$-Bit Schlüssels beträgt $2^n / 2$ und der worst-case beträgt + $2^n$, ist also um Faktor 2 langsamer. Der average-case für DES auf einem COPACOBANA beträgt 9 Tage, der + worst-case sind also 18 Tage. + + \item Anzahl der Verdoppelungen nach Moore's Law: $((2019 - 2006) * 12) / 18 = 8,6667 \approx 9$ + + Average Case zum Brechen von DES in 2006: 9 Tage + + Verbesserung nach $9$ Iterationen von Moore's Law: $9 / (2^9) = 0,0176$ + + Im average case lässt sich eine DES-Schlüsselsuche 2019 in weniger als einem Tag durchführen (weniger als einer + halben Stunde). + + Mit $8$ Iterationen gerechnet, kommt man auf $9 / (2^8) = 0,0351$ Tage, also knapp unter $1$ Stunde. + + \item Eine Implementierung als FPGA ist deutlich schneller, als eine Software Implementierung auf general purpose + Hardware zu den selben Kosten. Eine Implementierung als ASIC lässt sich nur verwenden um einen bestimmten + Algorithmus anzugreifen, während man FPGAs neu programmieren kann, um anderen Algorithmen anzugreifen. + + \item Ein einzelner FPGA konnte 2006 400 Millionen Schlüssel pro Sekunde testen. Unter Anwendung von 8 Iterationen + von Moore's Law (siehe c)) ergibt sich daraus eine Leistung von $400000000 * 2^8 = 102.400.000.000$ Schlüssel + pro Sekunde im Jahr 2019 + + Ein COPACOBANA enthält 120 FPGAs, von denen jeder $102400000000$ Schlüssel pro Sekunde testen kann. Der gesamte + COPACOBANA kann also $120 * 102400000000 = 12288000000000$ Schlüssel pro Sekunde testen. + + 15000 COPACOBANA kommen also auf $15000 * 12.288.000.000.000 = 184.320.000.000.000.000$ Schlüssel pro Sekunde. + + Eine Blockchiffre mit einer Schlüssellänge von 128-bit hat $2^{128}$ Mögliche Schlüssel. Eine durchschnittliche + Schlüsselsuche muss also $2^{128} / 2$ Schlüssel testen. + + Sei $p = 184.320.000.000.000.000 \frac{k}{s}$ (Schlüssel pro Sekunde) die Leistung des COPACOBANA Clusters und + $r = (2^{128} / 2) k$ die Anzahl der zu testenden Schlüssel, ergibt sich die Dauer des Angriffs mit $\frac{r}{p} + = \frac{(2^{128} / 2)}{184.320.000.000.000.000} s \approx 9.231 * 10^{20} \approx 2.564 * 10^{17} h \approx + 1.068 * 10^{16} d \approx 29271308980213 y$ + + \item Benötigte Rechenleistung $p$ (in Schlüssel pro Sekunde) um eine 128-bit Blockchiffre mit einer durchschnittlichen + Suchzeit von 24 Stunden zu brechen: + + $86400 = \frac{2^{128}/2}{p} \Rightarrow p = 1.969.226.660.422.097.589.487.121.570.785.695 \approx 1.969 * + 10^{30}$ + + \begin{align*} + 12288000000000 * (2^x) &> 1.969 * 10^{30} \\ + \Rightarrow x &> 57153 + \end{align*} + + Nach $57153$ Iterationen von Moore's Law, also $57153 * 18m = 1028754m \approx 85730y$, lässt sich eine 128-bit + Blockchiffre in weniger als 24 Stunden brechen. Das ist im Jahr $85730 + 2019 = 87749$ + +\end{enumerate} + +\section*{Aufgabe 2} + +\begin{enumerate}[a)] + + \item + + \begin{enumerate}[1.] + \item Ausgabe der f-Box $f_{out} = R_1 \oplus L_0$ + + \item Ausgabe der S-Boxen $s_{out} = P^{-1}(f_{out})$ + + \item Mit $s_{out}$ lässt sich der Input der S-Boxen $s_{in}$ einschränken + + \item $k_1 = E(R_0) \oplus s_{in}$ + \end{enumerate} + + \item Jede S-Box hat $2^6 = 64$ Mögliche Eingangswerte und $2^4 = 16$ Mögliche Ausgangswerte + + $\Rightarrow 64/16 = 4 \Rightarrow$ ca $4^8 = 65536$ Kandidaten + + \item Berechnungen wurden mit dem im Anhang befindlichen Code durchgeführt. Die inverse der P-Box wurde per Hand + erstellt. + + $s_{out_1}$ für $X_1,Y_1$: 0111 1101 1001 0101 1011 1100 1001 0000 $\Rightarrow$ 7 13 9 5 11 12 9 0 + + Mögliche Werte für $s_{in_1}$: $\{011110,000101,110110,101111\}$ $\{011010,000011,101100,100001\}$ + $\{000100,000111,100110,101011\}$ $\{010110,000111,111000,110101\}$ $\{001100, 000011, 100110,100001\}$ + $\{000000,001011,101100,100111\}$ $\{010100, 001011,111100, 110001\}$ $\{011010,011001,110000,110111\}$ + + $s_{out_2}$ für $X_2,Y_2$: 1000 0101 1101 0011 0010 0010 0110 1000 $\Rightarrow$ 8 5 13 3 2 2 6 8 + + Mögliche Werte für $s_{in_2}$: $\{001110, 011111,100110,100101\}$ $\{011100,011111,110000,111011\}$ $\{010010, + 000001,100000,100101\}$ $\{000110, 001111,110100,100001\}$ $\{000000,000101,100010,101101\}$ + $\{001010,000111,101000,100101\}$ $\{011100,011111,110100,100001\}$ $\{010000, 000111,111110,101101\}$ + + $e_{out_1} =$ 011101010011001011101000000000010000000000000000 + + $e_{out_2} =$ 101010000001001001111000000000010000000000000000 + + Weiterer Ansatz: Alle $4^8$ Permutationen von $s_{in_1}$ und $s_{in_2}$ erzeugen und die Ergebnisse $\oplus + e_{out_1}$ bzw. $e_{out_2}$ rechnen. Die Schnittmenge aus dem ersten und zweiten Schritt bilden. Diese + Schnittmenge enthält die Schlüsselkandidaten. + + \item PC-2 hat $2^{56}$ mögliche Inputs und $2^{48}$ mögliche Outputs. + + $2^{56} / 2^{48} = 1024$ Kandidaten + +\end{enumerate} + + +% \section*{Code} + +% \inputminted{rust}{./school/intro-crypto/uebung/06/des/src/main.rs} + +\end{document} + diff --git a/school/intro-crypto/uebung/06/ches2006_copa.pdf b/school/intro-crypto/uebung/06/ches2006_copa.pdf new file mode 100644 index 0000000..9b0db50 Binary files /dev/null and b/school/intro-crypto/uebung/06/ches2006_copa.pdf differ diff --git a/school/intro-crypto/uebung/06/des/.gitignore b/school/intro-crypto/uebung/06/des/.gitignore new file mode 100644 index 0000000..53eaa21 --- /dev/null +++ b/school/intro-crypto/uebung/06/des/.gitignore @@ -0,0 +1,2 @@ +/target +**/*.rs.bk diff --git a/school/intro-crypto/uebung/06/des/Cargo.lock b/school/intro-crypto/uebung/06/des/Cargo.lock new file mode 100644 index 0000000..c885cd8 --- /dev/null +++ b/school/intro-crypto/uebung/06/des/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "des" +version = "0.1.0" + diff --git a/school/intro-crypto/uebung/06/des/Cargo.toml b/school/intro-crypto/uebung/06/des/Cargo.toml new file mode 100644 index 0000000..4e37dd8 --- /dev/null +++ b/school/intro-crypto/uebung/06/des/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "des" +version = "0.1.0" +authors = ["Valentin Brandl "] + +[dependencies] diff --git a/school/intro-crypto/uebung/06/des/src/main.rs b/school/intro-crypto/uebung/06/des/src/main.rs new file mode 100644 index 0000000..9cf3067 --- /dev/null +++ b/school/intro-crypto/uebung/06/des/src/main.rs @@ -0,0 +1,235 @@ +use std::collections::HashSet; + +const P_1: [usize; 32] = [ + 9, 17, 23, 31, 13, 28, 2, 18, 24, 16, 30, 6, 26, 20, 10, 1, 8, 14, 25, 3, 4, 29, 11, 19, 32, + 12, 22, 7, 5, 27, 15, 21, +]; + +const P: [usize; 32] = [ + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, + 13, 30, 6, 22, 11, 4, 25, +]; + +const E: [usize; 48] = [ + 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, + 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1, +]; + +fn permutate(i: &[T], b: &[usize]) -> Vec { + let mut res: Vec<_> = (0..b.len()).map(|_| T::default()).collect(); + for (i, p) in i.iter().zip(b.iter()) { + res[*p - 1] = *i; + } + res +} + +trait Split { + fn split(&self) -> (u32, u32); +} + +impl Split for u64 { + fn split(&self) -> (u32, u32) { + ((*self >> 32) as u32, *self as u32) + } +} + +fn xor(a: &[bool], b: &[bool]) -> Vec { + assert!(a.len() == b.len()); + a.iter().zip(b.iter()).map(|(a, b)| a ^ b).collect() +} + +fn to_bin(i: T) -> Vec { + format!("{:b}", i) + .chars() + .map(|c| if c == '1' { true } else { false }) + .collect() +} + +fn show(b: &[bool], split: u8) { + let mut i = 1; + b.iter().map(|c| if *c { '1' } else { '0' }).for_each(|c| { + print!("{}", c); + if i % split == 0 { + print!(" "); + } + i += 1; + }); + println!(); +} + +fn reverse_des(i: u64, o: u64) { + let (l0, r0) = i.split(); + let (l1, r1) = o.split(); + let e_out = permutate(&to_bin(r0), &E); + println!("e_out: "); + show(&e_out, 100); + let f_out = r1 ^ l0; + let s_out = permutate(&to_bin(f_out), &P_1); + assert!(&to_bin(f_out) == &permutate(&s_out, &P)); + println!("s_out: "); + show(&s_out, 4); + println!(); +} + +fn do_it(s: &[[[bool; 6]; 4]], x: &[bool]) -> HashSet> { + let mut set1 = HashSet::new(); + + for a in s[0].iter() { + for b in s[1].iter() { + for c in s[2].iter() { + for d in s[3].iter() { + for e in s[4].iter() { + for f in s[5].iter() { + for g in s[6].iter() { + for h in s[7].iter() { + let mut v = Vec::with_capacity(48); + v.extend(a); + v.extend(b); + v.extend(c); + v.extend(d); + v.extend(e); + v.extend(f); + v.extend(g); + v.extend(h); + let r = xor(&v, x); + set1.insert(r); + } + } + } + } + } + } + } + } + set1 +} + +fn main() { + let x1: u64 = 0xF57DDDB12EAA799D; + let y1: u64 = 0x2EAA799D332924D8; + let x2: u64 = 0x15837977D5202437; + let y2: u64 = 0xD5202437B5D8FC31; + + let s_in_1 = [ + [ + [false, true, true, true, true, false], + [false, false, false, true, false, true], + [true, true, false, true, true, false], + [true, false, true, true, true, true], + ], + [ + [false, true, true, false, true, false], + [false, false, false, false, true, true], + [true, false, true, true, false, false], + [true, false, false, false, false, true], + ], + [ + [false, false, false, true, false, false], + [false, false, false, true, true, true], + [true, false, false, true, true, false], + [true, false, true, false, true, true], + ], + [ + [false, true, false, true, true, false], + [false, false, false, true, true, true], + [true, true, true, false, false, false], + [true, true, false, true, false, true], + ], + [ + [false, false, true, true, false, false], + [false, false, false, false, true, true], + [true, false, false, true, true, false], + [true, false, false, false, false, true], + ], + [ + [false, false, false, false, false, false], + [false, false, true, false, true, true], + [true, false, true, true, false, false], + [true, false, false, true, true, true], + ], + [ + [false, true, false, true, false, false], + [false, false, true, false, true, true], + [true, true, true, true, false, false], + [true, true, false, false, false, true], + ], + [ + [false, true, true, false, true, false], + [false, true, true, false, false, true], + [true, true, false, false, false, false], + [true, true, false, true, true, true], + ], + ]; + let e_out_1 = [ + false, true, true, true, false, true, false, true, false, false, true, true, false, false, + true, false, true, true, true, false, true, false, false, false, false, false, false, + false, false, false, false, true, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + ]; + + let s_in_2 = [ + [ + [false, false, true, true, true, false], + [false, true, true, true, true, true], + [true, false, false, true, true, false], + [true, false, false, true, false, true], + ], + [ + [false, true, true, true, false, false], + [false, true, true, true, true, true], + [true, true, false, false, false, false], + [true, true, true, false, true, true], + ], + [ + [false, true, false, false, true, false], + [false, false, false, false, false, true], + [true, false, false, false, false, false], + [true, false, false, true, false, true], + ], + [ + [false, false, false, true, true, false], + [false, false, true, true, true, true], + [true, true, false, true, false, false], + [true, false, false, false, false, true], + ], + [ + [false, false, false, false, false, false], + [false, false, false, true, false, true], + [true, false, false, false, true, false], + [true, false, true, true, false, true], + ], + [ + [false, false, true, false, true, false], + [false, false, false, true, true, true], + [true, false, true, false, false, false], + [true, false, false, true, false, true], + ], + [ + [false, true, true, true, false, false], + [false, true, true, true, true, true], + [true, true, false, true, false, false], + [true, false, false, false, false, true], + ], + [ + [false, true, false, false, false, false], + [false, false, false, true, true, true], + [true, true, true, true, true, false], + [true, false, true, true, false, true], + ], + ]; + let e_out_2 = [ + true, false, true, false, true, false, false, false, false, false, false, true, false, + false, true, false, false, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, true, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, + ]; + + let set1 = do_it(&s_in_1, &e_out_1); + let set2 = do_it(&s_in_2, &e_out_2); + + let intersection: HashSet<_> = set1.intersection(&set2).collect(); + println!("{}", intersection.len()); + + // reverse_des(x1, y1); + // reverse_des(x2, y2); +} diff --git a/school/intro-crypto/uebung/06/Ãœbung_6_EK1_WS1819.pdf b/school/intro-crypto/uebung/06/Ãœbung_6_EK1_WS1819.pdf new file mode 100644 index 0000000..3f94c54 Binary files /dev/null and b/school/intro-crypto/uebung/06/Ãœbung_6_EK1_WS1819.pdf differ