diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 40545a9578..c7268e1cd3 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -35,11 +35,14 @@ - [Incomplete and complete addition](design/gadgets/ecc/addition.md) - [Fixed-base scalar multiplication](design/gadgets/ecc/fixed-base-scalar-mul.md) - [Variable-base scalar multiplication](design/gadgets/ecc/var-base-scalar-mul.md) + - [Variable-base sign scalar multiplication](design/gadgets/ecc/var-base-sign-scalar-mul.md) - [Sinsemilla](design/gadgets/sinsemilla.md) - [MerkleCRH](design/gadgets/sinsemilla/merkle-crh.md) - [Decomposition](design/gadgets/decomposition.md) + - [Optimization for 4/5 bits range check](design/gadgets/decomposition/optimization4_5bits.md) - [SHA-256](design/gadgets/sha256.md) - [16-bit table chip](design/gadgets/sha256/table16.md) + - [Swap and Multiplexer](design/gadgets/swap_multiplexer.md) - [Background Material](background.md) - [Fields](background/fields.md) - [Polynomials](background/polynomials.md) diff --git a/book/src/design/gadgets/decomposition/optimization4_5bits.md b/book/src/design/gadgets/decomposition/optimization4_5bits.md new file mode 100644 index 0000000000..1716157234 --- /dev/null +++ b/book/src/design/gadgets/decomposition/optimization4_5bits.md @@ -0,0 +1,85 @@ +# Optimization for 4/5 bits range checks + +In the OrchardZSA circuit, we frequently perform range checks on 4, 5 and 10 bits. +While 10-bit range checks are already efficient, as they are executed with a single lookup, +we aim to optmize the range checks on 4 and 5 bits to enhance the overall circuit performance. +To achieve this, we would like to keep **one** lookup table for performance concerns. +Thus, we propose a slight modification to the lookup table. +Additionally, we need to update the [combined lookup expression](../decomposition.md#combined-lookup-expression) +to incorporate this optimization. + +## Lookup table + +Previously, the lookup table used in the Orchard circuit had the following structure: + +$$ +\begin{array}{|c|c|c|} +\hline +table\_idx & table\_x & table\_y \\\hline +\hline + 0 & X(S[0]) & Y(S[0]) \\\hline + 1 & X(S[1]) & Y(S[1]) \\\hline + 2 & X(S[2]) & Y(S[2]) \\\hline + \vdots & \vdots & \vdots \\\hline + 2^{10}-1 & X(S[2^{10}-1]) & Y(S[2^{10}-1]) \\\hline +\end{array} +$$ + +To check that a field element $v$ is a 10-bit value, we check that +$v$ belongs to the first column of the lookup table called $table\_idx$. + +The $table\_x$ and $table\_y$ columns are used to efficiently evaluate +[Sinsemilla hash](../sinsemilla.md#generator-lookup-table). + +To efficiently perform 4- and 5-bit range checks, we propose extending this table +by adding new rows and an additional column. +The new column will specify the type of range check that can be performed +with the corresponding row (4, 5 or 10 bits). + +$$ +\begin{array}{|c|c|c|c|} +\hline +table\_idx & table\_x & table\_y & table\_range\_check \\\hline +\hline + 0 & X(S[0]) & Y(S[0]) & 0 \\\hline + 1 & X(S[1]) & Y(S[1]) & 0 \\\hline + 2 & X(S[2]) & Y(S[2]) & 0 \\\hline + \vdots & \vdots & \vdots & \vdots \\\hline + 2^{10}-1 & X(S[2^{10}-1]) & Y(S[2^{10}-1]) & 0 \\\hline + 0 & X(S[0]) & Y(S[0]) & 4 \\\hline + 1 & X(S[1]) & Y(S[1]) & 4 \\\hline + 2 & X(S[2]) & Y(S[2]) & 4 \\\hline + \vdots & \vdots & \vdots & \vdots \\\hline + 2^4-1 & X(S[2^4-1]) & Y(S[2^4-1]) & 4 \\\hline + 0 & X(S[0]) & Y(S[0]) & 5 \\\hline + 1 & X(S[1]) & Y(S[1]) & 5 \\\hline + 2 & X(S[2]) & Y(S[2]) & 5 \\\hline + \vdots & \vdots & \vdots & \vdots \\\hline + 2^5-1 & X(S[2^5-1]) & Y(S[2^5-1]) & 5 \\\hline +\end{array} +$$ + +To verify that a field element $v$ is a 4-bit value (resp. a 5-bit value), +we check whether $(v, 4)$ (resp. $(v, 5)$) is present in the table defined by the columns $(table\_idx, table\_range\_check)$. + +## Combined lookup expression + +The [combined lookup expression](../decomposition.md#combined-lookup-expression) +must be updated to incorporate the new column and take advantage of the optimization +for 4-bit and 5-bit range checks. + +We aim to verify that $(value, tag)$ belongs to the table defined by the columns $(table\_idx, table\_range\_check)$ in our lookup table where +$$\begin{cases} value = q_\mathit{lookup} \cdot \left( (1 - q_\mathit{range\_check}) \left(q_\mathit{running} \cdot (z_i - 2^K \cdot z_{i+1}) + (1 - q_\mathit{running}) \cdot \textsf{word} \right) + q_\mathit{range\_check} \cdot z_i \right) \\ +tag = q_\mathit{lookup} \cdot q_\mathit{range\_check} \cdot num\_bits \end{cases}$$ +with +$ q_\mathit{range\_check} = \begin{cases} +1 \text{ for 4 or 5-bit range checks}\\ +0 \text{ otherwise} +\end{cases}$ +and +$num\_bits = \begin{cases} +4 \text{ for 4-bit range checks}\\ +5 \text{ for 5-bit range checks}\\ +0 \text{ otherwise} +\end{cases}$ + diff --git a/book/src/design/gadgets/ecc.md b/book/src/design/gadgets/ecc.md index e1025ee98f..4c131d145c 100644 --- a/book/src/design/gadgets/ecc.md +++ b/book/src/design/gadgets/ecc.md @@ -25,6 +25,7 @@ The following table shows how columns are used by the gates for various chip sub - $MVI$ - variable-base scalar multiplication, incomplete rounds. - $MVC$ - variable-base scalar multiplication, complete rounds. - $MVO$ - variable-base scalar multiplication, overflow check. +- $MVS$ - variable-base sign scalar multiplication. $$ \begin{array}{|c||c|c|c|c|c|c|c|c|c|c|} @@ -46,5 +47,7 @@ MVI & x_p & y_p & \lambda_2^{lo} & x_A^{hi} & \lambda_1^{hi} & \lambda_2^{hi} & \hline MVC & x_p & y_p & x_q & y_q & \lambda & \alpha & \beta & \gamma & \delta & z^{complete} \\\hline & & & x_r & y_r \\\hline +\hline +MVS & & signed\_y & & y & \text{window} & u \\\hline \end{array} $$ diff --git a/book/src/design/gadgets/ecc/var-base-sign-scalar-mul.md b/book/src/design/gadgets/ecc/var-base-sign-scalar-mul.md new file mode 100644 index 0000000000..6d974cdd6d --- /dev/null +++ b/book/src/design/gadgets/ecc/var-base-sign-scalar-mul.md @@ -0,0 +1,57 @@ +# Variable-base sign scalar multiplication + +In the OrchardZSA circuit, we need to evaluate $[\mathsf{v}] \mathsf{AssetBase}$ +where $\mathsf{v} = \mathsf{v^{old}} - \mathsf{v^{new}} = s \cdot m$ with $m \in [0, 2^{64})$ and $s \in \{-1, 1\}$. + +We will evaluate it in three steps: + +1. Check that $m$ is a 64-bit unsigned integer using the [decomposition](../decomposition.md) gadget + with $W = 6, K = 10$ and checking that the last window is a 4-bit value. +2. Evaluate $comm = [m] \mathsf{AssetBase}$ by using + a [variable-base long scalar multiplication](./var-base-scalar-mul.md). +3. Evaluate $[\mathsf{v}] \mathsf{AssetBase} = [s] comm$ by using a variable-base sign scalar multiplication. + +## Variable-base sign scalar multiplication gate + +We would like to evaluate $[s] comm$ where $s \in \{-1, 1\}$. + +To do that, we will reuse the sign mul gate with the $q_\texttt{mul_fixed_short}$ selector +from the [fixed-base short signed scalar multiplication](./fixed-base-scalar-mul.md#short-signed-scalar) +gadget with $u=0$ for the last window. + +### Layout + +The layout of the variable-base sign scalar multiplication is: + +$$ +\begin{array}{|c|c|c|c|c|} +\hline +y_P & y_{QR} & u & \text{window} & q_\texttt{mul_fixed_short} \\\hline +signed\_y & y & 0 & s & 1 \\\hline +\end{array} +$$ + +where $y$ is equal to the $y$-coordinate of the point $comm$ and +$signed\_y = s \cdot y = \begin{cases} +y \text{ if } s = 1 \\ +-y \text{ if } s = -1 +\end{cases}$. + +### Constraints + +$$ +\begin{array}{|c|l|l|} +\hline +\text{Degree} & \text{Constraint} & \text{Comment} \\\hline +3 & q_\texttt{mul_fixed_short} \cdot u \cdot (1-u) = 0 & \text{The last window must be a single bit.}\\\hline +3 & q_\texttt{mul_fixed_short} \cdot \left(signed\_y - y\right) \cdot \left(signed\_y + y\right) = 0 & \text{$signed\_y$ is equal to $y$ or $-y$.}\\\hline +3 & q_\texttt{mul_fixed_short} \cdot \left(s^2 - 1\right) = 0 & \text{The sign must be $1$ or $-1$.}\\\hline +3 & q_\texttt{mul_fixed_short} \cdot \left(s \cdot signed\_y - y\right) = 0 & \text{The correct sign is witnessed.}\\\hline +\end{array} +$$ + +The first constraint is not necessary here, but we keep it to not create a new gate. + +Finally, we could create the point $[s] comm$ such that +- its $x$-coordinate is equal to the $x$-coordinate of the point $comm$, and +- its $y$-coordinate is equal to $signed\_y$. diff --git a/book/src/design/gadgets/sinsemilla.md b/book/src/design/gadgets/sinsemilla.md index b5fee9fc46..b2af4f2b28 100644 --- a/book/src/design/gadgets/sinsemilla.md +++ b/book/src/design/gadgets/sinsemilla.md @@ -194,6 +194,11 @@ $$ $$ ### Layout +We will introduce two different layouts to evaluate Sinsemilla hash. +1. The first one supports Sinsemilla hash evaluations from **public** point $Q$ and is used in Orchard protocol. +2. The second one supports Sinsemilla hash evaluations from **public** and **private** point $Q$ and is used in OrchardZSA protocol. + +**Layout for Sinsemilla hash evaluation from public point only** $$ \begin{array}{|c|c|c|c|c|c|c|c|c|c|} \hline @@ -214,6 +219,33 @@ $$ $x_Q$, $z_0$, $z'_0$, etc. are copied in using equality constraints. +**Layout for Sinsemilla hash evaluation from public/private point** +$$ +\begin{array}{|c|c|c|c|c|c|c|c|c|} +\hline +\text{Step} & x_A & x_P & bits & \lambda_1 & \lambda_2 & q_{S1} & q_{S2} & q_{S4} \\\hline + & & y_Q & & & & 0 & 0 & 0 \\\hline + 0 & x_Q & x_{P[m_1]} & z_0 & \lambda_{1,0} & \lambda_{2,0} & 1 & 1 & 1 \\\hline + 1 & x_{A,1} & x_{P[m_2]} & z_1 & \lambda_{1,1} & \lambda_{2,1} & 1 & 1 & 0 \\\hline + 2 & x_{A,2} & x_{P[m_3]} & z_2 & \lambda_{1,2} & \lambda_{2,2} & 1 & 1 & 0 \\\hline + \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & 1 & 1 & 0 \\\hline + n-1 & x_{A,n-1} & x_{P[m_n]} & z_{n-1} & \lambda_{1,n-1} & \lambda_{2,n-1} & 1 & 0 & 0 \\\hline + 0' & x'_{A,0} & x_{P[m'_1]} & z'_0 & \lambda'_{1,0} & \lambda'_{2,0} & 1 & 1 & 0 \\\hline + 1' & x'_{A,1} & x_{P[m'_2]} & z'_1 & \lambda'_{1,1} & \lambda'_{2,1} & 1 & 1 & 0 \\\hline + 2' & x'_{A,2} & x_{P[m'_3]} & z'_2 & \lambda'_{1,2} & \lambda'_{2,2} & 1 & 1 & 0 \\\hline + \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & 1 & 1 & 0 \\\hline + n-1' & x'_{A,n-1} & x_{P[m'_n]} & z'_{n-1} & \lambda'_{1,n-1} & \lambda'_{2,n-1} & 1 & 2 & 0 \\\hline + n' & x'_{A,n} & & & y_{A,n} & & 0 & 0 & 0 \\\hline +\end{array} +$$ + +$x_Q$, $y_Q$, $z_0$, $z'_0$, etc. are copied in using equality constraints. + +For both layouts, the constraint linked to the $q_{S4}$ selector is +$q_{S4} \cdot (2 \cdot y_Q - Y_{A,0}) = 0$. +The value of $y_Q$ will be taken from the $\textsf{fixed_y_Q}$ column for the first layout +and from the $x_P$ column for the second layout. + ### Optimized Sinsemilla gate $$ \begin{array}{lrcl} diff --git a/book/src/design/gadgets/swap_multiplexer.md b/book/src/design/gadgets/swap_multiplexer.md new file mode 100644 index 0000000000..17a472957a --- /dev/null +++ b/book/src/design/gadgets/swap_multiplexer.md @@ -0,0 +1,67 @@ +# Swap and Multiplexer + +Swap gates are utilized to verify the Merkle path of commitment notes. +Multiplixer are utilized in OrchardZSA to evaluate note and value commitments +based on the transaction type (ZSA or native transaction). + +## Swap + +Given an input pair of field elements $(a,b)$ and a boolean value $swap$, +we would like to return +- $(a, b)$ if $swap = 0$, and +- $(b, a)$ if $swap = 1$. + +### Layout + +Let $(a_s, b_s) = SWAP(a, b, swap) = \begin{cases} +(a, b) \text{ if } swap = 0 \\ +(b, a) \text{ if } swap = 1 +\end{cases}$. + +We set all values $a_s$, $b_s$, $a$, $b$ and $swap$ on the same row in the layout. + +$$ +\begin{array}{|c|c|c|c|c|c|} +\hline +a_0 & a_1 & a_2 & a_3 & a_4 & q_\texttt{swap} \\\hline +a & b & a_s & b_s & swap & 1 \\\hline +\end{array} +$$ + +### Constraints + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_\texttt{swap} \cdot \BoolCheck{swap} = 0 \\\hline +3 & q_\texttt{swap} \cdot (a_s - \Ternary{swap}{b}{a}) = 0 \\\hline +3 & q_\texttt{swap} \cdot (b_s - \Ternary{swap}{a}{b}) = 0 \\\hline +\end{array} +$$ + +where $\Ternary{swap}{x}{y} = swap \cdot x + (1 - swap) y$. + +## Multiplexer + +Given two curve points $(x_0, y_0)$ and $(x_1, y_1)$ and a boolean value $choice$, +we would like to return +- $(x_0, y_0)$ if $choice=0$, and +- $(x_1, y_1)$ if $choice=1$. + +To perform this $MUX$ operation, we will call twice the $SWAP$ gates once for each coordinate. +Let $(x, y) = MUX((x_0, y_0), (x_1, y_1), choice)$. +We have +$$x=SWAP(x_0, x_1, choice)[0]$$ +$$y=SWAP(y_0, y_1, choice)[0]$$ + +### Layout + +$$ +\begin{array}{|c|c|c|c|c|c|} +\hline +a_0 & a_1 & a_2 & a_3 & a_4 & q_\texttt{swap} \\\hline +x_0 & x_1 & Swap(x_0, x_1, choice)[0] & Swap(x_0, x_1, choice)[1] & choice & 1 \\\hline +y_0 & y_1 & Swap(y_0, y_1, choice)[0] & Swap(y_0, y_1, choice)[1] & choice & 1 \\\hline +\end{array} +$$