From 79da6a2ca196d3a9ac4854c7d3623cde2b8ff7b8 Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Mon, 25 Jan 2021 11:07:54 +0100 Subject: [PATCH 01/10] Adds stub for fingerprinting --- applied-hash/Makefile | 4 + applied-hash/fingerprinting/.gitignore | 5 + applied-hash/fingerprinting/Makefile | 26 +++++ applied-hash/fingerprinting/abstract.tex | 22 +++++ applied-hash/fingerprinting/contents.tex | 69 +++++++++++++ applied-hash/fingerprinting/notes.tex | 45 +++++++++ applied-hash/fingerprinting/preamble.tex | 39 ++++++++ applied-hash/fingerprinting/slides.tex | 118 +++++++++++++++++++++++ 8 files changed, 328 insertions(+) create mode 100644 applied-hash/Makefile create mode 100644 applied-hash/fingerprinting/.gitignore create mode 100644 applied-hash/fingerprinting/Makefile create mode 100644 applied-hash/fingerprinting/abstract.tex create mode 100644 applied-hash/fingerprinting/contents.tex create mode 100644 applied-hash/fingerprinting/notes.tex create mode 100644 applied-hash/fingerprinting/preamble.tex create mode 100644 applied-hash/fingerprinting/slides.tex diff --git a/applied-hash/Makefile b/applied-hash/Makefile new file mode 100644 index 0000000..f802a49 --- /dev/null +++ b/applied-hash/Makefile @@ -0,0 +1,4 @@ +SUBDIR+= fingerprinting + +INCLUDE_MAKEFILES?=../makefiles +include ${INCLUDE_MAKEFILES}/subdir.mk diff --git a/applied-hash/fingerprinting/.gitignore b/applied-hash/fingerprinting/.gitignore new file mode 100644 index 0000000..5795ec5 --- /dev/null +++ b/applied-hash/fingerprinting/.gitignore @@ -0,0 +1,5 @@ +bibsp.sty +ltxobj/ +notes.pdf +slides.pdf + diff --git a/applied-hash/fingerprinting/Makefile b/applied-hash/fingerprinting/Makefile new file mode 100644 index 0000000..2999afa --- /dev/null +++ b/applied-hash/fingerprinting/Makefile @@ -0,0 +1,26 @@ +.PHONY: all +all: notes.pdf slides.pdf + +LATEXFLAGS+= -shell-escape + +SRC+= preamble.tex +SRC+= abstract.tex contents.tex + +DEPENDS+= bibsp.sty + +notes.pdf: notes.tex +notes.pdf: ${SRC} ${DEPENDS} + +slides.pdf: slides.tex +slides.pdf: ${SRC} ${DEPENDS} + + +.PHONY: clean +clean: + ${RM} notes.pdf slides.pdf + + +INCLUDE_MAKEFILES=../../makefiles +include ${INCLUDE_MAKEFILES}/tex.mk +INCLUDE_BIBSP=../../bibsp +include ${INCLUDE_BIBSP}/bibsp.mk diff --git a/applied-hash/fingerprinting/abstract.tex b/applied-hash/fingerprinting/abstract.tex new file mode 100644 index 0000000..4012d9d --- /dev/null +++ b/applied-hash/fingerprinting/abstract.tex @@ -0,0 +1,22 @@ +% What's the problem? +% Why is it a problem? Research gap left by other approaches? +% Why is it important? Why care? +% What's the approach? How to solve the problem? +% What's the findings? How was it evaluated, what are the results, limitations, +% what remains to be done? + +% XXX Summary +\emph{Summary:} +\dots + +% XXX Motivation and intended learning outcomes +\emph{Intended learning outcomes:} +\dots + +% XXX Prerequisites +\emph{Prerequisites:} +\dots + +% XXX Reading material +\emph{Reading:} +\dots diff --git a/applied-hash/fingerprinting/contents.tex b/applied-hash/fingerprinting/contents.tex new file mode 100644 index 0000000..8c71213 --- /dev/null +++ b/applied-hash/fingerprinting/contents.tex @@ -0,0 +1,69 @@ +\mode* + +\section{Introduction} + +\subsection[Hash functions]{What was a hash function now again?} + +\begin{frame} + \begin{definition}[One-way function\footfullcite{GoldreichFOC-1}] + \begin{itemize} + \item Let \(h\colon \{0,1\}^*\to \{0,1\}^*\). + \item \(h\) is \emph{one-way} if + \begin{enumerate} + \item there exists an efficient algorithm \(A\) such that \(A(x) + = h(x)\); + \item for every efficient algorithm \(A^\prime\), every positive + polynomial \(p(\cdot)\) and all sufficiently large \(n\)'s + \[\Prob{A^\prime(h(x), 1^n) \in h^{-1}(h(x))} < \frac{1}{p(n)}\] + \end{enumerate} + \end{itemize} + \end{definition} +\end{frame} + +\begin{frame} + \begin{definition}[Preimage resistance (one way)] + \begin{description} + \item[Input] hash function~\(H\), value~\(y\). + \item[Output] Any \(x\) such that \(H(x) = y\). + \end{description} + \end{definition} + + \begin{definition}[Second preimage resistance (weak collision resistance)] + \begin{description} + \item[Input] hash function~\(H\), value \(x\). + \item[Output] Any value \(x'\) such that \(H(x) = H(x')\). + \end{description} + \end{definition} + + \begin{definition}[Collision resistance (strong collision resistance)] + \begin{description} + \item[Input] hash function~\(H\). + \item[Output] Any two \(x, x'\) such that \(H(x) = H(x')\). + \end{description} + \end{definition} +\end{frame} + + +\section[Commitments]{Fingerprinting and commitments} + + +\section[Chaining]{Chaining and block chains} + + +\section{Tree hashing} + + +\section{Keyed hash functions} + + +\section{Password hashing} + + +\section{Proof-of-work} + + +\section{BitTorrent} + + +\section{Git} + diff --git a/applied-hash/fingerprinting/notes.tex b/applied-hash/fingerprinting/notes.tex new file mode 100644 index 0000000..90f77e2 --- /dev/null +++ b/applied-hash/fingerprinting/notes.tex @@ -0,0 +1,45 @@ +\documentclass{article} + +\usepackage[hyphens]{url} +\usepackage[hidelinks]{hyperref} + +\input{preamble.tex} + +\usepackage[noamsthm,notheorems]{beamerarticle} +\setjobnamebeamerversion{slides} + +%\usepackage{authblk} +%\let\institute\affil + +\declaretheorem[numbered=unless unique,style=theorem]{theorem} +\declaretheorem[numbered=unless unique,style=definition]{definition} +\declaretheorem[numbered=unless unique,style=definition]{assumption} +\declaretheorem[numbered=unless unique,style=definition]{protocol} +\declaretheorem[numbered=unless unique,style=example]{example} +%\declaretheorem[style=definition,numbered=unless unique, +% name=Example,refname={example,examples}]{example} +\declaretheorem[numbered=unless unique,style=remark]{remark} +\declaretheorem[numbered=unless unique,style=remark]{idea} +\declaretheorem[numbered=unless unique,style=exercise]{exercise} +\declaretheorem[numbered=unless unique,style=exercise]{question} +\declaretheorem[numbered=unless unique,style=solution]{solution} + +\begin{document} +\title{% + Applied Hash Functions +} +\author{Daniel Bosk} +\institute{% + KTH EECS +} + +\maketitle + +\begin{abstract} + \input{abstract.tex} +\end{abstract} + +\input{contents.tex} + +\printbibliography +\end{document} diff --git a/applied-hash/fingerprinting/preamble.tex b/applied-hash/fingerprinting/preamble.tex new file mode 100644 index 0000000..537ff27 --- /dev/null +++ b/applied-hash/fingerprinting/preamble.tex @@ -0,0 +1,39 @@ +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[british]{babel} +\usepackage{booktabs} + +\usepackage[all]{foreign} +\renewcommand{\foreignfullfont}{} +\renewcommand{\foreignabbrfont}{} + +\usepackage{newclude} +\usepackage{import} + +\usepackage[strict]{csquotes} +\usepackage[single]{acro} + +\usepackage[natbib,style=alphabetic,maxbibnames=99]{biblatex} +\addbibresource{applied-hash.bib} + +\usepackage{subcaption} + +\usepackage[noend]{algpseudocode} +\usepackage{xparse} + +\let\email\texttt + +\usepackage[outputdir=ltxobj]{minted} +\setminted{autogobble} + +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{mathtools} +\usepackage{amsthm} +\usepackage{thmtools} +\usepackage[unq]{unique} +\DeclareMathOperator{\powerset}{\mathcal{P}} + +\usepackage[binary-units]{siunitx} + +\usepackage{bibsp} diff --git a/applied-hash/fingerprinting/slides.tex b/applied-hash/fingerprinting/slides.tex new file mode 100644 index 0000000..128dc6b --- /dev/null +++ b/applied-hash/fingerprinting/slides.tex @@ -0,0 +1,118 @@ +\documentclass[ignoreframetext]{beamer} +\input{preamble.tex} + +\usetheme{Berlin} +\setbeamertemplate{footline}%{miniframes theme} +{% + \begin{beamercolorbox}[colsep=1.5pt]{upper separation line foot} + \end{beamercolorbox} + \begin{beamercolorbox}[ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{author in head/foot}% + \leavevmode{\usebeamerfont{author in head/foot}\insertshortauthor}% + \hfill% + {\usebeamerfont{institute in head/foot}\usebeamercolor[fg]{institute in head/foot}\insertshortinstitute}% + \end{beamercolorbox}% + \begin{beamercolorbox}[ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{title in head/foot}% + {\usebeamerfont{title in head/foot}\insertshorttitle} \hfill \insertframenumber% + \end{beamercolorbox}% + \begin{beamercolorbox}[colsep=1.5pt]{lower separation line foot} + \end{beamercolorbox} +} +\setbeamercovered{transparent} +\setbeamertemplate{bibliography item}[text] + +\AtBeginSection[]{% + \begin{frame} + \tableofcontents[currentsection] + \end{frame} +} + +\ProvideDocumentEnvironment{assumption}{o}{% + \IfValueTF{#1}{% + \begin{block}{Assumption: #1} + }{% + \begin{block}{Assumption} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{protocol}{o}{% + \IfValueTF{#1}{% + \begin{block}{Protocol: #1} + }{% + \begin{block}{Protocol} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{remark}{o}{% + \IfValueTF{#1}{% + \begin{alertblock}{Note: #1} + }{% + \begin{alertblock}{Note} + } +}{% + \end{alertblock} +} + +\ProvideDocumentEnvironment{idea}{o}{% + \IfValueTF{#1}{% + \begin{block}{Idea: #1} + }{% + \begin{block}{Idea} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{question}{o}{% + \setbeamercolor{block body}{bg=orange!15,fg=black} + \setbeamercolor{block title}{bg=orange,fg=white} + \setbeamercolor{local structure}{fg=orange} + \IfValueTF{#1}{% + \begin{block}{Question: #1} + }{% + \begin{block}{Question} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{exercise}{o}{% + \setbeamercolor{block body}{bg=yellow!10,fg=black} + \setbeamercolor{block title}{bg=yellow,fg=black} + \setbeamercolor{local structure}{fg=yellow} + \IfValueTF{#1}{% + \begin{block}{Exercise: #1} + }{% + \begin{block}{Exercise} + } +}{% + \end{block} +} + + +\begin{document} +\title{% + Applied Hash Functions +} +\author{Daniel Bosk} +\institute{% + KTH EECS +} + +\begin{frame} + \maketitle +\end{frame} + +\mode +\input{contents.tex} +\mode* + +\begin{frame}[allowframebreaks] + \printbibliography +\end{frame} +\end{document} From 6541fa51d83f25039e8b64a90c5dfbca849a431c Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Mon, 25 Jan 2021 20:47:54 +0100 Subject: [PATCH 02/10] Finishes fingerprinting slides --- applied-hash/fingerprinting/Makefile | 20 +- applied-hash/fingerprinting/contents.tex | 240 ++++++- applied-hash/fingerprinting/fig/.gitignore | 16 + applied-hash/fingerprinting/fig/Makefile | 25 + .../fingerprinting/fig/centralized.svg | 109 +++ .../fingerprinting/fig/file-parts.svg | 663 ++++++++++++++++++ .../fingerprinting/fig/git-challenge-1.svg | 3 + .../fingerprinting/fig/git-challenge-2.svg | 3 + .../fingerprinting/fig/git-commit.svg | 3 + .../fingerprinting/fig/git-objects.svg | 3 + .../fingerprinting/fig/merkle-tree.png | Bin 0 -> 45082 bytes applied-hash/fingerprinting/fig/p2p.svg | 234 +++++++ .../fingerprinting/fig/torrent-hashes.svg | 608 ++++++++++++++++ applied-hash/fingerprinting/notes.tex | 2 +- applied-hash/fingerprinting/preamble.tex | 2 +- applied-hash/fingerprinting/slides.tex | 2 +- 16 files changed, 1917 insertions(+), 16 deletions(-) create mode 100644 applied-hash/fingerprinting/fig/.gitignore create mode 100644 applied-hash/fingerprinting/fig/Makefile create mode 100644 applied-hash/fingerprinting/fig/centralized.svg create mode 100644 applied-hash/fingerprinting/fig/file-parts.svg create mode 100644 applied-hash/fingerprinting/fig/git-challenge-1.svg create mode 100644 applied-hash/fingerprinting/fig/git-challenge-2.svg create mode 100644 applied-hash/fingerprinting/fig/git-commit.svg create mode 100644 applied-hash/fingerprinting/fig/git-objects.svg create mode 100644 applied-hash/fingerprinting/fig/merkle-tree.png create mode 100644 applied-hash/fingerprinting/fig/p2p.svg create mode 100644 applied-hash/fingerprinting/fig/torrent-hashes.svg diff --git a/applied-hash/fingerprinting/Makefile b/applied-hash/fingerprinting/Makefile index 2999afa..bdb5352 100644 --- a/applied-hash/fingerprinting/Makefile +++ b/applied-hash/fingerprinting/Makefile @@ -8,17 +8,33 @@ SRC+= abstract.tex contents.tex DEPENDS+= bibsp.sty +FIGS+= centralized.pdf +FIGS+= p2p.pdf +FIGS+= file-parts.pdf +FIGS+= torrent-hashes.pdf +FIGS+= git-objects.pdf +FIGS+= git-commit.pdf +FIGS+= git-challenge-1.pdf git-challenge-2.pdf + notes.pdf: notes.tex -notes.pdf: ${SRC} ${DEPENDS} +notes.pdf: ${SRC} ${DEPENDS} $(addprefix fig/,${FIGS}) slides.pdf: slides.tex -slides.pdf: ${SRC} ${DEPENDS} +slides.pdf: ${SRC} ${DEPENDS} $(addprefix fig/,${FIGS}) + + +$(addprefix fig/, ${FIGS}): + ${MAKE} -C $(dir $@) $(notdir $@) .PHONY: clean clean: ${RM} notes.pdf slides.pdf +.PHONY: distclean +distclean: + ${MAKE} -C fig clean distclean + INCLUDE_MAKEFILES=../../makefiles include ${INCLUDE_MAKEFILES}/tex.mk diff --git a/applied-hash/fingerprinting/contents.tex b/applied-hash/fingerprinting/contents.tex index 8c71213..0a0c21f 100644 --- a/applied-hash/fingerprinting/contents.tex +++ b/applied-hash/fingerprinting/contents.tex @@ -1,8 +1,6 @@ \mode* -\section{Introduction} - -\subsection[Hash functions]{What was a hash function now again?} +\section[Hash functions]{What was a hash function now again?} \begin{frame} \begin{definition}[One-way function\footfullcite{GoldreichFOC-1}] @@ -44,26 +42,246 @@ \section{Introduction} \end{frame} -\section[Commitments]{Fingerprinting and commitments} +\section{Fingerprinting} + +\begin{frame} + \begin{definition}[Compressing] + \begin{itemize} + \item Function~\(f\colon \{0, 1\}^{l}\to \{0, 1\}^{l'}\) + \item We can have \(l > l'\). + \end{itemize} + \end{definition} + + \pause + + \begin{remark} + \begin{itemize} + \item Most hash functions are compressing. + \end{itemize} + \end{remark} +\end{frame} + +\begin{frame}[fragile] + \begin{example}[Compressing] + \begin{itemize} + \begin{minted}{text} +(1|11:27)dbosk@X1:WinDev2007Eval +$ du WinDev2007Eval-disk001.vdi +43G WinDev2007Eval-disk001.vdi +(0|11:28)dbosk@X1:WinDev2007Eval +$ sha256sum WinDev2007Eval-disk001.vdi +5260fe9713a5b6341aca8d7e61c9cdb9bb50ee9f5f0bc15e5427a07397df9d95 WinDev2007Eval-disk001.vdi +(0|11:32)dbosk@X1:WinDev2007Eval +$ + \end{minted} + \end{itemize} + \end{example} +\end{frame} +\begin{frame} + \begin{block}{Requirements} + \begin{description} + \item[Compressing property] to make the fingerprint small. + \item[Collision resistance] to reduce likelihood of collisions. + \end{description} + \end{block} +\end{frame} -\section[Chaining]{Chaining and block chains} +\subsection{BitTorrent} +\begin{frame} + \begin{figure} + \begin{subfigure}{0.45\columnwidth} + \centering + \includegraphics[width=\columnwidth]{fig/centralized.pdf} + \caption{Centralized} + \end{subfigure} + \hfill + \begin{subfigure}{0.45\columnwidth} + \centering + \includegraphics[width=\columnwidth]{fig/p2p.pdf} + \caption{Peer-to-peer (P2P)} + \end{subfigure} + \end{figure} +\end{frame} -\section{Tree hashing} +\begin{frame} + \begin{figure} + \begin{subfigure}{0.45\columnwidth} + \centering + \includegraphics[height=0.4\textheight]{fig/centralized.pdf} + \caption{Centralized} + \end{subfigure} + \hfill + \begin{subfigure}{0.45\columnwidth} + \centering + \includegraphics[height=0.4\textheight]{fig/p2p.pdf} + \caption{Peer-to-peer (P2P)} + \end{subfigure} + \end{figure} + \begin{question} + \begin{itemize} + \item How to get most out of the P2P case? + \end{itemize} + \end{question} +\end{frame} -\section{Keyed hash functions} +\begin{frame} + \begin{figure} + \begin{subfigure}{0.45\columnwidth} + \centering + \includegraphics[height=0.5\textheight]{fig/p2p.pdf} + \caption{Peer-to-peer (P2P)} + \end{subfigure} + \hfill + \begin{subfigure}{0.45\columnwidth} + \only<1>{% + \centering + \includegraphics[width=\columnwidth]{fig/file-parts.pdf} + \caption{File divided into parts} + } + \only<2>{% + \centering + \includegraphics[width=\columnwidth]{fig/torrent-hashes.pdf} + \caption{Hash values of file and parts} + } + \end{subfigure} + \end{figure} + \begin{solution} + \begin{itemize} + \item Must keep track of different parts of a file. + \end{itemize} + \end{solution} +\end{frame} -\section{Password hashing} +\begin{frame} + \begin{remark} + \begin{itemize} + \item We want a cryptographic hash function if we want authenticity + properties. + \item Will a malicious actor inject fake parts of files? + \item Authenticated torrent file gives authenticated file. + \end{itemize} + \end{remark} +\end{frame} -\section{Proof-of-work} +\subsection{Git} +\begin{frame} + \begin{remark} + \begin{itemize} + \item Git is a content-addressable file system. + \end{itemize} + \end{remark} -\section{BitTorrent} + \pause + \begin{definition}[Git blob {[binary large object]}] + \begin{itemize} + \item Name is hash value of content and a header. + \item Content is just the content. + \end{itemize} + \end{definition} +\end{frame} + +\begin{frame} + \begin{figure} + \centering + \includegraphics[height=0.8\textheight]{fig/git-objects.pdf} + \caption{Git objects with hashes \texttt{deadbeef}, \texttt{deadcode}, + \texttt{oobab1oc}, \texttt{000ff1ce}.} + \end{figure} +\end{frame} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item Blobs don't store file names etc., just content. + \item Tree objects solve the problem of storing the filename. + \item Also allow you to store a group of files together. + \end{itemize} + \end{remark} + + \pause + + \begin{definition}[Tree object] + \begin{itemize} + \item Blob with structured content: + \item file mode + \item type (blob, tree \etc) + \item human readable name + \end{itemize} + \end{definition} +\end{frame} + +\begin{frame} + \begin{figure} + \centering + \includegraphics[height=0.8\textheight]{fig/git-objects.pdf} + \caption{Tree objects with hashes \texttt{oobab1oc}, \texttt{000ff1ce}.} + \end{figure} +\end{frame} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item A tree doesn't keep track of versions. + \end{itemize} + \end{remark} + + \begin{definition}[Commit] + \begin{itemize} + \item Tree (current state) + \item Parent commits + \item Author + \item Commit log + \end{itemize} + \end{definition} +\end{frame} + +\begin{frame} + \begin{figure} + \includegraphics[height=0.8\textheight]{fig/git-commit.pdf} + \caption{A commit \texttt{feedc0de}.} + \end{figure} +\end{frame} + +\begin{frame} + \begin{exercise} + \begin{columns} + \begin{column}{0.40\columnwidth} + \begin{figure} + \includegraphics[height=0.6\textheight]{fig/git-challenge-2.pdf} + \caption{Some Git objects.} + \end{figure} + \end{column} + \begin{column}{0.45\columnwidth} + \begin{itemize} + \item What happened if the initial commit is \texttt{00bab10c}? + \end{itemize} + \end{column} + \end{columns} + \end{exercise} +\end{frame} -\section{Git} +%\begin{frame} +% \begin{exercise} +% \begin{columns} +% \begin{column}{0.40\columnwidth} +% \begin{figure} +% \includegraphics[height=0.6\textheight]{fig/git-challenge-1.pdf} +% \caption{Some Git objects.} +% \end{figure} +% \end{column} +% \begin{column}{0.45\columnwidth} +% \begin{itemize} +% \item What happened if the initial commit is \texttt{c00010ff}? +% \end{itemize} +% \end{column} +% \end{columns} +% \end{exercise} +%\end{frame} diff --git a/applied-hash/fingerprinting/fig/.gitignore b/applied-hash/fingerprinting/fig/.gitignore new file mode 100644 index 0000000..1034c98 --- /dev/null +++ b/applied-hash/fingerprinting/fig/.gitignore @@ -0,0 +1,16 @@ +centralized.pdf +centralized.pdf_tex +file-parts.pdf +file-parts.pdf_tex +git-challenge-1.pdf +git-challenge-1.pdf_tex +git-challenge-2.pdf +git-challenge-2.pdf_tex +git-commit.pdf +git-commit.pdf_tex +git-objects.pdf +git-objects.pdf_tex +p2p.pdf +p2p.pdf_tex +torrent-hashes.pdf +torrent-hashes.pdf_tex diff --git a/applied-hash/fingerprinting/fig/Makefile b/applied-hash/fingerprinting/fig/Makefile new file mode 100644 index 0000000..5627300 --- /dev/null +++ b/applied-hash/fingerprinting/fig/Makefile @@ -0,0 +1,25 @@ +.PHONY: all +all: centralized.pdf p2p.pdf +all: file-parts.pdf torrent-hashes.pdf +all: merkle-tree.pdf +all: git-commit.pdf +all: git-objects.pdf +all: git-challenge-1.pdf +all: git-challenge-2.pdf + + +.PHONY: clean +clean: + ${RM} centralized.pdf p2p.pdf + ${RM} centralized.pdf_tex p2p.pdf_tex + ${RM} file-parts.pdf torrent-hashes.pdf + ${RM} file-parts.pdf_tex torrent-hashes.pdf_tex + ${RM} merkle-tree.pdf merkle-tree.pdf_tex + ${RM} git-commit.pdf git-commit.pdf_tex + ${RM} git-objects.pdf git-objects.pdf_tex + ${RM} git-challenge-1.pdf git-challenge-1.pdf_tex + ${RM} git-challenge-2.pdf git-challenge-2.pdf_tex + + +INCLUDE_MAKEFILES=../../../makefiles +include ${INCLUDE_MAKEFILES}/doc.mk diff --git a/applied-hash/fingerprinting/fig/centralized.svg b/applied-hash/fingerprinting/fig/centralized.svg new file mode 100644 index 0000000..8df136d --- /dev/null +++ b/applied-hash/fingerprinting/fig/centralized.svg @@ -0,0 +1,109 @@ + + + + + image/svg+xml + + + + + + +applied-hash notes +\n + + + + + + + + + + + + + + + + + + diff --git a/applied-hash/fingerprinting/fig/file-parts.svg b/applied-hash/fingerprinting/fig/file-parts.svg new file mode 100644 index 0000000..a3b8524 --- /dev/null +++ b/applied-hash/fingerprinting/fig/file-parts.svg @@ -0,0 +1,663 @@ + + + + + image/svg+xml + + + + + + +applied-hash notes +\n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applied-hash/fingerprinting/fig/git-challenge-1.svg b/applied-hash/fingerprinting/fig/git-challenge-1.svg new file mode 100644 index 0000000..c0c1b76 --- /dev/null +++ b/applied-hash/fingerprinting/fig/git-challenge-1.svg @@ -0,0 +1,3 @@ +applied-hash notes + + \ No newline at end of file diff --git a/applied-hash/fingerprinting/fig/git-challenge-2.svg b/applied-hash/fingerprinting/fig/git-challenge-2.svg new file mode 100644 index 0000000..0b80aa8 --- /dev/null +++ b/applied-hash/fingerprinting/fig/git-challenge-2.svg @@ -0,0 +1,3 @@ +applied-hash notes + + \ No newline at end of file diff --git a/applied-hash/fingerprinting/fig/git-commit.svg b/applied-hash/fingerprinting/fig/git-commit.svg new file mode 100644 index 0000000..c5eae8b --- /dev/null +++ b/applied-hash/fingerprinting/fig/git-commit.svg @@ -0,0 +1,3 @@ +applied-hash notes + + \ No newline at end of file diff --git a/applied-hash/fingerprinting/fig/git-objects.svg b/applied-hash/fingerprinting/fig/git-objects.svg new file mode 100644 index 0000000..28906d7 --- /dev/null +++ b/applied-hash/fingerprinting/fig/git-objects.svg @@ -0,0 +1,3 @@ +applied-hash notes + + \ No newline at end of file diff --git a/applied-hash/fingerprinting/fig/merkle-tree.png b/applied-hash/fingerprinting/fig/merkle-tree.png new file mode 100644 index 0000000000000000000000000000000000000000..4572da1cff3ee5c63f254ab988bcbd38ba5918e9 GIT binary patch literal 45082 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 IsB + + + + image/svg+xml + + + + + + +applied-hash notes +\n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applied-hash/fingerprinting/fig/torrent-hashes.svg b/applied-hash/fingerprinting/fig/torrent-hashes.svg new file mode 100644 index 0000000..4942cc7 --- /dev/null +++ b/applied-hash/fingerprinting/fig/torrent-hashes.svg @@ -0,0 +1,608 @@ + + + + + image/svg+xml + + + + + + +applied-hash notes +\n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applied-hash/fingerprinting/notes.tex b/applied-hash/fingerprinting/notes.tex index 90f77e2..f6e9ab4 100644 --- a/applied-hash/fingerprinting/notes.tex +++ b/applied-hash/fingerprinting/notes.tex @@ -26,7 +26,7 @@ \begin{document} \title{% - Applied Hash Functions + Applied Hash Functions: Fingerprinting } \author{Daniel Bosk} \institute{% diff --git a/applied-hash/fingerprinting/preamble.tex b/applied-hash/fingerprinting/preamble.tex index 537ff27..4143818 100644 --- a/applied-hash/fingerprinting/preamble.tex +++ b/applied-hash/fingerprinting/preamble.tex @@ -24,7 +24,7 @@ \let\email\texttt \usepackage[outputdir=ltxobj]{minted} -\setminted{autogobble} +\setminted{autogobble,fontsize=\footnotesize} \usepackage{amsmath} \usepackage{amssymb} diff --git a/applied-hash/fingerprinting/slides.tex b/applied-hash/fingerprinting/slides.tex index 128dc6b..359c1d8 100644 --- a/applied-hash/fingerprinting/slides.tex +++ b/applied-hash/fingerprinting/slides.tex @@ -97,7 +97,7 @@ \begin{document} \title{% - Applied Hash Functions + Applied Hash Functions: Fingerprinting } \author{Daniel Bosk} \institute{% From 61446f7c11296cf831234b99398b18466fd0b91b Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Mon, 25 Jan 2021 20:53:28 +0100 Subject: [PATCH 03/10] Adds "what properties" for git --- applied-hash/fingerprinting/contents.tex | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/applied-hash/fingerprinting/contents.tex b/applied-hash/fingerprinting/contents.tex index 0a0c21f..cdd8838 100644 --- a/applied-hash/fingerprinting/contents.tex +++ b/applied-hash/fingerprinting/contents.tex @@ -285,3 +285,23 @@ \subsection{Git} % \end{exercise} %\end{frame} +\begin{frame} + \begin{exercise} + \begin{itemize} + \item What properties do we want from the hash function? + \end{itemize} + \end{exercise} +\end{frame} + +\begin{frame} + \begin{solution} + \begin{itemize} + \item Compression (short identifiers) + \item Collision resistance: + \begin{itemize} + \item Cryptographic: in case we want authentication. + \item Otherwise, just to avoid two different objects colliding. + \end{itemize} + \end{itemize} + \end{solution} +\end{frame} From f0a09c8b56f4635741a5257e66c41fa4ce1f29d8 Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Tue, 26 Jan 2021 08:57:17 +0100 Subject: [PATCH 04/10] Adds applied-hashes passwords WIP stub --- applied-hash/passwords/.gitignore | 5 ++ applied-hash/passwords/Makefile | 36 +++++++++ applied-hash/passwords/abstract.tex | 22 ++++++ applied-hash/passwords/contents.tex | 46 +++++++++++ applied-hash/passwords/fig/Makefile | 11 +++ applied-hash/passwords/notes.tex | 45 +++++++++++ applied-hash/passwords/preamble.tex | 39 +++++++++ applied-hash/passwords/slides.tex | 118 ++++++++++++++++++++++++++++ 8 files changed, 322 insertions(+) create mode 100644 applied-hash/passwords/.gitignore create mode 100644 applied-hash/passwords/Makefile create mode 100644 applied-hash/passwords/abstract.tex create mode 100644 applied-hash/passwords/contents.tex create mode 100644 applied-hash/passwords/fig/Makefile create mode 100644 applied-hash/passwords/notes.tex create mode 100644 applied-hash/passwords/preamble.tex create mode 100644 applied-hash/passwords/slides.tex diff --git a/applied-hash/passwords/.gitignore b/applied-hash/passwords/.gitignore new file mode 100644 index 0000000..5795ec5 --- /dev/null +++ b/applied-hash/passwords/.gitignore @@ -0,0 +1,5 @@ +bibsp.sty +ltxobj/ +notes.pdf +slides.pdf + diff --git a/applied-hash/passwords/Makefile b/applied-hash/passwords/Makefile new file mode 100644 index 0000000..074abbc --- /dev/null +++ b/applied-hash/passwords/Makefile @@ -0,0 +1,36 @@ +.PHONY: all +all: notes.pdf slides.pdf + +LATEXFLAGS+= -shell-escape + +SRC+= preamble.tex +SRC+= abstract.tex contents.tex + +DEPENDS+= bibsp.sty + +FIGS+= + +notes.pdf: notes.tex +notes.pdf: ${SRC} ${DEPENDS} $(addprefix fig/,${FIGS}) + +slides.pdf: slides.tex +slides.pdf: ${SRC} ${DEPENDS} $(addprefix fig/,${FIGS}) + + +$(addprefix fig/, ${FIGS}): + ${MAKE} -C $(dir $@) $(notdir $@) + + +.PHONY: clean +clean: + ${RM} notes.pdf slides.pdf + +.PHONY: distclean +distclean: + ${MAKE} -C fig clean + + +INCLUDE_MAKEFILES=../../makefiles +include ${INCLUDE_MAKEFILES}/tex.mk +INCLUDE_BIBSP=../../bibsp +include ${INCLUDE_BIBSP}/bibsp.mk diff --git a/applied-hash/passwords/abstract.tex b/applied-hash/passwords/abstract.tex new file mode 100644 index 0000000..4012d9d --- /dev/null +++ b/applied-hash/passwords/abstract.tex @@ -0,0 +1,22 @@ +% What's the problem? +% Why is it a problem? Research gap left by other approaches? +% Why is it important? Why care? +% What's the approach? How to solve the problem? +% What's the findings? How was it evaluated, what are the results, limitations, +% what remains to be done? + +% XXX Summary +\emph{Summary:} +\dots + +% XXX Motivation and intended learning outcomes +\emph{Intended learning outcomes:} +\dots + +% XXX Prerequisites +\emph{Prerequisites:} +\dots + +% XXX Reading material +\emph{Reading:} +\dots diff --git a/applied-hash/passwords/contents.tex b/applied-hash/passwords/contents.tex new file mode 100644 index 0000000..aff2b48 --- /dev/null +++ b/applied-hash/passwords/contents.tex @@ -0,0 +1,46 @@ +\mode* + +\section[Hash functions]{What was a hash function now again?} + +\begin{frame} + \begin{definition}[One-way function\footfullcite{GoldreichFOC-1}] + \begin{itemize} + \item Let \(h\colon \{0,1\}^*\to \{0,1\}^*\). + \item \(h\) is \emph{one-way} if + \begin{enumerate} + \item there exists an efficient algorithm \(A\) such that \(A(x) + = h(x)\); + \item for every efficient algorithm \(A^\prime\), every positive + polynomial \(p(\cdot)\) and all sufficiently large \(n\)'s + \[\Prob{A^\prime(h(x), 1^n) \in h^{-1}(h(x))} < \frac{1}{p(n)}\] + \end{enumerate} + \end{itemize} + \end{definition} +\end{frame} + +\begin{frame} + \begin{definition}[Preimage resistance (one way)] + \begin{description} + \item[Input] hash function~\(H\), value~\(y\). + \item[Output] Any \(x\) such that \(H(x) = y\). + \end{description} + \end{definition} + + \begin{definition}[Second preimage resistance (weak collision resistance)] + \begin{description} + \item[Input] hash function~\(H\), value \(x\). + \item[Output] Any value \(x'\) such that \(H(x) = H(x')\). + \end{description} + \end{definition} + + \begin{definition}[Collision resistance (strong collision resistance)] + \begin{description} + \item[Input] hash function~\(H\). + \item[Output] Any two \(x, x'\) such that \(H(x) = H(x')\). + \end{description} + \end{definition} +\end{frame} + + +\section{Password hashing} + diff --git a/applied-hash/passwords/fig/Makefile b/applied-hash/passwords/fig/Makefile new file mode 100644 index 0000000..d2d980e --- /dev/null +++ b/applied-hash/passwords/fig/Makefile @@ -0,0 +1,11 @@ +.PHONY: all +all: + + +.PHONY: clean +clean: + true + + +INCLUDE_MAKEFILES=../../../makefiles +include ${INCLUDE_MAKEFILES}/doc.mk diff --git a/applied-hash/passwords/notes.tex b/applied-hash/passwords/notes.tex new file mode 100644 index 0000000..df44d84 --- /dev/null +++ b/applied-hash/passwords/notes.tex @@ -0,0 +1,45 @@ +\documentclass{article} + +\usepackage[hyphens]{url} +\usepackage[hidelinks]{hyperref} + +\input{preamble.tex} + +\usepackage[noamsthm,notheorems]{beamerarticle} +\setjobnamebeamerversion{slides} + +%\usepackage{authblk} +%\let\institute\affil + +\declaretheorem[numbered=unless unique,style=theorem]{theorem} +\declaretheorem[numbered=unless unique,style=definition]{definition} +\declaretheorem[numbered=unless unique,style=definition]{assumption} +\declaretheorem[numbered=unless unique,style=definition]{protocol} +\declaretheorem[numbered=unless unique,style=example]{example} +%\declaretheorem[style=definition,numbered=unless unique, +% name=Example,refname={example,examples}]{example} +\declaretheorem[numbered=unless unique,style=remark]{remark} +\declaretheorem[numbered=unless unique,style=remark]{idea} +\declaretheorem[numbered=unless unique,style=exercise]{exercise} +\declaretheorem[numbered=unless unique,style=exercise]{question} +\declaretheorem[numbered=unless unique,style=solution]{solution} + +\begin{document} +\title{% + Applied Hash Functions: Passwords +} +\author{Daniel Bosk} +\institute{% + KTH EECS +} + +\maketitle + +\begin{abstract} + \input{abstract.tex} +\end{abstract} + +\input{contents.tex} + +\printbibliography +\end{document} diff --git a/applied-hash/passwords/preamble.tex b/applied-hash/passwords/preamble.tex new file mode 100644 index 0000000..4143818 --- /dev/null +++ b/applied-hash/passwords/preamble.tex @@ -0,0 +1,39 @@ +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[british]{babel} +\usepackage{booktabs} + +\usepackage[all]{foreign} +\renewcommand{\foreignfullfont}{} +\renewcommand{\foreignabbrfont}{} + +\usepackage{newclude} +\usepackage{import} + +\usepackage[strict]{csquotes} +\usepackage[single]{acro} + +\usepackage[natbib,style=alphabetic,maxbibnames=99]{biblatex} +\addbibresource{applied-hash.bib} + +\usepackage{subcaption} + +\usepackage[noend]{algpseudocode} +\usepackage{xparse} + +\let\email\texttt + +\usepackage[outputdir=ltxobj]{minted} +\setminted{autogobble,fontsize=\footnotesize} + +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{mathtools} +\usepackage{amsthm} +\usepackage{thmtools} +\usepackage[unq]{unique} +\DeclareMathOperator{\powerset}{\mathcal{P}} + +\usepackage[binary-units]{siunitx} + +\usepackage{bibsp} diff --git a/applied-hash/passwords/slides.tex b/applied-hash/passwords/slides.tex new file mode 100644 index 0000000..3ef5207 --- /dev/null +++ b/applied-hash/passwords/slides.tex @@ -0,0 +1,118 @@ +\documentclass[ignoreframetext]{beamer} +\input{preamble.tex} + +\usetheme{Berlin} +\setbeamertemplate{footline}%{miniframes theme} +{% + \begin{beamercolorbox}[colsep=1.5pt]{upper separation line foot} + \end{beamercolorbox} + \begin{beamercolorbox}[ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{author in head/foot}% + \leavevmode{\usebeamerfont{author in head/foot}\insertshortauthor}% + \hfill% + {\usebeamerfont{institute in head/foot}\usebeamercolor[fg]{institute in head/foot}\insertshortinstitute}% + \end{beamercolorbox}% + \begin{beamercolorbox}[ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{title in head/foot}% + {\usebeamerfont{title in head/foot}\insertshorttitle} \hfill \insertframenumber% + \end{beamercolorbox}% + \begin{beamercolorbox}[colsep=1.5pt]{lower separation line foot} + \end{beamercolorbox} +} +\setbeamercovered{transparent} +\setbeamertemplate{bibliography item}[text] + +\AtBeginSection[]{% + \begin{frame} + \tableofcontents[currentsection] + \end{frame} +} + +\ProvideDocumentEnvironment{assumption}{o}{% + \IfValueTF{#1}{% + \begin{block}{Assumption: #1} + }{% + \begin{block}{Assumption} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{protocol}{o}{% + \IfValueTF{#1}{% + \begin{block}{Protocol: #1} + }{% + \begin{block}{Protocol} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{remark}{o}{% + \IfValueTF{#1}{% + \begin{alertblock}{Note: #1} + }{% + \begin{alertblock}{Note} + } +}{% + \end{alertblock} +} + +\ProvideDocumentEnvironment{idea}{o}{% + \IfValueTF{#1}{% + \begin{block}{Idea: #1} + }{% + \begin{block}{Idea} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{question}{o}{% + \setbeamercolor{block body}{bg=orange!15,fg=black} + \setbeamercolor{block title}{bg=orange,fg=white} + \setbeamercolor{local structure}{fg=orange} + \IfValueTF{#1}{% + \begin{block}{Question: #1} + }{% + \begin{block}{Question} + } +}{% + \end{block} +} + +\ProvideDocumentEnvironment{exercise}{o}{% + \setbeamercolor{block body}{bg=yellow!10,fg=black} + \setbeamercolor{block title}{bg=yellow,fg=black} + \setbeamercolor{local structure}{fg=yellow} + \IfValueTF{#1}{% + \begin{block}{Exercise: #1} + }{% + \begin{block}{Exercise} + } +}{% + \end{block} +} + + +\begin{document} +\title{% + Applied Hash Functions: Passwords +} +\author{Daniel Bosk} +\institute{% + KTH EECS +} + +\begin{frame} + \maketitle +\end{frame} + +\mode +\input{contents.tex} +\mode* + +\begin{frame}[allowframebreaks] + \printbibliography +\end{frame} +\end{document} From c8288c8747c0474e7ef8aeaccd7f3d29081fc112 Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Tue, 26 Jan 2021 09:06:22 +0100 Subject: [PATCH 05/10] Fixes ref --- applied-hash/fingerprinting/.gitignore | 3 ++- applied-hash/fingerprinting/Makefile | 1 + applied-hash/fingerprinting/preamble.tex | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/applied-hash/fingerprinting/.gitignore b/applied-hash/fingerprinting/.gitignore index 5795ec5..31a3e79 100644 --- a/applied-hash/fingerprinting/.gitignore +++ b/applied-hash/fingerprinting/.gitignore @@ -1,5 +1,6 @@ -bibsp.sty ltxobj/ notes.pdf slides.pdf +bibsp.sty +crypto.bib diff --git a/applied-hash/fingerprinting/Makefile b/applied-hash/fingerprinting/Makefile index bdb5352..c7f39a2 100644 --- a/applied-hash/fingerprinting/Makefile +++ b/applied-hash/fingerprinting/Makefile @@ -7,6 +7,7 @@ SRC+= preamble.tex SRC+= abstract.tex contents.tex DEPENDS+= bibsp.sty +DEPENDS+= crypto.bib FIGS+= centralized.pdf FIGS+= p2p.pdf diff --git a/applied-hash/fingerprinting/preamble.tex b/applied-hash/fingerprinting/preamble.tex index 4143818..ec61d2a 100644 --- a/applied-hash/fingerprinting/preamble.tex +++ b/applied-hash/fingerprinting/preamble.tex @@ -14,7 +14,7 @@ \usepackage[single]{acro} \usepackage[natbib,style=alphabetic,maxbibnames=99]{biblatex} -\addbibresource{applied-hash.bib} +\addbibresource{crypto.bib} \usepackage{subcaption} From fb755ca42035e217afa79781fa3852487285b9c0 Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Tue, 26 Jan 2021 09:11:58 +0100 Subject: [PATCH 06/10] Fixes ref for passwords --- applied-hash/passwords/.gitignore | 3 ++- applied-hash/passwords/Makefile | 1 + applied-hash/passwords/preamble.tex | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/applied-hash/passwords/.gitignore b/applied-hash/passwords/.gitignore index 5795ec5..31a3e79 100644 --- a/applied-hash/passwords/.gitignore +++ b/applied-hash/passwords/.gitignore @@ -1,5 +1,6 @@ -bibsp.sty ltxobj/ notes.pdf slides.pdf +bibsp.sty +crypto.bib diff --git a/applied-hash/passwords/Makefile b/applied-hash/passwords/Makefile index 074abbc..3c1f14b 100644 --- a/applied-hash/passwords/Makefile +++ b/applied-hash/passwords/Makefile @@ -7,6 +7,7 @@ SRC+= preamble.tex SRC+= abstract.tex contents.tex DEPENDS+= bibsp.sty +DEPENDS+= crypto.bib FIGS+= diff --git a/applied-hash/passwords/preamble.tex b/applied-hash/passwords/preamble.tex index 4143818..ec61d2a 100644 --- a/applied-hash/passwords/preamble.tex +++ b/applied-hash/passwords/preamble.tex @@ -14,7 +14,7 @@ \usepackage[single]{acro} \usepackage[natbib,style=alphabetic,maxbibnames=99]{biblatex} -\addbibresource{applied-hash.bib} +\addbibresource{crypto.bib} \usepackage{subcaption} From 3806f071140571aaf93a85de3475831de20f4e3e Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Tue, 26 Jan 2021 09:17:51 +0100 Subject: [PATCH 07/10] Extracts hash review This way each part can just link to this one. Any updates don't have to be fixed everywhere. --- applied-hash/fingerprinting/contents.tex | 41 +--------------------- applied-hash/hash-review.tex | 43 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 40 deletions(-) create mode 100644 applied-hash/hash-review.tex diff --git a/applied-hash/fingerprinting/contents.tex b/applied-hash/fingerprinting/contents.tex index cdd8838..bf4c934 100644 --- a/applied-hash/fingerprinting/contents.tex +++ b/applied-hash/fingerprinting/contents.tex @@ -1,45 +1,6 @@ \mode* -\section[Hash functions]{What was a hash function now again?} - -\begin{frame} - \begin{definition}[One-way function\footfullcite{GoldreichFOC-1}] - \begin{itemize} - \item Let \(h\colon \{0,1\}^*\to \{0,1\}^*\). - \item \(h\) is \emph{one-way} if - \begin{enumerate} - \item there exists an efficient algorithm \(A\) such that \(A(x) - = h(x)\); - \item for every efficient algorithm \(A^\prime\), every positive - polynomial \(p(\cdot)\) and all sufficiently large \(n\)'s - \[\Prob{A^\prime(h(x), 1^n) \in h^{-1}(h(x))} < \frac{1}{p(n)}\] - \end{enumerate} - \end{itemize} - \end{definition} -\end{frame} - -\begin{frame} - \begin{definition}[Preimage resistance (one way)] - \begin{description} - \item[Input] hash function~\(H\), value~\(y\). - \item[Output] Any \(x\) such that \(H(x) = y\). - \end{description} - \end{definition} - - \begin{definition}[Second preimage resistance (weak collision resistance)] - \begin{description} - \item[Input] hash function~\(H\), value \(x\). - \item[Output] Any value \(x'\) such that \(H(x) = H(x')\). - \end{description} - \end{definition} - - \begin{definition}[Collision resistance (strong collision resistance)] - \begin{description} - \item[Input] hash function~\(H\). - \item[Output] Any two \(x, x'\) such that \(H(x) = H(x')\). - \end{description} - \end{definition} -\end{frame} +\input{../hash-review.tex} \section{Fingerprinting} diff --git a/applied-hash/hash-review.tex b/applied-hash/hash-review.tex new file mode 100644 index 0000000..8fd39c9 --- /dev/null +++ b/applied-hash/hash-review.tex @@ -0,0 +1,43 @@ +\mode* + +\section[Hash functions]{What was a hash function now again?} + +\begin{frame} + \begin{definition}[One-way function\footfullcite{GoldreichFOC-1}] + \begin{itemize} + \item Let \(h\colon \{0,1\}^*\to \{0,1\}^*\). + \item \(h\) is \emph{one-way} if + \begin{enumerate} + \item there exists an efficient algorithm \(A\) such that \(A(x) + = h(x)\); + \item for every efficient algorithm \(A^\prime\), every positive + polynomial \(p(\cdot)\) and all sufficiently large \(n\)'s + \[\Prob{A^\prime(h(x), 1^n) \in h^{-1}(h(x))} < \frac{1}{p(n)}\] + \end{enumerate} + \end{itemize} + \end{definition} +\end{frame} + +\begin{frame} + \begin{definition}[Preimage resistance {[one way]}] + \begin{description} + \item[Input] hash function~\(H\), value~\(y\). + \item[Output] Any \(x\) such that \(H(x) = y\). + \end{description} + \end{definition} + + \begin{definition}[Second preimage resistance {[weak collision resistance]}] + \begin{description} + \item[Input] hash function~\(H\), value \(x\). + \item[Output] Any value \(x'\) such that \(H(x) = H(x')\). + \end{description} + \end{definition} + + \begin{definition}[Collision resistance {[strong collision resistance]}] + \begin{description} + \item[Input] hash function~\(H\). + \item[Output] Any two \(x, x'\) such that \(H(x) = H(x')\). + \end{description} + \end{definition} +\end{frame} + From af350178f8ec94d86114daa1790f3be71f9286c2 Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Tue, 26 Jan 2021 09:19:33 +0100 Subject: [PATCH 08/10] Uses common hash-review.tex in passwords --- applied-hash/passwords/contents.tex | 41 +---------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/applied-hash/passwords/contents.tex b/applied-hash/passwords/contents.tex index aff2b48..33d301c 100644 --- a/applied-hash/passwords/contents.tex +++ b/applied-hash/passwords/contents.tex @@ -1,45 +1,6 @@ \mode* -\section[Hash functions]{What was a hash function now again?} - -\begin{frame} - \begin{definition}[One-way function\footfullcite{GoldreichFOC-1}] - \begin{itemize} - \item Let \(h\colon \{0,1\}^*\to \{0,1\}^*\). - \item \(h\) is \emph{one-way} if - \begin{enumerate} - \item there exists an efficient algorithm \(A\) such that \(A(x) - = h(x)\); - \item for every efficient algorithm \(A^\prime\), every positive - polynomial \(p(\cdot)\) and all sufficiently large \(n\)'s - \[\Prob{A^\prime(h(x), 1^n) \in h^{-1}(h(x))} < \frac{1}{p(n)}\] - \end{enumerate} - \end{itemize} - \end{definition} -\end{frame} - -\begin{frame} - \begin{definition}[Preimage resistance (one way)] - \begin{description} - \item[Input] hash function~\(H\), value~\(y\). - \item[Output] Any \(x\) such that \(H(x) = y\). - \end{description} - \end{definition} - - \begin{definition}[Second preimage resistance (weak collision resistance)] - \begin{description} - \item[Input] hash function~\(H\), value \(x\). - \item[Output] Any value \(x'\) such that \(H(x) = H(x')\). - \end{description} - \end{definition} - - \begin{definition}[Collision resistance (strong collision resistance)] - \begin{description} - \item[Input] hash function~\(H\). - \item[Output] Any two \(x, x'\) such that \(H(x) = H(x')\). - \end{description} - \end{definition} -\end{frame} +\input{../hash-review.tex} \section{Password hashing} From b6ab33c512a04bfffa0af4913a38aa3ecbdb993d Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Tue, 26 Jan 2021 09:44:21 +0100 Subject: [PATCH 09/10] Adds some material from auth/something-you-know --- applied-hash/passwords/contents.tex | 204 +++++++++++++++++++++++++++- 1 file changed, 202 insertions(+), 2 deletions(-) diff --git a/applied-hash/passwords/contents.tex b/applied-hash/passwords/contents.tex index 33d301c..a2cdae5 100644 --- a/applied-hash/passwords/contents.tex +++ b/applied-hash/passwords/contents.tex @@ -1,7 +1,207 @@ \mode* -\input{../hash-review.tex} +\mode{\input{../hash-review.tex}} -\section{Password hashing} +\section{Something you know} + +\subsection{\enquote{Proof of knowledge}} + +\begin{frame} + \begin{idea}[Something you know] + \begin{itemize} + \item We have a prover and a verifier. + \item Prover must convince verifier he knows some + secret. + \end{itemize} + \end{idea} + + \begin{idea}[Password] + \begin{itemize} + \item Prover and verifier shares a secret value. + + \item Prover tells verifier the value to convince the verifier. + \end{itemize} + \end{idea} +\end{frame} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item If the adversary learns the secret, he can convince the verifier he + is the prover. + \end{itemize} + \end{remark} + + \begin{example} + \begin{itemize} + \item Adversary might \enquote{overhear the conversation}. + \item Adversary might \enquote{trick} the prover to reveal the secret. + \item Adversary might guess the secret. + \end{itemize} + \end{example} +\end{frame} + +\subsection{Online or offline guessing?} + +\begin{frame} + \begin{definition}[Online] + \begin{itemize} + \item The adversary must interact with the system for each guess. + \end{itemize} + \end{definition} + + \pause + + \begin{example}[Online] + \begin{itemize} + \item Guessing the password of a Google account. + \item Must submit each guess to Google. + \end{itemize} + \end{example} +\end{frame} + +\begin{frame} + \begin{definition}[Offline] + \begin{itemize} + \item The adversary can verify the guess himself. + \end{itemize} + \end{definition} + + \pause + + \begin{example}[Offline] + \begin{itemize} + \item Guessing the password of an encrypted file. + \item For each guess, try to decrypt. + \end{itemize} + \end{example} + + \begin{example}[Offline] + \begin{itemize} + \item Guessing the password corresponding to a hash. + \item For each guess, hash and compare the result. + \end{itemize} + \end{example} +\end{frame} + +\subsection{Storing secrets} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item The user can store the secret in its mind. + \item This is assumed inaccessible (for now). + \end{itemize} + \end{remark} + + \pause + + \begin{question} + \begin{itemize} + \item The verifier is a machine. + \item The verifier must verify what the prover says. + \item This means that the verifier must have some data to check against. + \item How should this be stored? + \end{itemize} + \end{question} +\end{frame} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item Our concern is that someone can read this data. + \item Password reuse for other services? + \end{itemize} + \end{remark} +\end{frame} + +\begin{frame} + \begin{idea}[Password hashes] + \begin{itemize} + \item We want to compare user-entered and stored password. + \item We do an irreversible one-way transformation on both. + \item Then they are still comparable. + \item The preimage cannot be gained from storage. + \end{itemize} + \end{idea} + + \pause{} + + \begin{example} + \begin{itemize} + \item Cryptographic hash function \(h\colon \bin^*\to \bin^n\). + \item On registration, store \(y = h(p)\). + \item User authenticates with \(p'\), check if \(h(p') \stackrel{?}{=} + y\) equals what we stored. + \end{itemize} + \end{example} +\end{frame} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item Consider guessing again. + \item The used password space is small. + \item We only need to evaluate a subset: \(h\colon + \bin^{\color{red}{m}}\to \bin^n\). + \item With faster computers we can guess a lot. + \end{itemize} + \end{remark} + + \pause + + \begin{solution} + \begin{itemize} + \item Choose \(h\) to be slow to compute. + \item \Eg iterate it over itself 10\,000 times (\(h^{10000}(p)\)). + \item This will slow down guessing attacks. + \end{itemize} + \end{solution} +\end{frame} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item A list of password hashes reveals if two users have the same + password. + \item Can guess the password for all users at once: + \begin{enumerate} + \item Make a guess, compute the hash. + \item Check if it matches \emph{any} user's password. + \end{enumerate} + \end{itemize} + \end{remark} + + \pause + + \begin{solution} + \begin{itemize} + \item Add a \emph{salt}: a small random value (\eg 128 bits) unique for + each user. + \item Salt~\(s\rgets \bin^{128}\), change hash to \(h(s, p)\). + \item Now all hashes will be unique. + \end{itemize} + \end{solution} +\end{frame} + +\begin{frame} + \begin{remark} + \begin{itemize} + \item The salt is not a secret, it just adds uniqueness. + \item It can be stored in plain text along with the password hash. + \end{itemize} + \end{remark} +\end{frame} + +\begin{frame} + \begin{example} + \begin{itemize} + \item There are many libraries. + \item bcrypt~\cite{bcrypt} implements all this functionality. + \item Argon2 is another, more recent technique. + \item They should also be available in most languages and libraries. + \end{itemize} + \end{example} +\end{frame} From 370fd5b2f598a71970e56c536cf301001f7aa89e Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Mon, 5 Feb 2024 08:39:38 +0100 Subject: [PATCH 10/10] Makes passwords slides compile --- applied-hash/passwords/preamble.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/applied-hash/passwords/preamble.tex b/applied-hash/passwords/preamble.tex index ec61d2a..c7f0731 100644 --- a/applied-hash/passwords/preamble.tex +++ b/applied-hash/passwords/preamble.tex @@ -3,6 +3,9 @@ \usepackage[british]{babel} \usepackage{booktabs} +\usepackage[natbib,style=alphabetic,maxbibnames=99]{biblatex} +\addbibresource{crypto.bib} + \usepackage[all]{foreign} \renewcommand{\foreignfullfont}{} \renewcommand{\foreignabbrfont}{} @@ -13,9 +16,6 @@ \usepackage[strict]{csquotes} \usepackage[single]{acro} -\usepackage[natbib,style=alphabetic,maxbibnames=99]{biblatex} -\addbibresource{crypto.bib} - \usepackage{subcaption} \usepackage[noend]{algpseudocode}