diff --git a/.vscode/settings.json b/.vscode/settings.json
index 89262cb208ca649f0388c2b4fe2fd2e2b6b9e355..426d20c85b455454b647366f12ef5e287be53ee8 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -40,10 +40,15 @@
 		"colsep",
 		"cryptosystem",
 		"cryptosystem's",
+		"currentname",
 		"dbogatov",
+		"diagbox",
 		"distinguisher",
 		"ensuremath",
 		"eqref",
+		"exponentiate",
+		"firstline",
+		"firstnumber",
 		"frametitle",
 		"highlightline",
 		"highlightlinespecial",
@@ -55,8 +60,11 @@
 		"indistinguishability",
 		"keepaspectratio",
 		"labelsep",
+		"lastline",
 		"linestyle",
 		"linewidth",
+		"lrbox",
+		"lstinputlisting",
 		"lstlisting",
 		"mathbb",
 		"mathrm",
@@ -83,9 +91,12 @@
 		"psmatrix",
 		"psset",
 		"rearrangeable",
+		"scalebox",
 		"smallcaps",
+		"sqcases",
 		"subfigure",
 		"subname",
+		"subsecname",
 		"subtrees",
 		"tcblower",
 		"tcolorbox",
@@ -93,7 +104,9 @@
 		"titlecodebox",
 		"titleformat",
 		"toprule",
+		"totient",
 		"unstashed",
+		"usebox",
 		"usetheme"
 	]
-}
\ No newline at end of file
+}
diff --git a/listings/algorithm.tex b/listings/algorithm.tex
new file mode 100644
index 0000000000000000000000000000000000000000..a30b3bbfc3892b6f4a5c4423218e1c2ef951cab3
--- /dev/null
+++ b/listings/algorithm.tex
@@ -0,0 +1,16 @@
+$x \gets \text{position}[a]$
+$\text{position}[a] \gets \textsc{UniformRandom} (0 \ldots 2^L - 1)$
+for $\ell \in \{ 0, 1, \ldots , L \}$ do
+    $S \gets S \cup \textsc{ReadBucket}(\mathcal{P}(x, \ell))$
+end for
+data $\gets$ Read block $a$ from $S$
+if $op = write$ then
+    $S \gets (S - \{ (a, data) \} ) \cup \{ (a, data^{\mbox{*}} \} )$
+end if
+for $\ell \in \{ L, L-1, \ldots , 0 \}$ do
+    $S^\prime \gets \{ (a^\prime, data^\prime) \in S : \mathcal{P}(x, \ell) = \mathcal{P}( \text{position}[a^\prime], \ell) \}$
+    $S^\prime \gets$ Select $\min ( | S^\prime |, Z)$ blocks from $S^\prime$
+    $S \gets S - S^\prime$
+    $\textsc{WriteBucket} (\mathcal{P} (x, \ell), S^\prime)$
+end for
+return data
diff --git a/packages.tex b/packages.tex
index d7dfe8bc611246d90493a83583141331b0cbfd54..ed46c981561ab73240f6ac38309926855934641b 100644
--- a/packages.tex
+++ b/packages.tex
@@ -5,3 +5,5 @@
 \usepackage{booktabs}
 \usepackage{bm}
 \usepackage{mathtools}
+\usepackage{listings}
+\usepackage{fancybox}
diff --git a/preamble.tex b/preamble.tex
index c43f04f7cf98c4201f67e2fedc6d715783498b85..1c4edcd07b3b18753c7ee285dca113805cbc29f1 100644
--- a/preamble.tex
+++ b/preamble.tex
@@ -28,16 +28,34 @@
 }
 
 \makeatletter
-\def\beamer@framenotesbegin{% at beginning of slide
-	\usebeamercolor[fg]{normal text} 
-		\gdef\beamer@noteitems{}%
-		\gdef\beamer@notes{}% 
-}
+	\def\beamer@framenotesbegin{% at beginning of slide
+		\usebeamercolor[fg]{normal text} 
+			\gdef\beamer@noteitems{}%
+			\gdef\beamer@notes{}% 
+	}
 \makeatother
 
 
 \newcommand{\BigO}[1]{\mathcal{O}\left(#1\right)}
+\newcommand{\BigOmega}[1]{\Omega\left(#1\right)}
 \newcommand{\RAM}{\textbf{RAM}}
 
 \DeclarePairedDelimiter\ceil{\lceil}{\rceil}
 \DeclarePairedDelimiter\floor{\lfloor}{\rfloor}
+
+\lstset{
+	mathescape=true,
+	numbers=left,
+	tabsize=4,
+	numbersep=10pt,
+	breaklines=true,
+	showtabs=false,
+	morekeywords={for,end,do,while,if,then,else,Applies,when,return,true,false,Action},
+	basicstyle=\normalfont,
+	columns=fullflexible,
+	frame=leftline,
+	xleftmargin=15pt,
+	escapechar=|
+}
+
+\newsavebox{\mybox}
diff --git a/sections/path-oram-protocol.tex b/sections/path-oram-protocol.tex
index 82f56ba12de180baa5475f64e7438d207e8575c6..b1bdc74b5eb5499316c249d39e12acd0efff35cd 100644
--- a/sections/path-oram-protocol.tex
+++ b/sections/path-oram-protocol.tex
@@ -1,3 +1,5 @@
+% cSpell:ignore mybox
+
 \section{Path ORAM protocol}
 
 	\subsection{Overview}
@@ -21,11 +23,13 @@
 
 	\subsection{Server storage}
 
-		\begin{frame}{Binary tree}
+		\begin{frame}{\subsecname}
 			
-			The server stores a binary tree data structure of height $L$ and $2^L$ leaves.
-			We then need $L = \ceil*{ \log_2 N }$. 
-			The levels of the tree are numbered $0$ to $L$ where level $0$ denotes the root of the tree and level $L$ denotes the leaves.
+			\begin{block}{Binary tree}
+				The server stores a binary tree data structure of height $L$ and $2^L$ leaves.
+				We then need $L = \ceil*{ \log_2 N }$. 
+				The levels of the tree are numbered $0$ to $L$ where level $0$ denotes the root of the tree and level $L$ denotes the leaves.
+			\end{block}
 
 			\note{
 				Let us define $L$ --- the height of our tree.
@@ -34,11 +38,13 @@
 			}
 		\end{frame}
 
-		\begin{frame}{Bucket}
+		\begin{frame}{\subsecname}
 			
-			Each node in the tree is called a bucket. 
-			Each bucket can contain up to $Z$ real blocks. 
-			If a bucket has less than $Z$ real blocks, it is padded with dummy blocks to always be of size $Z$.
+			\begin{block}{Bucket}
+				Each node in the tree is called a bucket. 
+				Each bucket can contain up to $Z$ real blocks. 
+				If a bucket has less than $Z$ real blocks, it is padded with dummy blocks to always be of size $Z$.
+			\end{block}
 
 			\note{
 				Each node in a tree is a bucket that contains $Z$ blocks.
@@ -48,12 +54,14 @@
 			}
 		\end{frame}
 
-		\begin{frame}{Path}
+		\begin{frame}{\subsecname}
 			
-			Let $x \in \{ 0, 1, \ldots, 2^L - 1 \}$ denote the $x_{\text{th}}$ leaf node in the tree. 
-			Any leaf node $x$ defines a unique path from leaf $x$ to the root of the tree.
-			We use $\mathcal{P}(x)$ to denote set of buckets along the path from leaf $x$ to the root. 
-			Additionally, $\mathcal{P}(x,l)$ denotes the bucket in $\mathcal{P}(x)$ at level $l$ in the tree.
+			\begin{block}{Path}
+				Let $x \in \{ 0, 1, \ldots, 2^L - 1 \}$ denote the $x_{\text{th}}$ leaf node in the tree. 
+				Any leaf node $x$ defines a unique path from leaf $x$ to the root of the tree.
+				We use $\mathcal{P}(x)$ to denote set of buckets along the path from leaf $x$ to the root. 
+				Additionally, $\mathcal{P}(x,l)$ denotes the bucket in $\mathcal{P}(x)$ at level $l$ in the tree.
+			\end{block}
 
 			\note{
 				Let us define a path from leaf $x$ to root as $\mathcal{P}(x)$.
@@ -61,9 +69,9 @@
 			}
 		\end{frame}
 
-		\begin{frame}{Server storage}
+		\begin{frame}{\subsecname}
 			
-			\begin{block}{Observation}
+			\begin{block}{Server storage size}
 				Total server storage used is about $Z \cdot N$ blocks.
 				Since $Z$ is s small constant, server storage is $\BigO{N}$.
 			\end{block} 
@@ -73,3 +81,225 @@
 				The total server storage used is the order of $N$ since $Z$ is s small constant.
 			}
 		\end{frame}
+
+	\subsection{Client storage}
+
+		\begin{frame}{\subsecname}
+			
+			\begin{block}{Stash}
+				The client locally stores overflowing blocks in a local data structure $S$ called the stash.
+				The stash has a worst-case size of $\BigO{\log N} \cdot \omega (1)$ blocks with high probability.
+				The stash is usually empty after each ORAM read/write operation completes.
+			\end{block} 
+
+			\note{
+				The core component of the client is stash.
+				It is a local data structure that stores overflowing blocks.
+				PathORAM protocol is a randomized, and the error is the event that this stash overflows.
+				The analysis, though, shows that this happens with negligible probability.
+			}
+		\end{frame}
+
+		\begin{frame}{\subsecname}
+			
+			\begin{block}{Position map}
+				The client stores a position map, such that $x := \text{position}[a]$ means that block $a$ is currently mapped to the $x_\text{th}$ leaf node --- this means that block $a$ resides in some bucket in path $\mathcal{P}(x)$, or in the stash. 
+				The position map changes over time as blocks are accessed and remapped.
+			\end{block} 
+
+			\note{
+				Another core structure of the client is the position table.
+				It is a simple lookup table that maps the block identifier with identifier $a$ to some leaf $x$.
+				The bucket does not necessarily live in the leaf, but it is guaranteed to leave somewhere along the path or in the stash.
+				The key to security is the re-randomization of this table each access.
+			}
+		\end{frame}
+
+		\begin{frame}{\subsecname}
+			
+			\begin{block}{Bandwidth}
+				For each load or store operation, the client reads a path of $Z \log N$ blocks from the server and then writes them back, resulting in a total of $2Z \log N$ blocks bandwidth used per access. 
+				Since $Z$ is a constant, the bandwidth usage is $\BigO{\log N}$ blocks.
+			\end{block} 
+
+			\note{
+				Each read and write, client reads whole path and writes it back.
+				A path is $Z \log N$ blocks, and since $Z$ is a small constant, resulting usage is $\BigO{\log N}$ in the number of blocks.
+			}
+		\end{frame}
+
+		\begin{frame}{\subsecname}
+			
+			\begin{block}{Client storage size}
+				The position map is of size $N L = N \log N$ bits, which is of size $\BigO{N}$ blocks when the block size $\BigOmega{\log N}$.
+				The stash is at most $\BigO{\log N} \cdot \omega (1)$ blocks to obtain negligible failure probability.
+				The recursive construction can achieve client storage of $\BigO{\log N} \cdot \omega (1)$.
+			\end{block} 
+
+			\note{
+				Position map is the order of $N$ and the stash is order of $\log N$ for negligible error probability.
+				So, for the basic PAthORAM the client storage usage is order fo $N$.
+				However, it is possible to use recursive version of the ORAM, which I will talk about later, to lower the usage to the order of $\log N$.
+			}
+		\end{frame}
+
+	\subsection{The algorithm}
+
+		\newcommand{\algName}{\textsc{Access$(op, a, data^{\mbox{*}})$}}
+
+%%% fragile frame
+\begin{frame}[fragile]{Remap block}
+		
+	\lstinputlisting[
+		firstline=1, 
+		lastline=2,
+		firstnumber=1,
+		title=\algName%
+	]{listings/algorithm.tex}
+	
+	\note{
+		The client stash $S$ is initially empty. 
+		The server buckets are initialized to contain random encryptions of the dummy block. 
+		The client's position map is filled with independent random numbers between 0 and $2^L - 1$.
+	}
+
+\end{frame}
+%%% end fragile frame
+
+%%% fragile frame
+\begin{frame}[fragile]{Read path}
+	
+	\lstinputlisting[
+		firstline=3, 
+		lastline=5,
+		firstnumber=3,
+		title=\algName%
+	]{listings/algorithm.tex}
+
+	\note{
+		Read the path $\mathcal{P}(x)$ containing block $a$.
+	}
+
+\end{frame}
+%%% end fragile frame
+
+%%% fragile frame
+\begin{frame}[fragile]{Update block}
+	
+	\lstinputlisting[
+		firstline=6,
+		lastline=9,
+		firstnumber=6,
+		title=\algName%
+	]{listings/algorithm.tex}
+
+	\note{
+		If the access is a write, update the data stored for block $a$.
+	}
+
+\end{frame}
+%%% end fragile frame
+
+%%% fragile frame
+\begin{frame}[fragile]{Write path back}
+		
+	\lstinputlisting[
+		firstline=10, 
+		lastline=15,
+		firstnumber=10,
+		title=\algName%
+	]{listings/algorithm.tex}
+
+	\note{
+		Write the path back and possibly include some additional blocks from the stash if they can be placed into the path.
+		Buckets are greedily filled with blocks in the stash in the order of leaf to root, ensuring that blocks get pushed as deep down into the tree as possible.
+		A block $a^\prime$ can be placed in the bucket at level $\ell$ only if the path $\mathcal{P}( \text{position}[a^\prime])$ to the leaf of block $a^\prime$ intersects the path accessed $\mathcal{P}(x)$ at level $\ell$.
+		In other words, if $\mathcal{P}(x, \ell) = \mathcal{P}( \text{position}[a^\prime], \ell)$.
+	}
+
+\end{frame}
+%%% end fragile frame
+
+%%% fragile frame
+\begin{frame}[fragile]{Return}
+		
+	\lstinputlisting[
+		firstline=16,
+		lastline=16,
+		firstnumber=16,
+		title=\algName%
+	]{listings/algorithm.tex}
+
+	\note{
+		At the end, return the block.
+	}
+
+\end{frame}
+%%% end fragile frame
+
+\begin{frame}{Subroutines}
+	
+	\begin{block}{$\textsc{ReadBucket}(bucket)$}
+		The client reads all $Z$ blocks (including any dummy blocks) from the $bucket$ stored on the server. 
+		Blocks are decrypted as they are read.
+	\end{block} 
+
+	\begin{block}{$\textsc{WriteBucket}(bucket, blocks)$}
+		The client writes the blocks $blocks$ into the specified $bucket$ on the server. 
+		When writing, the client \emph{pads} blocks with dummy blocks to make it of size $Z$ --- note that this is important for security. 
+		All blocks (including dummy blocks) are re-encrypted, using a randomized encryption scheme, as they are written.
+	\end{block} 
+
+	\note{
+		There are two important subroutines in the algorithm.
+		
+		$\textsc{ReadBucket}(bucket)$ reads all $Z$ blocks --- remember, there are always exactly $Z$ blocks per bucket and decrypts them as it reads them.
+
+		$\textsc{WriteBucket}(bucket, blocks)$ writes blocks in the bucket on the server.
+		It pads blocks to make it $Z$ blocks total.
+		Remember that all bucket should be filled to make them indistinguishable to adversary.
+		Blocks are encrypted as they are written using randomized scheme --- every cipher text is different for the same plaintext.
+	}
+\end{frame}
+
+\begin{frame}{Complexity}
+	
+	\begin{block}{Computation}
+		Client's computation is $\BigO{\log N} \cdot \omega (1)$ per data access. 
+		We treat the server as a network storage device, so it only needs to do the computation necessary to retrieve and store $\BigO{\log N}$ blocks per data access.
+	\end{block} 
+
+	\note{
+		Each access the client reads and writes the whole path, which is order of $\log N$ in size.
+		It re-encrypts each block, so the total complexity is $\BigO{\log N} \cdot \omega (1)$.
+
+		Server, on the other hand, does not perform encryption, so its complexity is $\BigO{\log N}$.
+	}
+\end{frame}
+
+%%% fragile frame
+\begin{frame}[fragile]{Full algorithm}
+
+	\begin{lrbox}{\mybox}%
+
+		\lstinputlisting[
+			firstline=1,
+			lastline=16,
+			title=\algName%
+		]{listings/algorithm.tex}
+
+	\end{lrbox}%
+	
+	\begin{center}
+
+		\scalebox{0.75}{\usebox{\mybox}}
+
+	\end{center}
+
+	\note{
+		Please, take a few moments and look at the whole algorithm.
+		It is a great time now to ask any questions.
+	}
+
+\end{frame}
+%%% end fragile frame