Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typo Fixes and Extra Description #111

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion chapters/algebra-moonmath.tex
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ \subsection{The exponential map}
\Require $g$ group generator of order $n$
\Require $x \in \Z_n$
\Procedure{Exponentiation}{$g,x$}
\State Let $(b_0,\ldots,b_k)$ be a binary representation of $x$ \Comment{see example XXX}
\State Let $(b_0,\ldots,b_k)$ be a binary representation of $x$ \Comment{see \ref{def:binary_representation_integer}}
\State $h \gets g$
\State $y \gets e_{\G}$
\For{$0\leq j < k$}
Expand Down
2 changes: 1 addition & 1 deletion chapters/arithmetics-moonmath.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ \subsection{\concept{Euclidean division} with polynomials}

% https://math.stackexchange.com/questions/2140378/division-algorithm-for-polynomials-in-rx-where-r-is-a-commutative-ring-with-u
This algorithm works only when there is a notion of division by the leading coefficient of $B$. It can be generalized, but we will only need this somewhat simpler method in what follows.
\begin{example}[Polynomial Long Division] To give an example of how the previous algorithm works, let us divide the integer polynomial $A(x)=x^5+2x^3-9\in \Z[x]$ by the integer polynomial $B(x)=x^2+4x-1\in\Z[x]$. Since $B$ is not the zero polynomial, and the leading coefficient of $B$ is $1$, which is invertible as an integer, we can apply algorithm \ref{alg_polynom_euclid_alg}. Our goal is to find solutions to equation XXX\sme{add reference}, that is, we need to find the quotient polynomial $Q\in\Z[x]$ and the remainder polynomial $P \in \Z[x]$ such that $x^5+2x^3-9 = Q(x)\cdot (x^2+4x-1) + P(x)$. Using a the long division notation that is mostly used in anglophone countries, we compute as follows:
\begin{example}[Polynomial Long Division] To give an example of how the previous algorithm works, let us divide the integer polynomial $A(x)=x^5+2x^3-9\in \Z[x]$ by the integer polynomial $B(x)=x^2+4x-1\in\Z[x]$. Since $B$ is not the zero polynomial, and the leading coefficient of $B$ is $1$, which is invertible as an integer, we can apply algorithm \ref{alg_polynom_euclid_alg}. Our goal is to find solutions to equation \ref{eq_polynomial_euclidean_division_notation}\sme{check reference}, that is, we need to find the quotient polynomial $Q\in\Z[x]$ and the remainder polynomial $P \in \Z[x]$ such that $x^5+2x^3-9 = Q(x)\cdot (x^2+4x-1) + P(x)$. Using a long division notation that is mostly used in anglophone countries, we compute as follows:
\begin{equation}
\polylongdiv{X^5+2X^3-9}{X^2+4X-1}
\end{equation}
Expand Down
18 changes: 9 additions & 9 deletions chapters/circuit-compilers-moonmath.tex
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ \subsection{The Execution Phases} In contrast to normal executable programs, pro

After this is done, we have to do a consistency and type check for every occurrence of the assignment operator \texttt{<==}. We have to ensure that the expression on the right side of the operator is well defined and that the types of both side match.

Then we compile the right side of every occurrence of the assignment operator \texttt{<==}. If the right side is a constant or variable defined in this function, we draw a dotted line from the box-node that represents the left side of \texttt{<==} to the box node that represents the right side of the same operator. If the right side represents an argument of that function we draw a line from the box-node that represents the left side of \texttt{<==} to the box node that represents the right side of the same operator.
Then we compile the right side of every occurrence of the assignment operator \texttt{<==}. If the right side is a constant or variable defined in this function, we draw a dotted line from the box-node that represents the right side of \texttt{<==} to the box node that represents the left side of the same operator. If the right side represents an argument of that function we draw a line from the box-node that represents the left side of \texttt{<==} to the box node that represents the right side of the same operator.

If the right side of the \texttt{<==} operator is a function, we look into our database, find its associated circuit and draw it. If no circuit is associated to that function yet, we repeat the compilation process for that function, drawing edges from the function's argument to its input nodes and from the functions output nodes to the nodes on the right side of \texttt{<==}.

Expand Down Expand Up @@ -162,9 +162,9 @@ \section{Real World Circuit Languages}
\subsection{Circom}
Circom is a domain-specific programming language for designing arithmetic circuits. It is used to build circuits that can be compiled to rank-1 constraint systems and outputted as WebAssembly and C++ programs for efficient evaluation.

In this section, we will gives examples of how to write basic circuits in Circom. We will use those examples then later to compute associated proof in snarkjs.
In this section, we will gives examples of how to write basic circuits in Circom. We will use those examples later to compute associated proof in snarkjs.

To understand circom, we first have to provide definitions for the terms \hilight{signals},\hilight{templates}, and \hilight{components} to facilitate a better understanding of the examples discussed.
To understand Circom, we first have to provide definitions for the terms \hilight{signals},\hilight{templates}, and \hilight{components} to facilitate a better understanding of the examples discussed.

A \term{signal} refers to an element in the underlying finite field $\F$ of a circuit. The arithmetic circuits created using Circom operate on signals, which are immutable and can be defined as inputs or outputs. Input signals are private, unless specified as public, and all output signals are publicly accessible. The remaining signals are private and cannot be made public. Public signals are part of the instance and private signals are part of the witness in any valid assignment of a circuit.

Expand Down Expand Up @@ -205,7 +205,7 @@ \subsection{Circom}

\begin{example}[The 3-factorization problem in Circom]
\label{ex:3-fac-circom}
In this example we implement the 3-factorization problem \ref{ex:3-factorization} in Circom's language and compile into an R1CS and statement generator. In order to show, how Circom handles modularity \ref{modularity}, we write the code as follows:
In this example we implement the 3-factorization problem \ref{ex:3-factorization} in Circom's language and compile into an R1CS and statement generator. In order to show how Circom handles modularity \ref{modularity}, we write the code as follows:
\begin{lstlisting}
template Multiplier() {
signal input a ;
Expand Down Expand Up @@ -255,7 +255,7 @@ \subsection{Primitive Types}
% https://zeroknowledge.fm/172-2/ reference for all the languages
Primitive data types like booleans, (unsigned) integers, or strings are the most basic building blocks one can expect to find in every general high-level programing language. In order to write statements as computer programs that compile into circuits, it is therefore necessary to implement primitive types as constraint systems, and define their associated operations as circuits.

In this section, we look at some common ways to achieve this. After a recapitulation of the atomic type for the base field where the circuit is defined on, we start with an implementation of the boolean type and its associated boolean algebra as circuits. After that, we define unsigned integers based on the boolean type, and leave the implementation of signed integers as an exercise to the reader.
In this section, we look at some common ways to achieve this. After a review of the atomic type for the base field where the circuit is defined on, we start with an implementation of the boolean type and its associated boolean algebra as circuits. After that, we define unsigned integers based on the boolean type, and leave the implementation of signed integers as an exercise to the reader.

\subsubsection{The base-field type}
\label{def:base_field_type}
Expand Down Expand Up @@ -399,7 +399,7 @@ \subsubsection{The base-field type}
}
\end{center}
\end{example}
\begin{example}[$3$-factorization] Consider our $3$-factorization problem from \examplename{} \ref{ex:3-factorization} and the associated circuit $C_{3.fac\_zk}(\F_{13})$ we provided in \examplename{} \ref{ex:TJJ-circuit_1}. To understand the process of replacing high-level functions by their associated circuits inductively, we want define a \lgname{PAPER} statement that we brain-compile into an algebraic circuit equivalent to $C_{3.fac\_zk}(\F_{13})$:
\begin{example}[$3$-factorization] Consider our $3$-factorization problem from \examplename{} \ref{ex:3-factorization} and the associated circuit $C_{3.fac\_zk}(\F_{13})$ we provided in \examplename{} \ref{ex:TJJ-circuit_1}. To understand the process of replacing high-level functions by their associated circuits inductively, we want to define a \lgname{PAPER} statement that we brain-compile into an algebraic circuit equivalent to $C_{3.fac\_zk}(\F_{13})$:
\begin{lstlisting}
statement 3_fac_zk {F:F_13} {
fn main(x_1 : F, x_2 : F, x_3 : F) -> F{
Expand Down Expand Up @@ -1283,7 +1283,7 @@ \subsubsection{The boolean Type}
W_5:\;\; & W_1 \cdot (1- W_1) = 0 & \text{boolean constraints}\\
W_6:\;\; & W_2 \cdot (1- W_2) = 0 \\
W_7:\;\; & W_3 \cdot (1- W_3) = 0 \\
W_8:\;\; & W_4 \cdot (1- w_4) = 0 \\
W_8:\;\; & W_4 \cdot (1- W_4) = 0 \\
W_9:\;\; & W_1 \cdot W_2 = W_9 & \text{ first OR-operator constraint}\\
W_{10}:\;\; & W_3 \cdot (1-W_4) = W_{10} & \text{AND(.,NOT(.))-operator constraints}\\
I_1:\;\; & (W_1 + W_2 -W_9) \cdot W_{10} = I_1 & \text{AND-operator constraints}\\
Expand Down Expand Up @@ -1718,7 +1718,7 @@ \subsubsection{The Unsigned Integer Type} Unsigned integers of size \texttt{N},
\end{lstlisting}
Let $L_{mask\_merge}$ be the language defined by the circuit. Provide a constructive knowledge proof in $L_{mask\_merge}$ for the instance $I=(I_a, I_b) = (14, 7)$.
\end{exercise}
\subsection{Control Flow} Most programming languages of the imperative of functional style have some notion of basic control structures to direct the order in which instructions are evaluated. Contemporary circuit compilers usually provide a single thread of execution and provide basic flow constructs that implement control flow in circuits. In this part we look at some basic control flow constructions and their implementation in circuits.
\subsection{Control Flow} Most programming languages of the imperative or functional style have some notion of basic control structures to direct the order in which instructions are evaluated. Contemporary circuit compilers usually provide a single thread of execution and provide basic flow constructs that implement control flow in circuits. In this part we look at some basic control flow constructions and their implementation in circuits.
\subsubsection{The Conditional Assignment} Writing high-level code that compiles to circuits, it is often necessary to have a way for conditional assignment of values or computational output to variables. One way to realize this in many programming languages is in terms of the conditional ternary assignment operator $?:$ that branches the control flow of a program according to some condition and then assigns the output of the computed branch to some variable:
\begin{lstlisting}
variable = condition ? value_if_true : value_if_false
Expand Down Expand Up @@ -2127,7 +2127,7 @@ \subsection{Binary Field Representations} In applications, it is often necessary
$$
This is because the unsigned integers $2$ and $15$ are both in the modular $13$ remainder class of $2$ and hence are both representatives of $2$ in $\F_{13}$.

To see how circuit the associated circuit works, we want to enforce the binary representation of $7\in \F_{13}$. Since $m=4$ we have to enforce a $4$-bit representation for $7$, which is $<1,1,1,0>$, since $7= 1\cdot 2^0 + 1\cdot 2^1 + 1\cdot 2^2 + 0\cdot 2^3$. A valid circuit assignment is therefore given by $<S_0,S_1,S_2,S_3,S_4>=<1,1,1,0,7>$ and, indeed, the assignment satisfies the required $5$ constraints including the $4$ boolean constraints for $S_0$, $\ldots$, $S_3$:
To see how the associated circuit works, we want to enforce the binary representation of $7\in \F_{13}$. Since $m=4$ we have to enforce a $4$-bit representation for $7$, which is $<1,1,1,0>$, since $7= 1\cdot 2^0 + 1\cdot 2^1 + 1\cdot 2^2 + 0\cdot 2^3$. A valid circuit assignment is therefore given by $<S_0,S_1,S_2,S_3,S_4>=<1,1,1,0,7>$ and, indeed, the assignment satisfies the required $5$ constraints including the $4$ boolean constraints for $S_0$, $\ldots$, $S_3$:
\begin{align*}
1\cdot (1-1) &= 0 & \text{// boolean constraints}\\
1\cdot (1-1) &= 0 \\
Expand Down
10 changes: 5 additions & 5 deletions chapters/elliptic-curves-moonmath.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ \subsubsection{Elliptic Curves over extension fields}
\end{exercise}
\begin{exercise}
\label{exercise:BN128-extension}
Consider the \curvename{alt\_bn128} curve and its associated base field $\F_p$ from \examplename{} \ref{BN128}. As we know from example \ref{ex:embedding_degre_BN128} this curve has an embedding degree of $12$. Use Sage to find an irreducible polynomial $P\in \F_p[t]$ and write a sage program to implement the finite field extension $\F_{p^{12}}$ and to implement the curve extension $alt\_bn128(\F_{p^12})$ and compute the number of curve points.
Consider the \curvename{alt\_bn128} curve and its associated base field $\F_p$ from \examplename{} \ref{BN128}. As we know from example \ref{ex:embedding_degre_BN128} this curve has an embedding degree of $12$. Use Sage to find an irreducible polynomial $P\in \F_p[t]$ and write a sage program to implement the finite field extension $\F_{p^{12}}$ and to implement the curve extension $alt\_bn128(\F_{p^{12}})$ and compute the number of curve points.
\end{exercise}
\subsection{Full torsion groups}
\label{sec:full-torsion} As we will see in what follows, cryptographically interesting pairings are defined on so-called torsion subgroups of elliptic curves. To define \term{torsion groups} of an elliptic curve, let $\F$ be a finite field, $E(\F)$ an elliptic curve of order $n$ and $r$ a factor of $n$. Then the \term{$r$-torsion group} of the elliptic curve $E(\F)$ is defined as the set
Expand Down Expand Up @@ -1392,7 +1392,7 @@ \subsection{Pairing groups}
....: L_TJJ_G1.append(P)
sage: TJJ_G1 = Set(L_TJJ_G1)
\end{sagecommandline}
We get $\G_1= \{\Oinf, (7,2), (8,8), (8,5), (7,11)\}$ and as expected, $\G_1$ is identical to the $5$-torsion group of the (unextended) curve over the prime field $TJJ_13$ as computed in \examplename{} \ref{eq:TJJ13-logarithmic-order}.
We get $\G_1= \{\Oinf, (7,2), (8,8), (8,5), (7,11)\}$ and as expected, $\G_1$ is identical to the $5$-torsion group of the (unextended) curve over the prime field $TJJ\_13$ as computed in \examplename{} \ref{eq:TJJ13-logarithmic-order}.

In order to compute the group $\G_2$ for the tiny jubjub curve, we can use almost the same algorithm as we used for the computation of $\G_1$. Since $p=13$ we get the following:
\begin{sagecommandline}
Expand Down Expand Up @@ -1465,7 +1465,7 @@ \subsection{The Weil pairing}
\end{algorithmic}
\end{algorithm}

Understanding the details of how and why this algorithm works requires the concept of \term{divisors}, which is outside of the scope this book. The interested reader might look at \chaptname{} 6, \secname{} 6.8.3 in \cite{hoffstein-2008}, or at \href{https://static1.squarespace.com/static/5fdbb09f31d71c1227082339/t/5ff394720493bd28278889c6/1609798774687/PairingsForBeginners.pdf}{Craig Costello’s great tutorial on elliptic curve pairings}.\tbds{add this to references} As we can see, the algorithm is more efficient on prime numbers $r$, that have a low Hamming weight \ref{def:binary_representation_integer}.
Understanding the details of how and why this algorithm works requires the concept of \term{divisors}, which is outside of the scope this book. The interested reader might look at \chaptname{} 6, \secname{} 6.8.3 in \cite{hoffstein-2008}, or at \chaptname {} 3 in \cite{costello-pairings}. As we can see, the algorithm is more efficient on prime numbers $r$, that have a low Hamming weight \ref{def:binary_representation_integer}.

We call an elliptic curve $E(\F_p)$ \term{pairing-friendly} if there is a prime factor of the groups order such that the Weil pairing is efficiently computable with respect to that prime factor. In real-world applications of pairing-friendly elliptic curves, the embedding degree is usually a small number like $2$, $4$, $6$ or $12$, and the number $r$ is the largest prime factor of the curve's order.

Expand Down Expand Up @@ -1555,7 +1555,7 @@ \subsection{Try-and-increment hash functions}

Since the curve $TJJ\_13$ is defined over the field $\F_{13}$, and the binary representation of $13$ is $Bits(13)=<1,1,0,1>$, one way to implement a try-and-increment function is to apply SHA256 from Sage's hashlib library on the concatenation $s||c$ for some binary counter string $c$, and use the first $4$ bits of the image to try to hash into $\F_{13}$. In case we are able to hash to a value $x$ such that $x^3 +8\cdot x + 8$ is a quadratic residue in $\F_{13}$, we use the fifth bit to decide which of the two possible roots of $x^3 + 8\cdot x + 8$ we will choose as the $y$ coordinate. The result is a curve point different from the point at infinity. To project it onto the large prime order subgroup $TJJ\_13[5]$, we multiply it with the cofactor $4$. If the result is not the point at infinity, it is the result of the hash.

To make this concrete, let $s=<1,1,1,0,0,1,0,0,0,0>$ be our binary string that we want to hash onto $TJJ_13[5]$. We use a binary counter string starting at zero, that is, we choose $c=<0>$. Invoking Sage, we define the try-hash function as follows:
To make this concrete, let $s=<1,1,1,0,0,1,0,0,0,0>$ be our binary string that we want to hash onto $TJJ\_13[5]$. We use a binary counter string starting at zero, that is, we choose $c=<0>$. Invoking Sage, we define the try-hash function as follows:
\begin{sagecommandline}
sage: import hashlib
sage: def try_hash(s,c):
Expand Down Expand Up @@ -1595,7 +1595,7 @@ \subsection{Try-and-increment hash functions}
$$
\end{example}
\begin{exercise}
Use our definition of the $try\_hash$ algorithm to implement a hash function $H_{TJJ\_13[5]} : \{0,1\}^*\to TJJ\_13(\F_{13})[5]$ that maps binary strings of arbitrary length onto the $5$-torsion group of $TJJ13(\F_{13})$.
Use our definition of the $try\_hash$ algorithm to implement a hash function $H_{TJJ\_13[5]} : \{0,1\}^*\to TJJ\_13(\F_{13})[5]$ that maps binary strings of arbitrary length onto the $5$-torsion group of $TJJ\_13(\F_{13})$.
\end{exercise}
\begin{exercise}
Implement a cryptographic hash function $H_{secp256k1} : \{0,1\}^*\to secp256k1$ that maps binary strings of arbitrary length onto the elliptic curve \curvename{secp256k1}.
Expand Down
Loading