\documentclass[a4paper,11pt]{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{underscore}

\newcommand{\code}[1]{\texttt{#1}}
\newtheorem{theorem}{Theorem}

\title{Drawing thermal ellipsoids with OpenGL}
\author{Luc J. Bourhis}

\begin{document}

\maketitle

\section{From anisotropic displacements to ellispoids}
In this section, we will work in fractional coordinates.
Ignoring anomalous scattering, the form factor $F(k)$ of an atom with an anisotropic displacement tensor $U$, sitting on the position $x$, and that has a scattering factor $f(k)$ reads
\begin{align}
  F(k) = f(k) e^{k U k^T} e^{i 2\pi k x},
\end{align}
where $x$ is a 3-vector column of coordinates whereas $k$ is a 3-vector row of Miller indices. The associated electron density $\rho(x)$ is the inverse Fourier transform of $F(k)$: it transforms the product of the thermal smoothing with the scattering into a convolution of their Fourier transforms,
\begin{align}
  \rho(x) = \sum_k \left[\int \rho_0(y) e^{(x-y)^T U^{-1} (x-y)} d^3y
  \right] e^{i 2\pi k x},
\end{align}
where $\rho_0$ is the electron density without thermal smearing.\footnote{and $y$ is another 3-vector column} The apparition of $U^{-1}$ is just a mathematical property of the Fourier transforms. Thus $p(y) \ltimes e^{(y-x)^T U^{-1} (y-x)}$ can be viewed as a probability distribution that smoothes $\rho_0(y)$. One may wish to display the surface corresponding to let's say 50\% probability. These surfaces are quadrics of equations
\begin{align}
  (y-x)^T U^{-1} (y-x) = r,
  \label{quadrics}
\end{align}
for some constant $r$ depending on the sought probability. This is actually the standard mathematical form for a quadrics equation. This quadrics is an ellispoid if and only if $U$ is positive-definite. This is the only case of interest in term of graphical display but we wish to have a fail-safe procedure when $U$ is non-positive definite (NPD).

\section{Drawing ellispsoids with OpenGL}

From this point on, the crystallographic origin of $U$ does not matter anymore: we just deal with a symmetric matrix.

First we move the problem to the origin with the change of variable
\begin{align}
  z = y - x,\\
  \intertext{and the quadrics equation then becomes}
  z^T U^{-1} z = r
  \label{quadrics:at:orig}
\end{align}

Then we need to find a way to transform the problem into drawing a sphere because either GLU or GLUT provides tools to easily and efficiently draw that shape. The simplest idea is to seek a linear transformation that maps the points on the sphere $\cal S$ of radius $r$ centered at the origin onto our ellipsoid $\cal E$. Let $M$ be the matrix of that transformation: for any vectors $v$ lying on $\cal S$, $z=Mv$ shall lie on $\cal E$, i.e.
\begin{align}
  r &= z^T U^{-1} z = v^T M^T U^{-1} M v,\nonumber\\
  \intertext{and since $v^T v$ = r,}
  1 &= \frac{v^T M^T U^{-1} M v}{v^T v}\nonumber.
\end{align}
This is the Rayleigh quotient of the matrix $M^T U^{-1} M$, whose minimum and maximum values as $v$ spans $\cal S$ are respectively the minimum and maximum eigenvalue of that matrix. Thus this matrix is the identity matrix and we can conclude that $U=M M^T$.

Reciproquely, if $U=M M^T$ for some matrix $M$, then for any vector $z=Mv$ with $v$ on $\cal S$, we have
\begin{align}
  r &= v^T v = z^T M^{-T} M^{-1} z = z^T U^{-1} z,\nonumber
\end{align}
and therefore $z$ lies on $\cal E$. Thus we can conclude that
\begin{theorem}
  A linear transformation of matrix $M$ maps $\cal S$ onto $\cal E$ if and only if
  \begin{align}
    U = M M^T.
    \label{mapping:condition}
  \end{align}
\end{theorem}

It shall be obvious that
\begin{theorem}
  If $M$ is solution of \eqref{mapping:condition}, then $MQ$ is also solution for any orthogonal matrix $Q$.
\end{theorem}

Two particular choices stand out from this infinite number of solutions, which we will now discuss.

\subsection{A scaling followed by a rotation}
In this section, $U$ is the matrix of the thermal displacement tensor in Cartesian coordinates.
Since $U$ is a symmetric matrix, it can be diagonalised:
\begin{align}
  U &= R \Delta R^T,\\
  \intertext{where $\Delta$ is a diagonal matrix and where $R$ is a rotation matrix. Thus a possible mapping satisfying \eqref{mapping:condition} is}
  M &= R \Delta^\frac{1}{2}
\end{align}

The advantage of this method lies in its geometrical interpretation: $\Delta^\frac{1}{2}$ transforms the sphere into an ellipsoid with the correct dimensions but whose principal axes are the axes of the basis the coordinates $v$ are referred to; then $R$ rotates this ellipsoid into its correct position. As a result drawing the great circles on the sphere that lies in the planes of equations\footnote{we denote $v=\begin{pmatrix}
  v_1\\
  v_2\\
  v_3
\end{pmatrix}$} $v_1=0$, $v_2=0$, and $v_3=0$ will result in drawing the principal ellipses on the ellipsoid. Those are useful visual guides to assess its shape.

In the \code{cctbx}, this is the method currently implemented in class \code{proto\_ellipsoid} in \code{gltbx/quadrics.h} -- the change of frame is actually implemented in class \code{ellipsoid_to_sphere_transform}. Bands are drawn about the great circles using textures created in class \code{ellipsoid_principal_sections_texture}. This is also the method used in Olex2.

\subsection{The Cholesky factor}

The Cholesky decomposition of $U$ reads
\begin{align}
  U = L L^T
\end{align}
where $L$ is lower triangular. Thus $L$ is a possible solution of \eqref{mapping:condition}.
The main advantage of this method is that the Cholesky decomposition algorithm is much faster than the eigenvalue decomposition used in the previous section, and the former is particularly trivial to implement for a 3x3 matrix. A further advantage is that it is possible to start with $U$ in fractional coordinates, which is the input one would get from a CIF or a .res file, thus saving the cost of the computation of the Cartesian $U$ that is required by the method described in the previous section.

However, there is a drawback. Since $L$ is a mapping that does not preserve orthogonality, the 3 great circles on the sphere introduced in the previous section are not mapped onto the principal ellipses on the ellipsoid. Thus we completely loose the ability to draw those visual clues. If this is not deemed important, then the Cholesky method discussed in this section shall be preferred.

This is the method used by Coot.

\end{document}


\section{Wavelet Analysis of Time Series}

\subsection{Introduction}

Several approaches have been proposed for time
series  prediction by the WT, based on a
neural network \cite{starck:gonghui99,pred:bashir00},
Kalman filtering \cite{pred:cristi00,pred:hong98}, or
an AR (autoregression) model \cite{pred:soltani00}.
In~\cite{starck:gonghui99,pred:soltani00} the undecimated Haar transform
was used. This choice of the Haar transform
was motivated by the fact that the wavelet
coefficients are calculated only from data obtained previously in time,
and the choice of an undecimated wavelet transform avoids aliasing problems.

The \`a trous wavelet transform with a wavelet function related to a spline
function, as described earlier, is not consistent with a directed
(time-varying) data stream. We now keep the wavelet function, but alter the
wavelet transform, to make of it a multiscale transform
which is appropriate for a data stream. We consider a signal s(1),
s(2),..., s(n), where n is the present time-point.
\begin{enumerate}
\item For index k sufficiently large, carry out an \`a trous wavelet transform
 on $\{s(1), s(2), ... , s(k)\}$.
\item Retain the detail coefficient values, and the continuum value, for the
   kth time-point only (cf. equation 8): $w_{1,k},w_{2,k},w_{J,k},c_{J,k}$.
     Note that summing these values gives $s(k)$.
\item If k is less than n, set k to k+1 and return to Step 1.
\end{enumerate}

This produces an additive decomposition of the signal, which is similar to
the \`a trous wavelet transform decomposition
with the $B_3$ spline on $\{s(1),s(2),...,s(k),...,s(n)\}$. The computational time
is evidently greater, $O(n^2)$ as against $O(n)$.

We have not touched on an important matter in regard to equation 2: how
to handle signal boundaries. Although other strategies could be
envisaged, we use a mirror approach. This is tantamount, of course, to
redefining the discrete filter associated with
the scaling function in the signal boundary region; and to redefining
the associated wavelet function in this region. This strategy is of
particular relevance when we work on an ordered data stream. We hypothesize
future data based on values in the immediate past. Not
surprisingly there is discrepancy in fit in the succession of scales, which
grows with scale as larger numbers of immediately past values
are taken into account.

\subsection{The redundant Haar wavelet transform}

\begin{figure}[htb]
\centerline{
\vbox{
\psfig{figure=fig_haartrous.ps,bbllx=1cm,bblly=20cm,bburx=19.cm,bbury=24.5cm,width=15cm,height=4.5cm,clip=}
}}
\caption{This figure shows which pixels of the input signal are used
to calculate the last wavelet coefficient in the different scales.}
\label{fig_haar}
\end{figure}
The Haar wavelet transform was first described in the early years of this
century and is described in almost every text on the wavelet
transform. As already mentioned, the asymmetry of the wavelet function
used makes it a good choice for edge detection, i.e.\ localized
jumps. The usual Haar wavelet transform, however, is a decimated one.
We now develop a non-decimated or redundant version of this
transform. This will be an \`a trous algorithm, but with a different pair
of scaling and wavelet functions compared to those used previously.

The non-decimated Haar algorithm is exactly the same as the \`a trous
algorithm, except that the low-pass filter $h$,
$(\frac{1}{16}, \frac{1}{4}, \frac{3}{8},
\frac{1}{4}, \frac{1}{16})$,
is replaced by the simpler filter $(\frac{1}{2},\frac{1}{2})$.
There h is now non-symmetric.
Consider the creation of the first wavelet resolution level. We
have  created it from  by convolving the original signal with h. Then:
\begin{eqnarray}
c_{j+1,l} = 0.5( c_{j,l-2^j} +  c_{j,l})
\end{eqnarray}
and
\begin{eqnarray}
w_{j+1,l} =  c_{j,l}  - c_{j+1,l}
\end{eqnarray}
At any time point, $l$, we never use information after $l$ in
calculating the
wavelet coefficient.
Figure \ref{fig_haar} shows which pixels of the input signal are used
to calculate the last wavelet coefficient in the different scales.
A wavelet coefficient at a
position $t$ is calculated from the signal samples at positions less
than or equal to $t$, but never larger.
% Examples of the \`a trous Haar transform.
% the Haar \`a trous wavelet transform, will be seen later.

\subsection{Autoregressive Multiscale Prediction}
\label{sect_AR_pred}
\subsubsection{Stationary signal}

\begin{figure}[htb]
\centerline{
\vbox{
\psfig{figure=fig_haarpred.ps,bbllx=1cm,bblly=20cm,bburx=19.cm,bbury=24.5cm,width=15cm,height=4.5cm,clip=}
}}
\caption{Wavelet coefficients which are used for the prediction of the next value.}
\label{fig_haarpred}
\end{figure}
Assuming a stationary signal $D = (d_1, \dots, d_N)$,
the AR (autoregressive) multiscale prediction model is:
\begin{eqnarray}
d_{t+1} = \sum_{j=1}^J \sum_{k=1}^{A_j} a_{j,k} w_{j,t-2^{j}(k-1)}  +
\sum_{k=1}^{A_{J+1}} a_{J+1,k} c_{J,t-2^{J}(k-1)}  + \epsilon(t+1)
\end{eqnarray}
where ${\cal W} = {w_{1}, \dots, w_J, c_J}$ represents the Haar \`a trous
wavelet transform of $D$ ($D = \sum_{j=1}^J w_j + c_J$).
For example, choosing $A_j = 1$ for all resolution levels $j$ leads
to the equation
\begin{eqnarray}
d_{t+1} = \sum_{j=1}^J  a_{j} w_{j,t} + a_{J+1} c_{J,t}  + \epsilon(t+1)
\end{eqnarray}
Figure~\ref{fig_haarpred} shows which wavelet coefficients are used
for the prediction using  $A_j = 2$ for all resolution levels $j$,
and a wavelet transform with five scales (four wavelet scales + the
smoothed array). In this case, we can see that only ten coefficients
are used, but taking into account low resolution information. This means
that a long term prediction can easily be introduced, either by increasing
the number of scales in the wavelet transform, or by increasing the
AR order in the last scales, but with a very small additional number of
parameters.
To find the $Q = \sum_{j=1}^{J+1} A_{j}$ unknown parameters: \\
$$\{\{a_{1,1},...,a_{1,A_1}\},...,
\{a_{j,1},...,a_{j,A_j}\},...,
\{a_{J,1},...,a_{j,A_J}\},\{a_{J+1,1},...,a_{j,A_J+1}\}\}$$
of our model, we need to resolve the following equation: $A X = S$,
where $A,X,W$ are defined by:
\begin{eqnarray*}
A^t & = & (L_{N-1}, \dots, L_{N-P}) \\
L_i & = & (w_{1,i}, \dots, w_{1,i-2 A_1}, \dots, w_{2,i}, \dots, w_{2,i-2^2 A_2},
\dots, w_{J,i}, \dots, w_{J,i-2^J A_J}, c_{J,i}, \dots, c_{J,i-2^J A_{J+1}}) \\
X^t & = & (a_{1,1},\dots, a_{1,A_1},a_{2,1}, \dots,a_{2,A_2},
 \dots, a_{J,1}, \dots, a_{J,A_j}, \dots, a_{J+1,1},
 \dots, a_{J+1,A_{J+1}})  \\
S^t & = & (d_N, \dots, d_{i+1},  \dots, d_{N-P+1})
\end{eqnarray*}
We have $P$ equations and $Q$ unknowns, so $A$ is a $Q \times P$ matrix
($P$ rows
$L_i$, each with $Q$ elements),
$X$ and $S$ are respectively $Q$- and $P$-sized vectors. When $Q$ is larger
than $P$, many minimization methods may be used to find $X$. In our experiments,
we used the standard SVD method.

\subsubsection{Non-stationary signal}
When the signal is not stationary, the previous method will not
correctly model our data. However, in many cases, the
non-stationary part affects the low frequency components, while
the high frequencies may still give rise to stationary behavior.
Then we can separate our signal $D$ into two parts,
the low and the high frequencies $L$ and $H$:
\begin{eqnarray*}
L & = & c_J \\
H & = & D - L = \sum_{j=1}^J w_j \\
d_{t+1} & = & l_{t+1} + h_{t+1} \\
\end{eqnarray*}
The smoothed array of the wavelet transform is first subtracted from
the data, and we consider now that the signal $H$ is stationary.
Our prediction will be the coaddition of two predicted values,
one on the signal $H$ by the AR Multiscale model, and the second on
the low frequency component by some other method.
The AR-Multiscale model gives:
\begin{eqnarray}
h_{t+1} =
\sum_{j=1}^J \sum_{k=1}^{A_j} a_{j,k} w_{j,t-2^{j}(k-1)} +  \epsilon(t+1)
\end{eqnarray}
We have now $Q = \sum_{j=1}^{J} A_{j}$ unknown parameters:
$$\{\{a_{1,1},...,a_{1,A_1}\},...,
\{a_{j,1},...,a_{j,A_j}\},...,
\{a_{J,1},...,a_{j,A_J}\} \}$$ and
we need to resolve the following equation: $A X = S$,
where $A,X,W$ are defined by:
\begin{eqnarray*}
A^t & = & (L_{N-1}, \dots, L_{N-P}) \\
L_i & = & (w_{1,i}, \dots, w_{1,i-2 A_1}, \dots, w_{2,i}, \dots, w_{2,i-2^2 A_2},
\dots, w_{J,i}, \dots, w_{J,i-2^J A_J}) \\
X^t & = & (a_{1,1},\dots, a_{1,A_1},a_{2,1}, \dots,a_{2,A_2},
 \dots, a_{J,1}, \dots, a_{J,A_j})  \\
S^t & = & (h_N, \dots, h_{i+1},  \dots, h_{N-P+1})
\end{eqnarray*}
Many methods may be used for the prediction of $l_{t+1}$. The problem
is simplified by the fact that $L$ is very smooth. We used a polynomial
fitting of degree 3 in our experiments.

\subsubsection{AR order determination}
The AR order at the different scales must now be defined.
It can be a user parameter,
but an automatic method is generally preferable. At each scale $j$,
we need to know how many coefficients should be used. This value $A_j$
may be determined by looking at how the wavelet coefficients at the
scale $j$ are correlated. Therefore each scale is first analyzed separately,
and the best AR order $A_j$ at scale $j$ minimizes:
\begin{eqnarray*}
J(A_j) = \log \sigma_{A_j}^2 + {\cal P}(A_j)
\end{eqnarray*}
where $\sigma_{A_j}$ is the prediction error, and
${\cal P}$ is a penalty function, which increases with the AR order.
Examples of penalty functions are:
\begin{itemize}
\item AIC: $AIC = \log \sigma_{A_j}^2 + \frac{2 A_j}{N}$
\item AICC: $AICC = \log \sigma_{A_j}^2 + \frac{N +  A_j}{N - A_j - 2}$
\item SIC: $SIC = \log \sigma_{A_j}^2 + \frac{ A_j\log N }{N}$
\end{itemize}

\subsection{Wavelets and autocorrelation function: mr1d\_acor}
\index{mr1d\_acor}
Program {\em mr1d\_acor} calculates the autocorrelation at each scale
of the wavelet transform.
{\bf
\begin{center}
 USAGE: mr1d\_acor option signal\_in autocor\_out
\end{center}}
where options are:
\begin{itemize}
\baselineskip=0.4truecm
\item {\bf [-n number\_of\_scales]} \\
Number of scales used in the multiresolution transform.
\item {\bf [-S Nbr\_of\_Lags]} \\
Default is 10.
\end{itemize}

\subsection{Transition detection: mr1d\_nowcast}
\index{mr1d\_nowcast}
Program {\em mr1d\_nowcast} detects the transitions in all scales at a
given position. The wavelet transform used is the Haar transform,
so a given wavelet coefficient at position $x$ and at scale $j$ ($j=1..P$,
$P$ being the number of scales)
is calculated from pixel values between  positions $x-2^{j}+1$ and $x$.
Only pixels in the signal which are on the left of a given position $x$
(or before a given time for temporal signal) are
used for the calculation of the wavelet coefficients at position $x$.
This allows us to detect a new event in a temporal series
irrespective of the time
scale of the event.
By default, the analysed position is the last one of the signal, but other
positions can equally well be analyzed using the ``-x'' option. The program
prints for each scale $j$ the following information corresponding to
the position $x$:
\begin{itemize}
\item {\bf No detection} \\
 if the wavelet coefficient $\mid w_j(x) \mid  < k \sigma_j$
\item {\bf New upward detection}\\
 if $  w_j(x) > k \sigma_j$  and $\mid w_j(x-1) \mid  < k \sigma_j$
\item {\bf New downward detection}\\
 if $  w_j(x) < - k \sigma_j$ and $\mid w_j(x-1) \mid  < k \sigma_j$
\item {\bf Positive significant structure}\\
 if $  w_j(x) > k \sigma_j$ and $\mid w_j(x-1) \mid  > k \sigma_j$ \\
The first detected coefficient of the structure is also given.
\item {\bf Negative significant structure}\\
 if $  w_j(x) < -k \sigma_j$ and $\mid w_j(x-1) \mid  > k \sigma_j$ \\
The first detected coefficient of the structure is also given.
\item {\bf End of significant structure}\\
 if $\mid w_j(x) \mid  < k \sigma_j$ and $\mid w_j(x-1) \mid  > k \sigma_j$
\end{itemize}
Furthermore the signal to noise ratio of the wavelet coefficient is given.
{\bf
\begin{center}
 USAGE: mr1d\_nowcast option signal\_in
\end{center}}
where options are:
\begin{itemize}
\item {\bf [-m type\_of\_noise]}
{\small
\begin{enumerate}
\baselineskip=0.4truecm
\item Gaussian Noise
\item Poisson Noise
\item Poisson Noise + Gaussian Noise
\item Multiplicative Noise
\item Non-stationary additive noise
\item Non-stationary multiplicative noise
\item Undefined stationary noise
\item Undefined noise
\end{enumerate}
}
 Default is Gaussian noise.
\item {\bf [-g sigma]}
\item {\bf [-c gain,sigma,mean]}
\item {\bf [-n number\_of\_scales]}
\item {\bf [-s NSigma]}
\item {\bf [-x Position]}  \\
Position to analyse. Default is the last point.
\end{itemize}
\subsubsection*{Examples:}
\begin{itemize}
\item mr1d\_nowcast sig.dat  \\
Analyse the last point of the signal with all default option.
\item mr1d\_nowcast -x 55 -s 10 sig.dat  \\
Analyse the point at position 55, and detect the transition with a
signal to noise ratio equal to 10.
\end{itemize}

\subsection{Prediction: mr1d\_fcast}
\index{mr1d\_nowcast}

Program {\em mr1d\_fcast} performs a forecasting by four different methods:
the standard AR model (AR), an AR method per scale (and the prediction
is the coaddition of the predicted wavelet coefficients),
the multiresolution AR model (MAR), and a neural network.
The program can be used in two modes: the evaluation and the prediction
mode. In the evaluation mode, the first part of the time series is used
to predict the second part, and the output file contains the same
number of values as the input file. The initial values (corresponding to
the initial part of the signal) are identical,
and the other values are the predicted ones.
The error prediction is calculated
and printed on the standard output device (screen window).
In the prediction mode,
the output file contains more values than the input file. The last values
correspond to the predicted values.
For the AR and MAR models, the order of the model can either be fixed
by the user (``-a option''), or automatically calculated.
In case of an automatic
MAR model order estimation, the order can be different at each scale.

By default, the signal is assumed to be stationary.
If the ``-h'' option is set,
we assume a non-stationary signal. In that case, the last scale of the
wavelet transform is analyzed differently (i.e. not with the AR model).
Several methods can be selected by the ``-B'' option.
The default is the polynomial extrapolation of order 2.

If the ``-L'' option is set, only the last pixels will be used in the
analysis.

{\bf
\begin{center}
 USAGE: mr1d\_fcast option signal\_in  signal\_out
\end{center}}
where options are:
\begin{itemize}
\item {\bf [-P predict\_method]}
{\small
\begin{enumerate}
\baselineskip=0.4truecm
\item  Autoregressive model.
\item  Autoregressive model per scale.
\item  Multiresolution Autoregressive model.
\item  Neural network.
\end{enumerate}
}
Default is Multiresolution Autoregressive Model.
\item {\bf [-n number\_of\_scales]} \\
Number of scales to be used in the Multiresolution AR model. Default is 5.
\item {\bf [-a AR\_Order]} \\
AR oder used for the prediction. Default is automatically estimated.
\item {\bf [-O Estimation\_AR\_Order\_Method]}
{\small
\begin{enumerate}
\item AIC
\item AICC
\item BIC
\end{enumerate}}
Default is BIC method.
\item {\bf[-h]} \\
Non stationary signal. Default is stationary.
\item {\bf[-p Number\_of\_Predict]} \\
Number of prediction. Default is 0.
\item {\bf[-m MinAROrder]} \\
Minimum AR model order. Default is 1.
\item {\bf[-M MaxAROrder]} \\
Maximum AR model order. Default is 10.
\item {\bf[-w]} \\
Write to disk some infomation about the prediction error and the
 AR model order.
The file contains a 1D table
of size $N+3$, where $N$ is the number of scales ($N = 1$ when the
MAR model is not used).
\begin{verbatim}
  T[0] = prediction error
  T[1] = Number_of_scale
  T[2] = Percentage of prediction in the interval [Pred-SigmaNoise, Pred+SigmaNoise].
  for j = 0 to Number_of_scale-1 do T[j] = AR order at scale j
\end{verbatim}
\item {\bf[-L NPix]]} \\
Analyse the last NPix pixels. Default is all pixels.
\item {\bf [-B extrapol\_type]}
{\small
\begin{enumerate}
\item Constant border ($c_J(N+i) = c_J(N)$, where $c_J$ is the last scale,
$N$ the number of pixels).
\item Mirror border ($c_J(N+i) = c_J(N-i)$).
\item Double mirror border ($c_J(N+i) = 2 c_J(N) - c_J(N-i)$).
\item Polynomial extrapolation (deg 1).
\item Polynomial extrapolation (deg 2).
\end{enumerate}}
Default is 5. Only used if the ``-h'' option is set.
\item {\bf[-T Poly\_Nbr\_Pix]} \\
Number of pixels used for the polynomial extrapolation.
Default is 5. Only used if the ``-h'' option is set and if a polynomial
extrapolation is used.
\end{itemize}
\subsubsection*{Examples:}
\begin{itemize}
\item mr1d\_fcast sig.dat eval.dat \\
Evaluate the prediction by MAR method.
\item mr1d\_fcast -p 1 sig.dat pred.dat \\
Make a prediction at position N+1.
\end{itemize}

\section{Time-Frequencies Analsysis}

\subsection{The Short Term Fourier Transform: im1d\_stf}
 \index{im1d\_stf}
The Short-Term Fourier Transform of a 1D signal $f$ is defined by:
\begin{eqnarray}
STFT(t, \nu) = \int_{-\infty}^{+\infty} e^{-j2\pi\nu \tau} f(\tau)g(\tau-t) d\tau
\end{eqnarray}
If $g$ is the Gaussian window, this corresponds to the Gabor transform.
The energy density function, called the {\em spectrogram}, is given by:
\begin{eqnarray}
SPEC(t, \nu) = \mid STFT(t, \nu) \mid^2
=  \mid  \int_{-\infty}^{+\infty} e^{-j2\pi\nu \tau} f(\tau)g(\tau-t) d\tau \mid^2
\end{eqnarray}
Most used windows are:
{\small
\begin{itemize}
\itemsep=1truecm
\baselineskip=0.4truecm
\item Truncated window function:
$
\hat{W}(\nu) =  \left\{
  \begin{array}{ll}
    1   &  \mbox{ if }  \mid \hat{P}(\nu) \mid \ge \sqrt{\epsilon}    \\
    0   &   otherwise
  \end{array}
  \right.
$
where $\epsilon$ is the regularization parameter.
\item Rectangular window:
$
\hat{W}(\nu) =  \left\{
  \begin{array}{ll}
    1   &  \mbox{ if }  \mid  \nu \mid \le \Omega    \\
    0   &   otherwise
  \end{array}
  \right.
$
where $\Omega$ defines the band-width.
\item Triangular window:
$
\hat{W}(\nu) =  \left\{
  \begin{array}{ll}
    1 - \frac{\nu}{\Omega}  &  \mbox{ if }  \mid  \nu \mid \le \Omega    \\
    0   &   otherwise
  \end{array}
  \right.
$
\item Hamming Window:
$
\hat{W}(\nu) =  \left\{
  \begin{array}{ll}
    0.54 + 0.46 \cos(\frac{2\pi \nu}{\Omega})    &  \mbox{ if }  \mid  \nu \mid \le \Omega    \\
    0   &   otherwise
  \end{array}
  \right.
$

\item Hanning Window:
$
\hat{W}(\nu) =  \left\{
  \begin{array}{ll}
    \cos(\frac{\pi \nu}{\Omega})    &  \mbox{ if }  \mid  \nu \mid \le \Omega    \\
    0   &   otherwise
  \end{array}
  \right.
$

\item Gaussian Window:
$
\hat{W}(\nu) =  \left\{
  \begin{array}{ll}
     \exp(-4.5 \frac{\nu^2}{\Omega^2})    &  \mbox{ if }  \mid  \nu \mid \le \Omega    \\
    0   &   otherwise
  \end{array}
  \right.
$

\item Blackman Window:
$
\hat{W}(\nu) =  \left\{
  \begin{array}{ll}
  0.42 + 0.5  \cos(\frac{\pi \nu}{\Omega}) +  0.08  \cos(\frac{2\pi \nu}{\Omega})  &  \mbox{ if }  \mid  \nu \mid \le \Omega    \\
    0   &   otherwise
  \end{array}
  \right.
$
\end{itemize}
 }

The inverse transform is obtained by:
\begin{eqnarray}
f(t) =  \int_{-\infty}^{+\infty}  g(t-\tau)  \int_{-\infty}^{+\infty} e^{j2\pi\nu \tau} STFT(\tau, \nu) d\nu d\tau
\end{eqnarray}

\bigskip
Program {\em im1d\_stf} calculate the short term Fourier Transform of a signal.
It outputs three files: the real part of the STF,  the imaginary part
of the STF, and the spectrogram. When the ``-r'' option is set, the
the signal is reconstructed from the STF real and imaginary parts
(the spectrogram is not used for the reconstruction).

\smallskip
The command line is:
{\bf
\begin{center}
 USAGE: im1d\_stf option signal\_in image\_out
\end{center}}
where options are:
\begin{itemize}
\baselineskip=0.4truecm
\item {\bf [-t type\_of\_window ]}
\begin{enumerate}
\itemsep=0.1truecm
\baselineskip=0.4truecm
\item Hamming window
\item Hanning window
\item Gaussian window
\item Blackman window
\item Rectangular window
\end{enumerate}
Default is Hamming window.
\item {\bf [-w window\_size]} \\
Window size. Default is 1024.
If the signal has less than 1024 pixels, the default value is
the number of pixels divided by four.
\item {\bf [-W window\_param]} \\
 Window parameter. Default is 0.5.
\item {\bf [-S Step]} \\
 Step between two points. Default is WindowSize/2.
\item {\bf [-r]} \\
 Reverse transform.
\item {\bf [-v]} \\
Verbose. Default is no.
\end{itemize}

\subsubsection*{Examples:}
\begin{itemize}
\item im1d\_stf sig.fits stf \\
Creates three files, ``stf\_re.fits'', ``stf\_im.fits'',  ``stf\_spec.fits'',
corresponding respectively the STF real part, the STF imaginary part and
the spectrogram.
\item  im1d\_stf -r stf rec \\
Reconstruct a signal from its STF (i.e. ``stf\_re.fits'' and ``stf\_im.fits'').
\end{itemize}

\subsection{Time-Frequency Distribution: im1d\_tfreq}
\index{im1d\_tfreq}

% \subsubsection*{The Wigner-Ville Distribution.}
\index{Wigner-Ville transform}
\index{transform!Wigner-Ville transform}

The Wigner-Ville
distribution \cite{ima:wigner32,ima:ville48} of a signal $s(t)$ is
\begin{eqnarray}
W(t, \nu) = \frac{1}{2\pi} \int s^*(t - \frac{1}{2}\tau )
           s(t + \frac{1}{2}\tau ) e^{-i\tau 2 \pi \nu} d\tau
\end{eqnarray}
where $s^*$ is the conjugate of $s$.
The Wigner-Ville transform is always real (even for a complex signal).
In practice, its use is limited by the existence of interference terms,
even if they can be attenuated using specific averaging approaches.
More details can be found in \cite{ima:cohen95,ima:mallat98}.

% \subsubsection*{The Choi-Williams Distribution.}
% The Choi-Williams distribution of a signal $s(t)$ is
% \begin{eqnarray}
% W(t, \nu) = \frac{1}{4\pi^{\frac{3}{2}}} \int \int
%    \frac{1}{\sqrt{\tau^2/\sigma}} s^*(u - \frac{1}{2}\tau )
%            s(u + \frac{1}{2}\tau ) e^{-\sigma(u-t)^2/\tau^2 - 2i\tau \pi \nu} d\tau
% \end{eqnarray}
%
% \bigskip

Program {\em im1d\_stf} calculates the short term Fourier Transform of a signal.
It outputs three files: the real part of the STF,  the imaginary part
of the STF, and the spectrogram.

\smallskip
The command line is:
{\bf
\begin{center}
 USAGE: im1d\_stf option signal\_in image\_out
\end{center}}
where options are:
\begin{itemize}
\baselineskip=0.4truecm
\item {\bf [-T TimeFrequency\_Distrib ]}
\begin{enumerate}
\itemsep=0.1truecm
\baselineskip=0.4truecm
\item Short Term Fourier Transform Spectogram
\item Wigner-Ville Distribution
% \item Choi-Williams Distribution
\end{enumerate}
Default is 1.
\item {\bf [-t type\_of\_window ]}
\begin{enumerate}
\itemsep=0.1truecm
\baselineskip=0.4truecm
\item Hamming window
\item Hanning window
\item Gaussian window
\item Blackman window
\item Rectangular window
\end{enumerate}
default is Hamming window.
% \item {\bf [-F type\_of\_window (freq. domain) ]} \\
%  Only for Choi-Williams distribution.
% Default is Hamming window.
\item {\bf [-w window\_size (time domain)]} \\
Window size. Default is 1024.
If the signal has less than 1024 pixels, the default value is
the number of pixels divided by four.
\item {\bf [-W window\_param (time domain)]} \\
 Window parameter. Default is $0.5$.
\item {\bf [-S Step]} \\
 Step between two points. Default is WindowSize / 2.
\item {\bf [-v]} \\
Verbose. Default is no.
\end{itemize}


\section{Results}
The program was configured to generate a dataset of one million games of Blackjack. This number was chosen, because adding more 0\textquotesingle s to this number increases the time it takes to generate and refine the data set a lot. With one million it took my laptop approximately 5 minutes to generate and 1 minute to refine the data. I could wait longer for more data, but it is not expected to make a difference in the results. one million should be enough data to minimize the coincidence and give reliable results. \\
 \\
Figure 1 and table 1 show all hand values considered difficult with the total number of occurrences when
\begin{itemize}
    \item The player decided to draw
    \item The player decided to pass
    \item The player decided to draw and won
    \item the player decided to pass and won
\end{itemize}
An interesting trend appears in the graph with this data. You can see that, the higher the hand value, the less successful it is to draw a card (Blue in figure 1). So drawing a card with a hand value of 12 is more successful than drawing a card at a hand value of 17. This makes sense, because a lower hand value can draw more different cards without going over 21, so has a higher probability of winning.
The same happens to the passing card results, but in opposite order. The higher the hand value, the higher the probability passing will be successful (Red in figure 1). The interesting part in this graph is the differences between these two trends. For the outer two columns the results are very clear:
\begin{itemize}
    \item 12: Probability to win much better by drawing
    \item 13: Probability to win better by drawing
    \item 16: Probability to win better by passing
    \item 17: Probability to win way, way better by passing
\end{itemize}
In the middle of the graph is the most important data. As expected are 14 and 15 the most difficult hands to make a decision for. When you look at the data it is slightly better to draw a card at a value of 14 and to pass at a value of 15. Based on the big dataset, it is safe to say that is also the best move in this situation. Making the right decision won\textquotesingle t make a big difference for your results while playing the game in real life, but if you happen to play one million games with a value of 14 or 15 in your hand, you could increase your win probability.

\input{fig/GraphWinChanceCardValue.tex}

Figure 2 and table 2 show the total number of occurrences of each possible outcome over the entire experiment of one million games of Blackjack. You can see that the dealer won 513440 / 1000000 * 100 = 51,3 percent of the games, the player won 421942 / 1000000 * 100 = 42,2 percent of the games and only 64618 / 1000000 * 100 = 6,5 percent of the games resulted in a tie. This has a ratio of 1,22 / 1 / 0.15 with Dealer / Player / Tied. This means that, in the long run, the dealer always wins 1,22 times more games than the player. That is 22 percent more games.

\input{fig/GraphTotalWins.tex}


\documentclass{ximera}
\input{../preamble}
\title{Exercises: Arc Length}
%%%%%\author{Philip T. Gressman}

\begin{document}
\begin{abstract}
We practice computing arc length.
\end{abstract}
\maketitle

\begin{exercise}%[APEX0704ARCL04]
Find the arc length of the function on the given interval: \(\displaystyle f(x) = \sqrt{8}x\) on \([-1, 1]\)
\[ L = \answer{6}. \]
%%
%%
\end{exercise}

\begin{exercise}
Find the arc length of the function on the given interval: \(\displaystyle f(x) = \ln \left(\cos x\right)\) on \([0, \pi/4]\).
(You may use the fact that $\int \sec x ~ dx = \ln |\sec x + \tan x| + C$.)
\[ L = \answer{\ln (1 + \sqrt{2})}. \]
\end{exercise}

\begin{exercise}%[APEX0704ARCL13]
Set up the integral to compute the arc length of the function on the given interval: \(\displaystyle f(x) = x^2\) on \([0, 1]\).
\[ L = \int_{\answer{0}}^{\answer{1}} \answer{\sqrt{1+4x^2}} \ dx\]
%
%
\end{exercise}

\begin{question}%%%%%[2017C.03]
Let \(\displaystyle y = \frac{x^4}{16} + \frac{1}{2x^2}\). Find the arc length for \(1 \leq x \leq \sqrt{2}\).
\[ L = \answer{\frac{7}{16}}. \]
\end{question}

\section*{Sample Quiz Questions}

\begin{question}%%%%%[Arclen01]

Compute the arc length of the curve \[y = \frac{3}{4}x^{-2} + \frac{1}{24}x^{4} - 1\] between the endpoints \(x = \sqrt{3}\) and \(x = \sqrt{6}\).
(Hints won't be revealed until after you choose a response.)
\begin{multiplechoice}
\choice{\(\displaystyle \frac{5}{12}\)}
\choice{\(\displaystyle \frac{7}{12}\)}
\choice{\(\displaystyle \frac{3}{4}\)}
\choice{\(\displaystyle \frac{11}{12}\)}
\choice{\(\displaystyle \frac{13}{12}\)}
\choice[correct]{\(\displaystyle \frac{5}{4}\)}
\end{multiplechoice}
\begin{feedback}
Applying the formula for arc length gives that
\[
\begin{aligned}
L & = \int_{\sqrt{3}}^{\sqrt{6}} \sqrt{1 + \left( \frac{dy}{dx} \right)^2}~dx
   = \int_{\sqrt{3}}^{\sqrt{6}} \sqrt{1 + \left( -\frac{3}{2}x^{-3} + \frac{1}{6}x^{3} \right)^2}~dx
\end{aligned}
\]
\begin{hint}
\[
\begin{aligned}
  & = \int_{\sqrt{3}}^{\sqrt{6}} \sqrt{1 + \frac{9}{4}x^{-6} - \frac{1}{2} + \frac{1}{36}x^{6}} ~ dx
   = \int_{\sqrt{3}}^{\sqrt{6}} \sqrt{ \left( \frac{3}{2}x^{-3} + \frac{1}{6}x^{3} \right)^2} ~ dx \\
  & = \int_{\sqrt{3}}^{\sqrt{6}} \left( \frac{3}{2}x^{-3} + \frac{1}{6}x^{3} \right) ~ dx
   = \left.  \left( -\frac{3}{4}x^{-2} + \frac{1}{24}x^{4} \right) \right|_{\sqrt{3}}^{\sqrt{6}} \\
  & =  \left( -\frac{1}{8} + \frac{3}{2} \right) - \left( -\frac{1}{4} + \frac{3}{8} \right)
   = \frac{5}{4}.
\end{aligned}
\]
Note that you must always take the positive square root in going from line two to line three. In particular, if you get a negative answer, you have likely taken the negative square root.
\end{hint}
\end{feedback}

\end{question}

\section*{Sample Exam Questions}

\begin{question}(2017 Midterm 1)
Compute the length of the curve $x = \frac{1}{8} (y^2 + 2y) - \ln (y+1)$ between $y=0$ and $y = 2$.
\begin{multipleChoice}
\choice[correct]{$\displaystyle 1 + \ln 3$}
\choice{$\displaystyle 2 + \ln 6$}
\choice{$\displaystyle 3 + \ln 9$}
\choice{$\displaystyle 4 + \ln 12$}
\choice{$\displaystyle 5 + \ln 15$}
\choice{none of the above}
\end{multipleChoice}
\end{question}

\begin{question}%%%%%[2018.S.4]
 Find the arc length of the following curve between $x=-1$ and $x=1$:
\[ y = 3 \cosh \frac{x}{3}. \]
(Note: $\cosh x = (e^x + e^{-x})/2$.)
\begin{multiplechoice}
\choice{\(\displaystyle \frac{e}{3} - \frac{1}{3e}\)}
\choice{\(\displaystyle \frac{e}{2} - \frac{1}{2e}\)}
\choice{\(\displaystyle e - \frac{1}{e}\)}
\choice{\(\displaystyle 2 e - \frac{2}{e}\)}
\choice[correct]{\(\displaystyle 3 e - \frac{3}{e}\)}
\choice{none of the above}
\end{multiplechoice}

\end{question}

\begin{question}
 A certain curve $y = f(x)$ in the plane has the property that its length between the endpoints $x=0$ and $x=a$ is equal to
\[ \int_0^a \sqrt{1 + \sin^2 t} ~ dt \]
for every value of $a > 0$.  Assuming the curve passes through the points $(0,0)$ and $\left(\frac{\pi}{2},1\right)$, what is $f\left( \frac{\pi}{4} \right)$?
\begin{multipleChoice}
\choice{$\displaystyle \frac{1}{2}$}
\choice{$\displaystyle \frac{1}{\sqrt{2}}$}
\choice[correct]{$\displaystyle 1 - \frac{1}{\sqrt{2}}$}
\choice{$\displaystyle 0$}
\choice{$\displaystyle - \frac{1}{\sqrt{2}}$}
\choice{none of these}
\end{multipleChoice}
\end{question}

\begin{question}%%%%%[2015C.13]

Find the length of the part of the curve \(\displaystyle y = \frac{3}{16} e^{2x} + \frac{1}{3} e^{-2x}\) for \(0 \leq x \leq \ln 2\).
\begin{multiplechoice}
\choice[correct]{\(\displaystyle \frac{13}{16}\)}
\choice{\(\displaystyle \frac{11}{16}\)}
\choice{\(\displaystyle \frac{3}{8}\)}
\choice{\(\displaystyle \frac{9}{8}\)}
\choice{\(\displaystyle \frac{29}{64}\)}
\choice{\(\displaystyle \frac{3}{4}\)}
\end{multiplechoice}

\end{question}

\begin{question}%%%%%[2016C.01]

Find the length of the part of the curve \(\displaystyle y = \frac{x^4}{4} + \frac{1}{8x^2}\) for \(1 \leq x \leq 2\).
\begin{multiplechoice}
\choice[correct]{\(\displaystyle \frac{13}{16}\)}
\choice{\(\displaystyle \frac{11}{16}\)}
\choice{\(\displaystyle \frac{7}{8}\)}
\choice{\(\displaystyle \frac{13\sqrt{2}}{16}\)}
\choice{\(\displaystyle \frac{11\sqrt{2}}{16}\)}
\choice{\(\displaystyle \frac{7\sqrt{2}}{8}\)}
\end{multiplechoice}

\end{question}

\end{document}


\chapter{Symmetric-key Cryptography} % Main chapter title
\label{Symmetric-key Cryptography} % For referencing the chapter elsewhere, use \ref{Chapter1}

\textit{Symmetric-key} cryptography (also commonly referred to as \textit{private-key cryptography}) is a system of cryptography which
uses the same keys for both encryption of plaintext and decryption of ciphertext. The keys must be shared between the different
parties accessing and handling the information. The requirement that all (authorized) parties must have access to the secret key
is the biggest drawback of symmetric-key cryptography \cite{wiki:symmetric_key_cryptography}.

This chapter will discuss and implement the different types of symmetric-key cryptography algorithms.
First we will explore and implement the various classical cryptography examples (some of which are discussed in the
\hyperref[Early Cryptography]{Early Cryptography} chapter). From there, we will continue and take a look at more complex modern-day algorithms
and discuss their implementation.

\section{Transposition Ciphers}

One of the simplest methods of cryptography, a transposition cipher, works by changing the ordering of the message to make it seemingly unreadable.
This is similar to an anagram but with a regular defined structure to make it easily decryptable (assuming you know the defined structure or the \textit{key}).

Mathematically, the ciphertext will be a permutation of the original plaintext. We can use an encryption function to encrypt our plaintext and then use
the \textit{inverse} of our encryption function to decrypt our ciphertext. A generic transposition cipher (one with no specific encryption function)
can be expressed mathematically as follows: $$\mathlarger{P \rightarrow E, f(x)}$$

In this example, we are mapping the set $P$ containing the plaintext to the set $E$ containing the ciphertext using the encryption function $f(x)$.
In mathematics, this would be referred to a \textit{bijection} from set $P$ to $E$. Keep in mind that while transposition ciphers certainly
are functions, we can not easily assign them a simple algebraic formula since they deal with the positions of letters rather than the letters themselves.

Decryption of the ciphertext is defined in a similar fashion, but instead we use the \textit{inverse bijection} from our ciphertext set $E$ to $P$.
Notice that now our function $f(x)$ is inversed becoming: $f^{-1}(x)$. The algebraic expression for decryption is written as follows:
$$\mathlarger{E \rightarrow P, f^{-1}(x)}$$

Though there are many different types of transposition ciphers, in this section we will only discuss one and it's benefits, drawbacks, and efficiency.

\subsection{Rail Fence Cipher}

The \textit{rail fence cipher} (also referred to as a \textit{ZigZag} cipher) is a form of transposition cipher which arranges letters from
the plaintext in different "rails." It works by writing letters downwards and diagonally on following "rails" of an
\textit{imaginary fence} (hence where the name of this cipher comes from). When we reach the bottom rail, we begin writing
letters upwards. Likewise, when we reach the top rail, we begin writing letters downwards again until the whole plaintext is
written on our rail fence. For instance, if our fence has \textit{3} rails and our plaintext is:
'\textit{WE ARE DISCOVERED FLEE AT ONCE}', the ciphertext would look like so:

\begin{listing}[H]
    \begin{minted}[mathescape,
        numbersep=5pt,
        frame=lines,
        framesep=2mm]{text}

W . . . E . . . C . . . R . . . L . . . T . . . E
. E . R . D . S . O . E . E . F . E . A . O . C .
. . A . . . I . . . V . . . D . . . E . . . N . .

    \end{minted}
    \caption{Example of plaintext encrypted using the rail fence cipher. In this example, we have removed
    all whitespaces in the plaintext.}
\end{listing}

This is then read off to get the ciphertext:

\begin{minted}[mathescape,
    numbersep=5pt,
    frame=lines,
    framesep=2mm]{text}

WECRL TEERD SOEEF EAOCA IVDEN
\end{minted}

Decryption is done in a similar fashion by laying out the ciphertext in appropriate rails. Let's take a look at how
you go about decrypting the ciphertext above. First, we must know the height and \textit{cycle} of the ciphertext. The height
is simply the amount of rails that was used to encrypt the plaintext. A cycle is the number of letters which run from the top
row to the bottom row and then up again, but stops before the top-most row (where a new cycle begins). The cycle can be
written mathematically as: $$\mathlarger{2R - 2}$$

This simply says that each cycle is double our number of rails, minus 2. This is because, when we double our number of rails
(for going up and down) we wil have a duplicate position at the bottom row, thus we subtract $1$. We then also
subtract $1$ since our cycle does not include the top-most row. Do note that the rail index is \textit{zero based}. This means
that the \textit{first} rail will have an index of \textit{0} and the last rail will have an index of $n - 1$.

Next, we will need to know the distance between every character on a specific rail. If we refer back to our example,
you will notice that both the top and bottom rails have the \textit{same} spacing between each character. This is because,
both the top and bottom row are where cycles connect. If you think of it as a triangle, the vertices of the triangle are
layed out on the bottom and top rows. The equation for calculating the character distance is: $$\mathlarger{C - 2R}$$

In simple terms, we are getting the \textit{distance} between our cycle and our current rail (factoring both up and
 down movements). As previously mentioned, distance patterns alternate on middle rows, this alternation is our cycle
  minus our \textit{current} character distance. This can be written mathematically as follows: $$\mathlarger{D_n = C - D_c}$$

Where $C$ is our cycle, $D_c$ is our current character distance, and $D_n$ is our new character distance.

There is one last step to calculating the character distance: handling the bottom rail. The aforementioned distance equation
will \textit{not} work for the bottom rail. Instead, the character distance for the bottom rail is our cycle.
In fact, the top rail is also the cycle but we don't need to manually handle that case as our equation does that for us
(the subtraction is factored when the rail index is \textit{0}).

Given the cycle and character distance, we can simply reconstruct the rail fence by laying out the cipher
text according to the appropriate character distance.

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \def\boxgap{+0.0cm}
        \def\minboxsz{0.8cm}
        \def\boxlinewidth{0.04cm}
        \def\stripgap{1cm}
        \def\lsgap{0.5cm}

        \node at(4.4, 3.2) {\Large Original Message: Hello World};
        \node at(4.4, -0.6) {\Large Encrypted Message: Horel ollWd};
        \draw[step=0.8cm,gray] (0,0) grid (11*\minboxsz,3*\minboxsz);
        \draw [->, thick, blue!25] (0.1, 2.3) -- (2.0, 0.4) -- (3.6, 2.0) -- (5.2, 0.4) -- (6.8, 2.0) -- (8.7, 0.1);
        \draw [->, thick, red!50] (0.2, 2.6) -- (8.6, 2.6);
        \node at(1*\minboxsz/2, 5*\minboxsz/2) {\Large H};
        \node at(3*\minboxsz/2, 3*\minboxsz/2) {\Large e};
        \node at(5*\minboxsz/2, 1*\minboxsz/2) {\Large l};
        \node at(7*\minboxsz/2, 3*\minboxsz/2) {\Large l};
        \node at(9*\minboxsz/2, 5*\minboxsz/2) {\Large o};
        \node at(13*\minboxsz/2, 1*\minboxsz/2) {\Large W};
        \node at(15*\minboxsz/2, 3*\minboxsz/2) {\Large o};
        \node at(17*\minboxsz/2, 5*\minboxsz/2) {\Large r};
        \node at(19*\minboxsz/2, 3*\minboxsz/2) {\Large l};
        \node at(21*\minboxsz/2, 1*\minboxsz/2) {\Large d};
    \end{tikzpicture}
    \caption{A diagram of the rail fence cipher which demonstrates how plaintext is arranged on the rails.}
\end{figure}

Now that we have discussed the theory behind the Rail Fence cipher, we will go ahead and implement it.
First we will write the encryption function. To encrypt plaintext we need two key pieces of information:
our plaintext and the amount of rails to encrypt with.

\begin{minted}[mathescape,
    numbersep=5pt,
    frame=lines,
    framesep=2mm]{python}
# Encryption function which takes in the plain_text and rail number.
def encrypt(plain_text, rails):
    # Create our cipher_text string and initialize to empty
    cipher_text = str()

    # TODO: Encryption

    return cipher_text
\end{minted}

As discussed previously, when encrypting, the message is laid out in rails according to the cycle.
Therefore, we will need to calculate the cycle within our function.
We can use the aforementioned equation to calculate the cycle. We use the \textit{max} function to
make sure that our cycle stays above 1, it is simply a special case for an encryption with one rail.\footnote{Although
encrypting plaintext with one rail won't yield particularly interesting results, we still make sure our algorithm can support it.}

\begin{minted}{python}
cycle = max(rails * 2 - 2, 1) # 1 is special case for 1 rail
\end{minted}

Next we will write the letters of the plaintext to their corresponding position on the rail.
We will iterate through every rail and layout characters which belong to that rail.

In every iteration, we must calculate a few key pieces of data. First, we will need to know the distance between
each character on the specific rail. As discussed, there is an alternating pattern between each character on a rail,
one for a character going down a cycle, and one for a character going up a cycle (with the top and bottom rails
having a constant spacing between characters). Since the top and bottom rails have the same spacing, if the rail
is the bottom rail, we set our distance to the cycle. Second, we will need to have a pointer variable which
keeps a reference to the current character we are looking at. This will simply be initialized to our rail (the start position
of the rail in the text).

Laying out the letters is actually quite simply. Since we know the distance between each character, we can continue
iterating through the plaintext until our pointer is \textit{greater} than the length of our plaintext. In every iteration,
we increment the pointer by our character distance, making sure to alternate between the two distance patterns.

Here is the iteration code along with the rest of the encryption function.

\begin{listing}[H]
    \begin{minted}[mathescape,
        numbersep=5pt,
        frame=lines,
        framesep=2mm]{python}
def encrypt(plain_text, rails):
    cipher_text = str()
    cycle = max((rails - 1) * 2, 1) # 1 is special case for 1 rail

    for rail in range(rails):
        ptr = rail
        character_distance = cycle - 2 * rail

        # Both the bottom and top rails have a (same) character distance of the cycle.
        if rail == rails - 1:
            character_distance = cycle

        # While we have *something* to write
        while ptr < len(plain_text):
            cipher_text += plain_text[ptr]
            ptr += character_distance

            # If this is not the top or bottom rail
            # alternate between two distance patterns
            if rail != 0 and rail != rails - 1:
                character_distance = cycle - character_distance

    return cipher_text
        \end{minted}
        \caption{Full implementation of encryption in the rail fence cipher.}
\end{listing}

The implementation for decryption is almost identical. Like encryption, when decrypting we must layout our ciphertext in the corresponding
rails. To do this, we can use the \textit{same} algorithm that we used for encryption.

\begin{listing}[H]
    \begin{minted}[mathescape,
        numbersep=5pt,
        frame=lines,
        framesep=2mm]{python}
def decrypt(cipher_text, rails):
    plain_text = [''] * len(cipher_text)
    cipher_index = 0
    cycle = max((rails - 1) * 2, 1)  # 1 is special case for 1 rail

    for rail in range(rails):
        ptr = rail
        character_distance = cycle - 2 * rail

        # Both the bottom and top rails have a (same) character distance of the cycle.
        if rail == rails - 1:
            character_distance = cycle

        # While we have *something* to write
        while ptr < len(plain_text):
            plain_text[ptr] = cipher_text[cipher_index]
            cipher_index += 1

            ptr += character_distance

            # If this is not the top or bottom rail
            # alternate between two distance patterns
            if rail != 0 and rail != rails - 1:
                character_distance = cycle - character_distance

    return ''.join(plain_text)
        \end{minted}
        \caption{Full implementation of decryption in the rail fence cipher.}
\end{listing}

As you can see, there are only slight differences between the encryption and decryption implementations. The first difference is the
way we build our result text. When we \textit{encrypt}, we append characters to a string (which is our ciphertext). We can do this because
our ciphertext is \textit{one-dimensional}. Conversely, when we decrypt, since we are laying out characters on rails, we must preserve the order of the
fence; we can think of this as \textit{two-dimensional} (since we are not just laying out character horizontally).
The second change, is the introduction of a second pointer variable: the \textit{cipher index}.
This is simply used to track the current reading-index of the ciphertext (so we know what character to read next).
There are some other \textit{small} changes in the decryption code but those are self-explanatory so they will not be covered.

\section{Substitution Ciphers}

A substitution cipher is a type of cryptography technique where each unit of plaintext is replaced with a unit of ciphertext; a unit may refer to a single
letter of the plaintext, a pair of letters, alternating patterns of the aforementioned, and so on \cite{wiki:substitution_cipher}.

A substitution cipher can be compared with a transposition cipher---the two are rather similar. In a transposition cipher, the units of plaintext are rearranged as a
permutation, but the units \textit{always} remained unchanged. The latter is unlike a substitution cipher which preserves the order of the plaintext but alters
the units.

\subsection{Caesar Cipher}
The Caesar Cipher, arguably the most popular form of substitution ciphers is another very simple form of cryptography.
It works by replacing each letter by a certain number of letters up or down in the alphabet. The amount of
letters that we move by is known as the \textit{shift offset}. If you shift the letter \textit{A} by 3 spaces, you get
the letter \textit{D}. If you shift the letter \textit{B}, you get the letter \textit{E}.

% Caesar cipher diagram
\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \def\boxgap{+0.053cm}
        \def\minboxsz{0.8cm}
        \def\boxlinewidth{0.04cm}

        \draw[gray, dotted, line width=0.04cm] (1, 3) -- (1.4, 3);
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz] (a1) at (2, 3) {\Large A};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of a1] (b1) {\Large B};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of b1] (c1) {\Large C};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of c1] (d1) {\Large D};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of d1, fill=cyan] (e1) {\Large \textbf{E}};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of e1] (f1) {\Large F};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of f1, dashed, gray] (g1) {\Large \textcolor{gray}{G}};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of g1, dashed, gray] (h1) {\Large \textcolor{gray}{H}};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of h1, dashed, gray] (i1) {\Large \textcolor{gray}{I}};

        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, dashed, gray] (x2) at (0, 0) {\Large \textcolor{gray}{X}};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of x2, dashed, gray] (y2) {\Large \textcolor{gray}{Y}};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of y2, dashed, gray] (z2) {\Large \textcolor{gray}{Z}};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of z2] (a2) {\Large A};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of a2, fill=cyan] (b2) {\Large \textbf{B}};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of b2] (c2) {\Large C};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of c2] (d2) {\Large D};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of d2] (e2) {\Large E};
        \node[rectangle, draw, line width=\boxlinewidth, minimum size=\minboxsz, right = \boxgap of e2] (f2) {\Large F};
        \draw[gray, dotted, line width=0.04cm] (7.8, 0) -- (8.2, 0);

        \draw [->, line width=0.04cm, gray] (a1) to[out=270, in=90] (x2);
        \draw [->, line width=0.04cm, gray] (b1) to[out=270, in=90] (y2);
        \draw [->, line width=0.04cm, gray] (c1) to[out=270, in=90] (z2);
        \draw [->, line width=0.04cm] (d1) to[out=270, in=90] (a2);
        \draw [->, line width=0.04cm] (e1) to[out=270, in=90] (b2);
        \draw [->, line width=0.04cm] (f1) to[out=270, in=90] (c2);
        \draw [->, line width=0.04cm, gray] (g1) to[out=270, in=90] (d2);
        \draw [->, line width=0.04cm, gray] (h1) to[out=270, in=90] (e2);
        \draw [->, line width=0.04cm, gray] (i1) to[out=270, in=90] (f2);
    \end{tikzpicture}
    \caption{A diagram of the Caesar cipher using a shift offset of \textit{3}.}
\end{figure}

Here is a simple example of a message encrypted using the cipher with a shift offset of 3:

\begin{minted}[mathescape,
               numbersep=5pt,
               frame=lines,
               framesep=2mm]{text}

Plaintext message:
HELLO WORLD

Ciphertext message:
KHOOR ZRUOG
\end{minted}

Even though the ciphertext appears to be unreadable, substitution cipher remains to be one of the weakest forms of cryptography.
This is for several reasons:
\begin{itemize}
    \item The possible number of keys is very small, since the key is an offset by which to shift by, it is limited to the number of letters in the alphabet.
    In the case of the English alphabet, one could very easily try all 25 possibilities.
    \item Since the structure of the original message remains intact, the ciphertext could be subjected to frequency-analysis which would reveal patterns about the message;
    potentially revealing the key.
    \item By studying multiple different ciphertexts, one could notice patterns within them and find out the key through that.
\end{itemize}

The substitution cipher can be expressed mathematically as follows: $$\mathlarger{E_i(n)=(n+k)\mod{26}}$$

Here we say that the encryption of the $ith$ letter $n$ is equal to a shift of $n+k$ where $k$ is the shift offset (or the key). The result of the shift
is divided by $26$ where the remainder of the division is used to make sure that the shift wraps around the alphabet; if the
shift goes beyond the range of the alphabet ($0$ to $26$), it wraps around back to the beginning.

Decryption is done in a similar manner, but instead subtracting by $k$. $$\mathlarger{P_i(n)=(n-k)\mod{26}}$$

Please note that even though this example is for the English alphabet, the aforementioned equations should work for most languages assuming that they are modified
to the count of the specific languages' alphabet.

The concept of shifting letters is rather intuitive but how do we shift letters in code? This is done by representing
each letter as a \textit{number} and then \textit{adding} or \textit{subtracting} from this number by our shift
offset. The \textit{ASCII} (American Standard Code for Information Interchange) scheme is an encoding which
provides the numerical representation of letters; this is known as an \textit{ordinal} \cite{caesar_cipher_invent_with_python}.
We can use ASCII to implement this cipher.

In the ASCII encoding scheme, the capital letters: \textit{A} through \textit{Z} are represented by the ordinals $65$ through
$90$. The lowercase letters: \textit{a} through \textit{z} are represented by the ordinals $97$ through $122$.
Lastly, the numeric digits $0$ through $9$ are represented by the ordinals $48$ through $57$.

Modern computers typically use the \textit{UTF-8} encoding instead of ASCII. Fortunately, UTF-8 is backwards compatible
with ASCII which means that the ordinals in UTF-8 will be the same as in ASCII.

The figure below shows the relevant parts of the ASCII table in all of it's glory!

\begin{table}[H]
    \centering
        \begin{tabular}{ | c c | c c | c c | c c | c c | c c |  }
            \hline
            \multicolumn{12}{|c|}{ASCII Table} \\
            \hline
        % x & n     & x  & n & x  & n & x  & n & x  & n  & x   & n
            32 & (space) & 48 & 0 & 64 & @ & 80 & P & 96 & ` & 112 & p \\
            33 & !     & 49 & 1 & 65 & A & 81  & Q & 97  & a  & 113 & q \\
            34 & "  & 50 & 2 & 66 & B & 82 & R & 98 & b & 114 & r \\
            35 & \# & 51 & 3 & 67 & C & 83 & S & 99 & c & 115 & s \\
            36 & \$ & 52 & 4 & 68 & D & 84 & T & 100 & d & 116 & t \\
            37 & \% & 53 & 5 & 69 & E & 85 & U & 101 & e & 117 & u \\
            38 & \& & 54 & 6 & 70 & F & 86 & V & 102 & f & 118 & v \\
            39 & '  & 55 & 7 & 71 & G & 87 & W & 103 & g & 119 & w \\
            40 & (  & 56 & 8 & 72 & H & 88 & X & 104 & h & 120 & x \\
            41 & )  & 57 & 9 & 73 & I & 89 & Y & 105 & i & 121 & y \\
            42 & *  & 58 & : & 74 & J & 90 & Z & 106 & j & 122 & z \\
            43 & +  & 59 & ; & 75 & K & 91 & [ & 107 & k & 123 & \{ \\
            44 & ,  & 60 & < & 76 & L & 92 & \textbackslash & 108 & l & 124 & $\vert$ \\
            45 & -  & 61 & = & 77 & M & 93 & ] & 109 & m & 125 & \} \\
            46 & .  & 62 & > & 78 & N & 84 & \textasciicircum & 110 & n & 126 & \textasciitilde \\
            47 & /  & 63 & ? & 79 & O & 85 & \textunderscore & 111 & o & 127 & (delete) \\
            \hline
       \end{tabular}
       \caption{The relevant parts of the ASCII table.}
\end{table}

Assume you wanted to shift the letter \textit{"A"} by three spaces, you would do the following:
\begin{itemize}
    \item Convert "A" to it's respective ASCII ordinal: 65.
    \item Add 3 to 65, to get the ordinal: 68.
    \item Convert the new ordinal: 68, back to it's letter form to get \textit{"D"}.
\end{itemize}

In Python, the \texttt{chr()} and \texttt{ord()} allows us to convert from letters and ordinals, respectively \cite{caesar_cipher_invent_with_python}.
The \texttt{chr()} function takes an integer as a parameter and returns the respective ASCII character \cite{caesar_cipher_invent_with_python}. Conversely,
the \texttt{ord()} function takes a character as a parameter and returns the respective ASCII ordinal \cite{caesar_cipher_invent_with_python}.

The code below represents an implementation of the Caesar cipher:

\begin{listing}[H]
    \begin{minted}[mathescape,
        numbersep=5pt,
        frame=lines,
        framesep=2mm]{python}
def cipher(message, shift):
    result = str()
    for character in message:
        new_ordinal = ord(character) + shift
        result += chr(new_ordinal)

    print(f"Your translated text is {result}")

# 1 is encrypt, 2 is decrypt
mode = int(input("Should I encrypt (1) or decrypt (2)? "))

# Make sure that our shift offset is within range.
shift = int(input("What is the shift offset? ")) % 26
message = input("What is the message? ")

if mode == 1:
    cipher(message, shift)
elif mode == 2:
    cipher(message, -shift)
else:
    print("Invalid mode input. Try again.")
    \end{minted}
    \caption{Full implementation of Caesar cipher in Python.}
\end{listing}

The code for Caesar cipher is rather simple. The actual cipher process rests within the \texttt{cipher()} function.
Encryption and decryption processes are the reverse of each other---yet even then, they share code which is quite alike.
The only difference between the two is the \textit{direction} in which they shift in. Since the direction is a binary decision,
represented by a subtraction or addition, we can simply combine both processes into a generic function. In order to encrypt
using the \texttt{cipher()} function, we pass in the shift as a \textit{positive} value; when we decrypt, we pass in the shift
value as a \textit{negative}. More specifically, the encryption and decryption functions are defined as follows:

\begin{listing}[H]
    \begin{minted}[mathescape,
        numbersep=5pt,
        frame=lines,
        framesep=2mm]{python}
    def encrypt(message, shift):
        return cipher(message, shift)

    def decrypt(message, shift):
        return cipher(message, -shift)
    \end{minted}
\end{listing}

The above code illustrates the similarity between the two processes. As you can see, whether we decrypt or encrypt is
determined by the sign of the shift offset.

\subsection{Breaking the Caesar Cipher}

The simplicity of Caesar cipher is unparalleled to other ciphers---we can see this in the implementation of the cipher.
For instance, the transposition cipher (mentioned earlier in this chapter), though simple, required changes in encryption and
decryption processes. Nevertheless, simplicity does come with a cost, as discussed earlier, Caesar cipher is rather insecure.
We can easily try all 26 different keys to figure out the cipher text; this is known as a \textit{brute force} method
of breaking a cipher. The following code shows how we can break a Caesar cipher through brute force.

\begin{listing}[H]
    \begin{minted}[mathescape,
        numbersep=5pt,
        frame=lines,
        framesep=2mm]{python}
def cipher(message, shift):
    result = str()
    for character in message:
        new_ordinal = ord(character) + shift
        result += chr(new_ordinal)

    print(f"Your translated text is {result}")

def solve(message, max_key):
    # Start at the shift offset of 1
    for i in range(1, max_key):
        cipher(message, -i)

message = input("What do you want to solve? ")
max_key = int(input("What is the max key? "))
solve(message, max_key)
    \end{minted}
    \caption{Implementation of a Caesar cipher solver in Python.}
\end{listing}

The solver code is rather simple, we run the \texttt{cipher()} on every possible shift offset from \textit{1}
to the \textit{max key size}. Recall that the message \textit{"Hello"} is encrypted to \textit{"Khoor"} when encrypting with a
shift offset of \textit{3}. Let's take a look at a sample run of the solver on the encrypted message: \textit{"Khoor"}.

\newcommand{\reducedstrut}{\vrule width 0pt height .9\ht\strutbox depth .9\dp\strutbox\relax}
\newcommand{\yellow}[1]{%
  \begingroup
  \setlength{\fboxsep}{0pt}%
  \colorbox{yellow}{\reducedstrut#1\/}%
  \endgroup
}

\begin{minted}[
        escapeinside=||,
        mathescape=true,
        numbersep=5pt,
        frame=lines,
        framesep=2mm]{text}
What do you want to solve? Khoor
What is the max key? 26
Your translated text is Jgnnq
Your translated text is Ifmmp
|$\yellow{\texttt{Your translated text is Hello}}$|
Your translated text is Gdkkn
Your translated text is Fcjjm
Your translated text is Ebiil
Your translated text is Dahhk
Your translated text is C`ggj
Your translated text is B_ffi
Your translated text is A^eeh
Your translated text is @]ddg
Your translated text is ?\ccf
Your translated text is >[bbe
Your translated text is =Zaad
Your translated text is <Y``c
Your translated text is ;X__b
Your translated text is :W^^a
Your translated text is 9V]]`
Your translated text is 8U\\_
Your translated text is 7T[[^
Your translated text is 6SZZ]
Your translated text is 5RYY\
Your translated text is 4QXX[
Your translated text is 3PWWZ
Your translated text is 2OVVY
\end{minted}
\begingroup
    \captionof{listing}{Sample run of a Caesar cipher solver in Python.}
\endgroup

The highlighted text above shows the decrypted message: "Hello." As you can see, we were able to decrypt our ciphertext
using the brute force method rather simply.

Even though Caesar cipher is rather basic and can be easily broken, it is not invaluable. Undoubtedly, Caesar cipher gives
off the impression of an encrypted message---and to the laymen, \textit{it is}. For simple usage, Caesar cipher does indeed
obscure the meaning of messages. In brief, since Caesar cipher is simple to implement and is rather efficient in the
encryption and decryption processes, it is certainly not a candidate which should be ruled out; rather, build on the
concepts established by the Caesar cipher in order to create a better cipher.

\section{Block Ciphers}

A block cipher is a type of cryptography algorithm which operates on \textit{fixed-length} groups, comprised of bits---called a \textit{block} \cite{wiki:block_cipher}.
Block ciphers play an integral role in modern-day cryptography design; many cryptography methods are based off the design of the block cipher \cite{wiki:block_cipher}.

Essentially, a block cipher takes a block of plaintext and produces a block of ciphertext, and vice-versa for decryption.
The size of a block can be any integer but is fixed within the scheme.

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \node at (4.6, 2.5) [rectangle, draw, align=center, minimum width=3.5cm, minimum height=1cm] {Round Key};
        \node at (4.6, 0) [rectangle, draw, fill=black!10, align=center, text width = 2cm, minimum width=3.5cm, minimum height=1.6cm] {Encryption Process};
        \node at (0, 0) [rectangle, draw, align=center, minimum width=3.5cm, minimum height=1cm] {Block of Plaintext};
        \node at (9.2, 0) [rectangle, draw, align=center, minimum width=3.5cm, minimum height=1cm] {Block of Ciphertext};
        \draw[->, line width=0.5mm] (1.75, 0) -- (2.85, 0);
        \draw[->, line width=0.5mm] (4.6+1.75, 0) -- (4.6+1.75+1.1, 0);
        \draw[->, line width=0.5mm] (4.6, 2) -- (4.6, 0.8);
    \end{tikzpicture}
    \caption{A diagram of the basic flow of a block cipher.}
\end{figure}

Though there are different types of block ciphers, most are referred to as \textit{iterated block ciphers} \cite{wiki:block_cipher}.
In an iterated block cipher, for every block of plaintext, the cipher produces an identically sized block of ciphertext. Each iteration of the cipher is
known as a \textit{round} \cite{wiki:block_cipher}. In each round, the blocks are operated on via a reversible transformation function
known as a \textit{round function} \cite{wiki:block_cipher}.

The round function will also typically take in different \textit{round keys} as a secondary input. These round keys are created from the original key.

\begin{align*}
    \mathlarger{M_i = R_{K_i}(M_{i-1})}
\end{align*}

The equation above defines the generic operation of a round where $M_0$ represents the plaintext and $M_r$ represents the ciphertext, where
$r$ represents the number of rounds.

\begin{align*}
    \mathlarger{M_0\;} & \mathlarger{= M \oplus K_0} \\
    \mathlarger{M_i\;} & \mathlarger{= R_{K_i}(M_{i - 1});\; i=1 \ldots r} \\
    \mathlarger{C\;} & \mathlarger{= M_r \oplus K_{r + 1}} \\
\end{align*}

\subsection{Feistel Cipher}

A \textit{Feistel cipher} (also commonly referred to as \textit{Feistel network}) is a cryptographic model used for creating block ciphers \cite{wiki:feistel_cipher}.
In a Feistel cipher, a block is split into two equal-sized halves. The round function is then applied to one half, which is then XORed with the other half \cite{wiki:feistel_cipher}.
The resulting halves are then swapped with each other \cite{wiki:feistel_cipher}.

The basic encryption process for a Feistel cipher where $F(K, R)$ represents the round function and $K_0,K_1,\ldots,K_n$ represents the subkeys for the rounds
$0,1,\ldots,n$ respectively---are as follows:

\begin{enumerate}
    \item Split the plaintext into two equal halves, $L_0$ and $R_0$, respectively.
    \item For each round $i = 0,1,\ldots,n$ where $n$ represents the amount of rounds, compute the following:
        \begin{align*}
            \mathlarger{L_{i + 1}\;} & \mathlarger{= R_i} \\
            \mathlarger{R_{i + 1}\;} & \mathlarger{= L_i \oplus F(R_i,K_i)}
        \end{align*}

        where $F(K,R)$ represents the round function.
\end{enumerate}

The resulting block of ciphertext is then $(L_{n + 1},R_{n + 1})$.

The process to decrypt a block of ciphertext is the reverse of the encryption process. For each round $i = n,n-1,\ldots,0$ where $n$ represents the amount of rounds,
we compute the following:
\begin{align*}
    \mathlarger{R_{i}\;} & \mathlarger{= L_i+1} \\
    \mathlarger{L_{i}\;} & \mathlarger{= R_i+1 \oplus F(L_i+1,K_i)}
\end{align*}

Once again, the resulting block of plaintext is then $(L_0,R_0)$.

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \definecolor{greenarrow}{RGB}{0,120,10}
        \definecolor{redarrow}{RGB}{120,0,0}
        \node at (1, 6) {Plaintext};
        \node at (0, 5.4) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$L_0$};
        \node at (2, 5.4) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$R_0$};

        \draw[fill=purple!10] (1, 4.5) ellipse (0.5cm and 0.3cm);
        \node at (1, 4.5) {$K_0$};
        \node at (1, 3.5) [rectangle, draw, fill=yellow!10, align=center, minimum width=0.5cm, minimum height=0.5cm] {F};
        \draw[->] (1, 4.2) -- (1, 3.75);
        \draw (0, 3.5) circle (0.2cm);
        \draw (0, 3.7) -- (0, 3.3);
        \draw (-0.2, 3.5) -- (0.2, 3.5);
        \draw[->] (0.75, 3.5) -- (0.2, 3.5);
        \draw[->] (2, 3.5) -- (1.25, 3.5);

        \draw[fill=purple!10] (1, 2) ellipse (0.5cm and 0.3cm);
        \node at (1, 2) {$K_1$};
        \node at (1, 1) [rectangle, draw, fill=yellow!10, align=center, minimum width=0.5cm, minimum height=0.5cm] {F};
        \draw[->] (1, 1.7) -- (1, 1.25);
        \draw (0, 1) circle (0.2cm);
        \draw (0, 1.2) -- (0, 0.8);
        \draw (-0.2, 1) -- (0.2, 1);
        \draw[->] (0.75, 1) -- (0.2, 1);
        \draw[->] (2, 1) -- (1.25, 1);

        \newcommand{\down}{3}
        \draw[fill=purple!10] (1, 2-\down) ellipse (0.5cm and 0.3cm);
        \node at (1, 2-\down) {$K_n$};
        \node at (1, 1-\down) [rectangle, draw, fill=yellow!10, align=center, minimum width=0.5cm, minimum height=0.5cm] {F};
        \draw[->] (1, 1.7-\down) -- (1, 1.25-\down);
        \draw (0, 1-\down) circle (0.2cm);
        \draw (0, 1.2-\down) -- (0, 0.8-\down);
        \draw (-0.2, 1-\down) -- (0.2, 1-\down);
        \draw[->] (0.75, 1-\down) -- (0.2, 1-\down);
        \draw[->] (2, 1-\down) -- (1.25, 1-\down);

        \draw[->, draw=greenarrow, thick] (0, 5.15) -- (0, 3.7);
        \draw[draw=greenarrow, thick] (0, 3.3) -- (0, 3.1) -- (2, 2.9) -- (2, 0.6) -- (0, 0.4);
        \draw[->, draw=redarrow, thick] (2, 5.15) -- (2, 3.1) -- (0, 2.9) -- (0, 1.2);
        \draw[draw=redarrow, thick] (0, 0.8) -- (0, 0.6) -- (2, 0.4);
        \draw[->, draw=greenarrow, thick] (0, 0) -- (0, -1.8);
        \draw[->, draw=greenarrow, thick] (0, -2.2) -- (0, -2.5);
        \draw[->, draw=redarrow, thick] (2, 0) -- (2, -2.5);

        \node at (0, -2.8) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$R_{n+1}$};
        \node at (2, -2.8) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$L_{n+1}$};
        \node at (1, -3.5) {Ciphertext};

        \draw[thick,dashed] (1, 0.2) -- (1, -0.4);

        \begin{scope}[xshift=6cm]
        \node at (1, 6) {Ciphertext};
        \node at (0, 5.4) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$R_{n+1}$};
        \node at (2, 5.4) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$L_{n+1}$};

        \draw[fill=purple!10] (1, 4.5) ellipse (0.5cm and 0.3cm);
        \node at (1, 4.5) {$K_n$};
        \node at (1, 3.5) [rectangle, draw, fill=yellow!10, align=center, minimum width=0.5cm, minimum height=0.5cm] {F};
        \draw[->] (1, 4.2) -- (1, 3.75);
        \draw (0, 3.5) circle (0.2cm);
        \draw (0, 3.7) -- (0, 3.3);
        \draw (-0.2, 3.5) -- (0.2, 3.5);
        \draw[->] (0.75, 3.5) -- (0.2, 3.5);
        \draw[->] (2, 3.5) -- (1.25, 3.5);

        \draw[fill=purple!10] (1, 2) ellipse (0.5cm and 0.3cm);
        \node at (1, 2) {$K_{n-1}$};
        \node at (1, 1) [rectangle, draw, fill=yellow!10, align=center, minimum width=0.5cm, minimum height=0.5cm] {F};
        \draw[->] (1, 1.7) -- (1, 1.25);
        \draw (0, 1) circle (0.2cm);
        \draw (0, 1.2) -- (0, 0.8);
        \draw (-0.2, 1) -- (0.2, 1);
        \draw[->] (0.75, 1) -- (0.2, 1);
        \draw[->] (2, 1) -- (1.25, 1);

        \draw[fill=purple!10] (1, 2-\down) ellipse (0.5cm and 0.3cm);
        \node at (1, 2-\down) {$K_0$};
        \node at (1, 1-\down) [rectangle, draw, fill=yellow!10, align=center, minimum width=0.5cm, minimum height=0.5cm] {F};
        \draw[->] (1, 1.7-\down) -- (1, 1.25-\down);
        \draw (0, 1-\down) circle (0.2cm);
        \draw (0, 1.2-\down) -- (0, 0.8-\down);
        \draw (-0.2, 1-\down) -- (0.2, 1-\down);
        \draw[->] (0.75, 1-\down) -- (0.2, 1-\down);
        \draw[->] (2, 1-\down) -- (1.25, 1-\down);

        \draw[->, draw=redarrow, thick] (0, 5.15) -- (0, 3.7);
        \draw[draw=redarrow, thick] (0, 3.3) -- (0, 3.1) -- (2, 2.9) -- (2, 0.6) -- (0, 0.4);
        \draw[->, draw=greenarrow, thick] (2, 5.15) -- (2, 3.1) -- (0, 2.9) -- (0, 1.2);
        \draw[draw=greenarrow, thick] (0, 0.8) -- (0, 0.6) -- (2, 0.4);
        \draw[->, draw=redarrow, thick] (0, 0) -- (0, -1.8);
        \draw[->, draw=redarrow, thick] (0, -2.2) -- (0, -2.5);
        \draw[->, draw=greenarrow, thick] (2, 0) -- (2, -2.5);

        \node at (0, -2.8) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$L_0$};
        \node at (2, -2.8) [rectangle, draw, fill=blue!10, align=center, minimum width=2cm, minimum height=0.4cm] {$R_0$};
        \node at (1, -3.5) {Plaintext};

        \draw[thick,dashed] (1, 0.2) -- (1, -0.4);
        \end{scope}
    \end{tikzpicture}
    \caption{A diagram depicting the encryption and decryption process in a Feistel cipher.}
\end{figure}

\subsubsection{Data Encryption Standard}

The \textit{Data Encryption Standard} (or \textit{DES} for short) is a symmetric-key algorithm. The algorithm was developed in the early 1970s by IBM and is based
off the design of the Feistel cipher. The algorithm (after a few changes) was eventually published as an official United States \textit{Federal Information Processing
Standard} (or \textit{FIPS} for short) in 1977. The publication of the algorithm resulted in international adoption and academic critic \cite{wiki:des}.

The Data Encryption Standard is now generally regarded to as insecure (for many applications) \cite{wiki:des}. This is mainly because DES has a relatively small key size of
56 bits. Despite this, DES was "highly influential in the advancements of modern cryptography." \cite{wiki:des}

DES is structured much like any other iterated block cipher. In the cipher, a block consists of 64-bits \cite{wiki:des}. Also, DES uses a key to modify the
transformational operations---a key is effectively only 56-bits as the algorithm uses 8-bits for error checking (and thus disregarding them in the actual operations)
\cite{wiki:des}.

DES additionally makes use of \textit{initial} and \textit{final} permutations. Before transforming a block, an initial permutation table is applied to the 64-bit block of data.
Once the block is operated on, a final permutation table is applied to the resulting 64-bit block of data. The initial permutation table reverses the actions of the
final permutation table, and vice-versa \cite{wiki:des}.

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \node at (3, 11) {Plaintext (64 bits)};
        \draw[fill=blue!10] (0, 10) rectangle (6, 9.5);
        \node at (3, 9.75) {Initial Permutation (IP)};
        \begin{scope}[yshift=8.2cm]
        \draw[fill=yellow!10] (2.2, 0.25) rectangle (3.8, -0.25);
        \node at (3, 0) {F};
        \draw[draw=red] (0.5, 0) circle [radius=0.2];
        \draw[draw=red] (0.3, 0) -- (0.7, 0);
        \draw[draw=red] (0.5, 0.2) -- (0.5, -0.2);
        \draw[->] (5.5, 0) -- (3.8, 0);
        \draw[->] (2.2, 0) -- (0.7, 0);
        \end{scope}
        \begin{scope}[yshift=6.2cm]
        \draw[fill=yellow!10] (2.2, 0.25) rectangle (3.8, -0.25);
        \node at (3, 0) {F};
        \draw[draw=red] (0.5, 0) circle [radius=0.2];
        \draw[draw=red] (0.3, 0) -- (0.7, 0);
        \draw[draw=red] (0.5, 0.2) -- (0.5, -0.2);
        \draw[->] (5.5, 0) -- (3.8, 0);
        \draw[->] (2.2, 0) -- (0.7, 0);
        \end{scope}
        \begin{scope}[yshift=3.0cm]
        \draw[fill=yellow!10] (2.2, 0.25) rectangle (3.8, -0.25);
        \node at (3, 0) {F};
        \draw[draw=red] (0.5, 0) circle [radius=0.2];
        \draw[draw=red] (0.3, 0) -- (0.7, 0);
        \draw[draw=red] (0.5, 0.2) -- (0.5, -0.2);
        \draw[->] (5.5, 0) -- (3.8, 0);
        \draw[->] (2.2, 0) -- (0.7, 0);
        \end{scope}
        \begin{scope}[yshift=1.0cm]
        \draw[fill=yellow!10] (2.2, 0.25) rectangle (3.8, -0.25);
        \node at (3, 0) {F};
        \draw[draw=red] (0.5, 0) circle [radius=0.2];
        \draw[draw=red] (0.3, 0) -- (0.7, 0);
        \draw[draw=red] (0.5, 0.2) -- (0.5, -0.2);
        \draw[->] (5.5, 0) -- (3.8, 0);
        \draw[->] (2.2, 0) -- (0.7, 0);
        \end{scope}
        \draw[fill=blue!10] (0, 0) rectangle (6, -0.5);
        \node at (3, -0.25) {Final Permutation (FP)};
        \node at (3, -1.5) {Ciphertext (64 bits)};

        \draw[->] (0.5, 11) -- (0.5, 10);
        \draw[->] (5.5, 11) -- (5.5, 10);

        \draw[->] (0.5, 9.5) -- (0.5, 8.4);
        \draw (0.5, 8) -- (0.5, 7.5) -- (5.5, 6.9) -- (5.5, 5.5) -- (0.5, 4.9) -- (0.5, 4.8);
        \draw[dashed] (0.5, 4.8) -- (0.5, 3.5);
        \draw[->] (0.5, 3.5) -- (0.5, 3.2);
        \draw[->] (0.5, 2.8) -- (0.5, 2.3) -- (5.5, 1.7) -- (5.5, 0);

        \draw[->] (5.5, 9.5) -- (5.5, 7.5) -- (0.5, 6.9) -- (0.5, 6.4);
        \draw (0.5, 6) -- (0.5, 5.5) -- (5.5, 4.9) -- (5.5, 4.8);
        \draw[dashed] (5.5, 4.8) -- (5.5, 3.5);
        \draw[->] (5.5, 3.5) -- (5.5, 2.3) -- (0.5, 1.7) -- (0.5, 1.2);
        \draw[->] (0.5, 0.8) -- (0.5, 0);

        \draw[->] (0.5, -0.5) -- (0.5, -1.5);
        \draw[->] (5.5, -0.5) -- (5.5, -1.5);

        \node at (3, 4.2) {for 16 rounds};
    \end{tikzpicture}
    \caption{The overall structure of DES.}
\end{figure}

In each round, a \textit{subkey} derived from the original key is used to transform the block of data (the subkeys are supplied in the reverse order when decrypting).
The subkeys are produced from a table known as the \textit{key schedule}. The key schedule defines how the original key should be rotated to create a subkey from a given
round. A \textit{permutation choice 1} (or \textit{PC1} for short) table is applied onto the original key before the subkey process. For each subkey, a \textit{permutation
choice 2} (or \textit{PC2} for short) table is applied.

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \node at (6, 10) {Key (64 bits)};
        \draw[fill=blue!10] (4, 9) rectangle (8, 8);
        \node at (6, 8.5) {PC1};
        \draw[->] (6, 9.8) -- (6, 9);

        \begin{scope}[yshift=6cm]
        \draw[fill=yellow!10] (5, 0.5) rectangle (7, -0.5);
        \node at (6, 0) {PC2};
        \draw[draw=red] (4, 1.1) rectangle (5, 0.7);
        \node at (4.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[draw=red] (7, 1.1) rectangle (8, 0.7);
        \node at (7.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[->] (5, 0.9) -- (5.5, 0.9) -- (5.5, 0.5);
        \draw[->] (7, 0.9) -- (6.5, 0.9) -- (6.5, 0.5);
        \draw[->] (5, 0) -- (3, 0);
        \end{scope}
        \begin{scope}[yshift=4cm]
        \draw[fill=yellow!10] (5, 0.5) rectangle (7, -0.5);
        \node at (6, 0) {PC2};
        \draw[draw=red] (4, 1.1) rectangle (5, 0.7);
        \node at (4.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[draw=red] (7, 1.1) rectangle (8, 0.7);
        \node at (7.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[->] (5, 0.9) -- (5.5, 0.9) -- (5.5, 0.5);
        \draw[->] (7, 0.9) -- (6.5, 0.9) -- (6.5, 0.5);
        \draw[->] (5, 0) -- (3, 0);
        \end{scope}
        \begin{scope}[yshift=1cm]
        \draw[fill=yellow!10] (5, 0.5) rectangle (7, -0.5);
        \node at (6, 0) {PC2};
        \draw[draw=red] (4, 1.1) rectangle (5, 0.7);
        \node at (4.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[draw=red] (7, 1.1) rectangle (8, 0.7);
        \node at (7.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[->] (5, 0.9) -- (5.5, 0.9) -- (5.5, 0.5);
        \draw[->] (7, 0.9) -- (6.5, 0.9) -- (6.5, 0.5);
        \draw[->] (5, 0) -- (3, 0);
        \end{scope}
        \begin{scope}[yshift=-1cm]
        \draw[fill=yellow!10] (5, 0.5) rectangle (7, -0.5);
        \node at (6, 0) {PC2};
        \draw[draw=red] (4, 1.1) rectangle (5, 0.7);
        \node at (4.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[draw=red] (7, 1.1) rectangle (8, 0.7);
        \node at (7.5, 0.9) {\textcolor{red}{$<<$}};
        \draw[->] (5, 0.9) -- (5.5, 0.9) -- (5.5, 0.5);
        \draw[->] (7, 0.9) -- (6.5, 0.9) -- (6.5, 0.5);
        \draw[->] (5, 0) -- (3, 0);
        \end{scope}

        \draw (6, 8) -- (6, 7.5);
        \draw[->] (6, 7.5) -- (4.5, 7.5) -- (4.5, 7.1);
        \draw[->] (6, 7.5) -- (7.5, 7.5) -- (7.5, 7.1);
        \draw[->] (4.5, 6.7) -- (4.5, 5.1);
        \draw[->] (7.5, 6.7) -- (7.5, 5.1);
        \draw (4.5, 4.7) -- (4.5, 3.5);
        \draw[dashed] (4.5, 3.5) -- (4.5, 2.5);
        \draw[->] (4.5, 2.5) -- (4.5, 2.1);
        \draw (7.5, 4.7) -- (7.5, 3.5);
        \draw[dashed] (7.5, 3.5) -- (7.5, 2.5);
        \draw[->] (7.5, 2.5) -- (7.5, 2.1);
        \draw[->] (4.5, 1.7) -- (4.5, 0.1);
        \draw[->] (7.5, 1.7) -- (7.5, 0.1);

        \node at (1, 6) {Subkey 1 (48 bits)};
        \node at (1, 4) {Subkey 2 (48 bits)};
        \node at (1, 1) {Subkey 15 (48 bits)};
        \node at (1, -1) {Subkey 16 (48 bits)};
    \end{tikzpicture}
    \caption{The structure of the DES key schedule. The $\mathsmaller{<<}$ denotes a rotation to the left.}
\end{figure}

The round $F(K, R)$ function is defined as follows:

\begin{enumerate}
    \item The 32-bit half-block is expanded to 48-bits using the \textit{expansion permutation table} (E). The expansion permutation duplicates half of the bits in the
          32-bit block in order to expand the data.
    \item The result of the expansion is then combined with the given subkey for the round (using a XOR operation).
    \item The result of the key combination is split into eight 6-bit blocks of data which is then processed by the \textit{substitution boxes}---one 6-bit block for
    each substitution-box. Each substitution-box replaces the 6-bit input data with a 4-bit output. The substitution values are non-linearly transformed.
    \item Lastly, the outputs from the substitution process are combined into one 32-bit block of data which is rearranged by a fixed permutation table known as the
        \textit{permutation-box}. The permutation-box shuffles the output of each substitution to increase cryptographic security.
\end{enumerate}

\begin{figure}[H]
    \centering
    \begin{tikzpicture}
        \node at (1, 6) {Half Block (32 bits)};
        \node at (5, 6) {Subkey (48 bits)};
        \draw[fill=blue!10] (0, 5.25) rectangle (2, 4.75);
        \node at (1, 5) {E};
        \draw[draw=red] (3.15, 4) circle [radius=0.2];
        \draw[draw=red] (2.95, 4) -- (3.35, 4);
        \draw[draw=red] (3.15, 4.2) -- (3.15, 3.8);
        \draw[->] (1, 5.8) -- (1, 5.25);
        \draw[->] (1, 4.75) -- (1, 4) -- (2.95, 4);
        \draw[->] (5, 5.8) -- (5, 4) -- (3.35, 4);
        \draw[->] (3.15, 3.8) -- (3.15, 3.4);
        \draw (0, 3.4) -- (6.3, 3.4);
        \begin{scope}[xshift=0cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S1};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \begin{scope}[xshift=0.8cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S2};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \begin{scope}[xshift=1.6cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S3};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \begin{scope}[xshift=2.4cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S4};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \begin{scope}[xshift=3.2cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S5};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \begin{scope}[xshift=4cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S6};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \begin{scope}[xshift=4.8cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S7};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \begin{scope}[xshift=5.6cm]
        \draw[fill=yellow!10] (0, 3) rectangle (0.7, 2.5);
        \node at (0.35, 2.75) {S8};
        \draw[->] (0, 3.4) -- (0, 3);
        \draw[->] (0.14, 3.4) -- (0.14, 3);
        \draw[->] (0.28, 3.4) -- (0.28, 3);
        \draw[->] (0.42, 3.4) -- (0.42, 3);
        \draw[->] (0.56, 3.4) -- (0.56, 3);
        \draw[->] (0.7, 3.4) -- (0.7, 3);
        \draw (0.1, 2.5) -- (0.1, 2.1);
        \draw (0.267, 2.5) -- (0.267, 2.1);
        \draw (0.433, 2.5) -- (0.433, 2.1);
        \draw (0.6, 2.5) -- (0.6, 2.1);
        \end{scope}
        \draw (0.1, 2.1) -- (6.2, 2.1);
        \draw[->] (3.15, 2.1) -- (3.15, 1.5);
        \draw[fill=green!10] (0, 1.5) rectangle (6.3, 0.5);
        \node at (3.15, 1) {P};
        \draw[->] (3.15, 0.5) -- (3.15, 0);
    \end{tikzpicture}
    \caption{The structure of the round function in DES. \textit{S1-S8} denote their respective substitution box.}
\end{figure}


\documentclass[../main]{subfiles}
\begin{document}

\chapter{Algebra, Number Theory and Related Assumptions}

\section{Divisors, primes, etc.}

\begin{lemma}
		If $n, m \in{} \mathbb{N}$ and $m > 1$, then n is invertible modulo m (there exists p such that np mod m = 1) whenever gcd(n, m) = 1, i. e. when n, m are comprime.
\end{lemma}

\section{Primes and factoring}

\noindent
$\textbf{wFactor}_A (n):$\\
$(x, y) \leftarrow{} \mathbb{N} \times{} \mathbb{N} \; with \; |x| = |y| = n$\\
$N \leftarrow{} x \cdot{} y$\\
$(z, w) \leftarrow{} A(N)$\\
$\textbf{Result:} \; z \cdot{} w = N$\\
$$Pr(wFactor_A (n) = 1) = \varepsilon{} (n)$$

\noindent
$\textbf{for} \; i \leftarrow{} 1 \; to \; t \; \textbf{do}$\\
$\quad{}\quad{}r \leftarrow{} \{0, 1\}^{n-1}$\\
$\quad{}\quad{}p \leftarrow{} 1\mid\mid r$\\
$\quad{}\quad{}\textbf{if} \; p \; is \; prime \; \textbf{then}$\\
$\quad{}\quad{}\quad{}\quad{}\textbf{Result:} \; p$\\
$\textbf{Result:} \; fail$\\

\begin{theorem}
	There exists a constant c such that for every $n > 1$ the number of primes that can be represented in exactly n bits is at least equal to $\frac{c \cdot{} 2^{n-1}}{n}$.
\end{theorem}

\begin{theorem}
	If $(\mathbb{G}, \cdot)$ has order m, then for each $g \in{} \mathbb{G}$, it is true that $g^m = 1_{\mathbb{G}}$.
\end{theorem}

\begin{corollary}
	If $(\mathbb{G}, \cdot)$ has order $m > 1$, then for every $g \in{} \mathbb{G}$ and for every i, $g^i = g^{[i \; mod \; m]}$.
\end{corollary}

\begin{theorem}
	Let $N > 1$. For every natural $e > 0$, we define $f_e : \mathbb{Z}_N* \rightarrow{} \mathbb{Z}_N*$ assuming $f_e (x) = x^e \; mod \; N$.
	If $gcd(e, \Phi (N)) = 1$, then $f_e$ is a permutation. Moreover, if d is the inverse of e (modulo $\Phi (N)$), then $f_d$ is the inverse of $f_e$.
\end{theorem}

\noindent
$\textbf{RSAInv}_{A, GenRSA}(n):$\\
$(N, e, d) \leftarrow{} GenRSA(1^n)$\\
$y \leftarrow{} \mathbb{Z}_N*$\\
$x \leftarrow{} A(N, e, y)$\\
$\textbf{Result:} \; x^e mod N = y$
$$Pr(RSAInv_{A, GenRSA}(n) = 1) = \varepsilon{} (n)$$

\noindent
$(N, p, q) \leftarrow{} \textbf{GenModulus}(1^n)$\\
$M \leftarrow{} (p-1)(q-1)$\\
$e \leftarrow{} \{1, \ldots, M\} \; such \; that \; gcd(e, M) = 1$\\
$d \leftarrow{} e^{-1} mod M$\\
$\textbf{Result:} \; (N, e, d)$

\begin{lemma}
	If $\mathbb{G}$ has order m and $g \in{} \mathbb{G}$ has order i, then $i|m$.
\end{lemma}

\begin{theorem}
	If $\mathbb{G}$ has prime order then $\mathbb{G}$ is cyclic and every $g \in{} \mathbb{G}$ with $g \neq{} 1_{\mathbb{G}}$ generates $\mathbb{G}.$
\end{theorem}

\noindent
$\textbf{DLog}_{A, GenCG} (n):$\\
$(\mathbb{G}, q, g) \leftarrow{} GenCG(1^n)$\\
$h \leftarrow{} \mathbb{G}$\\
$x \leftarrow{} A(\mathbb{G}, q, g, h)$\\
$\textbf{Result:} \; g^x  =    n $
$$Pr(DLog_{A, GenCG} (n) = 1) = \varepsilon{} (n)$$

% slides 43-49

\begin{theorem}
	If factoring is hard relative to \textbf{GenModulus}, then $f_{GenModulus}$ is a one-way function.
\end{theorem}

% Proof 16/11/2021
\begin{theorem}
	If $\mathbb{G}$ is a finite group where $m = |\mathbb{G}|$ is the order of $\mathbb{G}$, then for every $g \in{} \mathbb{G}$, it holds that $g^n = 1_{\mathbb{G}}$.
\end{theorem}

\paragraph{Proof}
	\begin{itemize}
		\item Let us make the assumption that $\mathbb{G}$ is abelian (this of course makes the proof less general, but has the advantage of simplifying it).
		\item Take $\mathbb{G} = \{g_1, \ldots, g_m\}$ and consider any $g \in{} \mathbb{G}$.
		\item Of course
				$$g_1 \cdot{} g_2 \cdot{} g_3 \cdot{} \ldots{} \cdot{} g_m = (gg_1)\cdot{}(gg_2)\ldots(gg_m) \quad\quad \textcolor{red}{(*)}$$
				Indeed, the factors in the rhs are all distinct elements of $\mathbb{G}$ because if $gg_i = gg_j$;
				\newline
				then $g^{-1}gg_i = g^{-1}gg_j$ and $g_i = g_j$, which would contradict the fact that $|\{g_1, \ldots, g_m\}| = m$.
		\item Since $\mathbb{G}$ is abelian, we can rearrange the rhs of \textcolor{red}{(*)} and obtain that
				$$g_1g_2 \cdots{} g_m = g^m \cdot{} (g_1 \cdot{} g_2 \cdots g_m)$$
		\item We can then multiply both sides of this equation by $(g_1 g_2 \cdots{} g_m)^{-1}$ and obtain:
				\begin{align*}
					1_{\mathbb{G}} &= (g_1 g_2 \cdots{} g_m) \cdot (g_1 g_2 \cdots{} g_m)^{-1}	\\
					&= g^m \cdot (g_1 g_2 \cdots{} g_m) \cdot (g_1 g_2 \cdots{} g_m)^{-1}		\\
					&= g^m \cdot 1_{\mathbb{G}}										\\
					&= g^m
				\end{align*}
	\end{itemize}

\end{document}