diff --git a/book/book.toml b/book/book.toml index e86492cb..c1e225a2 100644 --- a/book/book.toml +++ b/book/book.toml @@ -6,3 +6,4 @@ src = "src" title = "The Orchard Book" [preprocessor.katex] +macros = "macros.txt" diff --git a/book/macros.txt b/book/macros.txt new file mode 100644 index 00000000..af590a07 --- /dev/null +++ b/book/macros.txt @@ -0,0 +1,35 @@ +# Conventions + +\bconcat:{\mathop{\kern 0.1em||\kern 0.1em}} +\Repr:{\star} + +# Conversions + +\ItoLEBSP:{\mathsf{I2LEBSP}_{#1}} + +# Fields and curves + +\BaseLength:{\ell^\mathsf{#1\vphantom{p}}_{\mathsf{base}}} + +# Key components + +\AuthSignPublic:{\mathsf{ak}} +\NullifierKey:{\mathsf{nk}} +\InViewingKey:{\mathsf{ivk}} +\DiversifiedTransmitBase:{\mathsf{g_d}} +\DiversifiedTransmitBaseRepr:{\mathsf{g\Repr_d}} +\DiversifiedTransmitPublic:{\mathsf{pk_d}} +\DiversifiedTransmitPublicRepr:{\mathsf{pk\Repr_d}} + +# Commitments and hashes + +\SinsemillaHash:{\mathsf{SinsemillaHash}} +\SinsemillaCommit:{\mathsf{SinsemillaCommit}} +\SinsemillaShortCommit:{\mathsf{SinsemillaShortCommit}} +\CommitIvk:{\mathsf{Commit}^{\InViewingKey}} +\NoteCommit:{\mathsf{NoteCommit}} + +# Circuit constraint helper methods + +\BoolCheck:{\texttt{bool\_check}({#1})} +\ShortLookupRangeCheck:{\texttt{short\_lookup\_range\_check}({#1})} diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 728f7ba2..4a637b88 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -22,4 +22,7 @@ - [Fixed-base scalar multiplication](design/circuit/gadgets/ecc/fixed-base-scalar-mul.md) - [Variable-base scalar multiplication](design/circuit/gadgets/ecc/var-base-scalar-mul.md) - [Sinsemilla](design/circuit/gadgets/sinsemilla.md) + - [MerkleCRH](design/circuit/gadgets/sinsemilla/merkle-crh.md) + - [CommitIvk](design/circuit/gadgets/sinsemilla/commit-ivk.md) + - [NoteCommit](design/circuit/gadgets/sinsemilla/note-commit.md) - [Decomposition](design/circuit/gadgets/decomposition.md) diff --git a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md new file mode 100644 index 00000000..3b71d1f8 --- /dev/null +++ b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md @@ -0,0 +1,229 @@ +# $\CommitIvk$ + +## Message decomposition + +$\SinsemillaShortCommit$ is used in the +[$\CommitIvk$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). +The input to $\SinsemillaShortCommit$ is: + +$$\ItoLEBSP{\BaseLength{Orchard}}(\AuthSignPublic) \bconcat \ItoLEBSP{\BaseLength{Orchard}}(\NullifierKey),$$ + +where $\AuthSignPublic$, $\NullifierKey$ are Pallas base field elements, and $\BaseLength{Orchard} = 255.$ + +Sinsemilla operates on multiples of 10 bits, so we start by decomposing the message into +chunks: + +$$ +\begin{align} +\ItoLEBSP{\BaseLength{Orchard}}(\AuthSignPublic) &= a \bconcat b_0 \bconcat b_1 \\ + &= (\text{bits 0..=249 of } \AuthSignPublic) \bconcat + (\text{bits 250..=253 of } \AuthSignPublic) \bconcat + (\text{bit 254 of } \AuthSignPublic) \\ +\ItoLEBSP{\BaseLength{Orchard}}(\NullifierKey) &= b_2 \bconcat c \bconcat d_0 \bconcat d_1 \\ + &= (\text{bits 0..=4 of } \NullifierKey) \bconcat + (\text{bits 5..=244 of } \NullifierKey) \bconcat + (\text{bits 245..=253 of } \NullifierKey) \bconcat + (\text{bit 254 of } \NullifierKey) \\ +\end{align} +$$ + +Then we recompose the chunks into message pieces: + +$$ +\begin{array}{|c|l|} +\hline +\text{Length (bits)} & \text{Piece} \\\hline +250 & a \\ +10 & b = b_0 \bconcat b_1 \bconcat b_2 \\ +240 & c \\ +10 & d = d_0 \bconcat d_1 \\\hline +\end{array} +$$ + +Each message piece is constrained by $\SinsemillaHash$ to its stated length. Additionally, +$\AuthSignPublic$ and $\NullifierKey$ are witnessed as field elements, so we know they are +canonical. However, we need additional constraints to enforce that: + +- The chunks are the correct bit lengths (or else they could overlap in the decompositions + and allow the prover to witness an arbitrary $\SinsemillaShortCommit$ message). +- The chunks contain the canonical decompositions of $\AuthSignPublic$ and $\NullifierKey$ + (or else the prover could witness an input to $\SinsemillaShortCommit$ that is + equivalent to $\AuthSignPublic$ and $\NullifierKey$ but not identical). + +Some of these constraints can be implemented with reusable circuit gadgets. We define a +custom gate controlled by the selector $q_\CommitIvk$ to hold the remaining constraints. + +## Bit length constraints + +Chunks $a$ and $c$ are directly constrained by Sinsemilla. For the remaining chunks, we +use the following constraints: + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline + & \ShortLookupRangeCheck{b_0, 4} \\\hline + & \ShortLookupRangeCheck{b_2, 5} \\\hline + & \ShortLookupRangeCheck{d_0, 9} \\\hline +3 & q_\CommitIvk \cdot \BoolCheck{b_1} = 0 \\\hline +3 & q_\CommitIvk \cdot \BoolCheck{d_1} = 0 \\\hline +\end{array} +$$ + +where $\BoolCheck{x} = x \cdot (1 - x)$ and $\ShortLookupRangeCheck{}$ is a +[short lookup range check](../decomposition.md#short-range-check). + +## Decomposition constraints + +We have now derived or witnessed every subpiece, and range-constrained every subpiece: +- $a$ ($250$ bits) is witnessed and constrained outside the gate; +- $b_0$ ($4$ bits) is witnessed and constrained outside the gate; +- $b_1$ ($1$ bits) is witnessed and boolean-constrained in the gate; +- $b_2$ ($5$ bits) is witnessed and constrained outside the gate; +- $c$ ($240$ bits) is witnessed and constrained outside the gate; +- $d_0$ ($9$ bits) is witnessed and constrained outside the gate; +- $d_1$ ($1$ bits) is witnessed and boolean-constrained in the gate. + +We can now use them to reconstruct both the (chunked) message pieces, and the original +field element inputs: + +$$ +\begin{align} +b &= b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2 \\ +d &= d_0 + 2^9 \cdot d_1 \\ +\AuthSignPublic &= a + 2^{250} \cdot b_0 + 2^{254} \cdot b_1 \\ +\NullifierKey &= b_2 + 2^5 \cdot c + 2^{245} \cdot d_0 + 2^{254} \cdot d_1 \\ +\end{align} +$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +2 & q_\CommitIvk \cdot (b - (b_0 + b_1 \cdot 2^4 + b_2 \cdot 2^5)) = 0 \\\hline +2 & q_\CommitIvk \cdot (d - (d_0 + d_1 \cdot 2^9)) = 0 \\\hline +2 & q_\CommitIvk \cdot (a + b_0 \cdot 2^{250} + b_1 \cdot 2^{254} - \AuthSignPublic) = 0 \\\hline +2 & q_\CommitIvk \cdot (b_2 + c \cdot 2^5 + d_0 \cdot 2^{245} + d_1 \cdot 2^{254} - \NullifierKey) = 0 \\\hline +\end{array} +$$ + +## Canonicity checks + +At this point, we have constrained $\ItoLEBSP{\BaseLength{Orchard}}(\AuthSignPublic)$ and +$\ItoLEBSP{\BaseLength{Orchard}}(\NullifierKey)$ to be 255-bit values, with top bits $b_1$ +and $d_1$ respectively. We have also constrained: + +$$ +\begin{align} +\ItoLEBSP{\BaseLength{Orchard}}(\AuthSignPublic) &= \AuthSignPublic \pmod{q_\mathbb{P}} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\NullifierKey) &= \NullifierKey \pmod{q_\mathbb{P}} \\ +\end{align} +$$ + +where $q_\mathbb{P}$ is the Pallas base field modulus. The remaining constraints will +enforce that these are indeed canonically-encoded field elements, i.e. + +$$ +\begin{align} +\ItoLEBSP{\BaseLength{Orchard}}(\AuthSignPublic) &< q_\mathbb{P} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\NullifierKey) &< q_\mathbb{P} \\ +\end{align} +$$ + +The Pallas base field modulus has the form $q_\mathbb{P} = 2^{254} + t_\mathbb{P}$, where +$$t_\mathbb{P} = \mathtt{0x224698fc094cf91b992d30ed00000001}$$ +is 126 bits. We therefore know that if the top bit is not set, then the remaining bits +will always comprise a canonical encoding of a field element. Thus the canonicity checks +below are enforced if and only if $b_1 = 1$ (for $\AuthSignPublic$) or $d_1 = 1$ (for +$\NullifierKey$). + +> In the constraints below we use a base-$2^{10}$ variant of the method used in libsnark +> (originally from [[SVPBABW2012](https://eprint.iacr.org/2012/598.pdf), Appendix C.1]) for +> range constraints $0 \leq x < t$: +> +> - Let $t'$ be the smallest power of $2^{10}$ greater than $t$. +> - Enforce $0 \leq x < t'$. +> - Let $x' = x + t' - t$. +> - Enforce $0 \leq x' < t'$. + +### $\AuthSignPublic$ with $b_1 = 1 \implies \AuthSignPublic \geq 2^{254}$ + +In these cases, we check that $\textsf{ak}_{0..=253} < t_\mathbb{P}$: + +1. $b_1 = 1 \implies b_0 = 0.$ + + Since $b_1 = 1 \implies \AuthSignPublic_{0..=253} < t_\mathbb{P} < 2^{126},$ we know that + $\AuthSignPublic_{126..=253} = 0,$ and in particular + $$b_0 := \AuthSignPublic_{250..=253} = 0.$$ + +2. $b_1 = 1 \implies 0 \leq a < t_\mathbb{P}.$ + + To check that $a < t_\mathbb{P}$, we use two constraints: + + a) $0 \leq a < 2^{130}$. This is expressed in the custom gate as + $$b_1 \cdot z_{a,13} = 0,$$ + where $z_{a,13}$ is the index-13 running sum output by $\SinsemillaHash(a).$ + + b) $0 \leq a + 2^{130} - t_\mathbb{P} < 2^{130}$. To check this, we decompose + $a' = a + 2^{130} - t_\mathbb{P}$ into thirteen 10-bit words (little-endian) using + a running sum $z_{a'}$, looking up each word in a $10$-bit lookup table. We then + enforce in the custom gate that + $$b_1 \cdot z_{a',13} = 0.$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_\CommitIvk \cdot b_1 \cdot b_0 = 0 \\\hline +3 & q_\CommitIvk \cdot b_1 \cdot z_{a,13} = 0 \\\hline +2 & q_\CommitIvk \cdot (a + 2^{130} - t_\mathbb{P} - a') = 0 \\\hline +3 & q_\CommitIvk \cdot b_1 \cdot z_{a',13} = 0 \\\hline +\end{array} +$$ + +### $\NullifierKey$ with $d_1 = 1 \implies \NullifierKey \geq 2^{254}$ + +In these cases, we check that $\textsf{nk}_{0..=253} < t_\mathbb{P}$: + +1. $d_1 = 1 \implies d_0 = 0.$ + + Since $d_1 = 1 \implies \NullifierKey_{0..=253} < t_\mathbb{P} < 2^{126},$ we know that $\NullifierKey_{126..=253} = 0,$ and in particular $$d_0 := \NullifierKey_{245..=253} = 0.$$ + +2. $d_1 = 1 \implies 0 \leq b_2 + 2^5 \cdot c < t_\mathbb{P}.$ + + To check that $0 \leq b_2 + 2^5 \cdot c < t_\mathbb{P}$, we use two constraints: + + a) $0 \leq b_2 + 2^5 \cdot c < 2^{140}$. $b_2$ is already constrained individually to + be a $5$-bit value. $z_{c,13}$ is the index-13 running sum output by + $\SinsemillaHash(c).$ By constraining $$d_1 \cdot z_{c,13} = 0,$$ we constrain + $b_2 + 2^5 \cdot c < 2^{135} < 2^{140}.$ + + b) $0 \leq b_2 + 2^5 \cdot c + 2^{140} - t_\mathbb{P} < 2^{140}$. To check this, we + decompose ${b_2}c' = b_2 + 2^5 \cdot c + 2^{140} - t_\mathbb{P}$ into fourteen + 10-bit words (little-endian) using a running sum $z_{{b_2}c'}$, looking up each + word in a $10$-bit lookup table. We then enforce in the custom gate that + $$d_1 \cdot z_{{b_2}c',14} = 0.$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_\CommitIvk \cdot d_1 \cdot d_0 = 0 \\\hline +3 & q_\CommitIvk \cdot d_1 \cdot z_{c,13} = 0 \\\hline +2 & q_\CommitIvk \cdot (b_2 + c \cdot 2^5 + 2^{140} - t_\mathbb{P} - {b_2}c') = 0 \\\hline +3 & q_\CommitIvk \cdot d_1 \cdot z_{{b_2}c',14} = 0 \\\hline +\end{array} +$$ + +## Region layout + +The constraints controlled by the $q_\CommitIvk$ selector are arranged across 9 +advice columns, requiring two rows. + +$$ +\begin{array}{|c|c|c|c|c|c|c|c|c|c} + & & & & & & & & & q_\CommitIvk \\\hline +\AuthSignPublic & a & b & b_0 & b_1 & b_2 & z_{a,13} & a' & z_{a',13} & 0 \\\hline +\NullifierKey & c & d & d_0 & d_1 & & z_{c,13} & {b_2}c' & z_{{b_2}c',14} & 1 \\\hline +\end{array} +$$ diff --git a/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md b/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md new file mode 100644 index 00000000..fc8e6a10 --- /dev/null +++ b/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md @@ -0,0 +1,69 @@ +# MerkleCRH + +## Message decomposition +$\mathsf{SinsemillaHash}$ is used in the [$\mathsf{MerkleCRH^{Orchard}}$ hash function](https://zips.z.cash/protocol/protocol.pdf#orchardmerklecrh). The input to $\mathsf{SinsemillaHash}$ is: + +$${l\star} \,||\, {\textsf{left}\star} \,||\, {\textsf{right}\star},$$ + +where: +- ${l\star} = \textsf{I2LEBSP}_{10}(l) = \textsf{I2LEBSP}_{10}(\textsf{MerkleDepth}^\textsf{Orchard} - 1 - \textsf{layer})$, +- ${\textsf{left}\star} = \textsf{I2LEBSP}_{\ell_{\textsf{Merkle}}^{\textsf{Orchard}}}(\textsf{left})$, +- ${\textsf{right}\star} = \textsf{I2LEBSP}_{\ell_{\textsf{Merkle}}^{\textsf{Orchard}}}(\textsf{right})$, + +with $\ell_{\textsf{Merkle}}^{\textsf{Orchard}} = 255.$ $\textsf{left}$ and $\textsf{right}$ are allowed to be non-canonical $255$-bit encodings. + +We break these inputs into the following `MessagePiece`s: + +$$ +\begin{aligned} +a \text{ (250 bits)} &= a_0 \,||\, a_1 \\ + &= {l\star} \,||\, (\text{bits } 0..=239 \text{ of } \textsf{ left }) \\ +b \text{ (20 bits)} &= b_0 \,||\, b_1 \,||\, b_2 \\ + &= (\text{bits } 240..=249 \text{ of } \textsf{left}) \,||\, (\text{bits } 250..=254 \text{ of } \textsf{left}) \,||\, (\text{bits } 0..=4 \text{ of } \textsf{right}) \\ +c \text{ (250 bits)} &= \text{bits } 5..=254 \text{ of } \textsf{right} +\end{aligned} +$$ + +$a,b,c$ are constrained by the $\textsf{SinsemillaHash}$ to be $250$ bits, $20$ bits, and $250$ bits respectively. + +In a custom gate, we check this message decomposition by enforcing the following constraints: + +1. $a_0 = l$ +
+$z_{1,a}$, the index-1 running sum output of $\textsf{SinsemillaHash}(a)$, is copied into the gate. $z_{1,a}$ has been constrained by the $\textsf{SinsemillaHash}$ to be $240$ bits. We recover the subpieces $a_0, a_1$ using $a, z_{1,a}$: +$$ +\begin{aligned} +z_{1,a} &= \frac{a - a_0}{2^{10}}\\ + &= a_1 \\ + \implies a_0 &= a - z_{1,a} \cdot 2^{10}. +\end{aligned} +$$ +$l + 1$ is loaded into a fixed column at each layer of the hash. It is used both as a gate selector, and to fix the value of $l$. We check that $$a_0 = (l + 1) - 1.$$ +> Note: The reason for using $l + 1$ instead of $l$ is that $l = 0$ when $\textsf{layer} = 31$ (hashing two leaves). We cannot have a zero-valued selector, since a constraint gated by a zero-valued selector is never checked. + +2. $b_1 + 2^5 \cdot b_2 = z_{1,b}$ +
+$z_{1,b}$, the index-1 running sum output of $\textsf{SinsemillaHash}(b)$, is copied into the gate. $z_{1,b}$ has been constrained by the $\textsf{SinsemillaHash}$ to be $10$ bits. We witness the subpieces $b_1, b_2$ outside this gate, and constrain them each to be $5$ bits. Inside the gate, we check that $$b_1 + 2^5 \cdot b_2 = z_{1,b}.$$ +We also recover the subpiece $b_0$ using $(b, z_{1,b})$: +$$ +\begin{aligned} +z_{1,b} &= \frac{b - b_{0..=10}}{2^{10}}\\ + \implies b_0 &= b - (z_{1,b} \cdot 2^{10}). +\end{aligned} +$$ + +We have now derived or witnessed every subpiece, and range-constrained every subpiece: +- $a_0$ ($10$ bits), derived as $a_0 = a - 2^{10} \cdot z_{1,a}$; +- $a_1$ ($240$ bits), equal to $z_{1,a}$; +- $b_0$ ($10$ bits), derived as $b_0 = b - 2^{10} \cdot z_{1,b}$; +- $b_1$ ($5$ bits) is witnessed and constrained outside the gate; +- $b_2$ ($5$ bits) is witnessed and constrained outside the gate; +- $b_1 + 2^5 \cdot b_2$ is constrained to equal $z_{1, b}$, +and we use them to reconstruct the original field element inputs: + +3. $\mathsf{left} = a_1 + 2^{240} \cdot b_0 + 2^{254} \cdot b_1$ + +4. $\mathsf{right} = b_2 + 2^5 \cdot c$ + +## Circuit components +The Orchard circuit spans $10$ advice columns while the $\textsf{Sinsemilla}$ chip only uses $5$ advice columns. We distribute the path hashing evenly across two $\textsf{Sinsemilla}$ chips to make better use of the available circuit area. Since the output from the previous layer hash is copied into the next layer hash, we maintain continuity even when moving from one chip to the other. diff --git a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md new file mode 100644 index 00000000..0250c46f --- /dev/null +++ b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md @@ -0,0 +1,451 @@ +# NoteCommit + +## Message decomposition + +$\SinsemillaCommit$ is used in the +[$\NoteCommit$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). +The input to $\SinsemillaCommit$ is: + +$$\DiversifiedTransmitBaseRepr \bconcat + \DiversifiedTransmitPublicRepr \bconcat + \ItoLEBSP{64}(\mathsf{v}) \bconcat + \ItoLEBSP{\BaseLength{Orchard}}(\rho) \bconcat + \ItoLEBSP{\BaseLength{Orchard}}(\psi),$$ + +where: +- $\DiversifiedTransmitBaseRepr, \DiversifiedTransmitPublicRepr$ are representations of + Pallas curve points, with $255$ bits used for the $x$-coordinate and $1$ bit used for + the $y$-coordinate. +- $\rho, \psi$ are Pallas base field elements. +- $\mathsf{v}$ is a $64$-bit value. +- $\BaseLength{Orchard} = 255.$ + +Sinsemilla operates on multiples of 10 bits, so we start by decomposing the message into +chunks: + +$$ +\begin{aligned} +\DiversifiedTransmitBaseRepr &= a \bconcat b_0 \bconcat b_1 \bconcat b_2 \\ + &= (\text{bits 0..=249 of } \mathsf{x(g_d)}) \bconcat + (\text{bits 250..=253 of } \mathsf{x(g_d)}) \bconcat + (\text{bit 254 of } \mathsf{x(g_d)}) \bconcat + (ỹ \text{ bit of } \mathsf{g_d}) \\ +\DiversifiedTransmitPublicRepr &= b_3 \bconcat c \bconcat d_0 \bconcat d_1 \\ + &= (\text{bits 0..=3 of } \mathsf{x(pk_d)}) \bconcat + (\text{bits 4..=253 of } \mathsf{x(pk_d)}) \bconcat + (\text{bit 254 of } \mathsf{x(pk_d)}) \bconcat + (ỹ \text{ bit of } \mathsf{pk_d}) \\ +\ItoLEBSP{64}(v) &= d_2 \bconcat d_3 \bconcat e_0 \\ + &= (\text{bits 0..=7 of } v) \bconcat + (\text{bits 8..=57 of } v) \bconcat + (\text{bits 58..=63 of } v) \\ +\ItoLEBSP{\BaseLength{Orchard}}(\rho) &= e_1 \bconcat f \bconcat g_0 \\ + &= (\text{bits 0..=3 of } \rho) \bconcat + (\text{bits 4..=253 of } \rho) \bconcat + (\text{bit 254 of } \rho) \\ +\ItoLEBSP{\BaseLength{Orchard}}(\psi) &= g_1 \bconcat g_2 \bconcat h_0 \bconcat h_1 \\ + &= (\text{bits 0..=8 of } \psi) \bconcat + (\text{bits 9..=248 of } \psi) \bconcat + (\text{bits 249..=253 of } \psi) \bconcat + (\text{bit 254 of } \psi) \\ +\end{aligned} +$$ + +Then we recompose the chunks into message pieces: + +$$ +\begin{array}{|c|l|} +\hline +\text{Length (bits)} & \text{Piece} \\\hline +250 & a \\ + 10 & b = b_0 \bconcat b_1 \bconcat b_2 \bconcat b_3 \\ +250 & c \\ + 60 & d = d_0 \bconcat d_1 \bconcat d_2 \bconcat d_3 \\ + 10 & e = e_0 \bconcat e_1 \\ +250 & f \\ +250 & g = g_0 \bconcat g_1 \bconcat g_2 \\ + 10 & h = h_0 \bconcat h_1 \bconcat h_2 \\\hline +\end{array} +$$ + +where $h_2$ is 4 zero bits (corresponding to the padding applied by the Sinsemilla +[$\mathsf{pad}$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillahash)). + +Each message piece is constrained by $\SinsemillaHash$ to its stated length. Additionally: +- $\DiversifiedTransmitBase$ and $\DiversifiedTransmitPublic$ are witnessed and checked + to be valid elliptic curve points. +- $\mathsf{v}$ is witnessed as a field element, but its decomposition is sufficient to + constrain it to be a 64-bit value. +- $\rho$ and $\psi$ are witnessed as field elements, so we know they are canonical. + +However, we need additional constraints to enforce that: + +- The chunks are the correct bit lengths (or else they could overlap in the decompositions + and allow the prover to witness an arbitrary $\SinsemillaCommit$ message). +- The chunks contain the canonical decompositions of $\DiversifiedTransmitBase$, + $\DiversifiedTransmitPublic$, $\rho$, and $\psi$ (or else the prover could witness + multiple equivalent inputs to $\SinsemillaCommit$). + +Some of these constraints are implemented with reusable circuit gadgets. We define a +custom gate controlled by a pair of selectors $(q_{\NoteCommit,1}, q_{\NoteCommit,2})$ to +hold the remaining constraints. We will need to witness 40 separate variables in a single +region, so we use two selectors that we activate on adjacent rows, in order to limit the +required rotations to the set `[Rotation::prev(), Rotation::cur(), Rotation::next()]`. + +## Bit length constraints + +Chunks $a$, $c$, and $f$ are directly constrained by Sinsemilla. For the remaining chunks, +we use the following constraints: + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline + & \ShortLookupRangeCheck{b_0, 4} \\\hline + & \ShortLookupRangeCheck{b_3, 4} \\\hline + & \ShortLookupRangeCheck{d_2, 8} \\\hline + & \ShortLookupRangeCheck{e_0, 6} \\\hline + & \ShortLookupRangeCheck{e_1, 4} \\\hline + & \ShortLookupRangeCheck{g_1, 9} \\\hline + & \ShortLookupRangeCheck{h_0, 5} \\\hline +3 & q_{\NoteCommit,1} \cdot \BoolCheck{b_1} = 0 \\\hline +3 & q_{\NoteCommit,1} \cdot \BoolCheck{b_2} = 0 \\\hline +3 & q_{\NoteCommit,1} \cdot \BoolCheck{d_0} = 0 \\\hline +3 & q_{\NoteCommit,1} \cdot \BoolCheck{d_1} = 0 \\\hline +3 & q_{\NoteCommit,1} \cdot \BoolCheck{g_0} = 0 \\\hline +3 & q_{\NoteCommit,1} \cdot \BoolCheck{h_1} = 0 \\\hline + & d_3 := z_{d,1} \\\hline + & g_2 := z_{g,1} \\\hline +\end{array} +$$ + +where: +- $\BoolCheck{x} = x \cdot (1 - x)$. +- $\ShortLookupRangeCheck{}$ is a [short lookup range check](../decomposition.md#short-range-check). +- $z_{d,1}$ is the index-1 running sum output of $\SinsemillaHash(d),$ constrained by the + hash to be 50 bits. +- $z_{g,1}$ is the index-1 running sum output of $\SinsemillaHash(g),$ constrained by the + hash to be 240 bits. +- $d_3$ and $g_2$ are equality-constrained to their respective running sum outputs. + +## Decomposition constraints + +We have now derived or witnessed every subpiece, and range-constrained every subpiece: +- $a$ ($250$ bits) is witnessed and constrained outside the gate; +- $b_0$ ($4$ bits) is witnessed and constrained outside the gate; +- $b_1$ ($1$ bit) is witnessed and boolean-constrained in the gate; +- $b_2$ ($1$ bit) is witnessed and boolean-constrained in the gate; +- $b_3$ ($4$ bits) is witnessed and constrained outside the gate; +- $c$ ($250$ bits) is witnessed and constrained outside the gate; +- $d_0$ ($1$ bit) is witnessed and boolean-constrained in the gate; +- $d_1$ ($1$ bit) is witnessed and boolean-constrained in the gate; +- $d_2$ ($8$ bits) is witnessed and constrained outside the gate; +- $d_3$ ($50$ bits), equal to $z_{d,1}$; +- $e_0$ ($6$ bits) is witnessed and constrained outside the gate; +- $e_1$ ($4$ bit) is witnessed and constrained outside the gate; +- $f$ ($250$ bits) is witnessed and constrained outside the gate; +- $g_0$ ($1$ bit) is witnessed and boolean-constrained in the gate; +- $g_1$ ($9$ bits) is witnessed and constrained outside the gate; +- $g_2$ ($240$ bits), equal to $z_{g,1}$; +- $h_0$ ($5$ bits) is witnessed and constrained outside the gate; +- $h_1$ ($1$ bit) is witnessed and boolean-constrained in the gate; +- $h_2$ ($4$ bit) is a zero term, and can be omitted as the other chunks will not overlap it. + +We can now use them to reconstruct both the (chunked) message pieces, and the original +field element inputs: + +$$ +\begin{align} +b &= b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2 + 2^6 \cdot b_3 \\ +d &= d_0 + 2 \cdot d_1 + 2^2 \cdot d_2 + 2^{10} \cdot d_3 \\ +e &= e_0 + 2^6 \cdot e_1 \\ +g &= g_0 + 2 \cdot g_1 + 2^{10} \cdot g_2 \\ +h &= h_0 + 2^5 \cdot h_1 \\ +\mathsf{x(g_d)} &= a + 2^{250} \cdot b_0 + 2^{254} \cdot b_1 \\ +\mathsf{x(pk_d)} &= b_3 + 2^4 \cdot c + 2^{254} \cdot d_0 \\ +\mathsf{v} &= d_2 + 2^8 \cdot d_3 + 2^{58} \cdot e_0 \\ +\rho &= e_1 + 2^4 \cdot f + 2^{254} \cdot g_0 \\ +\psi &= g_1 + 2^9 \cdot g_2 + 2^{249} \cdot h_0 + 2^{254} \cdot h_1 \\ +\end{align} +$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +2 & q_{\NoteCommit,1} \cdot (b - (b_0 + b_1 \cdot 2^4 + b_2 \cdot 2^5 + b_3 \cdot 2^6)) = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (d - (d_0 + d_1 \cdot 2 + d_2 \cdot 2^2 + d_3 \cdot 2^{10})) = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (e - (e_0 + e_1 \cdot 2^6)) = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (g - (g_0 + g_1 \cdot 2 + g_2 \cdot 2^{10})) = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (h - (h_0 + h_1 \cdot 2^5)) = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (a + b_0 \cdot 2^{250} + b_1 \cdot 2^{254} - \mathsf{x(g_d)}) = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (b_3 + c \cdot 2^4 + d_0 \cdot 2^{254} - \mathsf{x(pk_d)} = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (d_2 + d_3 \cdot 2^8 + e_0 \cdot 2^{58} - \mathsf{v}) = 0 \\\hline +2 & q_{\NoteCommit,2} \cdot (e_1 + f \cdot 2^4 + g_0 \cdot 2^{254} - \rho) = 0 \\\hline +2 & q_{\NoteCommit,2} \cdot (g_1 + g_2 \cdot 2^9 + h_0 \cdot 2^{249} + h_1 \cdot 2^{254} - \psi) = 0 \\\hline +\end{array} +$$ + + +Note that only the $ỹ$ LSB of the $y$-coordinates $\mathsf{y(g_d), y(pk_d)}$ was input to the hash, while the other bits of the $y$-coordinate were unused. However, we must still check that the witnessed $ỹ$ bit matches the original point's $y$-coordinate. The checks for $\mathsf{y(g_d), y(pk_d)}$ will follow the same format. For each $y$-coordinate, we witness: + +$$ +\begin{align} +y &= \textsf{LSB} \bconcat k_0 \bconcat k_1 \bconcat k_2 \bconcat k_3\\ + &= \textsf{LSB} + \bconcat \text{ (bits $1..=9$ of $y$) } + \bconcat \text{ (bits $10..=249$ of $y$) } + \bconcat \text{ (bits $250..=253$ of $y$) } + \bconcat \text{ (bit $254$ of $y$) }, +\end{align} +$$ + +where $\textsf{LSB}$ is $b_2$ for $\mathsf{y(g_d)}$, and $d_1$ for $\mathsf{y(pk_d)}$. Let $$j = \textsf{LSB} + 2 \cdot k_0 + 10 \cdot k_1.$$ We decompose $j$ to be $250$ bits using $25$ [ten-bit lookups](../decomposition.md#lookup-decomposition). + +Recall that $b_2 = ỹ(g_d)$ and $d_1 = ỹ(pk_d)$ were pieces input to the Sinsemilla hash and have already been boolean-constrained. To constrain the remaining chunks, we use the following constraints: + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline + & \ShortLookupRangeCheck{k_0, 9} \\\hline + & \ShortLookupRangeCheck{k_2, 4} \\\hline +3 & q_{\NoteCommit,3} \cdot \BoolCheck{k_3} = 0 \\\hline + & k_1 := z_{j,1} \\\hline +\end{array} +$$ + +Then, to check that the decomposition was correct: +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +2 & q_{\NoteCommit,3} \cdot \left(j - (\textsf{LSB} + 2 \cdot k_0 + 10 \cdot k_1) \right) = 0 \\\hline +2 & q_{\NoteCommit,3} \cdot \left(y - (j + 2^{250} \cdot k_2 + 2^{254} \cdot k_3) \right) = 0 \\\hline +\end{array} +$$ + +## Canonicity checks + +At this point, we have constrained $\ItoLEBSP{\BaseLength{Orchard}}(\mathsf{x(g_d)})$, +$\ItoLEBSP{\BaseLength{Orchard}}(\mathsf{x(pk_d)})$, +$\ItoLEBSP{\BaseLength{Orchard}}(\rho)$, and $\ItoLEBSP{\BaseLength{Orchard}}(\psi)$ to be +255-bit values, with top bits $b_1$, $d_0$, $g_0$, and $h_1$ respectively. We have also +constrained: + +$$ +\begin{align} +\ItoLEBSP{\BaseLength{Orchard}}(\mathsf{x(g_d)}) &= \mathsf{x(g_d)} \pmod{q_\mathbb{P}} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\mathsf{x(pk_d)}) &= \mathsf{x(pk_d)} \pmod{q_\mathbb{P}} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\rho) &= \rho \pmod{q_\mathbb{P}} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\psi) &= \psi \pmod{q_\mathbb{P}} \\ +\end{align} +$$ + +where $q_\mathbb{P}$ is the Pallas base field modulus. The remaining constraints will +enforce that these are indeed canonically-encoded field elements, i.e. + +$$ +\begin{align} +\ItoLEBSP{\BaseLength{Orchard}}(\mathsf{x(g_d)}) &< q_\mathbb{P} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\mathsf{x(pk_d)}) &< q_\mathbb{P} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\rho) &< q_\mathbb{P} \\ +\ItoLEBSP{\BaseLength{Orchard}}(\psi) &< q_\mathbb{P} \\ +\end{align} +$$ + +The Pallas base field modulus has the form $q_\mathbb{P} = 2^{254} + t_\mathbb{P}$, where +$$t_\mathbb{P} = \mathtt{0x224698fc094cf91b992d30ed00000001}$$ +is 126 bits. We therefore know that if the top bit is not set, then the remaining bits +will always comprise a canonical encoding of a field element. Thus the canonicity checks +below are enforced if and only if the corresponding top bit is set to 1. + +> In the constraints below we use a base-$2^{10}$ variant of the method used in libsnark +> (originally from [[SVPBABW2012](https://eprint.iacr.org/2012/598.pdf), Appendix C.1]) for +> range constraints $0 \leq x < t$: +> +> - Let $t'$ be the smallest power of $2^{10}$ greater than $t$. +> - Enforce $0 \leq x < t'$. +> - Let $x' = x + t' - t$. +> - Enforce $0 \leq x' < t'$. + +### $\mathsf{x(g_d)}$ with $b_1 = 1 \implies \mathsf{x(g_d)} \geq 2^{254}$ + +In these cases, we check that $\mathsf{x(g_d)}_{0..=253} < t_\mathbb{P}$: + +1. $b_1 = 1 \implies b_0 = 0.$ + + Since $b_1 = 1 \implies \mathsf{x(g_d)}_{0..=253} < t_\mathbb{P} < 2^{126},$ we know that + $\mathsf{x(g_d)}_{126..=253} = 0,$ and in particular + $$b_0 := \mathsf{x(g_d)}_{250..=253} = 0.$$ + +2. $b_1 = 1 \implies 0 \leq a < t_\mathbb{P}.$ + + To check that $a < t_\mathbb{P}$, we use two constraints: + + a) $0 \leq a < 2^{130}$. This is expressed in the custom gate as + $$b_1 \cdot z_{a,13} = 0,$$ + where $z_{a,13}$ is the index-13 running sum output by $\SinsemillaHash(a).$ + + b) $0 \leq a + 2^{130} - t_\mathbb{P} < 2^{130}$. To check this, we decompose + $a' = a + 2^{130} - t_\mathbb{P}$ into thirteen 10-bit words (little-endian) using + a running sum $z_{a'}$, looking up each word in a $10$-bit lookup table. We then + enforce in the custom gate that + $$b_1 \cdot z_{a',13} = 0.$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_{\NoteCommit,2} \cdot b_1 \cdot b_0 = 0 \\\hline +3 & q_{\NoteCommit,2} \cdot b_1 \cdot z_{a,13} = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (a + 2^{130} - t_\mathbb{P} - a') = 0 \\\hline +3 & q_{\NoteCommit,2} \cdot b_1 \cdot z_{a',13} = 0 \\\hline +\end{array} +$$ + +### $\mathsf{y(g_d)}$ with $k_3 = 1 \implies \mathsf{y(g_d)} \geq 2^{254}$ + +In these cases, we check that $\mathsf{y(g_d)}_{0..=253} < t_\mathbb{P}$: + +1. $k_3 = 1 \implies k_2 = 0.$ + + Since $k_3 = 1 \implies \mathsf{y(g_d)}_{0..=253} < t_\mathbb{P} < 2^{126},$ we know that + $\mathsf{y(g_d)}_{126..=253} = 0,$ and in particular + $$k_2 := \mathsf{y(g_d)}_{250..=253} = 0.$$ + +2. $k_3 = 1 \implies 0 \leq j < t_\mathbb{P}.$ + + To check that $j < t_\mathbb{P}$, we use two constraints: + + a) $0 \leq j < 2^{130}$. This is expressed in the custom gate as + $$k_3 \cdot z_{j,13} = 0,$$ + where $z_{j,13}$ is the index-13 running sum output by the $10$-bit lookup decomposition of $j$. + + b) $0 \leq j + 2^{130} - t_\mathbb{P} < 2^{130}$. To check this, we decompose + $j' = j + 2^{130} - t_\mathbb{P}$ into thirteen 10-bit words (little-endian) using + a running sum $z_{j'}$, looking up each word in a $10$-bit lookup table. We then + enforce in the custom gate that + $$k_3 \cdot z_{j',13} = 0.$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_{\NoteCommit,3} \cdot k_3 \cdot k_2 = 0 \\\hline +3 & q_{\NoteCommit,3} \cdot k_3 \cdot z_{j,13} = 0 \\\hline +2 & q_{\NoteCommit,3} \cdot (j + 2^{130} - t_\mathbb{P} - j') = 0 \\\hline +3 & q_{\NoteCommit,3} \cdot k_3 \cdot z_{j',13} = 0 \\\hline +\end{array} +$$ + +### $\mathsf{x(pk_d)}$ with $d_0 = 1 \implies \mathsf{x(pk_d)} \geq 2^{254}$ + +In these cases, we check that $\mathsf{x(pk_d)}_{0..=253} < t_\mathbb{P}$: + +1. $d_0 = 1 \implies 0 \leq b_3 + 2^{4} \cdot c < t_\mathbb{P}.$ + + To check that $0 \leq b_3 + 2^{4} \cdot c < t_\mathbb{P},$ we use two constraints: + + a) $0 \leq b_3 + 2^{4} \cdot c < 2^{140}.$ $b_3$ is already constrained individually + to be a $4$-bit value. $z_{c,13}$ is the index-13 running sum output by + $\SinsemillaHash(c).$ By constraining $$d_0 \cdot z_{c,13} = 0,$$ we constrain + $b_3 + 2^4 \cdot c < 2^{134} < 2^{140}.$ + + b) $0 \leq b_3 + 2^{4} \cdot c + 2^{140} - t_\mathbb{P} < 2^{140}$. To check this, we + decompose ${b_3}c' = b_3 + 2^{4} \cdot c + 2^{140} - t_\mathbb{P}$ into fourteen + 10-bit words (little-endian) using a running sum $z_{{b_3}c'}$, looking up each + word in a $10$-bit lookup table. We then enforce in the custom gate that + $$d_0 \cdot z_{{b_3}c',14} = 0.$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_{\NoteCommit,2} \cdot d_0 \cdot z_{c,13} = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (b_3 + c \cdot 2^4 + 2^{140} - t_\mathbb{P} - {b_3}c') = 0 \\\hline +3 & q_{\NoteCommit,2} \cdot d_0 \cdot z_{{b_3}c',14} = 0 \\\hline +\end{array} +$$ + +### $\mathsf{y(pk_d)}$ +This can be checked in exactly the same way as $\mathsf{y(g_d)}$, with $b_2$ replaced by $d_1$. + +### $\rho$ with $g_0 = 1 \implies \rho \geq 2^{254}$ + +In these cases, we check that $\rho_{0..=253} < t_\mathbb{P}$: + +1. $g_0 = 1 \implies 0 \leq e_1 + 2^{4} \cdot f < t_\mathbb{P}.$ + + To check that $0 \leq e_1 + 2^{4} \cdot f < t_\mathbb{P},$ we use two constraints: + + a) $0 \leq e_1 + 2^{4} \cdot f < 2^{140}.$ $e_1$ is already constrained individually + to be a $4$-bit value. $z_{f,13}$ is the index-13 running sum output by + $\SinsemillaHash(f).$ By constraining $$g_0 \cdot z_{f,13} = 0,$$ we constrain + $e_1 + 2^4 \cdot f < 2^{134} < 2^{140}.$ + + b) $0 \leq e_1 + 2^{4} \cdot f + 2^{140} - t_\mathbb{P} < 2^{140}$. To check this, we + decompose ${e_1}f' = e_1 + 2^{4} \cdot f + 2^{140} - t_\mathbb{P}$ into fourteen + 10-bit words (little-endian) using a running sum $z_{{e_1}f'}$, looking up each + word in a $10$-bit lookup table. We then enforce in the custom gate that + $$g_0 \cdot z_{{e_1}f',14} = 0.$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_{\NoteCommit,2} \cdot g_0 \cdot z_{f,13} = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (e_1 + f \cdot 2^4 + 2^{140} - t_\mathbb{P} - {e_1}f') = 0 \\\hline +3 & q_{\NoteCommit,2} \cdot g_0 \cdot z_{{e_1}f',14} = 0 \\\hline +\end{array} +$$ + +### $\psi$ with $h_1 = 1 \implies \psi \geq 2^{254}$ + +In these cases, we check that $\psi_{0..=253} < t_\mathbb{P}$: + +1. $h_1 = 1 \implies h_0 = 0.$ + + Since $h_1 = 1 \implies \psi_{0..=253} < t_\mathbb{P} < 2^{126},$ we know that $\psi_{126..=253} = 0,$ + and in particular $h_0 := \psi_{249..=253} = 0.$ + +2. $h_1 = 1 \implies 0 \leq g_1 + 2^{9} \cdot g_2 < t_\mathbb{P}.$ + + To check that $0 \leq g_1 + 2^{9} \cdot g_2 < t_\mathbb{P},$ we use two constraints: + + a) $0 \leq g_1 + 2^{9} \cdot g_2 < 2^{140}.$ $g_1$ is already constrained individually + to be a $9$-bit value. $z_{g,13}$ is the index-13 running sum output by + $\SinsemillaHash(g).$ By constraining $$h_1 \cdot z_{g,13} = 0,$$ we constrain + $g_1 + 2^9 \cdot g_2 < 2^{129} < 2^{130}.$ + + b) $0 \leq g_1 + 2^{9} \cdot g_2 + 2^{130} - t_\mathbb{P} < 2^{130}$. To check this, + we decompose ${g_1}{g_2}' = g_1 + 2^{9} \cdot g_2 + 2^{130} - t_\mathbb{P}$ into + thirteen 10-bit words (little-endian) using a running sum $z_{{g_1}{g_2}'}$, + looking up each word in a $10$-bit lookup table. We then enforce in the custom gate + that $$h_1 \cdot z_{{g_1}{g_2}',13} = 0.$$ + +$$ +\begin{array}{|c|l|} +\hline +\text{Degree} & \text{Constraint} \\\hline +3 & q_{\NoteCommit,2} \cdot h_1 \cdot h_0 = 0 \\\hline +3 & q_{\NoteCommit,2} \cdot h_1 \cdot z_{g,13} = 0 \\\hline +2 & q_{\NoteCommit,1} \cdot (g_1 + g_2 \cdot 2^9 + 2^{130} - t_\mathbb{P} - {g_1}{g_2}') = 0 \\\hline +3 & q_{\NoteCommit,2} \cdot g_0 \cdot z_{{g_1}{g_2}',14} = 0 \\\hline +\end{array} +$$ + +## Region layout + +The constraints controlled by the $(q_{\NoteCommit,1}, q_{\NoteCommit,2})$ selectors are +arranged in a single region across 10 advice columns, requiring four rows. + +$$ +\begin{array}{|c|c|c|c|c|c|c|c|c|c|cc} + & & & & & & & & & & q_{\NoteCommit,1} & q_{\NoteCommit,2} \\\hline +a' & {b_3}c' & {e_1}f' & {g_1}{g_2}' & a & b & b_2 & b_3 & c & d & 0 & 0 \\\hline +d_1 & d_2 & z_{d,1} & e & e_0 & e_1 & f & g & g_1 & h & 1 & 0 \\\hline +h_0 & h_1 & x(g_d) & x(pk_d) & v & b_0 & b_1 & d_0 & g_0 & z_{g,1} & 0 & 1 \\\hline +z_{a',13} & z_{{b_3}c',14} & z_{{e_1}f',14} & z_{{g_1}{g_2}',14} & z_{a,13} & z_{c,13} & z_{f,13} & z_{g,13} & \psi & \rho & 0 & 0 \\\hline +\end{array} +$$