\documentclass[12pt,english]{mrl}
\usepackage{graphicx}
\usepackage{listings}

\renewcommand{\familydefault}{\rmdefault}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{color}
\usepackage{babel}
\usepackage{verbatim}
\usepackage{float}
\usepackage{url}
\usepackage{amsthm}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage[unicode=true,pdfusetitle,
 bookmarks=true,bookmarksnumbered=false,bookmarksopen=false,
 breaklinks=false,pdfborder={0 0 1},backref=false,colorlinks=true]
 {hyperref}
\usepackage{breakurl}

\makeatletter

\makeatletter

\newcommand{\h}{\mathcal{H}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\floatstyle{ruled}
\newfloat{algorithm}{tbp}{loa}
\providecommand{\algorithmname}{Algorithm}
\floatname{algorithm}{\protect\algorithmname}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
\numberwithin{equation}{section}
\numberwithin{figure}{section}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
\usepackage{algpseudocode}

\makeatother

\begin{document}
\begin{frontmatter}

\begin{fmbox}
\hfill\setlength{\fboxrule}{0px}\setlength{\fboxsep}{5px}\fbox{\includegraphics[width=2in]{byterubLogo.png}}
\dochead{Research bulletin \hfill MRL-0003}
\title{ByteRub is Not That Mysterious}
\date{25 September 2014}
\author[
   addressref={mrl},
   email={lab@byterub.cc}
]{\fnm{Shen} \snm{Noether}}

\address[id=mrl]{
  \orgname{ByteRub Research Lab}
}
\end{fmbox}

\end{frontmatter}

\section{Introduction}
Recently, there have been some vague fears about the CryptoNote
source code and protocol floating around the internet based on the
fact that it is a more complicated protocol than, for instance, Bitcoin.
The purpose of this note is to try and clear up some misconceptions,
and hopefully remove some of the mystery surrounding ByteRub Ring Signatures.
I will start by comparing the mathematics involved in CryptoNote
ring signatures (as described in \cite{CN}) to the mathematics in
\cite{FS}, on which CryptoNote is based. After this, I will compare
the mathematics of the ring signature to what is actually in the
CryptoNote codebase.

\section{CryptoNote Origins}

As noted in (\cite{CN}, 4.1) by Saberhagen, group ring signatures have a history
starting as early as 1991 \cite{CH}, and various ring signature
schemes have been studied by a number of researchers throughout the
past two decades. As claimed in (\cite{CN} 4.1), the main ring signature
used in CryptoNote appears to be based on \cite{FS}, with some changes
to accomodate block-chain technology.

\subsection{Traceable Ring Signatures}

In \cite{FS}, Fujisaki and Suzuki introduced a scheme for a ring
signature designed to ``leak secrets anonymously, without the risk
of identity escrow.'' This lack of a need for ``identity escrow,''
allows users of the ring signature to hide themselves in a group with
an inherently higher level of trustlessness compared to schemes relying
on a group manager.

In ring-signature schemes relying on a group manager, such as the
original ring signatures described in \cite{CH}, a designated trusted
person guards the secrets of the group participants. While anonymous,
such schemes rely, of course, on the manager not being compromised.
The result of having a group-manager, in terms of currencies, is essentially
the same as having a trusted organization or node to mix your coins.

In contrast, the traceable ring signature scheme given in \cite{FS}
has no group manager, and is thus inherently more trustless, but potentially
has other vulnerabilities which will be discussed, and which \cite{CN}
attempts to mitigate via blockchain technology.

According to \cite{FS}, there are four formal security requirements
to their traceable ring signature scheme:
\begin{itemize}
\item Public Traceability - Anyone who creates two signatures for different
messages with respect to the same tag can be traced. (In CryptoNote,
if the user opts not to use a one-time key for each transaction, then
they will be traceable, however if they desire anonymity, then they
will use the one-time key. Thus as stated on page 5 of \cite{CN},
the traceability property is weakened in CryptoNote.)
\item Tag-Linkability - Every two signatures generated by the same signer
with respect to the same tag are linked. (This aspect in CryptoNote
refers to each transaction having a key-image which
prevents double spending.) %

\item Anonymity - As long as a signer does not sign on two different messages
with respect to the same tag, the identity of the signer is indistinguishable
from any of the possible ring members. In addition, any two signatures
generated with respect to two distinct tags are always unlinkable.
(In terms of CryptoNote, if the signer attempts to use the same key-image
more than once, then they can be identified out of the group. The
unlinkability aspect is retained and is a key part of CryptoNote.)
\item Exculpability - An honest ring member cannot be accused of signing
twice with respect to the same tag. In other words, it should be infeasible
to counterfeit a tag corresponding to another person's secret key.
(In terms of CryptoNote, this says that key-images cannot be faked.)
\end{itemize}
In addition, \cite{FS} provide a ring signature protocol on page
10 of their paper, which is equivalent to the CryptoNote ring signature
algorithm, as described on page 9-10 of \cite{CN}. It is worthwhile
to note that \cite{FS} is a publicly peer-reviewed publication appearing
in Lecture Notes in Computer Science, as opposed to typical crypto-currency
protocol descriptions, where it is  unclear whether or not they have been reviewed or not.

\subsection{Traceability vs CryptoNote}

In the original traceable ring signature algorithm described in \cite{FS},
it is possible to use the tag $L$ corresponding to a signature multiple
times. However, multiple uses of the tag allow the user to be traced;
in other words, the signer's index can be determined out of the group of users
signing. It is worthwhile to note that, due to the exculpability
feature of the protocol (\cite{FS} 5.6, \cite{CN}, A2), keys cannot
be stolen this way, unless an attacker is able to solve the Elliptic
Curve Discrete Logarithm Problem (ECDLP) upon which a large portion of modern
cryptography is based (\cite{Si} XI.4).

The process to trace a tag $L$ used more than once is described
on (\cite{FS}, page 10). In the CryptoNote protocol, however, key
images (tags) used more than once are rejected by the block-chain
as double-spends, and hence traceability is not an aspect of CryptoNote.

\subsection{Tag-Linkability vs CryptoNote}

In essence, the tag-linkability aspect of the traceable ring signature
protocol is what prevents CryptoNote transactions from being double-spends.
The relevant protocols are referred to as ``Trace'' in (\cite{FS},
5) and ``LNK'' in the CryptoNote paper. Essentially all that is
required is to be able to keep track of the key images which have
been used before, and to verify that a key image is not used again.

If one key-image is detected on the block-chain before
another key-image, then the second key image is detected as a double-spend
transaction. As key-images cannot be forged, being exculpable, the
double-spender must in fact be the same person, and not another person
trying to steal a wallet.

\section{One-Time Ring Signatures (mathematics)}

The security of the ring signature scheme as described in (\cite{FS}
10, \cite{CN} 10) and implemented in the CryptoNote source relies on the known
security properties of Curve25519. Note that this is the same curve
used in OpenSSH 6.5, Tor, Apple iOS, and many other%
\footnote{\url{http://ianix.com/pub/curve25519-deployment.html}%
} security systems.

\subsection{\label{sub:Twisted-Edwards-Curves}Twisted Edwards Curves}

The basic security in the CryptoNote Ring Signature algorithm is guaranteed
by the ECDLP (\cite{Si}, XI.4) on the Twisted Edwards curve ed25519.
The security properties of curve ed25519 are described in \cite{Bern},
by noted cryptographer Daniel Bernstein, and in (\cite{BCPM}) by
a team from Microsoft Research. Bernstein notes about ed25519 the ``every known
attack is more expensive than performing a brute-force search on a
typical 128-bit secret-key cipher.''

The curve ed25519 is a singular curve of genus $1$ with
a group law, and described by $-x^{2}+y^{2}=1+\left(\frac{-121665}{121666}\right)x^{2}y^{2}$.
This curve is considered over the finite field $\mathbb{F}_{q}$,
$q=2^{255}-19$. For those readers unfamiliar with algebraic geometry,
an algebraic curve is considered as a one dimensional sort of space, consisting
of all points $\left(x,y\right)$ satisfying the above equation. All
points are also considered modulo $q$. By virtue of its genus, ed25519
has a ``group structure'' which, for the purpose of this discussion, means if $P=\left(x_{1},y_{1}\right)$
is a point on the curve, and $Q=\left(x_{2},y_{2}\right)$ is another
point on the curve, then these points can be added (or subtracted) and the sum (or difference), $P+Q$ (or $P-Q$)
will also be on the curve. The addition is \textbf{not} the naive
adding of $x_{1}+x_{2}$ and $y_{1}+y_{2}$, but instead points are
added using the rule
\[
P+Q=\left(\frac{x_{1}y_{2}+y_{1}x_{2}}{1+dx_{1}x_{2}y_{1}y_{2}},\frac{y_{1}y_{2}+x_{1}x_{2}}{1-dx_{1}x_{2}y_{1}y_{2}}\right)
\]
 where $d=\left(\frac{-121665}{121666}\right)$ (\cite{BBJLP} 6,
\cite{BCPM}). The mathematics of curves of genus one are explained
in great detail in \cite{Si} for the interested reader.

Based on the above, we can compute $P+P$ for any
such point. In order to shorten notation, we rely on our algebraic intuition and denote $2P = P + P$.
If $n\in\mathbb{Z}$, then $nP$ denotes the repeated sum $$\underbrace{P+P+\cdots+P}_{n\ times}$$
using the above nonlinear addition law. As an example of how this
differs from ordinary addition, consider the following system of equations:
\begin{eqnarray*}
aP+bQ&=&X \\
aP^{\prime}+bQ^{\prime}&=&Y
\end{eqnarray*}
 where $a,b,c,d$ are integers and $P,Q,X$ are points. If this were a standard
 system of linear equations then one could use linear algebraic techniques
to easily solve for $a$ and $b$, assuming that $P,Q,X,Y,P^{\prime}$,
and $Q^{\prime}$ are known. However, even if $a,b$ are very small
the above system is extremely difficult to solve using the ed25519
addition law. For example, if $a=1$ and $b=1$, we have
\begin{eqnarray*}
\left(\frac{x_{P}y_{Q}+y_{P}x_{Q}}{1+dx_{P}x_{Q}y_{P}y_{Q}},\frac{y_{P}y_{Q}+x_{P}x_{Q}}{1-dx_{P}x_{Q}y_{P}y_{Q}}\right)&=&\left(x_{X},y_{X}\right) \\
\left(\frac{x_{P^{\prime}}y_{Q^{\prime}}+y_{P^{\prime}}x_{Q^{\prime}}}{1+dx_{P^{\prime}}x_{Q^{\prime}}y_{P^{\prime}}y_{Q^{\prime}}},\frac{y_{P^{\prime}}y_{Q^{\prime}}+x_{P^{\prime}}x_{Q^{\prime}}}{1-dx_{P^{\prime}}x_{Q^{\prime}}y_{P^{\prime}}y_{Q^{\prime}}}\right)&=&\left(x_{Y},y_{Y}\right)
\end{eqnarray*}
 So in reality, this is a system of $4$ nonlinear equations. To convince
yourself that it is in fact difficult to figure out $a$ and $b$,
try writing the above systems assuming $a=2$, $b=1$. It should become
clear that the problem is extremely difficult when $a,b$ are chosen
to be very large. As of yet, there are no known methods available to
efficiently solve this system for large values of $a$ and $b$.

Consider the following problem. Suppose your friend has a random integer
$q$, and computes $qP$ using the above form of addition. Your friend
then tells you the $x$ and $y$ coordinates $qP=\left(x,y\right)$,
but not what $q$ itself is. Without asking, how do you find out what
$q$ is? $ $A naive approach might be to start with $P$ and keep
adding $P+P+P...$ until you reach $qP$ (which you will know because
you will end up at $\left(x,y\right)$). But if $q$ is very large
then this naive approach might take billions of years using modern
supercomputers. Based on what mathematicians currently know about
the problem and the number of possible $q$, none of the currently
known attacking techniques can, as a general rule, do better in any
practical sense than brute force.

In CryptoNote, your secret key is essentially just a very, very large
number $x$ (for other considerations, see section \ref{sub:generate_keys},
we choose $x$ to be a multiple of $8$). There is a special point
$G$ on the curve ed25519 called ``the base point'' of the curve
which is used as the starting point to get $xG$. Your public key is just $xG$, and you are protected by the above problem from someone using known information to determine the private key.

\subsection{\label{sub:Relation-to-Diffie}Relation to Diffie Helman}

Included in a ring signature are the following equations
involving your secret key $x$:

\begin{eqnarray*}
P&=&xG \\
I&=&x\mathcal{H}_{p}\left(P\right) \\
r_{s}&=&q_{s}-c_{s}x.
\end{eqnarray*}

Here $s$ is a number giving the index in the group signature to
your public key, and $\mathcal{H}_{p}\left(P\right)$ is a hash function which
deterministically takes the point $P$ to another point $P^{\prime}=x^{\prime}G$,
where $x^{\prime}$ is another very large uniformly chosen number.
The value $q_s$ is chosen uniformly at random, and $c_s$ is computed using
another equation involving random values.
The particular hash function used in CryptoNote is Keccak1600,
used in other applications such as SHA-3; it is currently considered
to be secure (\cite{FIPS}).

The above equations can be written as follows:
\begin{eqnarray*}
P&=&xG \\
P^{\prime}&=&xx^{\prime}G^{\prime} \\
r_{s}&=&q_{s}-c_{s}x
\end{eqnarray*}

Solving the top two equations
is equivalent to the ECDH (as outlined in a previous note (\cite{SN}))
and is the same practical difficulty as the ECDLP.
Although the equations appear linear, they are in fact highly non-linear,
as they use the addition described in \ref{sub:Twisted-Edwards-Curves} and above.
The third equation (with unknowns $q_{s}$ and $x$), has the difficulty
of finding a random number (either $q_{s}$ or $x$) in $\mathbb{F}_{q}$,
a very large finite field; this is not feasible.
Note that as the third equation has two unknowns, combining
it with the previous two equations does not help; an attacker needs to
determine at least one of the random numbers $q_{s}$ or $x$.

\subsection{\label{sub:Time-Cost-to}Time Cost to Guess q or x }

Since $q$ and $x$ are assumed to be random very large numbers in
$\mathbb{F}_{q}$ , with $q=2^{255}-19$ (generated as 32-byte
integers), this is equivalent to a 128-bit security level (\cite{BCPM}),
which is known to take billions of years to compute with current supercomputers.

\subsection{Review of Proofs in Appendix}

In the CryptoNote appendix, there are four proofs of the four basic
properties required for security of the one-time ring-signature scheme:
\begin{itemize}
\item Linkability (protection against double-spending)
\item Exculpability (protection of your secret key)
\item Unforgeability (protection against forged ring signatures)
\item Anonymity (Ability to hide a transaction within other transactions)
\end{itemize}
These theorems are essentially identical to those in \cite{FS} and show that
the ring signature protocol satisfies the above traits. The first
theorem shows that only the secret keys corresponding
to the public keys included in a group can produce a signature for
that group. This relies on the ECDLP for the solution of two simultaneous
(non-linear) elliptic curve equations, which, as explained in \ref{sub:Relation-to-Diffie},
is practically unsolvable. The second theorem uses the same reasoning,
but shows that in order to create a fake signature that passes verification,
one would need to be able to solve the ECDLP. The third and fourth theorems
are taken directly from \cite{FS}.

\section{One-Time Ring Signatures (Application)}

To understand how CryptoNote is implementing the One-Time Ring signatures,
I built a model in Python of Crypto-ops.cpp and Crypto.cpp from the ByteRub source
code using naive Twisted Edwards Curve operations (taken
from code by Bernstein), rather than the apparently reasonably optimized
operations existing in the CryptoNote code. Functions
are explained in the code comments below. Using the model will produce
a working ring signature that differs slightly from the ByteRub ring
signatures only because of hashing and packing differences between
the used libraries. The full code is hosted at the following address:
\begin{center}
\url{https://github.com/ShenNoether/MiniNero/blob/master/MiniNero.py}
\end{center}
Note that most of the important helper functions in crypto-ops.cpp in the CryptoNote source
are pulled from the reference implementation of Curve25519. This reference
implentation was coded by Matthew Dempsky (Mochi Media, now Google)%
\footnote{\url{http://nacl.cr.yp.to/}%
}.

In addition, after comparing the python code to the paper, and in
turn comparing the python code to the actual ByteRub source, it is
fairly easy to see that functions like \texttt{generate\_ring\_sig} are
all doing what they are supposed to based on the protocol described
in the whitepaper. For example, here is the ring signature generation algorithm
used in the CryptoNote source:

\begin{algorithm}[H]
\caption{Ring Signatures}

\begin{algorithmic}
\State $i\gets 0$
\While {$i<numkeys$}
	\If {$i= s$}
		\State $k \gets random\ \mathbb{F}_q\  element$
		\State $L_i \gets k \cdot G$
		\State $R_i \gets k\cdot \mathcal{H}_p(P_i)$
	\Else
		\State $k1 \gets random\ \mathbb{F}_q\  element$
		\State $k2 \gets random\ \mathbb{F}_q\  element$
		\State $L_i\gets k_1 P_i + k_2  G$
		\State $R_i\gets k_1 I+k_2 \mathcal{H}_p(P_i)$
		\State $c_i \gets k_1$
		\State $r_i \gets k_2$
	\EndIf
	\State $i \gets i+1$
\EndWhile
\State $h \gets \mathcal{H}_s(prefix+L_i's+R_i's))$
\State $c_{s} \gets h-\sum_{i\neq s} c_i$
\State $r_s \gets k - x c_s$
\State \Return $(I, \{c_{i}\}, \{r_i\})$
\end{algorithmic}
\end{algorithm}

Comparing this with \cite{CN} shows that it agrees with the whitepaper.
Similarly, here is the algorithm used in the CryptoNote source
to verify ring signatures:

\begin{algorithm}[H]
\caption{VER}

\begin{algorithmic}
\State $i=0$
\While {$i<numkeys$}
	\State $L_i^{\prime}\gets c_i P_i + r_i  G$
	\State $R_i^{\prime}\gets r_i \mathcal{H}_p(P_i)+c_i I$
	\State $i \gets i+1$
\EndWhile
\State $h \gets \mathcal{H}_s(prefix+L_i's+R_i's))$
\State $h \gets h-\sum_{i\neq s} c_i$
 \State \Return $(h == 0 (mod\ q)) == 0$
\end{algorithmic}
\end{algorithm}

\subsection{Important Crypto-ops Functions}

Descriptions of important functions in Crypto-ops.cpp. Even more references
and information is given in the comments in the MiniNero.py code linked
above.

\subsubsection{ge\_frombytes\_vartime}

Takes as input some data and converts to a point on ed25519. For a
reference of the equation used, $\beta=uv^{3}\left(uv^{7}\right)^{\left(q-5\right)/8}$,
see (\cite{BBJLP}, section 5).

\subsubsection{ge\_fromfe\_frombytesvartime}

Similar to the above, but compressed in another form.

\subsubsection{ge\_double\_scalarmult\_base\_vartime}

Takes as inputs two integers $a$ and $b$ and a point $A$ on ed25519
and returns the point $aA+bG$, where $G$ is the ed25519 base point.
Used for the ring signatures when computing, for example, $ $$L_{i}$
with $i\neq s$ as in (\cite{CN}, 4.4)

\subsubsection{ge\_double\_scalarmult\_vartime}

Takes as inputs two integers $a$ and $b$ and two points $A$ and $B$ on ed25519
and outputs $aA+bB$. Used, for example, when computing the $R_{i}$
in the ring signatures with $i\neq s$ (\cite{CN}, 4.4)

\subsubsection{ge\_scalarmult}

Given a point $A$ on ed25519 and an integer $a$, this computes
the point $aA$. Used for example when computing $L_{i}$ and $R_{i}$
when $i=s$.

\subsubsection{ge\_scalarmult\_base}

Takes as input an integer $a$ and computes $aG$, where $G$ is the
ed25519 base point.

\subsubsection{ge\_p1p1\_to\_p2}

There are different representations of curve points for ed25519, this
converts between them. See MiniNero for more reference.

\subsubsection{ge\_p2\_dbl}

This takes a point in the ``p2'' representation and doubles it.

\subsubsection{ge\_p3\_to\_p2}

Takes a point in the ``p3'' representation on ed25519 and turns
it into a point in the ``p2'' representation.

\subsubsection{ge\_mul8}

This takes a point $A$ on ed25519 and returns $8A$.

\subsubsection{sc\_reduce}

Takes a 64-byte integer and outputs the lowest 32 bytes modulo the
prime $q$. This is not a CryptoNote-specific function, but comes
from the standard ed25519 library.

\subsubsection{sc\_reduce32}

Takes a 32-byte integer and outputs the integer modulo $q$. Same
code as above, except skipping the 64$\to$32 byte step.

\subsubsection{sc\_mulsub}

Takes three integers $a,b,c$ in $\mathbb{F}_{q}$ and returns $c-ab$
modulo $q$.

\subsection{Important Hashing Functions}

\subsubsection{cn\_fast\_hash}

Takes data and returns the Keccak1600 hash of the data.

\subsection{Crypto.cpp Functions }

\subsubsection{random\_scalar}

Generates a 64-byte integer and then reduces it to a 32 byte integer
modulo $q$ for 128-bit security as described in section \ref{sub:Time-Cost-to}.

\subsubsection{hash\_to\_scalar}

Inputs data (for example, a point $P$ on ed25519) and outputs $\mathcal{H}_{s}\left(P\right)$,
which is the Keccak1600 hash of the data. The function then converts
the hashed data to a 32-byte integer modulo $q$.

\subsubsection{\label{sub:generate_keys}generate\_keys}

Returns a secret key and public key pair, using \texttt{random\_scalar} (as
described above) to get the secret key. Note that, as described in
\cite{Bern}, the key set for ed25519 actually is only multiples of
$8$ in $\mathbb{F}_{q}$, and hence \texttt{ge\_scalarmult\_base} includes
a \texttt{ge\_mul8} to ensure the secret key is in the key set. This prevents
transaction malleability attacks as described in (\cite{Bern},
{\it c.f.} section on ``small subgroup attacks''). This is part of the
\textbf{GEN} algorithm as described in (\cite{CN}, 4.4).

\subsubsection{check\_key}

Inputs a public key and outputs if the point is on the curve.

\subsubsection{secret\_key\_to\_public\_key}

Inputs a secret key, checks it for some uniformity conditions, and
outputs the corresponding public key, which is essentially just $8$
times the base point times the point.

\subsubsection{hash\_to\_ec}

Inputs a key, hashes it, and then does the equivalent in bitwise operations
of multiplying the resulting integer by the base point and then by $8$.

\subsubsection{generate\_key\_image}

Takes as input a secret key $x$ and public key $P$, and returns
$I=x\mathcal{H}_{p}\left(P\right)$, the key image. This is part of
the \textbf{GEN} algorithm as described in (\cite{CN}, 4.4).

\subsubsection{generate\_ring\_signature}

Computes a ring signature, performing \textbf{SIG} as in (\cite{CN},
4.4) given a key image $I$, a list of $n$ public keys $P_{i}$,
and a secret index. Essentially there is a loop on $i$, and if the
secret-index is reached, then an if-statement controls the special
computation of $L_{i},R_{i}$ when $i$ is equal to the secret index.
The values $c_{i}$ and $r_{i}$ for the signature are computed throughout
the loop and returned along with the image to create the total signature
$\left(I,c_{1},...,c_{n},r_{1},...,r_{n}\right).$

\subsubsection{check\_ring\_signature}

Runs the \textbf{VER} algorithm in (\cite{CN}, 4.4). The verifier
uses a given ring signature to compute $L_{i}^{\prime}=r_{i}G_{i}$,
$R_{i}^{\prime}=r_{i}\mathcal{H}_{p}\left(P_{i}\right)+c_{i}I$, and
finally to check if $\sum_{i=0}^{n}c_{i}=\mathcal{H}_{s}\left(m,L_{0}^{\prime},...,L_{n}^{\prime},R_{0}^{\prime},...,R_{n}^{\prime}\right)\ mod\ l$.

\subsubsection{generate\_key\_derivation}

Takes a secret key $b$, and a public key $P$, and outputs $8\cdot bP$.
(The $8$ being for the purpose of the secret key set, as described
in \ref{sub:generate_keys}). This is used in derive\_public\_key
as part of creating one-time addresses.

\subsubsection{derivation\_to\_scalar}

Performs $\mathcal{H}_{s}\left(-\right)$ as part of generating keys in
(\cite{CN}, 4.3, 4.4). It hashes an output index together with the
point.

\subsubsection{derive\_public\_key}

Takes a derivation $rA$ (computed via \texttt{generate\_key\_derivation}),
a point $B$, and an output index, computes a scalar via \texttt{derivation\_to\_scalar},
and then computes $\mathcal{H}_{s}\left(rA\right)+B$.

\subsubsection{generate\_signature}

This takes a prefix, a public key, and a secret key, and generates
a standard (not ring) transaction signature (similar to a Bitcoin
transaction signature).

\subsubsection{check\_signature}

This checks if a standard (not ring) signature is a valid signature.

\section{Conclusion}
Despite the ring signature functions in the original CryptoNote source being poorly commented, the code can be traced back to established and used sources, and is relatively straightfoward. The Python implementation provided with this review gives further indication of the code's correctness. Furthermore, the elliptic curve mathematics underlying the ring signature scheme has been extremely-well studied; the concept of ring signatures is not novel, even if their application to cryptocurrencies is.

\medskip{}

\begin{thebibliography}{BBJLP}
\bibitem[BBJLP]{BBJLP} Bernstein, Daniel J., et al. "Twisted
edwards curves." Progress in Cryptology\textendash{}AFRICACRYPT
2008. Springer Berlin Heidelberg, 2008. 389-405.

\bibitem[BCPM]{BCPM} Bos, Joppe W., et al. "Selecting
Elliptic Curves for Cryptography: An Efficiency and Security Analysis."
IACR Cryptology ePrint Archive 2014 (2014): 130.

\bibitem[Bern]{Bern} Bernstein, Daniel J. "Curve25519:
new Diffie-Hellman speed records." Public Key Cryptography-PKC
2006. Springer Berlin Heidelberg, 2006. 207-228.

\bibitem[CH]{CH} Chaum, David, and Eugene Van Heyst. "Group
signatures." Advances in Cryptology\textemdash{}EUROCRYPT\textquoteright{}91.
Springer Berlin Heidelberg, 1991.

\bibitem[CN]{CN} van Saberhagen, Nicolas. "CryptoNote
v 2.0." (2013).

\bibitem[FIPS]{FIPS} SHA, NIST DRAFT. "standard: Permutation-based
hash and extendable-output functions." DRAFT FIPS 202
(2014).

\bibitem[Fu]{Fu} Fujisaki, Eiichiro. "Sub-linear size
traceable ring signatures without random oracles." IEICE
TRANSACTIONS on Fundamentals of Electronics, Communications and Computer
Sciences 95.1 (2012): 151-166.

\bibitem[FS]{FS} Fujisaki, Eiichiro, and Koutarou Suzuki. "Traceable
ring signature." Public Key Cryptography\textendash{}PKC
2007. Springer Berlin Heidelberg, 2007. 181-200.

\bibitem[IAN]{IAN} IANIX http://ianix.com/pub/curve25519-deployment.html

\bibitem[Si]{Si} Silverman, Joseph H. The arithmetic of elliptic
curves. Vol. 106. Dordrecht: Springer, 2009.

\bibitem[SN]{SN} http://lab.byterub.cc/pubs/multiple\_equations\_attack.pdf\end{thebibliography}
\end{document}


\chapter{{\bf \matchesymbol} and {\bf \lambdaesymbol}}\label{matche}

In this appendix we describe \scheme|matche| and \scheme|lambdae|,
pattern-matching macros for writing concise miniKanren programs.
These macros were designed by Will Byrd and implemented by Ramana
Kumar with the help of Dan Friedman.

To illustrate the use of \scheme|matche| and \scheme|lambdae|
we will rewrite the explicit definition of \scheme|appendo|, which uses
the core miniKanren operators \scheme|==|, \scheme|conde|, and \scheme|exist|.

\schemedisplayspace
\begin{schemedisplay}
(define appendo
  (lambda (l s out)
    (conde
      ((== '() l) (== s out))
      ((exist (a d res)
         (== `(,a . ,d) l)
         (== `(,a . ,res) out)
         (appendo d s res))))))
\end{schemedisplay}

We can shorten the \scheme|appendo| definition using \scheme|matche|.
\scheme|matche| resembles \scheme|pmatch| (Appendix~\ref{pmatch})
syntactically, but uses unification rather than uni-directional
pattern matching.  \scheme|matche| expands into a \scheme|conde|;
each \scheme|matche| clause becomes a \scheme|conde|
clause\footnote{The \scheme|matcha| and \scheme|matchu| forms are
  identical to \scheme|matche|, except they expand into uses of
  \scheme|conda| and \scheme|condu|, respectively.}.  As with
\scheme|pmatch| the first expression in each clause is an implicitly
quasiquoted pattern.  Unquoted identifiers in a pattern are introduced
as unassociated logic variables whose scope is limited to the pattern
and goals in that clause.

Here is \scheme|appendo| defined with \scheme|matche|.

\schemedisplayspace
\begin{schemedisplay}
(define appendo
  (lambda (l s out)
    (match-e `(,l ,s ,out)
      (`(() ,s ,s))
      (`((,a . ,d) ,s (,a . ,res)) (appendo d s res)))))
\end{schemedisplay}

\noindent The pattern in the first clause attempts to unify the first
argument of \scheme|appendo| with the empty list, while also unifying
\scheme|appendo|'s second and third arguments.  The same unquoted
identifier can appear more than once in a \scheme|matche| pattern;
this is not allowed in \scheme|pmatch|.

We can make \scheme|appendo| even shorter by using \scheme|lambdae|.
\scheme|lambdae| just expands into a \scheme|lambda| wrapped around a
\scheme|matche|---the \scheme|matche| matches against the
\scheme|lambda|'s argument list\footnote{The \scheme|lambdaa| and \scheme|lambdau| forms are
  identical to \scheme|lambdae|, except they expand into uses of
  \scheme|matcha| and \scheme|matchu|, respectively.}.

\schemedisplayspace
\begin{schemedisplay}
(define appendo
  (lambda-e (l s out)
    (`(() ,s ,s))
    (`((,a . ,d) ,s (,a . ,res)) (appendo d s res))))
\end{schemedisplay}

The double-underscore symbol \scheme|__| represents a pattern wildcard
that matches any value without binding it to a variable.  For example,
the pattern in \scheme|pairo|

\schemedisplayspace
\begin{schemedisplay}
(define pairo
  (lambda-e (x)
    (`((__ . __)))))
\end{schemedisplay}

\noindent matches any pair, regardless of the values of its car and
cdr.

\scheme|lambdae| and \scheme|matche| also support nominal logic (see
Chapter~\ref{akchapter}).  Just as unquoted identifiers in a pattern
are introduced as unassociated logic variables, using unquote splicing
in a pattern introduces a fresh nom whose scope is limited to the
pattern and goals in that clause.  For example, the goal constructor

\schemedisplayspace
\begin{schemedisplay}
(define foo
  (lambda (t)
    (fresh (a b)
      (exist (x y)
        (conde
          ((== (tie a (tie b `(,x ,b))) t))
          ((== (tie a (tie b `(,y ,b))) t))
          ((== (tie a (tie b `(,b ,y))) t))
          ((== (tie a (tie b `(,b ,y))) t)))))))
\end{schemedisplay}

\noindent can be re-written as

\schemedisplayspace
\begin{schemedisplay}
(define foo
  (lambda-e (t)
    (`(tie-tag ,@a (tie-tag ,@b (,x ,@b))))
    (`(tie-tag ,@a (tie-tag ,@b (,y ,@b))))
    (`(tie-tag ,@a (tie-tag ,@b (,@b ,y))))
    (`(tie-tag ,@a (tie-tag ,@b (,@b ,y))))))
\end{schemedisplay}

\noindent where \scheme|'tie-tag| is the tag returned by the
\scheme|tie| constructor\footnote{Unfortunately, this explicit pattern
matching breaks the abstraction of the \scheme|tie| constructor.}.

Here is the definition of \scheme|lambdae|,
and its impure variants \scheme|lambdaa| and \scheme|lambdau|.

\schemedisplayspace
\begin{schemedisplay}
(define-syntax lambdae
  (syntax-rules ()
    ((_ (x ...) c c* ...)
     (lambda (x ...) (matche (quasiquote (unquote x) ...) (c c* ...) ())))))

(define-syntax lambdaa
  (syntax-rules ()
    ((_ (x ...) c c* ...)
     (lambda (x ...) (matcha (quasiquote (unquote x) ...) (c c* ...) ())))))

(define-syntax lambdau
  (syntax-rules ()
    ((_ (x ...) c c* ...)
     (lambda (x ...) (matchu (quasiquote (unquote x) ...) (c c* ...) ())))))
\end{schemedisplay}

Here is the definition of \scheme|matche|, and its impure variants \scheme|matcha| and \scheme|matchu|.

\schemedisplayspace
\begin{schemedisplay}
(define-syntax exist*
  (syntax-rules ()
    ((_ (x ...) g0 g ...)
     (lambdag@ (a)
       (inc
         (let* ((x (var 'x)) ...)
           (bind* (g0 a) g ...)))))))

(define-syntax fresh*
  (syntax-rules ()
    ((_ (x ...) g0 g ...)
     (lambdag@ (a)
       (inc
         (let* ((x (nom 'x)) ...)
           (bind* (g0 a) g ...)))))))

(define-syntax matche
  (syntax-rules ()
    ((_ (f x ...) g* . cs)
     (let ((v (f x ...))) (matche v g* . cs)))
    ((_ v g* . cs) (mpat conde v (g* . cs) ()))))

(define-syntax matcha
  (syntax-rules ()
    ((_ (f x ...) g* . cs)
     (let ((v (f x ...))) (matcha v g* . cs)))
    ((_ v g* . cs) (mpat conda v (g* . cs) ()))))
\end{schemedisplay}

\newpage

\begin{schemedisplay}
(define-syntax matchu
  (syntax-rules ()
    ((_ (f x ...) g* . cs)
     (let ((v (f x ...))) (matchu v g* . cs)))
    ((_ v g* . cs) (mpat condu v (g* . cs) ()))))

(define-syntax mpat
  (syntax-rules (__ quote unquote unquote-splicing expand cons)
    ((_ co v () (l ...)) (co l ...))
    ((_ co v (pat) xs as ((g ...) . cs) (l ...))
     (mpat co v cs (l ... ((fresh* as (exist* xs (== `pat v) g ...))))))
    ((_ co v ((__ g0 g ...) . cs) (l ...))
     (mpat co v cs (l ... ((exist () g0 g ...)))))
    ((_ co v (((unquote y) g0 g ...) . cs) (l ...))
     (mpat co v cs (l ... ((exist (y) (== y v) g0 g ...)))))
    ((_ co v (((unquote-splicing b) g0 g ...) . cs) (l ...))
     (mpat co v cs (l ... ((fresh (b) g0 g ...)))))
    ((_ co v ((pat g ...) . cs) ls)
     (mpat co v (pat expand) () () ((g ...) . cs) ls))
    ((_ co v (__ expand . k) (x ...) as cs ls)
     (mpat co v ((unquote y) . k) (y x ...) as cs ls))
    ((_ co v ((unquote y) expand . k) (x ...) as cs ls)
     (mpat co v ((unquote y) . k) (y x ...) as cs ls))
    ((_ co v ((unquote-splicing b) expand . k) xs (a ...) cs ls)
     (mpat co v ((unquote b) . k) xs (b a ...) cs ls))
    ((_ co v ((quote c) expand . k) xs as cs ls)
     (mpat co v (c . k) xs as cs ls))
    ((_ co v ((a . d) expand . k) xs as cs ls)
     (mpat co v (d expand a expand cons . k) xs as cs ls))
    ((_ co v (d a expand cons . k) xs as cs ls)
     (mpat co v (a expand d cons . k) xs as cs ls))
    ((_ co v (a d cons . k) xs as cs ls)
     (mpat co v ((a . d) . k) xs as cs ls))
    ((_ co v (c expand . k) xs as cs ls)
     (mpat co v (c . k) xs as cs ls))))
\end{schemedisplay}


\documentclass[a4paper]{article}
\begin{document}

\title{The rsync algorithm}

\author{Andrew Tridgell \quad\quad Paul Mackerras\\
Department of Computer Science \\
Australian National University \\
Canberra, ACT 0200, Australia}

\maketitle

\begin{abstract}
  This report presents an algorithm for updating a file on one machine
  to be identical to a file on another machine.  We assume that the
  two machines are connected by a low-bandwidth high-latency
  bi-directional communications link.  The algorithm identifies parts
  of the source file which are identical to some part of the
  destination file, and only sends those parts which cannot be matched
  in this way.  Effectively, the algorithm computes a set of
  differences without having both files on the same machine.  The
  algorithm works best when the files are similar, but will also
  function correctly and reasonably efficiently when the files are
  quite different.
\end{abstract}

\section{The problem}

Imagine you have two files, $A$ and $B$, and you wish to update $B$ to be
the same as $A$. The obvious method is to copy $A$ onto $B$.

Now imagine that the two files are on machines connected by a slow
communications link, for example a dialup IP link.  If $A$ is large,
copying $A$ onto $B$ will be slow.  To make it faster you could
compress $A$ before sending it, but that will usually only gain a
factor of 2 to 4.

Now assume that $A$ and $B$ are quite similar, perhaps both derived
from the same original file. To really speed things up you would need
to take advantage of this similarity. A common method is to send just
the differences between $A$ and $B$ down the link and then use this
list of differences to reconstruct the file.

The problem is that the normal methods for creating a set of
differences between two files rely on being able to read both files.
Thus they require that both files are available beforehand at one end
of the link.  If they are not both available on the same machine,
these algorithms cannot be used (once you had copied the file over,
you wouldn't need the differences).  This is the problem that rsync
addresses.

The rsync algorithm efficiently computes which parts of a source file
match some part of an existing destination file.  These parts need not
be sent across the link; all that is needed is a reference to the part
of the destination file.  Only parts of the source file which are not
matched in this way need to be sent verbatim.  The receiver can then
construct a copy of the source file using the references to parts of
the existing destination file and the verbatim material.

Trivially, the data sent to the receiver can be compressed using any
of a range of common compression algorithms, for further speed
improvements.

\section{The rsync algorithm}

Suppose we have two general purpose computers $\alpha$ and $\beta$.
Computer $\alpha$ has access to a file $A$ and $\beta$ has access to
file $B$, where $A$ and $B$ are ``similar''.  There is a slow
communications link between $\alpha$ and $\beta$.

The rsync algorithm consists of the following steps:

\begin{enumerate}
\item $\beta$ splits the file $B$ into a series of non-overlapping
  fixed-sized blocks of size S bytes\footnote{We have found that
  values of S between 500 and 1000 are quite good for most purposes}.
  The last block may be shorter than $S$ bytes.

\item For each of these blocks $\beta$ calculates two checksums:
  a weak ``rolling'' 32-bit checksum (described below) and a strong
  128-bit MD4 checksum.

\item $\beta$ sends these checksums to $\alpha$.

\item $\alpha$ searches through $A$ to find all blocks of length $S$
  bytes (at any offset, not just multiples of $S$) that have the same
  weak and strong checksum as one of the blocks of $B$. This can be
  done in a single pass very quickly using a special property of the
  rolling checksum described below.

\item $\alpha$ sends $\beta$ a sequence of instructions for
  constructing a copy of $A$.  Each instruction is either a reference
  to a block of $B$, or literal data.  Literal data is sent only for
  those sections of $A$ which did not match any of the blocks of $B$.
\end{enumerate}

The end result is that $\beta$ gets a copy of $A$, but only the pieces
of $A$ that are not found in $B$ (plus a small amount of data for
checksums and block indexes) are sent over the link. The algorithm
also only requires one round trip, which minimises the impact of the
link latency.

The most important details of the algorithm are the rolling checksum
and the associated multi-alternate search mechanism which allows the
all-offsets checksum search to proceed very quickly. These will be
discussed in greater detail below.

\section{Rolling checksum}

The weak rolling checksum used in the rsync algorithm needs to have
the property that it is very cheap to calculate the checksum of a
buffer $X_2 .. X_{n+1}$ given the checksum of buffer $X_1 .. X_n$ and
the values of the bytes $X_1$ and $X_{n+1}$.

The weak checksum algorithm we used in our implementation was inspired
by Mark Adler's adler-32 checksum.  Our checksum is defined by
$$ a(k,l) = (\sum_{i=k}^l X_i) \bmod M $$
$$ b(k,l) = (\sum_{i=k}^l (l-i+1)X_i) \bmod M $$
$$ s(k,l) = a(k,l) + 2^{16} b(k,l) $$

where $s(k,l)$ is the rolling checksum of the bytes $X_k \ldots X_l$.
For simplicity and speed, we use $M = 2^{16}$.

The important property of this checksum is that successive values can
be computed very efficiently using the recurrence relations

$$ a(k+1,l+1) = (a(k,l) - X_k + X_{l+1}) \bmod M $$
$$ b(k+1,l+1) = (b(k,l) - (l-k+1) X_k + a(k+1,l+1)) \bmod M $$

Thus the checksum can be calculated for blocks of length S at all
possible offsets within a file in a ``rolling'' fashion, with very
little computation at each point.

Despite its simplicity, this checksum was found to be quite adequate as
a first-level check for a match of two file blocks.  We have found in
practice that the probability of this checksum matching when the
blocks are not equal is quite low.  This is important because the much
more expensive strong checksum must be calculated for each block where
the weak checksum matches.

\section{Checksum searching}

Once $\alpha$ has received the list of checksums of the blocks of $B$,
it must search $A$ for any blocks at any offset that match the
checksum of some block of $B$.  The basic strategy is to compute the
32-bit rolling checksum for a block of length $S$ starting at each
byte of $A$ in turn, and for each checksum, search the list for a
match.  To do this our implementation uses a
simple 3 level searching scheme.

The first level uses a 16-bit hash of the 32-bit rolling checksum and
a $2^{16}$ entry hash table.  The list of checksum values (i.e., the
checksums from the blocks of $B$) is sorted according to the 16-bit
hash of the 32-bit rolling checksum.  Each entry in the hash table
points to the first element of the list for that hash value, or
contains a null value if no element of the list has that hash value.

At each offset in the file the 32-bit rolling checksum and its 16-bit
hash are calculated.  If the hash table entry for that hash value is
not a null value, the second-level check is invoked.

The second-level check involves scanning the sorted checksum list
starting with the entry pointed to by the hash table entry, looking
for an entry whose 32-bit rolling checksum matches the current value.
The scan terminates when it reaches an entry whose 16-bit hash
differs.  If this search finds a match, the third-level check is
invoked.

The third-level check involves calculating the strong checksum for the
current offset in the file and comparing it with the strong checksum
value in the current list entry.  If the two strong checksums match,
we assume that we have found a block of $A$ which matches a block of
$B$.  In fact the blocks could be different, but the probability of
this is microscopic, and in practice this is a reasonable assumption.

When a match is found, $\alpha$ sends $\beta$ the data in $A$ between
the current file offset and the end of the previous match, followed by
the index of the block in $B$ that matched.  This data is sent
immediately a match is found, which allows us to overlap the
communication with further computation.

If no match is found at a given offset in the file, the rolling
checksum is updated to the next offset and the search proceeds.  If a
match is found, the search is restarted at the end of the matched
block.  This strategy saves a considerable amount of computation for
the common case where the two files are nearly identical.  In
addition, it would be a simple matter to encode the block indexes as
runs, for the common case where a portion of $A$ matches a series of
blocks of $B$ in order.

\section{Pipelining}

The above sections describe the process for constructing a copy of one
file on a remote system.  If we have a several files to copy, we can
gain a considerable latency advantage by pipelining the process.

This involves $\beta$ initiating two independent processes. One of the
processes generates and sends the checksums to $\alpha$ while the
other receives the difference information from $\alpha$ and
reconstructs the files.

If the communications link is buffered then these two processes can
proceed independently and the link should be kept fully utilised in
both directions for most of the time.

\section{Results}

To test the algorithm, tar files were created of the Linux kernel
sources for two versions of the kernel. The two kernel versions were
1.99.10 and 2.0.0. These tar files are approximately 24MB in size and
are separated by 5 released patch levels.

Out of the 2441 files in the 1.99.10 release, 291 files had changed in
the 2.0.0 release, 19 files had been removed and 25 files had been
added.

A ``diff'' of the two tar files using the standard GNU diff utility
produced over 32 thousand lines of output totalling 2.1 MB.

The following table shows the results for rsync between the two files
with a varying block size.\footnote{All the tests in this section were
  carried out using rsync version 0.5}

\vspace*{5mm}
\begin{tabular}{|l|l|l|l|l|l|l|} \hline
{\bf block} & {\bf matches} & {\bf tag}  & {\bf false}  & {\bf data} & {\bf written}  & {\bf read} \\
{\bf size}  &               & {\bf hits} & {\bf alarms} &            &                &            \\ \hline \hline

300         & 64247         & 3817434    & 948          & 5312200    & 5629158        & 1632284   \\ \hline
500         & 46989         & 620013     & 64           & 1091900    & 1283906        & 979384    \\ \hline
700         & 33255         & 571970     & 22           & 1307800    & 1444346        & 699564    \\ \hline
900         & 25686         & 525058     & 24           & 1469500    & 1575438        & 544124    \\ \hline
1100        & 20848         & 496844     & 21           & 1654500    & 1740838        & 445204    \\ \hline
\end{tabular}
\vspace*{5mm}

In each case, the CPU time taken was less than the
time it takes to run ``diff'' on the two files.\footnote{The wall
  clock time was approximately 2 minutes per run on a 50 MHz SPARC 10
  running SunOS, using rsh over loopback for communication.  GNU diff
  took about 4 minutes.}

The columns in the table are as follows:

\begin{description}
\item [block size] The size in bytes of the checksummed blocks.
\item [matches] The number of times a block of $B$ was found in $A$.
\item [tag hits] The number of times the 16-bit hash of the rolling
  checksum matched a hash of one of the checksums from $B$.
\item [false alarms] The number of times the 32-bit rolling checksum
  matched but the strong checksum didn't.
\item [data] The amount of file data transferred verbatim, in bytes.
\item [written] The total number of bytes written by $\alpha$,
  including protocol overheads. This is almost all file data.
\item [read] The total number of bytes read by $\alpha$, including
  protocol overheads. This is almost all checksum information.
\end{description}

The results demonstrate that for block sizes above 300 bytes, only a
small fraction (around 5\%) of the file was transferred. The amount
transferred was also considerably less than the size of the diff file
that would have been transferred if the diff/patch method of updating
a remote file was used.

The checksums themselves took up a considerable amount of space,
although much less than the size of the data transferred in each
case. Each pair of checksums consumes 20 bytes: 4 bytes for the
rolling checksum plus 16 bytes for the 128-bit MD4 checksum.

The number of false alarms was less than $1/1000$ of the number of
true matches, indicating that the 32-bit rolling checksum is quite
good at screening out false matches.

The number of tag hits indicates that the second level of the
checksum search algorithm was invoked about once every 50
characters.  This is quite high because the total number of blocks in
the file is a large fraction of the size of the tag hash table. For
smaller files we would expect the tag hit rate to be much closer to
the number of matches.  For extremely large files, we should probably
increase the size of the hash table.

The next table shows similar results for a much smaller set of files.
In this case the files were not packed into a tar file first. Rather,
rsync was invoked with an option to recursively descend the directory
tree. The files used were from two source releases of another software
package called Samba. The total source code size is 1.7 MB and the
diff between the two releases is 4155 lines long totalling 120 kB.

\vspace*{5mm}
\begin{tabular}{|l|l|l|l|l|l|l|} \hline
{\bf block} & {\bf matches} & {\bf tag}  & {\bf false}  & {\bf data} & {\bf written}  & {\bf read} \\
{\bf size}  &               & {\bf hits} & {\bf alarms} &            &                &            \\ \hline \hline

300         & 3727          & 3899       & 0            & 129775     & 153999         & 83948       \\ \hline
500         & 2158          & 2325       & 0            & 171574     & 189330         & 50908       \\ \hline
700         & 1517          & 1649       & 0            & 195024     & 210144         & 36828        \\ \hline
900         & 1156          & 1281       & 0            & 222847     & 236471         & 29048        \\ \hline
1100        & 921           & 1049       & 0            & 250073     & 262725         & 23988        \\ \hline
\end{tabular}
\vspace*{5mm}

\section{Availability}

An implementation of rsync which provides a convenient interface
similar to the common UNIX command rcp has been written and is
available for download from http://rsync.samba.org/

\end{document}


\documentclass[runningheads]{llncs}
\usepackage[utf8]{inputenc}
\usepackage{mathtools}
\usepackage{algorithm}
\usepackage{algorithmic}

\usepackage{graphicx}
\usepackage{caption}
\usepackage{subcaption}
\usepackage{siunitx}
\usepackage[linguistics]{forest} % Trees

%\usepackage{algpseudocode}
%\usepackage{algorithmicx}
\usepackage{amssymb}

\usepackage{hyperref} % For clickable \href{} URLs

% Colored table cells
%\usepackage[table,xcdraw]{xcolor}

\title{A Critical Analysis of the\\Boolean Satisfiability Problem}
\author{Simeon Wuthier}
%
\authorrunning{S. Wuthier}

\institute{
    \textit{Department of Computer Science}\\
    \textit{University of Colorado, Colorado Springs}\\
    \email{swuthier@uccs.edu}\\
}

\date{15 December, 2020}

\begin{document}
\maketitle
\footnotetext[0]{The format of this paper is in ACM; Lecture Notes in Computer Science (LLNCS)}

\section{Introduction}

The Boolean satisfiability problem (SAT) is a propositional logic problem with applications spanning across physics, mathematics, computer science, cryptography, artificial intelligence, and many others. As a widely used modeling framework for solving combinatorial problems, SAT is the first NP-complete decision problem, introduced in 1971 from the Cook-Levin theorem \cite{cook1971complexity}. The theorem states that the SAT problem is NP-complete, and that any other NP problem can be reduced to SAT in polynomial time by using a deterministic Turing machine. Because SAT is NP-complete, unless \emph{$P = NP$}, all algorithms that solve SAT instances require a worst-case time complexity that is exponential. Despite this potential restriction on the algorithm's performance, modern SAT algorithms have become very effective at tackling instances that require a large search space, allowing significant improvements that would otherwise make some problems unrealistic for the traditional brute-force approach. Since the structure of the problem has been taken advantage of, with a handful of mechanisms that achieve a much faster execution time \cite{silva2003grasp}\cite{moskewicz2001chaff}\cite{een2003extensible}\cite{goldberg2007berkmin}, the SAT problem has never achieved an execution time that is polynomial in the worst-case. If such an algorithm was to exist, theoretically or not, then the Cook-Levin theorem would allow every NP problem to reduce to it, making other challenging problems such as the knapsack problem, hamiltonian path problem, traveling salesman problem, as well as protein folding and countless other problems optimally solvable in polynomial time. Likewise, if such a problem were to be proven impossible to achieve polynomial time, then \emph{$P \neq NP$}, making it clear that some problems simply cannot ever be solves quickly.  %Being one of the most studies problems in theoretical computer science

\subsection{Contributions}
This study tackles the SAT problem head-on, in order to build a powerful working implementation, and discuss the current optimizations at play, as well as the optimizations made by the worlds fastest algorithm, and the corresponding algorithm analysis for each. The original implementation made from this project\footnote{Working implementation can be found at \url{https://simewu.github.io/SAT-solver}} was build in JavaScript and is cross-platform.

\section{Preliminaries}
The SAT problem can be described as follows.

\begin{definition}
Let $x_1,...,x_m$ be Boolean variables that are part of a formula, $F$, where $x_i\in\{true, false\} \forall x\in F$. A \textbf{literal} can be either $x$ or $\neg x$ (logical not). A \textbf{clause} is some number of literals joined by $\lor$ (logical or) and surrounded by parenthesis. The Boolean \textbf{formula}, $F$ joins some number of clauses with $\land$ (logical and). Then given F with Boolean variables X=\{$x_1,...,x_m$\}, decide whether or not there exists a function $f\to\{true, false\}$ such that when one replaces $x_i$ by $f(x_i)$ in S, the evaluated Boolean sentence will be logically true, where $f(S)=true$. We say that $S$ is \textbf{satisfiable}. $F$ is in \textbf{conjunctive normal form}\footnote{A conjunction is another word for \emph{and}, while a disjunction is means a \emph{or}.}, which states that all clauses must only be joined by a logical and, and all literals must only be joined by a logical or.
\label{def:SAT}
\end{definition}

While the conjunctive normal form may appear to apply to a very restricted subset of Boolean propositions, Whitesitt proves that every Boolean proposition can be reduced to conjunctive normal form \cite{whitesitt2012boolean}.

\subsection{Universal Formatting}
\label{sec:dimacs}
The DIMACS format is a universal conjunctive normal form syntax guideline that allows all SAT applications to be understandable to all SAT solvers \cite{challenge1993satisfiability}. The file format ends with the \emph{.cnf} file extension and they all contain a header. Comments begin with the letter \emph{c}, and data is delimited by one or more spaces. The first non-comment must be \emph{p cnf} followed by the number of \emph{variables} used in the SAT instance, then the number of clauses (or rows of data) in the file.

\section{Performance Strategies}
While the traditional brute force method of iterating through the permutation of all variable possibilities is sufficient for smaller programs, the time complexity is in $\Omega(2^n)$ making it unreasonable for larger SAT instances.

\begin{figure*}[h]
\begin{forest}
  [
    [\textit{$x_1=0$}
        [\textit{$x_2=0$}
            [\textit{$x_3=0$}
            ]
            [\textit{$x_3=1$}
            ]
        ]
        [\textit{$x_2=1$}
            [\textit{$x_3=0$}
            ]
            [\textit{$x_3=1$}
            ]
        ]
    ]
    [\textit{$x_1=1$}
        [\textit{$x_2=0$}
            [\textit{$x_3=0$}
            ]
            [\textit{$x_3=1$}
            ]
        ]
        [\textit{$x_2=1$}
            [\textit{$x_3=0$}
            ]
            [\textit{$x_3=1$}
            ]
        ]
    ]
  ]
\end{forest}
\caption{The brute-force decision tree to solve a SAT problem with three variables. A brute force solver must traverse each node, where the leaf nodes will have an assignment for every variable and can be plugged in to check for satisfiability. After visiting every leaf node, a brute-force solver will be able to conclude unsatisfiability by means of proof by exhaustion.}
\end{figure*}

The implementation presented in this paper uses a few core optimizations, which are as follows: unit propagation, two-watched literals, no-good learning, and conflict-directed back-jumping, which are discussed in further detail in Section~\ref{sec:experimentation}.

\subsection{World Record}
As of 2020, the current world record belongs to Hansen \emph{et al.} \cite{hansen2019faster} at a time complexity of $O(1.307^n)$, which uses a method known as biased PPSZ. Fourteen years earlier, Paturi \emph{et al.} introduced the PPSZ algorithm \cite{paturi2005improved} which has a time complexity of $O(1.308^n)$. Both algorithms assume a unique $3-SAT$ instance, which requires exactly three variables within each clause, and has a single unique solution, making it non-ambiguous. The optimization included adding a heuristic to the literal selection, as opposed to the traditional PPSZ. The pseudocode for biased PPSZ can be found in Algorithm~\ref{alg:biased-ppsz}. This time complexity was derived from the time complexity $2^{S_kn-\delta|\mathcal{D}|}$, where $S_k$ is the upper probability that a variable is guessed by the PPSZ algorithm, not requiring additional bias. $n$ is the size of the input, and $\delta$ refers to the gain over the PPSZ algorithm for the average of $x,y,z$, which is the three variables within each clause of a $3-SAT$ instance. $\mathcal{D}$ is the maximal set of disjoint clauses assuming that the clauses of $\mathcal{D}$ are unnegated, where $|\mathcal{D}|$ is the number of clauses \cite{hansen2019faster}. After assigning the worst-case variable values to the time complexity, the formula gave a time complexity of $O(1.306995^n)$. They mention that many improvements and optimizations can be made on their work, to decrease this value further.

\begin{algorithm}[h]
\caption{The biased-PPSZ algorithm, with a time complexity of $O(1.307^n).$}
\label{alg:biased-ppsz}
\begin{algorithmic}[1]
    \STATE // $\beta$ is an assignment variable
    \STATE // $\pi$ is a permutation of the variables, ordered strategically
    \STATE // $F$ is the input k-CNF formula, and $P$ is the heuristic
    \STATE \textbf{function} \textsc{BiasedPPSZ}($\beta, \pi, F, P$)
    \STATE $V \xleftarrow{}$ var($F$), the variables of $F$
    \STATE $\alpha \xleftarrow{}$ the empty assignment on $V$
    \FOR{$x\in V$ in the order of $\pi$}
        \IF{$P(F,z)\in\{0,1\}$}
            \STATE $\alpha(x)\xleftarrow{}P(F,x)$
        \ELSE
            \STATE $\alpha(x)\xleftarrow{}\beta(x)$
        \ENDIF
        \STATE $F\xleftarrow{}F|_{x=\alpha(x)}$
    \ENDFOR
    \IF{$F$ has been satisfied}
        \RETURN $\alpha$
    \ELSE
        \RETURN \texttt{failure}
    \ENDIF
 \end{algorithmic}
\end{algorithm}

\section{Experimentation}
\label{sec:experimentation}
%unit propagation, two-watch literals, no-good learning, and conflict-directed back-jumping, which are discussed in further detail in Section~\ref{sec:experimentation}.

As stated in the previous section, the implementation of this paper uses unit propagation, two-watched literals, no-good learning, and conflict-directed back-jumping. This section will describe each of these mechanisms, then discuss the environment, design choices, and how validation was achieved.

\subsection{Unit Propagation}
A \emph{unit clause} is defined as a clause with a single literal in it that has not been set (i.e. the only literal with an unknown value). Because all clauses are joined by a logical and, every clause must evaluate to $true$, when only a single unset literal is present if it takes the form of $\neg x_i$, $x_i=false$, otherwise $x_i=true$. \emph{Unit propagation} is the practice of discovering a unit clause and setting the value, which may trigger other clauses to become unit clauses. Following this chain of events allows the additional assignment of variables with a certainty of their value.

\subsection{Two-watched Literals}
Two-watched literals is a technique that speeds up unit propagation detection. Because unit propagation is only triggered when a clause has one remaining variable to be set, instead of iterating through each variable within a clause to check for unit propagation, two-watched literals allow a great reduction in the number of computations required to determine if unit propagation is possible. The technique consists of only monitoring two unset literals within each clause. When one of these variables becomes set, there is the possibility for a unit propagation. To be certain, the algorithm will look for another unset literal. If no unset literal is found, then the other watched variable will receive a value by way of unit propagation, otherwise, the algorithm will begin watching the newly found unset variable. This allows performance optimization when the size of each clause is greater than two.

\subsection{No-good Learning}
\emph{Nogood} learning is a technique used alongside backtracking, where failures are analyzed through the decision tree, and \emph{nogoods} are derived from the variable assignments, to avoid reaching the same failure in future runs \cite{nogoodlearningdefinition}. Lecoutre \emph{et al.} apply this into the constraint satisfaction problem in order to demonstrate the effectiveness of such a mechanism. The study found that no-goods work more efficiently when a restart policy is used, by almost one order of magnitude \cite{lecoutre2007nogood}.

\subsection{Conflict-directed Back-jumping}
The implementation of this paper uses a restart policy known as conflict-directed back-jumping, which is triggered after \emph{nogood} learning when a conflict is found. Proposed in 1994, conflict-directed back-jumping is based on checking whether each constraint caused an inconsistency, and if so the mechanism will jump further, and avoid the extra computational overhead \cite{prosser1994binary}.

\begin{figure*}[h]
\centering
\includegraphics[width=0.8\textwidth]{Figures/screenshot.png}
\caption{The SAT solving implementation presented in this project, working on solving a Sudoku. It is hosted at \url{https://simewu.github.io/SAT-solver} and the original source code at \url{https://github.com/simewu/SAT-solver}. The left box is the editor, the right box shows the instance mathematical format, which updates in real-time, and the lower box provides the results consisting of either the solution to the SAT instance (satisfiable or unsatisfiable) along with the variable's that prove the solution or the results from the benchmark. Both functionalities can be triggered by clicking the blue button, or the yellow button, respectively.}
\label{fig:screenshot}
\end{figure*}

\subsection{Environment and Design Choices}
The application underwent numerous design choices that favor usability over performance. The choice to use JavaScript in a web application was the biggest of the design choices, as it allowed creating an interactive application at the cost of CPU resources. Likewise, the application cannot be comparable to traditional SAT solvers, since JavaScript is slower than C, and interpreted rather than compiled. Design choices also include an interactive user interface, as opposed to a terminal-style application. Figure~\ref{fig:screenshot} shows the interface along with a description of the controls. For added usability, the interface was split into two halves, each running the Ace library\footnote{The Ace code editor is available at \url{https://ace.c9.io}} which allows high-performance code editing. Both editors display the same information, however, the left editor is in DIMACS format, while the right displays the SAT instance in mathematical terms.

Regarding design choices of the algorithm itself, the \texttt{solveSAT} function takes in an array of clauses, where each clause is an array of literals, and each literal is an integer either negative or positive depicting whether or not it is negated or not, respectively. A \texttt{State} class is used to capture the current state of the solver, by holding information about its recursive depth, the assignment of the variables and clauses, including the newly learned clauses. Cloning the state at any given point will save the entire SAT solving instance, allowing for greater modularity and future functionality, such as pausing the solver and resuming at a different time, or spreading out the CPU utilization across time in order to not overwhelm the system. The \texttt{Variable} class, similar to the \texttt{State} class, is responsible for holding the state of every variable, such as whether or not it is set, the sign, and two-watched array, which the solver looks at to check for unit propagation.

Because the algorithm initially chooses the variable assignments randomly, the SAT solver finds solutions randomly, and any ambiguities can be discovered by repeatedly solving the instance, otherwise, it can be concluded with the increasing probability that the SAT instance is unique. Section~\ref{sec:validating-correctness} elaborates on this by providing a unique instance along with one that is ambiguous.

The entire application is maintained within a single \emph{index.html} document, consisting of everything except the Ace editor library, which is held in the \emph{libs} folder. The source code \footnote{The solver is available at \url{https://github.com/simewu/SAT-solver}} is stored within Github, to allow for version control and additional features, such as hosting, and collaboration in the future.

\subsection{Validating Correctness}
\label{sec:validating-correctness}
Because SAT is such a famous problem in theoretical computer science, there exist many DIMACS files (explained in Section~\ref{sec:dimacs}) that are SAT instances aimed at solving specific problems, or benchmarking how effective the solver is. The following example provides a unique solution ($x_1=true, x_2=false, x_3=true$), that a SAT solver can use to verify correctness.
$$(\neg x_1 \lor x_3)\land (x_1 \lor x_2)\land \neg x_2$$
Ambiguities can be introduced by adding literals or clauses that provide multiple correct variable assignments. The following instance contains exactly two solutions, $\{x_1=true, x_2=false\}$ and $\{x_1=false, x_2=true\}$:
$$(x_1 \lor x_2)\land (\neg x_1 \lor \neg x_2)$$

More complex instances can be tested, such as the one provided by Kwon \emph{et al.} that solves Sudokes \cite{kwon2006optimized}, which was incorporated into the application under $\textsc{Presets}\xrightarrow{}\textsc{Functioning Sudoku}$. The results have been compared with a famous solver known as \emph{MiniSAT} \cite{sorensson2010minisat}, showing that the solver is capable of more complex instances without conflict.

\section{Empirical Analysis}
A benchmarking button was included in the application. This feature generates an instance with $C$ clauses consisting of $L$ random literals ($x_i$ or $\neg x_i$). The performance of concluding that it is either SAT or UNSAT is logged. $C$ and $L$ are varied. The first experiment made $C$ the control ($C=512$) and $L$ the independent variable ($C\in {1, 2, 4, 8, 16, 32, 64, 128, 512, 1024, 2048, 4096, 8192}$) in Figure~\ref{fig:literal_perf}, and $L$ the control with $C$ being the independent variable in Figure~\ref{fig:clause_perf}, and the time duration in milliseconds (ms) was the dependent variable. This experiment found a solver bias in favor of $C$ as opposed to $L$, showing that the number of clauses is more efficient to scale.

\begin{figure*}[h]
\begin{subfigure}{0.5\columnwidth}
    \centering
    \includegraphics[width=1\textwidth]{Figures/literal_perf.pdf}%\hfill
    \caption{Time duration of number of literals. The control was the number of clauses, at 512 clauses.}
    \label{fig:literal_perf}
\end{subfigure}
\hfill
\begin{subfigure}{0.5\columnwidth}
    \centering
    \includegraphics[width=1\textwidth]{Figures/clause_perf.pdf}%\hfill
    \caption{Time duration of number of clauses. The control was the number of literals, at 512 clauses.}
    \label{fig:clause_perf}
\end{subfigure}
\end{figure*}

The next experiment did not consist of any control variables, but instead  made both $C$ and $L$ independent variables in a nested \emph{for} loop, where $C, L \in {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192}$. As shown in Figure~\ref{fig:clause_literal}, the trade-off between $L$ and $C$ scale almost proportionally.

\begin{figure*}[h]
    \centering
    \includegraphics[width=0.7\textwidth]{Figures/clause_literal.pdf}
    \caption{Three-dimensional contour of number of clauses to number of literals, where the color represents the total execution time of the SAT instance. Ten samples were taken per data point, and the average was plotted.}
    \label{fig:clause_literal}
\end{figure*}

\begin{figure*}[h]
    \centering
    \includegraphics[width=0.7\textwidth]{Figures/num_operations.pdf}
    \caption{Three-dimensional contour of number of clauses to number of literals, where the color represents the total number of read/write operations for each instance. Ten samples were taken per data point, and the average was plotted.}
    \label{fig:num_operations}
\end{figure*}

\begin{table}[]
\centering
\tiny
\begin{tabular}{l|l}
Input Size & Operations \\ \hline
1          & 3          \\
2          & 19.4       \\
4          & 98.8       \\
8          & 478.4      \\
16         & 1835.2     \\
32         & 7702.4     \\
64         & 31910.4    \\
128        & 125376     \\
256        & 494873.6   \\
512        & 1935974    \\
1024       & 7941018    \\
2048       & 31660646   \\
4096       & $1.26\times 10^8$   \\
8192       & $5.02\times 10^8$
\end{tabular}
\caption{Assuming $C=L$ (i.e. the number of clauses is equal to the number of literals), the number of operations increases at an exponential rate.}
\label{tab:operations-table}
\end{table}

\subsection{Read/Write Operations}
The next experiment was done by counting the number of variable reads, and the number of variable writes required to solve the SAT instance. Figure~\ref{fig:num_operations} visualizes the results and shows how increasing the number of clauses significantly increases the number of operations when compared to increasing the number of literals. To have a more complete analysis, assuming $C=L$, the number of operations increases exponentially, as seen in Table~\ref{tab:operations-table}, where an input size of 8192 has $5.02\times 10^8$.

\clearpage

\subsection{Additional Information}

Of all the randomly generated SAT instances, where the number of clauses and number of literals varied between 1 and 8192, this study found that \textbf{86.53\%} of the instances were satisfiable, leaving only 13.47\% as unsatisfiable. The instance generator was unbiased, where $P(x_i=true) = 0.5$, and 19,600 total instances were generated, showing that this is a somewhat universal behavior.

\noindent\rule{12.5cm}{0.4pt}
\\

The application can be accessed at \url{https://simewu.github.io/SAT-solver}.
\footnotesize
\bibliographystyle{splncs04}
\bibliography{references.bib}
\end{document}


\documentclass{article}

% the purpose of this particular document is to serve as a staging area potential blog posts, for the purpose of editing, revision, and review.

% packages
	\usepackage{amsmath, amsthm, mathtools}
	\usepackage{mdframed}
	\usepackage{geometry, enumerate}
	\usepackage{parskip}
	\usepackage{graphicx}
	\usepackage{dsfont} % for math bf text

% theorems and such
  	\newtheorem{theorem}{Theorem}
  	\newtheorem{corollary}{Corollary}
  	\newtheorem{lemma}[theorem]{Lemma}
  	\newtheorem*{remark}{Remark}
  	\newtheorem*{exe}{Exercise}
  	\newtheorem{prop}{Proposition}
  	\newtheorem{example}{Example}
  	\newtheorem{definition}{Definition}

% custom commands
	\newcommand{\ceil}[1]{\left \lceil #1 \right \rceil}
	\newcommand{\floor}[1]{\lfloor #1 \rfloor}
	\newcommand{\X}[1]{\, \text{mod} \, #1}
	\newcommand{\divv}{\,|\,}
	\newcommand{\ndiv}{\,\not|\,}
	\newcommand{\GCD}[2]{GCD\,(#1, #2)}
	\newcommand{\LCM}[2]{LCM\,(#1, #2)}

\begin{document}

\title{Elementary Number Theory : \S5}
\author{Henry Slayer $|$ University of California, Santa Cruz}
\date{}
\maketitle
\section*{Congruence}
Congruence is a way of thinking about the integers in a more relational, streamlined, and cyclic way. By fixing a \textit{modulus}, we partition the integers into unique \textit{residues}. The modulus is the reference point, which we pivot off of in terms of divisibility. Simply put, when we say that $a$ is congruent to $b$ modulo $m$, we're saying that $a - b$ is a multiple of $m$. Working with congruence lets us cut the integers down to size, and study their properties in a more relative way. \\\\
For example, the integers modulo 5 can be described with 5 representatives, the \textit{residue classes} modulo 5. Modulo 5, every integer is congruent to either 0, 1, 2, 3, or 4. Loosely speaking, we can consider the representatives as all possible remainders upon division by the modulus. Hence, in the general case, when we consider the integers modulo $m$, often denoted $\mathds{Z}/m$, we use the representative classes: 0, 1, 2, $\dots$ $n-1$. \\\\
I remember that the first time I was introduced to congruence, it all felt very confusing. Was an integer still an integer modulo $m$? What was all of this business about \textit{classes} and \textit{unique systems of representatives}? In truth, they're all the same thing, and in practice, simple modular arithmetic is really just integer arithmetic, except we simplify based on remainders when dividing by the modulus. The richness of the modular worlds will become more apparent when we study quadratic residues and compound congruence. For now, however, we start with some simple definitions.
\begin{mdframed}
\begin{definition}
Let $a$ and $b$ be integers. Then, $a$ is congruent to $b$ modulo $m$ if $(a - b)$ is divisible by $m$. We denote this relationship by
\[a\equiv b\X{m}\]
Equivalently, we can say
\begin{center}
$m\divv (a-b)$\\\medskip
$b$ is the remainder when $a$ is divided by $m$\\\medskip
Or, $(a-b)$ is a multiple of $m$.
\end{center}
\end{definition}
\end{mdframed}

\subsubsection*{Well-Definedness of Modular Arithmetic}
So, we map the integers to the $m$ unique representatives $0, 1, \dots m-1$ modulo $m$, which cycles through the integers like clockwork. However, before we can \textit{do} anything with our new frame of reference, we need to be sure that it is well-defined. That is, we want to be sure that we can actually use residue classes as placeholders for the integers, without losing any information in the process.
\begin{mdframed}
\begin{prop} Operations in modular arithmetic, taking a unique residue class as a distinct representative, are well-defined. In other words, if $x\equiv \overline{x} \X{m}$, and $y\equiv\overline{y}\X{m}$, then $x + y\equiv\overline{x} + \overline{y}\X{m}$, and $xy\equiv\overline{x}\overline{y}\X{m}$.
\end{prop}
\begin{proof}
Suppose that $x\equiv \overline{x}$, and $y\equiv\overline{y}$, modulo $m$. Then, for integers $j$ and $k$,
\[x = mj + \overline{x}, \quad y = mk + \overline{y} \]
So, combining terms, $x + y$ can be suggestively written as
\[x + y = \overline{x} + \overline{y} + m(j + k) \]
Which, modulo $m$, implies that $x + y\equiv\overline{x} + \overline{y}\X{m}$. \\
We task the reader with proving the multiplicative case, which is much of the same, requiring just a bit more algebraic re-arrangement.
\end{proof}
\end{mdframed}

\subsubsection*{Properties of Modular Arithmetic}
Modular arithmetic enjoys the following basic properties, among more:
\begin{enumerate}[(i)]
\item If $a\equiv b\X{m}$, $b\equiv a\X{m}$.
\item Suppose that $a\equiv b\X{m}$ and $c\equiv d\X{m}$. Then: \\
$a + c\equiv b+d\X{m}$\\
$ac\equiv bd\X{m}$
\item $ax\equiv ay\X{m}$ implies that $x\equiv y\X{m}$.
\end{enumerate}
In brief, modular arithmetic operates in expected ways, and when the hurdle of shifting from integers-as-integers to integers-as-representatives is overcome, I've found the modular worlds to be quite delightful. Division, modulo $m$, isn't defined, but, as we'll find, the cyclic nature of modular systems affords a close enough substitute. (EXAMPLE?)

\subsubsection*{Linear Congruences}
Linear congruences are congruences of the form
\[ax\equiv b \X{m}\]
for a given modulus $m$.As it turns out, these congruences are really only linear diophantine equations in disguise. For $ax\equiv b\X{m}$ is really saying that $ax - b = my$, for integers $x$ and $y$, which is really just $ax - my = b$. This observation leads us to the following.
\begin{mdframed}
\begin{prop} The congruence
\[ax\equiv 1\X{m}\]
has a solution if and only if $\GCD{a}{m} = 1$.
\end{prop}
\begin{proof}
We can prove this simply by translating back and forth between the language of congruences, and the language of linear diophantine equations.
Suppose $ax\equiv 1 \X{m}$. Then, $ax - 1 = my$, for some integer $y$. In turn, this implies that $ax - my = 1$. From previous sections, we know that this equation is solvable if and only if $\GCD{a}{m} = 1$.\\
Conversely, suppose that $\GCD{a}{m}=1$. Then, for some choice of integers $x$ and $y$, $ax + my = 1$. With just a bit of re-arrangement, we can write this as $ax - 1 = m(-y)$, which in turn demonstrates that $ax\equiv 1\X{m}$.
\end{proof}
\end{mdframed}
Now, if we happen to solve for $x$ in a congruence like the one above, $x$ is considered the \textit{multiplicative inverse} of $a$, modulo $m$. Modular inverses are computationally useful, and bring us about as close as we can get to division in the modular world. By the proposition above, we can see that the divisibility relationship between a residue class $a$ and the modulus determines if $a$ will have a multiplicative inverse, or not. However, it is important to observe that inverses come in pairs (or a residue class can be its own inverse, as is always the case with 1).
\begin{mdframed}
\begin{prop}
Modulo $m$, any residue class $a$ has a unique multiplicative inverse $b$ if and only if $\GCD{a}{m} = 1$. Furthermore, this inverse is unique.
\end{prop}
\begin{proof}
The former part of the statement holds as a direct consequence of the previous proposition, but what of uniqueness? Suppose that an residue class $a$ had two distinct representatives. That is, $ab\equiv ac\equiv 1\X{m}$. Then,
\[c \equiv 1\cdot c \equiv (ab)\cdot c \equiv (ac)\cdot b \equiv 1\cdot b \equiv b\]
And, as $c\equiv b$, they are for all purposes the same residue class in our modular world.
\end{proof}
\end{mdframed}

\subsubsection*{Solubility of Linear Diophantine Equations}
The connections between linear diophantine equations and linear congruences run deep. In particular, modular arithmetic gives us a powerful tool for disproving the existence of solutions to linear diophantine equations.

\end{document}


%% SECTION HEADER ////////////////////////////////////////////////////////////////////////////////
\section[Guided waves based SHM]{Guided waves based SHM}
\label{sec22}
The approach behind adopting elastic waves propagation methods in SHM includes generating elastic waves in the examined structure and recording their displacement as a function of time~\cite{Ostachowicz2012}.
The produced waves are travelling in packets, those packets keep propagating until
they reflect from discontinuities, edges or damage in the structure. The reflected waves hold information about the location and the size of the damage.

Designing a robust SHM system requires knowledge in various scientific fields e.g. mechanical and electrical engineering, as well as in computer science, mathematics, and physics~\cite{Willberg2013}.
Moreover, it requires a deep understanding of various material types and the design of transducers working alone and in networks.
Also, there is a need to be familiar with signal processing methods and damage evaluation techniques~\cite{Willberg2013}.

In this literature we will focus on the guided wave-based SHM techniques for composite materials, which has brought large attention in the past two decades~\cite{Mitra2016}.
Guided waves which are essentially elastic waves propagating within bounded
structures~\cite{Mitra2016}, e.g. in a thin-plate, they are being guided by the boundaries of the plate.

There are a few benefits from adopting guided wave-based sche\-mes for SHM in structures over vibration based methods.
The transducers that are utilised in SHM systems are generally affordable, also usually, due to the lightweight of those transducers, it can be implemented easily in the structure.
In addition, it is possible to scan a relatively large area compared to a little number of transducers~\cite{Mitra2016}.
Moreover, an important advantage for guided waves over a vibration-based scheme
is their high sensitivity for detecting small defects due to the ability to use high-frequency signals (excited and registered).
In such a case, guided waves are not so sensitive to low-frequency vibrations~\cite{Mitra2016,Croxford2007}.

Various types of guided waves have been investigated for the purpose of SHM.
A well-known approach is the use of Lamb waves, that propagate
within thin-plates and shells bounded by stress-free surfaces~\cite{Mitra2016}.
Lamb waves were given their name after Horace Lamb, who discovered them and
developed a theory to describe the phenomena of their propagation
~\cite{Ostachowicz2012}.
However, Lamb could not able to generate those waves physically, until
Worlton~\cite{Worlton1961} who saw the opportunity to utilise Lamb waves
characteristics in damage detection~\cite{Ostachowicz2012}.
Lamb waves, in general, are generated and received by piezoelectric (PZT)
transducers~\cite{Cai2012}.
Due to the multi-mode and dispersion properties, the propagation of Lamb waves
is quite complex~\cite{Ostachowicz2012}.
In practical applications, two forms of Lamb waves arise depending on the
distribution of the displacement on the top and bottom bounding surfaces, these
forms are symmetric, denoted as \(S_0,S_1,S_2,...., \)and antisymmetric, denoted as
\(A_0,A_1,A_2,....,\) ~\cite{Ostachowicz2012}.
Fig.~\ref{fig:LambModes} illustrates the propagation of the fundamental Lamb waves for \(A_0\) and \(S_0\) modes in a structure.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}[!ht]
	\begin{center}
		\centering
		\includegraphics[width=1\textwidth]{Figures/Chapter_1/fig_Lamb_wave_modes.png}
	\end{center}
	\caption{Fundamental Lamb wave modes: (a)~\(A_0\) mode, (b)~\( S_0\) mode}
	\label{fig:LambModes}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{}
Regardless of Lamb waves promising characteristics, using them for SHM
applications hold some essential challenges.
Among them are the dispersive nature of Lamb wave propagating modes that can convert into each other in the presence of defects and other changes in the mechanical
impedance~\cite{Willberg2015}.
Moreover, ascribed to some flaws in the bonding within actuators sensors and
the structure, random noise will emerge in the relevant sensors due to the high
sensitivity of Lamb waves toward structural perturbations.
Also, noise arising from environmental sources, like temperature changing, or
anisotropy of the material also summed up to the received signals making them
very complicated and challenging to recognize and interpret~\cite{Willberg2015}.
Moreover, an essential point concerns the choice of a carrier frequency for the
Lamb waves because the higher the frequency is, the damage detection of small
size is more likely detected.
However,  when the frequency increases, the number of propagating wave modes will increase accordingly.
As a result, multiple wave modes propagate and each wave mode has different velocity which causes a problem with reflection identification and misinterpretation of the location and the size of the damage~\cite{Ostachowicz2012}.
It was found that each wave mode shows a varying sensitivity to individual
damage.
\textcite{Kessler2002b,Ihn2008} found that \(A0\) mode is suitable for delaminations to be detected in composite materials, and \(S0\) mode was found suitable for cracks detection in metallic elements~\cite{Ihn2004,Ihn2008}.
It was also observed that the design of the transducer influences in a great manner the excited and registered wave modes~\cite{Ostachowicz2010}.


\chapter{Chapter 6. Tableaux Propositional Logic}

%\section*{4.7 Self-Study Questions}
%
%	\begin{enumerate}
%
%		\item[4.7.1]
%
%	\end{enumerate}
%
\section*{6.6 Exercises}

\begin{enumerate}

	\item[6.6.1] One way of putting it is as saying that an inference is valid iff the premises together with the negation of the conclusion are unsatisfiable or inconsistent.

	\item[6.6.2]

	\begin{enumerate}[(a)]

		\item Suppose for contradiction that there is a valuation $v$ such that $\llbracket \neg (p\rightarrow q)\rrbracket_v =1$ and $\llbracket \neg (q \rightarrow p)\rrbracket_v =1$. $\llbracket \neg (p\rightarrow q)\rrbracket_v =1$ would mean that $\llbracket p\rightarrow q\rrbracket_v =0$, from which would follow that $\llbracket p\rrbracket_v =1$ and $\llbracket q\rrbracket_v =0$. (An implication is not true iff the first argument is true and the second argument is false). For $\llbracket \neg (q \rightarrow p)\rrbracket_v =1$ to hold, $\llbracket (q \rightarrow p)\rrbracket_v =0$ must be true, from which follows that $\llbracket q\rrbracket_v =1$ and $\llbracket p\rrbracket_v =0$. As we'd already established that $\llbracket p\rrbracket_v =1$ and $\llbracket q\rrbracket_v =0$, this is a contradiction. Hence such a $v$ cannot exist, so the set is unsatisfiable.

		\item This follows immediately from our observation 5.2.11.(i) that $\vDash p\lor\neg p$. This means that for all $v$, $\llbracket p\lor\neg p\rrbracket_v=1$. Now suppose that there is a valuation $v$ such that $\llbracket \neg (p\lor\neg p)\rrbracket_v=1$. Since $\llbracket \neg (p\lor\neg p)\rrbracket_v=1-\llbracket p\lor\neg p\rrbracket_v$, it would follow that $\llbracket p\lor\neg p\rrbracket_v=0$ in contradiction to 5.2.11.(i). Hence, there is no such valuation $v$ and $\{\neg(p\lor\neg p)\}$ is unsatisfiable.

	\item Suppose for contradiction that there is a valuation $v$ such that $\llbracket \neg p\rrbracket_v = 1$ and $\llbracket \neg p\rightarrow p\rrbracket_v = 1$. From $\llbracket\neg p\rrbracket_v =1$ follows that $\llbracket p\rrbracket_v=0\ (*)$. From $\llbracket \neg p\rightarrow p\rrbracket_v = 1$ follows that $max (1- \llbracket\neg p\rrbracket_v, \llbracket p\rrbracket_v) = 1$. So either $1 - \llbracket \neg p\rrbracket_v $ must be $1$ or $\llbracket p\rrbracket_v$ must be $1$. By $(*)$ follows that the latter is not the case, so $1 - \llbracket \neg p\rrbracket_v =1$ must hold. This would mean that  $\llbracket \neg p\rrbracket_v = 0 $. But we've already assumed that $\llbracket \neg p\rrbracket_v = 1$. Contradiction! Hence such a $v$ cannot exist, so the set is unsatisfiable.

	\item Suppose for contradiction that there is a $v$ such that $\llbracket\neg p\rrbracket_v=1$ and $\llbracket(p\to q)\to p\rrbracket_v=1$. Since $\llbracket\neg p\rrbracket_v=1$ and $\llbracket\neg p\rrbracket_v=1-\llbracket p\rrbracket_v$, it follows that $\llbracket p\rrbracket_v=0$. Now consider $\llbracket(p\to q)\to p\rrbracket_v$. We know that $\llbracket(p\to q)\to p\rrbracket_v=max(1-\llbracket p\to q\rrbracket_v, \llbracket p\rrbracket)=max(1-max(1-\llbracket p\rrbracket_v,\llbracket q\rrbracket_v), \llbracket p\rrbracket)$. Since $\llbracket p\rrbracket_v=0$, we can infer that $max(1-max(1-\llbracket p\rrbracket_v,\llbracket q\rrbracket_v), \llbracket p\rrbracket)=max(1-max(1-0,\llbracket q\rrbracket_v),0)=max(1-max(1,\llbracket q\rrbracket_v),0)=max(1-1,0)-max(0,0)=0$, in contradiction to $\llbracket(p\to q)\to p\rrbracket_v=1$. Hence there can be no such $v$ and our set is unsatisfiable.

\end{enumerate}

	\item[6.6.3] We need to show two things: (a) if $\vDash \neg (\phi_1\land\mathellipsis\land\phi_n)$, then $\{\phi_1, \mathellipsis,\phi_n\}$ is unsatisfiable, and (b) if $\{\phi_1, \mathellipsis,\phi_n\}$ is unsatisfiable, then $\vDash \neg (\phi_1\land\mathellipsis\land\phi_n)$. We do so in turn:

	\begin{enumerate}[(a)]

		\item Suppose that $\vDash \neg (\phi_1\land\mathellipsis\land\phi_n)$. This means that for each $v$, $\llbracket \neg (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v=1$. Since $\llbracket \neg (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v=1-\llbracket (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v$, we can infer that $\llbracket (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v=0$. Now consider $\llbracket (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v$. We can easily show that $\llbracket (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v=min(\llbracket \phi_1\rrbracket_v, \mathellipsis, \llbracket\phi_n\rrbracket_v)$ (exercise, proof this by induction on natural numbers). Since $min(\llbracket \phi_1\rrbracket_v, \mathellipsis, \llbracket\phi_n\rrbracket_v)=0$, it follows that some $\phi_i$ for $1\leq i\leq n$ must be such that $\llbracket\phi_i\rrbracket_v=0$. But that just means that for each valuation $v$, some $\phi_i$ must be false. Hence there can be no valuation that makes all the members of $\{\phi_1, \mathellipsis,\phi_n\}$ true, which is what we needed to show.

		\item Suppose that $\{\phi_1, \mathellipsis,\phi_n\}$ is unsatisfiable, i.e. there is no valuation that that makes all the members of $\{\phi_1, \mathellipsis,\phi_n\}$ true. We wish to derive that $\vDash \neg (\phi_1\land\mathellipsis\land\phi_n)$, i.e. for all valuations $v$, $\neg (\phi_1\land\mathellipsis\land\phi_n)$ is true. So let $v$ be arbitrary. Since $\{\phi_1, \mathellipsis,\phi_n\}$ is unsatisfiable, it follows that  that some $\phi_i$ for $1\leq i\leq n$ must be such that $\llbracket\phi_i\rrbracket_v=0$. Now consider $\llbracket (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v$. We've already observed that $\llbracket (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v=min(\llbracket \phi_1\rrbracket_v, \mathellipsis, \llbracket\phi_n\rrbracket_v)$. Since there is a $\phi_i$ such that $\llbracket\phi_i\rrbracket_v=0$, it follows that $min(\llbracket \phi_1\rrbracket_v, \mathellipsis, \llbracket\phi_n\rrbracket_v)=0$. Since $\llbracket \neg (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v=1-\llbracket (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v$, it immediately follows that $\llbracket \neg (\phi_1\land\mathellipsis\land\phi_n)\rrbracket_v=1$, as desired.

	\end{enumerate}

	\item[6.6.4]

	\begin{enumerate}[(a)]

\item $p\to q, r\to q\vdash (p\lor r)\to q$

\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=10mm},
single branches=true,
close with=\xmark
}
[p\to q, grouped [r\to q, grouped [\neg ((p\lor r)\to q), grouped [p\lor r [\neg q [\neg p [p, close] [r [\neg r, close] [q, close]]] [q, close]]]]]]
\end{prooftree}
\end{center}

\item $p\to (q\land r), \neg r\vdash \neg p$

\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=10mm},
single branches=true,
close with=\xmark
}
[p\to (q\land r), grouped [\neg r, grouped [\neg\neg p, grouped  [p [\neg p, close] [q\land r [q[r,close]]]]]]]
\end{prooftree}
\end{center}

\item $((p\to q)\to q)\to q$

\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=10mm},
single branches=true,
close with=\xmark
}
[\neg (((p\to q)\to q)\to q) [((p\to q)\to q) [\neg q [\neg (p\to q) [p [\neg q]]] [q, close]]]]
\end{prooftree}
\end{center}

Counter-model: $v(p)=1, v(q)=0$.

\newpage

\item $\vdash ((p\to q)\land (\neg p\to q))\to \neg p$
{\footnotesize
\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=10mm},
single branches=true,
close with=\xmark
}
[\neg (((p\to q)\land (\neg p\to q))\to \neg p)
	[((p\to q)\land (\neg p\to q))
		[\neg \neg p
			[p
				[p\to q
					[\neg p\to q
						[\neg p, close]
						[q
							[\neg\neg p [p]]
							[q]
							]
						]
					]
				]
			]
		]
]
\end{prooftree}
\end{center}

Counter-model: $v(p)=1, v(q)=1$
}

\item $p\leftrightarrow (q\leftrightarrow r)\vdash (p\leftrightarrow q)\leftrightarrow r$

{\footnotesize\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=5mm},
single branches=true,
close with=\xmark
}
[p\leftrightarrow (q\leftrightarrow r), grouped [\neg((p\leftrightarrow q)\leftrightarrow r),grouped
[p [(q\leftrightarrow r)
	[(p\leftrightarrow q) [\neg r
		[q [r,close] ]
		[\neg q [\neg r
			[p [q, close]]
			[\neg p [\neg q, close]]
			]]
		]]
	[\neg (p\leftrightarrow q) [r
		[q [r
			[p [\neg q, close]]
			[\neg p [q, close]]
			]]
		[\neg q [\neg r,close] ]
		]]
	]
	]
[\neg p [\neg(q\leftrightarrow r)
	[(p\leftrightarrow q) [\neg r
		[q [\neg r
			[p [q, close]]
			[\neg p [\neg q, close]]
			]]
		[\neg q [r,close] ]
		]]
	[\neg (p\leftrightarrow q) [r
		[q [\neg r,close] ]
		[\neg q [r
			[p [\neg q, close]]
			[\neg p [q,close]]
			]]
		]]
	]
	]
]
]
]
\end{prooftree}
\end{center}}

\newpage

\item $\neg(p\to q)\land \neg(p\to r)\vdash \neg q\lor \neg r$

\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=5mm},
single branches=true,
close with=\xmark
}
[\neg(p\to q)\land \neg(p\to r), grouped [\neg(\neg q\lor \neg r), grouped
	[\neg(p\to q) [\neg(p\to r)
		[\neg\neg q [\neg \neg r
			[p [\neg q, close]]
			]]
		]
	]
]
]
\end{prooftree}
\end{center}

\item $p\land (\neg r\lor s), \neg (q\to s)\vdash r$

\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=5mm},
single branches=true,
close with=\xmark
}
[p\land (\neg r\lor s), grouped  [\neg (q\to s), grouped [\neg r, grouped
	[p [(\neg r\lor s) [q [\neg s
	[\neg r]
	[s, close]
	]]]]
]
]
]
\end{prooftree}
\end{center}

Counter-model: $v(p)=1, v(q)=1, v(r)=0, v(s)=0$.

\newpage

\item $\vdash (p\to (q\to r))\to (q\to (p\to r))$

\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=5mm},
single branches=true,
close with=\xmark
}
[\neg((p\to (q\to r))\to (q\to (p\to r)))
	[(p\to (q\to r)) [\neg(q\to (p\to r))
	[q [\neg (p\to r)
	[p [\neg r
		[\neg p, close]
		[(q\to r)
			[\neg q, close]
			[r, close]
			]
		]
	]
	]
	]
	]
	]
]
\end{prooftree}
\end{center}

\item $\neg(p\land \neg q)\lor r, p\to (r\leftrightarrow s)\vdash p\leftrightarrow q$

(See last page. This was a tough one \smiley)

\begin{sidewaysfigure}[h!]
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=10mm},
single branches=true,
close with=\xmark
}
[\neg(p\land \neg q)\lor r, grouped [p\to (r\leftrightarrow s), grouped [\neg(p\leftrightarrow q), grouped
	[\neg(p\land \neg q)
		[\neg p
			[p [\neg q, close]]
			[\neg p [q
				[\neg p]
				[\neg\neg q [q]]
				]]
			]
		[(r\leftrightarrow s)
			[p [\neg q
				[\neg p, close]
				[\neg\neg q, close]
				]]
			[\neg p [q
				[\neg p
					[r [s]]
					[\neg r [\neg s]]
					]
				[\neg\neg q [q
					[r [s]]
					[\neg r [\neg s]]
					]]
				]]
			]
		]
	[r
		[\neg p
			[p [\neg q, close]]
			[\neg p [q]]
			]
		[(r\leftrightarrow s)
			[p [\neg q
				[r [s]]
				[\neg r [\neg s, close]]
				]]
			[\neg p [q
				[r [s]]
				[\neg r [\neg s, close]]
				]]
			]
		]
	]
]
]
\end{prooftree}\\[2ex]

Counter-model $v(p)=0, v(q)=1, v(r)=0$.

\end{sidewaysfigure}

\newpage

\item $p\leftrightarrow \neg\neg q, \neg q\to (r\land \neg s), s\to (p\lor q)\vdash (s\land q)\to p$

(Note: Here I made a short tableaux by strategically applying the rules in a certain order. You might get another tableaux if you use the rules in different order.)

\begin{center}
\begin{prooftree}
{
line numbering=false,
for tree={s sep'=5mm},
single branches=true,
close with=\xmark
}
[p\leftrightarrow \neg\neg q, grouped [\neg q\to (r\land \neg s), grouped [s\to (p\lor q), grouped [\neg((s\land q)\to p), grouped
	[s\land q [\neg p [s [q
		[\neg s, close]
		[p\lor q
			[p, close]
			[q
				[p [\neg\neg q, close]]
				[\neg p [\neg\neg\neg q [\neg q, close]]]
				]
			]
		]
		]
	]
	]
]
]
]
]
\end{prooftree}
\end{center}

\end{enumerate}

\end{enumerate}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "../../logic.tex"
%%% End: