From 9708e296c8caa30640416ced165544851fd87a5f Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Mon, 12 Jul 2021 20:58:12 +0100 Subject: [PATCH 01/12] [book] Document Merkle chip layout and message decomposition. --- book/src/SUMMARY.md | 2 + .../circuit/gadgets/sinsemilla/commit_ivk.md | 1 + .../circuit/gadgets/sinsemilla/merkle-crh.md | 69 +++++++++++++++++++ .../circuit/gadgets/sinsemilla/note_commit.md | 1 + 4 files changed, 73 insertions(+) create mode 100644 book/src/design/circuit/gadgets/sinsemilla/commit_ivk.md create mode 100644 book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md create mode 100644 book/src/design/circuit/gadgets/sinsemilla/note_commit.md diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 728f7ba2..9adf58e9 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -22,4 +22,6 @@ - [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) + - [Lookup Range Check](design/circuit/gadgets/lookup_range_check.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..30404ce4 --- /dev/null +++ b/book/src/design/circuit/gadgets/sinsemilla/commit_ivk.md @@ -0,0 +1 @@ +TODO \ No newline at end of file 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..7b0d7b0c --- /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})$, + +where $\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_{\star}$ +
+$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..=10}}{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. \ No newline at end of file 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..30404ce4 --- /dev/null +++ b/book/src/design/circuit/gadgets/sinsemilla/note_commit.md @@ -0,0 +1 @@ +TODO \ No newline at end of file From 2846593937a3f195232658d274caa8cc749c4fe3 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Mon, 12 Jul 2021 20:59:02 +0100 Subject: [PATCH 02/12] [book] Document CommitIvk message decomposition & canonicity checks --- book/src/SUMMARY.md | 1 + .../circuit/gadgets/sinsemilla/commit-ivk.md | 76 +++++++++++++++++++ .../circuit/gadgets/sinsemilla/commit_ivk.md | 1 - 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md delete mode 100644 book/src/design/circuit/gadgets/sinsemilla/commit_ivk.md diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 9adf58e9..55efc260 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -23,5 +23,6 @@ - [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) - [Lookup Range Check](design/circuit/gadgets/lookup_range_check.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..3cd56e9d --- /dev/null +++ b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md @@ -0,0 +1,76 @@ +# CommitIvk + +## Message decomposition +$\mathsf{SinsemillaShortCommit}$ is used in the [$\mathsf{CommitIvk}$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). The input to $\mathsf{SinsemillaShortCommit}$ is: + +$$\mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(ak) || \mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(nk),$$ + +where $\mathsf{ak, nk}$ are Pallas base field elements, and $\ell_{\textsf{base}}^{\textsf{Orchard}} = 255.$ + +We break these inputs into the following `MessagePiece`s: + +$$ +\begin{aligned} +a \text{ (250 bits)} &= \text{bits } 0..=249 \text{ of } \mathsf{ak} \\ +b \text{ (10 bits)} &= b_0||b_1||b_2 \\ + &= (\text{bits } 250..=253 \text{ of } \mathsf{ak}) || (\text{bit } 254 \text{ of } \mathsf{ak}) || (\text{bits } 0..=4 \text{ of } \mathsf{nk}) \\ +c \text{ (240 bits)} &= \text{bits } 5..=244 \text{ of } \mathsf{nk} \\ +d \text{ (10 bits)} &= d_0||d_1 \\ + &= (\text{bits } 245..=253 \text{ of } \mathsf{nk}) || (\text{bit } 254 \text{ of } \mathsf{nk}) +\end{aligned} +$$ + +$a,b,c,d$ are constrained by the $\textsf{SinsemillaHash}$ to be $250$ bits, $10$ bits, $240$ bits, and $10$ bits respectively. + +In a custom gate, we check this message decomposition by enforcing the following constraints: + +1. $b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2$ +
+$b_0, b_2$ are witnessed outside this gate, and constrained to be $4$ bits and $5$ bits respectively. $b_1$ is witnessed and boolean-constrained in this gate: +$$(b_1)(1 - b_1) = 0.$$ +From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: +$$b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2.$$ + +2. $d = d_0 + 2^9 \cdot d_1$ +
+$d_0$ is witnessed outside this gate, and constrained to be $9$ bits. $d_1$ is witnessed and boolean-constrained in this gate: +$$(d_1)(1 - d_1) = 0.$$ +From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: +$$d = d_0 + 2^9 \cdot d_1.$$ + +We have now derived or witnessed every subpiece, and range-constrained every subpiece: +- $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; +- $d_0$ ($9$ bits) is witnessed and constrained outside the gate; +- $d_1$ ($1$ bits) is witnessed and boolean-constrained in the gate, +and we use them to reconstruct the original field element inputs: + +3. $\textsf{ak} = a + 2^{250} \cdot b_0 + 2^{254} \cdot b_1$ +4. $\textsf{nk} = b_2 + 2^5 \cdot c + 2^{245} \cdot d_0 + 2^{254} \cdot d_1$ + +## Canonicity +The modulus of the Pallas base field is $p = 2^{254} + t_p,$ where $t_p = 45560315531419706090280762371685220353 < 2^{126}.$ + +### $\textsf{ak} = a (250 \text{ bits}) || b_0 (4 \text{ bits}) || b_1 (1 \text{ bit})$ +We check that $\mathsf{I2LEBSP_{\ell_{base}^{Orchard}}(ak)}$ is a canonically-encoded $255$-bit value, i.e. $\textsf{ak} < p$. If the high bit is not set $b_1 = 0$, we are guaranteed that $\textsf{ak} < 2^{254}$. Thus, we are only interested in cases when $b_1 = 1 \implies \textsf{ak} \geq 2^{254}$. In these cases, we check that $\textsf{ak}_{0..=253} < t_p < 2^{126}$: + +1. $b_1 = 1 \implies b_0 = 0.$ +Since $b_1 = 1 \implies \textsf{ak}_{0..=253} < 2^{126},$ we know that $\textsf{ak}_{126..=253} = 0,$ and in particular $b_0 = \textsf{ak}_{250..=253} = 0.$ So, we constrain $$b_1 \cdot b_0 = 0.$$ + +2. $b_1 = 1 \implies 0 \leq a < 2^{126}.$ +To check that $a < 2^{126}$, we use two constraints: + + a) $0 \leq a < 2^{130}$. This is expressed in the custom gate as $$b_1 \cdot z_{13,a} = 0,$$ where $z_{13,a}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(a).$ + + b) $0 \leq a + 2^{130} - t_p < 2^{130}$. To check this, we decompose $a' = a + 2^{130} - t_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_{13, a'} = 0.$$ + +### $\textsf{nk} = b_2 (5 \text{ bits}) || c (240 \text{ bits}) || d_0 (9 \text{ bits}) || d_1 (1 \text{ bit})$ +We check that $\mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(nk)$ is a canonically-encoded $255$-bit value, i.e. $\textsf{nk} < p$. If the high bit is not set $d_1 = 0$, we are guaranteed that $nk < 2^{254}$. Thus, we are only interested in cases when $d_1 = 1 \implies nk \geq 2^{254}$. In these cases, we check that $\textsf{nk}_{0..=253} < t_p < 2^{126}$: + +1. $d_1 = 1 \implies 0 \leq b_2 + 2^5 \cdot c < 2^{126}.$ +To check that $0 \leq b_2 + 2^5 \cdot c < 2^{126}$, 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_{13, c}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$d_1 \cdot z_{13,c} = 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_p < 2^{140}$. To check this, we decompose $b' = b_2 + 2^5 \cdot c + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{b'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$d_1 \cdot z_{14, b'} = 0.$$ \ No newline at end of file diff --git a/book/src/design/circuit/gadgets/sinsemilla/commit_ivk.md b/book/src/design/circuit/gadgets/sinsemilla/commit_ivk.md deleted file mode 100644 index 30404ce4..00000000 --- a/book/src/design/circuit/gadgets/sinsemilla/commit_ivk.md +++ /dev/null @@ -1 +0,0 @@ -TODO \ No newline at end of file From 47a29f10aa6a4c92886d886e9bf0fc5fc9e4e2ac Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Mon, 12 Jul 2021 20:59:50 +0100 Subject: [PATCH 03/12] [book] Document NoteCommit message decomposition & canonicity checks --- book/src/SUMMARY.md | 1 + .../circuit/gadgets/sinsemilla/note-commit.md | 155 ++++++++++++++++++ .../circuit/gadgets/sinsemilla/note_commit.md | 1 - 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 book/src/design/circuit/gadgets/sinsemilla/note-commit.md delete mode 100644 book/src/design/circuit/gadgets/sinsemilla/note_commit.md diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 55efc260..82d8fee9 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -24,5 +24,6 @@ - [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) - [Lookup Range Check](design/circuit/gadgets/lookup_range_check.md) - [Decomposition](design/circuit/gadgets/decomposition.md) 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..af37dc6a --- /dev/null +++ b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md @@ -0,0 +1,155 @@ +# NoteCommit + +## Message decomposition +$\mathsf{SinsemillaCommit}$ is used in the [$\mathsf{NoteCommit}$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). The input to $\mathsf{SinsemillaCommit}$ is: + +$$\mathsf{g\star_d} || \mathsf{pk\star_d} || \mathsf{I2LEBSP}_{64}(v) || \mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(\rho) || \mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(\psi),$$ + +where $\mathsf{g\star_d, pk\star_d}$ 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, $v$ is a $64$-bit value, and $\ell_{\textsf{base}}^{\textsf{Orchard}} = 255.$ + +We break these inputs into the following `MessagePiece`s: + +$$ +\begin{aligned} +a \text{ (250 bits)} &= \text{bits } 0..=249 \text{ of } \mathsf{x(g_d)} \\ +b \text{ (10 bits)} &= b_0 || b_1 || b_2 || b_3 \\ + &= (\text{bits } 250..=253 \textsf{ of } \mathsf{x(g_d)}) || (bit 254 \textsf{ of } \mathsf{x(g_d)}) || (ỹ \text{ bit of } \mathsf{g_d}) || (\text{bits } 0..=3 \textsf{ of } \mathsf{pk\star_d}) \\ +c \text{ (250 bits)} &= \text{bits } 4..=253 \textsf{ of } \mathsf{pk\star_d} \\ +d \text{ (60 bits)} &= d_0 || d_1 || d_2 || d_3 \\ + &= (\text{bit } 254 \text{ of } \mathsf{x(pk_d)}) || (ỹ \text{ bit of } \mathsf{pk_d}) || (0..=7 \text{ of v}) || (8..=57 \text{ of v}) \\ +e \text{ (10 bits)} &= e_0 || e_1 \\ + &= (\text{bits } 58..=63 \text{ of v}) || (\text{bits } 0..=3 \text{ of} \rho) \\ +f \text{ (250 bits)} &= \text{bits } 4..=253 \text{ of } \rho \\ +g \text{ (250 bits)} &= g_0 || g_1 || g_2 \\ + &= (\text{bit } 254 \text{ of } \rho) || (\text{bits } 0..=8 \text{ of } \psi) || (\text{bits } 9..=248 \text{ of } \psi) \\ +h \text{ (10 bits)} &= h_0 || h_1 || h_2 \\ + &= (\text{bits } 249..=253 \text{ of } \psi) || (\text{bit } 254 \text{ of } \psi) || 4 \text{ zero bits } \\ +\end{aligned} +$$ + +$a,b,c,d$ are constrained by the $\textsf{SinsemillaHash}$ to be: +- $a = 250$ bits, +- $b = 10$ bits, +- $c = 250$ bits, +- $d = 60$ bits, +- $e = 10$ bits, +- $f = 250$ bits, +- $g = 250$ bits, +- $h = 10$ bits. + +In a custom gate, we check this message decomposition by enforcing the following constraints: + +1. $b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2 + 2^6 \cdot b_3$ +
+$b_0, b_3$ are witnessed outside this gate, and constrained to be $4$ bits each. $b_1, b_2$ are witnessed and boolean-constrained in this gate: +$$ +\begin{aligned} +(b_1)(1 - b_1) &= 0 \\ +(b_2)(1 - b_2) &= 0 \\ +\end{aligned} +$$ +From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: +$$b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2 + 2^6 \cdot b_3$$ + +2. $d = d_0 + 2 \cdot d_1 + 2^2 \cdot d_2 + 2^{10} \cdot d_3$ +
+$d_0, d_1$ are witnessed and boolean-constrained in this gate: +$$ +\begin{aligned} +(d_0)(1 - d_0) &= 0 \\ +(d_1)(1 - d_1) &= 0 \\ +\end{aligned} +$$ +$d_2$ is witnessed outside this gate, and constrained to be $8$ bits. $d_3$ is copied into this gate as $d_3 = z_{1,d}$, where $z_{1,d}$ is the index-1 running sum output of $\textsf{SinsemillaHash}(d),$ constrained by the hash to be $50$ bits. From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: +$$d = d_0 + 2 \cdot d_1 + 2^2 \cdot d_2 + 2^{10} \cdot d_3$$ + +3. $e = e_0 + 2^6 \cdot e_1$ +
+$e_0, e_1$ are witnessed outside this gate, and constrained to be $6$ bits and $4$ bits respectively. +From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: +$$e_0 + 2^6 \cdot e_1$$ + +4. $g = g_0 + 2 \cdot g_1 + 2^{10} \cdot g_2$ +
+$g_0$ is witnessed and boolean-constrained in this gate: $$(g_0)(g_0 - 1) = 0.$$ $g_1$ is witnessed outside this gate, and constrained to be $9$ bits. $g_2$ is copied into this gate as $g_2 = z_{1,g}$, where $z_{1,g}$ is the index-1 running sum output of $\textsf{SinsemillaHash}(g),$ constrained by the hash to be $240$ bits. From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: +$$g = g_0 + 2 \cdot g_1 + 2^{10} \cdot g_2.$$ + +5. $h = h_0 + 2^5 \cdot h_1$ +
+$h_0$ is witnessed outside this gate, and constrained to be $5$ bits. $h_1$ is witnessed and boolean-constrained in this gate: $$(h_1)(h_1 - 1) = 0.$$ From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: +$$h = h_0 + 2^5 \cdot h_1$$ + +We have now derived or witnessed every subpiece, and range-constrained every subpiece: +- $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; +- $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_{1,d}$; +- $e_0$ ($6$ bits) is witnessed and constrained outside the gate; +- $e_1$ ($4$ bit) 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_{1,g}$; +- $h_0$ ($5$ bits) is witnessed and constrained outside the gate; +- $h_1$ ($1$ bit) is witnessed and boolean-constrained in the gate; + +and we use them to reconstruct the original field element inputs: + +6. $\mathsf{x(g_d)} = a + 2^250 \cdot b_0 + 2^254 \cdot b_1$ +7. $\mathsf{pk_d} = b_3 + 2^4 \cdot c + 2^254 \cdot d_0$ +8. $\mathsf{v} = d_2 + 2^8 \cdot d_3 + 2^58 \cdot e_0$ +9. $\rho = e_1 + 2^4 \cdot f + 2^254 \cdot g_0$ +10. $\psi = g_1 + 2^9 \cdot g_2 + 2^249 \cdot h_0 + 2^254 \cdot h_1$ + +## Canonicity +The modulus of the Pallas base field is $p = 2^{254} + t_p,$ where $t_p = 45560315531419706090280762371685220353 < 2^{126}.$ + +### $\mathsf{x(g_d)} = a \text{ (250 bits) } || b_0 \text{ (4 bits) } || b_1 \text{ (1 bit) }$ +We check that $\mathsf{x(g_d)}$ is a canonically-encoded $255$-bit value, i.e. $\mathsf{x(g_d)} < p$. If the high bit is not set $b_1 = 0$, we are guaranteed that $\mathsf{x(g_d)} < 2^{254}$. Thus, we are only interested in cases when $b_1 = 1 \implies \mathsf{x(g_d)} \geq 2^{254}$. In these cases, we check that $\mathsf{x(g_d)}_{0..=253} < t_p < 2^{126}$: + +1. $b_1 = 1 \implies b_0 = 0.$ +Since $b_1 = 1 \implies \mathsf{x(g_d)}_{0..=253} < 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 < 2^{126}.$ +To check that $a < 2^{126}$, we use two constraints: + + a) $0 \leq a < 2^{130}$. This is expressed in the custom gate as $$b_1 \cdot z_{13,a} = 0,$$ where $z_{13,a}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(a).$ + + b) $0 \leq a + 2^{130} - t_p < 2^{130}$. To check this, we decompose $a' = a + 2^{130} - t_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_{13, a'} = 0.$$ + + +### $\mathsf{x(pk_d)} = b_3 \text{ (4 bits) } || c \text{ (250 bits) } || d_0 \text{ (1 bit) }$ +We check that $\mathsf{x(pk_d)}$ is a canonically-encoded $255$-bit value, i.e. $\mathsf{x(pk_d)} < p$. If the high bit is not set $d_0 = 0$, we are guaranteed that $\mathsf{x(pk_d)} < 2^{254}$. Thus, we are only interested in cases when $d_0 = 1 \implies \mathsf{x(pk_d)} \geq 2^{254}$. In these cases, we check that $\mathsf{x(pk_d)}_{0..=253} < t_p < 2^{126}$: + +1. $d_0 = 0 \implies 0 \leq b_3 + 2^{4} \cdot c < 2^{126}.$ +To check that $0 \leq b_3 + 2^{4} \cdot c < 2^{126},$ 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_{13, c}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$d_0 \cdot z_{13,c} = 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_p < 2^{140}$. To check this, we decompose $b' = b_3 + 2^{4} \cdot c + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{b'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$d_0 \cdot z_{14, b'} = 0.$$ + +### $\rho = e_1 \text{ (4 bits) } || f \text{ (250 bits) } || g_0 \text{ (1 bit) }$ +We check that $\rho$ is a canonically-encoded $255$-bit value, i.e. $\rho < p$. If the high bit is not set $g_0 = 0$, we are guaranteed that $\rho < 2^{254}$. Thus, we are only interested in cases when $g_0 = 1 \implies \rho \geq 2^{254}$. In these cases, we check that $\rho_{0..=253} < t_p < 2^{126}$: + +1. $g_0 = 0 \implies 0 \leq e_1 + 2^{4} \cdot f < 2^{126}.$ +To check that $0 \leq e_1 + 2^{4} \cdot f < 2^{126},$ 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_{13, f}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$g_0 \cdot z_{13, f} = 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_p < 2^{140}$. To check this, we decompose $e' = e_1 + 2^{4} \cdot f + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{e'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$g_0 \cdot z_{14, e'} = 0.$$ + +### $\psi = g_1 \text{ (9 bits) } || g_2 \text{ (240 bits) } || h_0 \text{ (5 bits) } || h_1 \text{ (1 bit) }$ +We check that $\psi$ is a canonically-encoded $255$-bit value, i.e. $\psi < p$. If the high bit is not set $h_1 = 0$, we are guaranteed that $\psi < 2^{254}$. Thus, we are only interested in cases when $h_1 = 1 \implies \psi \geq 2^{254}$. In these cases, we check that $\psi_{0..=253} < t_p < 2^{126}$: + +1. $h_1 = 0 \implies h_0 = 0.$ +Since $h_1 = 1 \implies \psi_{0..=253} < 2^{126},$ we know that $\psi_{126..=253} = 0,$ and in particular $h_0 = \psi_{249..=253} = 0.$ So, we constrain $$h_1 \cdot h_0 = 0.$$ + +2. $h_1 = 0 \implies 0 \leq g_1 + 2^{9} \cdot g_2 < 2^{126}.$ +To check that $0 \leq g_1 + 2^{9} \cdot g_2 < 2^{126},$ we use two constraints: + + a) $0 \leq g_1 + 2^{9} \cdot g_2 < 2^{140}.$ $e_1$ is already constrained individually to be a $4$-bit value. $z_{13, f}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$h_1 \cdot z_{13, f} = 0,$$ we constrain $e_1 + 2^4 \cdot f < 2^{134} < 2^{140}.$ + + b) $0 \leq g_1 + 2^{9} \cdot g_2 + 2^{140} - t_p < 2^{140}$. To check this, we decompose $e' = g_1 + 2^{9} \cdot g_2 + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{e'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$h_1 \cdot z_{14, e'} = 0.$$ \ No newline at end of file diff --git a/book/src/design/circuit/gadgets/sinsemilla/note_commit.md b/book/src/design/circuit/gadgets/sinsemilla/note_commit.md deleted file mode 100644 index 30404ce4..00000000 --- a/book/src/design/circuit/gadgets/sinsemilla/note_commit.md +++ /dev/null @@ -1 +0,0 @@ -TODO \ No newline at end of file From ed20d539b24d2e44466e4a8565c9260048064c75 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Tue, 13 Jul 2021 11:49:36 +0100 Subject: [PATCH 04/12] [book] merkle-crh.md: corrections. Signed-off-by: Daira Hopwood --- book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md b/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md index 7b0d7b0c..303d12ff 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md +++ b/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md @@ -28,12 +28,12 @@ $a,b,c$ are constrained by the $\textsf{SinsemillaHash}$ to be $250$ bits, $20$ In a custom gate, we check this message decomposition by enforcing the following constraints: -1. $a_0 = l_{\star}$ +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..=10}}{2^{10}}\\ +z_{1,a} &= \frac{a - a_0}{2^{10}}\\ &= a_1 \\ \implies a_0 &= a - (z_{1,a} \cdot 2^{10}). \end{aligned} From 4a5a4cc43705b669ae4a8dc39d49c7ea2a54d4bc Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Tue, 13 Jul 2021 11:50:29 +0100 Subject: [PATCH 05/12] [book] merkle-crh.md: formatting. Signed-off-by: Daira Hopwood --- .../circuit/gadgets/sinsemilla/merkle-crh.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md b/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md index 303d12ff..fc8e6a10 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md +++ b/book/src/design/circuit/gadgets/sinsemilla/merkle-crh.md @@ -3,23 +3,23 @@ ## 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}, $$ +$${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})$, +- ${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})$, -where $\ell_{\textsf{Merkle}}^{\textsf{Orchard}} = 255.$ $\textsf{left}$ and $\textsf{right}$ are allowed to be non-canonical $255$-bit encodings. +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}) \\ +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} $$ @@ -35,7 +35,7 @@ $$ \begin{aligned} z_{1,a} &= \frac{a - a_0}{2^{10}}\\ &= a_1 \\ - \implies a_0 &= a - (z_{1,a} \cdot 2^{10}). + \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.$$ @@ -66,4 +66,4 @@ and we use them to reconstruct the original field element inputs: 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. \ No newline at end of file +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. From f376a61bb8b7bc6959916845283e3c1789eec69b Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 23 Jul 2021 13:37:54 +0100 Subject: [PATCH 06/12] [book] Add macros, constraint tables, and region layout to Commit^ivk I also merged in content from a page I wrote independently while reviewing the Action circuit PR, and made various cleanups to the Markdown source. --- book/book.toml | 1 + book/macros.txt | 28 ++ .../circuit/gadgets/sinsemilla/commit-ivk.md | 241 ++++++++++++++---- 3 files changed, 226 insertions(+), 44 deletions(-) create mode 100644 book/macros.txt 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..f4beaea8 --- /dev/null +++ b/book/macros.txt @@ -0,0 +1,28 @@ +# Conventions + +\bconcat:{\mathop{\kern 0.1em||\kern 0.1em}} + +# 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}} + +# Commitments and hashes + +\SinsemillaHash:{\mathsf{SinsemillaHash}} +\SinsemillaShortCommit:{\mathsf{SinsemillaShortCommit}} +\CommitIvk:{\mathsf{Commit}^{\InViewingKey}} + +# Circuit constraint helper methods + +\BoolCheck:{\texttt{bool\_check}({#1})} +\ShortLookupRangeCheck:{\texttt{short\_lookup\_range\_check}({#1})} diff --git a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md index 3cd56e9d..54c8e34d 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md +++ b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md @@ -1,76 +1,229 @@ # CommitIvk ## Message decomposition -$\mathsf{SinsemillaShortCommit}$ is used in the [$\mathsf{CommitIvk}$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). The input to $\mathsf{SinsemillaShortCommit}$ is: -$$\mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(ak) || \mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(nk),$$ +$\SinsemillaShortCommit$ is used in the +[$\CommitIvk$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). +The input to $\SinsemillaShortCommit$ is: -where $\mathsf{ak, nk}$ are Pallas base field elements, and $\ell_{\textsf{base}}^{\textsf{Orchard}} = 255.$ +$$\ItoLEBSP{\BaseLength{Orchard}}(\AuthSignPublic) \bconcat \ItoLEBSP{\BaseLength{Orchard}}(\NullifierKey),$$ -We break these inputs into the following `MessagePiece`s: +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{aligned} -a \text{ (250 bits)} &= \text{bits } 0..=249 \text{ of } \mathsf{ak} \\ -b \text{ (10 bits)} &= b_0||b_1||b_2 \\ - &= (\text{bits } 250..=253 \text{ of } \mathsf{ak}) || (\text{bit } 254 \text{ of } \mathsf{ak}) || (\text{bits } 0..=4 \text{ of } \mathsf{nk}) \\ -c \text{ (240 bits)} &= \text{bits } 5..=244 \text{ of } \mathsf{nk} \\ -d \text{ (10 bits)} &= d_0||d_1 \\ - &= (\text{bits } 245..=253 \text{ of } \mathsf{nk}) || (\text{bit } 254 \text{ of } \mathsf{nk}) -\end{aligned} +\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} $$ -$a,b,c,d$ are constrained by the $\textsf{SinsemillaHash}$ to be $250$ bits, $10$ bits, $240$ bits, and $10$ bits respectively. +Then we recompose the chunks into message pieces: -In a custom gate, we check this message decomposition by enforcing the following constraints: +$$ +\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} +$$ -1. $b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2$ -
-$b_0, b_2$ are witnessed outside this gate, and constrained to be $4$ bits and $5$ bits respectively. $b_1$ is witnessed and boolean-constrained in this gate: -$$(b_1)(1 - b_1) = 0.$$ -From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: -$$b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2.$$ +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: -2. $d = d_0 + 2^9 \cdot d_1$ -
-$d_0$ is witnessed outside this gate, and constrained to be $9$ bits. $d_1$ is witnessed and boolean-constrained in this gate: -$$(d_1)(1 - d_1) = 0.$$ -From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: -$$d = d_0 + 2^9 \cdot d_1.$$ +- 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](../lookup_range_check.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, -and we use them to reconstruct the original field element inputs: +- $d_1$ ($1$ bits) is witnessed and boolean-constrained in the gate. -3. $\textsf{ak} = a + 2^{250} \cdot b_0 + 2^{254} \cdot b_1$ -4. $\textsf{nk} = b_2 + 2^5 \cdot c + 2^{245} \cdot d_0 + 2^{254} \cdot d_1$ +We can now use them to reconstruct both the (chunked) message pieces, and the original +field element inputs: -## Canonicity -The modulus of the Pallas base field is $p = 2^{254} + t_p,$ where $t_p = 45560315531419706090280762371685220353 < 2^{126}.$ +$$ +\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} +$$ -### $\textsf{ak} = a (250 \text{ bits}) || b_0 (4 \text{ bits}) || b_1 (1 \text{ bit})$ -We check that $\mathsf{I2LEBSP_{\ell_{base}^{Orchard}}(ak)}$ is a canonically-encoded $255$-bit value, i.e. $\textsf{ak} < p$. If the high bit is not set $b_1 = 0$, we are guaranteed that $\textsf{ak} < 2^{254}$. Thus, we are only interested in cases when $b_1 = 1 \implies \textsf{ak} \geq 2^{254}$. In these cases, we check that $\textsf{ak}_{0..=253} < t_p < 2^{126}$: +$$ +\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} < 2^{126}$: 1. $b_1 = 1 \implies b_0 = 0.$ -Since $b_1 = 1 \implies \textsf{ak}_{0..=253} < 2^{126},$ we know that $\textsf{ak}_{126..=253} = 0,$ and in particular $b_0 = \textsf{ak}_{250..=253} = 0.$ So, we constrain $$b_1 \cdot b_0 = 0.$$ + + Since $b_1 = 1 \implies \AuthSignPublic_{0..=253} < 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 < 2^{126}.$ -To check that $a < 2^{126}$, we use two constraints: - a) $0 \leq a < 2^{130}$. This is expressed in the custom gate as $$b_1 \cdot z_{13,a} = 0,$$ where $z_{13,a}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(a).$ + To check that $a < 2^{126}$, we use two constraints: - b) $0 \leq a + 2^{130} - t_p < 2^{130}$. To check this, we decompose $a' = a + 2^{130} - t_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_{13, a'} = 0.$$ + 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).$ -### $\textsf{nk} = b_2 (5 \text{ bits}) || c (240 \text{ bits}) || d_0 (9 \text{ bits}) || d_1 (1 \text{ bit})$ -We check that $\mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(nk)$ is a canonically-encoded $255$-bit value, i.e. $\textsf{nk} < p$. If the high bit is not set $d_1 = 0$, we are guaranteed that $nk < 2^{254}$. Thus, we are only interested in cases when $d_1 = 1 \implies nk \geq 2^{254}$. In these cases, we check that $\textsf{nk}_{0..=253} < t_p < 2^{126}$: + 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.$$ -1. $d_1 = 1 \implies 0 \leq b_2 + 2^5 \cdot c < 2^{126}.$ -To check that $0 \leq b_2 + 2^5 \cdot c < 2^{126}$, we use two constraints: +$$ +\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} +$$ - a) $0 \leq b_2 + 2^5 \cdot c < 2^{140}$. $b_2$ is already constrained individually to be a $5$-bit value. $z_{13, c}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$d_1 \cdot z_{13,c} = 0,$$ we constrain $b_2 + 2^5 \cdot c < 2^{135} < 2^{140}.$ +### $\NullifierKey$ with $d_1 = 1 \implies \NullifierKey \geq 2^{254}$ - b) $0 \leq b_2 + 2^5 \cdot c + 2^{140} - t_p < 2^{140}$. To check this, we decompose $b' = b_2 + 2^5 \cdot c + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{b'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$d_1 \cdot z_{14, b'} = 0.$$ \ No newline at end of file +In these cases, we check that $\textsf{nk}_{0..=253} < t_\mathbb{P} < 2^{126}$: + +1. $d_1 = 1 \implies d_0 = 0.$ + + Since $d_1 = 1 \implies \NullifierKey_{0..=253} < 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 < 2^{126}.$ + + To check that $0 \leq b_2 + 2^5 \cdot c < 2^{126}$, 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 all 10 +advice columns, requiring two rows. + +$$ +\begin{array}{|c|c|c|c|c|c|c|c|c|c|c} + & & & & & & & & & & q_\CommitIvk \\\hline +a & b & c & d & \AuthSignPublic & \NullifierKey & b_0 & b_1 & b_2 & d_0 & 0 \\\hline +d_1 & z_{a,13} & a' & z_{a',13} & z_{c,13} & {b_2}c' & z_{{b_2}c',14} & & & & 1 \\\hline +\end{array} +$$ From 5aa05713e7bacd57cb7a8c80ce13aedf8c5de928 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 23 Jul 2021 13:45:08 +0100 Subject: [PATCH 07/12] [book] Use \CommitIvk macro in page heading We can't use KaTeX on the SUMMARY page that generates the sidebar, so that continues to use a CamelCase approximation. --- book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md index 54c8e34d..3e425194 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md +++ b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md @@ -1,4 +1,4 @@ -# CommitIvk +# $\CommitIvk$ ## Message decomposition From 0375c648016e7323b8a9c9585b2d66d7ad540cb8 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 24 Jul 2021 17:02:11 +0100 Subject: [PATCH 08/12] [book] Update NoteCommit page to match Commit^ivk style Constraint tables have been added along with the region layout. I also fixed numerous bugs in the constraints (most of which appeared to be copy-pasta bugs). --- book/macros.txt | 7 + .../circuit/gadgets/sinsemilla/note-commit.md | 411 ++++++++++++++---- 2 files changed, 322 insertions(+), 96 deletions(-) diff --git a/book/macros.txt b/book/macros.txt index f4beaea8..af590a07 100644 --- a/book/macros.txt +++ b/book/macros.txt @@ -1,6 +1,7 @@ # Conventions \bconcat:{\mathop{\kern 0.1em||\kern 0.1em}} +\Repr:{\star} # Conversions @@ -15,12 +16,18 @@ \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 diff --git a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md index af37dc6a..d2921c32 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md +++ b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md @@ -1,155 +1,374 @@ # NoteCommit ## Message decomposition -$\mathsf{SinsemillaCommit}$ is used in the [$\mathsf{NoteCommit}$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). The input to $\mathsf{SinsemillaCommit}$ is: -$$\mathsf{g\star_d} || \mathsf{pk\star_d} || \mathsf{I2LEBSP}_{64}(v) || \mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(\rho) || \mathsf{I2LEBSP}_{\ell_{\textsf{base}}^{\textsf{Orchard}}}(\psi),$$ +$\SinsemillaCommit$ is used in the +[$\NoteCommit$ function](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit). +The input to $\SinsemillaCommit$ is: -where $\mathsf{g\star_d, pk\star_d}$ 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, $v$ is a $64$-bit value, and $\ell_{\textsf{base}}^{\textsf{Orchard}} = 255.$ +$$\DiversifiedTransmitBaseRepr \bconcat + \DiversifiedTransmitPublicRepr \bconcat + \ItoLEBSP{64}(\mathsf{v}) \bconcat + \ItoLEBSP{\BaseLength{Orchard}}(\rho) \bconcat + \ItoLEBSP{\BaseLength{Orchard}}(\psi),$$ -We break these inputs into the following `MessagePiece`s: +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} -a \text{ (250 bits)} &= \text{bits } 0..=249 \text{ of } \mathsf{x(g_d)} \\ -b \text{ (10 bits)} &= b_0 || b_1 || b_2 || b_3 \\ - &= (\text{bits } 250..=253 \textsf{ of } \mathsf{x(g_d)}) || (bit 254 \textsf{ of } \mathsf{x(g_d)}) || (ỹ \text{ bit of } \mathsf{g_d}) || (\text{bits } 0..=3 \textsf{ of } \mathsf{pk\star_d}) \\ -c \text{ (250 bits)} &= \text{bits } 4..=253 \textsf{ of } \mathsf{pk\star_d} \\ -d \text{ (60 bits)} &= d_0 || d_1 || d_2 || d_3 \\ - &= (\text{bit } 254 \text{ of } \mathsf{x(pk_d)}) || (ỹ \text{ bit of } \mathsf{pk_d}) || (0..=7 \text{ of v}) || (8..=57 \text{ of v}) \\ -e \text{ (10 bits)} &= e_0 || e_1 \\ - &= (\text{bits } 58..=63 \text{ of v}) || (\text{bits } 0..=3 \text{ of} \rho) \\ -f \text{ (250 bits)} &= \text{bits } 4..=253 \text{ of } \rho \\ -g \text{ (250 bits)} &= g_0 || g_1 || g_2 \\ - &= (\text{bit } 254 \text{ of } \rho) || (\text{bits } 0..=8 \text{ of } \psi) || (\text{bits } 9..=248 \text{ of } \psi) \\ -h \text{ (10 bits)} &= h_0 || h_1 || h_2 \\ - &= (\text{bits } 249..=253 \text{ of } \psi) || (\text{bit } 254 \text{ of } \psi) || 4 \text{ zero bits } \\ +\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} $$ -$a,b,c,d$ are constrained by the $\textsf{SinsemillaHash}$ to be: -- $a = 250$ bits, -- $b = 10$ bits, -- $c = 250$ bits, -- $d = 60$ bits, -- $e = 10$ bits, -- $f = 250$ bits, -- $g = 250$ bits, -- $h = 10$ bits. +Then we recompose the chunks into message pieces: -In a custom gate, we check this message decomposition by enforcing the following constraints: - -1. $b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2 + 2^6 \cdot b_3$ -
-$b_0, b_3$ are witnessed outside this gate, and constrained to be $4$ bits each. $b_1, b_2$ are witnessed and boolean-constrained in this gate: $$ -\begin{aligned} -(b_1)(1 - b_1) &= 0 \\ -(b_2)(1 - b_2) &= 0 \\ -\end{aligned} +\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} $$ -From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: -$$b = b_0 + 2^4 \cdot b_1 + 2^5 \cdot b_2 + 2^6 \cdot b_3$$ -2. $d = d_0 + 2 \cdot d_1 + 2^2 \cdot d_2 + 2^{10} \cdot d_3$ -
-$d_0, d_1$ are witnessed and boolean-constrained in this gate: +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{aligned} -(d_0)(1 - d_0) &= 0 \\ -(d_1)(1 - d_1) &= 0 \\ -\end{aligned} +\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} $$ -$d_2$ is witnessed outside this gate, and constrained to be $8$ bits. $d_3$ is copied into this gate as $d_3 = z_{1,d}$, where $z_{1,d}$ is the index-1 running sum output of $\textsf{SinsemillaHash}(d),$ constrained by the hash to be $50$ bits. From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: -$$d = d_0 + 2 \cdot d_1 + 2^2 \cdot d_2 + 2^{10} \cdot d_3$$ -3. $e = e_0 + 2^6 \cdot e_1$ -
-$e_0, e_1$ are witnessed outside this gate, and constrained to be $6$ bits and $4$ bits respectively. -From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: -$$e_0 + 2^6 \cdot e_1$$ +where: +- $\BoolCheck{x} = x \cdot (1 - x)$. +- $\ShortLookupRangeCheck{}$ is a [short lookup range check](../lookup_range_check.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. -4. $g = g_0 + 2 \cdot g_1 + 2^{10} \cdot g_2$ -
-$g_0$ is witnessed and boolean-constrained in this gate: $$(g_0)(g_0 - 1) = 0.$$ $g_1$ is witnessed outside this gate, and constrained to be $9$ bits. $g_2$ is copied into this gate as $g_2 = z_{1,g}$, where $z_{1,g}$ is the index-1 running sum output of $\textsf{SinsemillaHash}(g),$ constrained by the hash to be $240$ bits. From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: -$$g = g_0 + 2 \cdot g_1 + 2^{10} \cdot g_2.$$ - -5. $h = h_0 + 2^5 \cdot h_1$ -
-$h_0$ is witnessed outside this gate, and constrained to be $5$ bits. $h_1$ is witnessed and boolean-constrained in this gate: $$(h_1)(h_1 - 1) = 0.$$ From these witnessed subpieces, we check that we recover the original `MessagePiece` input to the hash: -$$h = h_0 + 2^5 \cdot h_1$$ +## 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_{1,d}$; +- $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_{1,g}$; +- $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. -and we use them to reconstruct the original field element inputs: +We can now use them to reconstruct both the (chunked) message pieces, and the original +field element inputs: -6. $\mathsf{x(g_d)} = a + 2^250 \cdot b_0 + 2^254 \cdot b_1$ -7. $\mathsf{pk_d} = b_3 + 2^4 \cdot c + 2^254 \cdot d_0$ -8. $\mathsf{v} = d_2 + 2^8 \cdot d_3 + 2^58 \cdot e_0$ -9. $\rho = e_1 + 2^4 \cdot f + 2^254 \cdot g_0$ -10. $\psi = g_1 + 2^9 \cdot g_2 + 2^249 \cdot h_0 + 2^254 \cdot h_1$ +$$ +\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} +$$ -## Canonicity -The modulus of the Pallas base field is $p = 2^{254} + t_p,$ where $t_p = 45560315531419706090280762371685220353 < 2^{126}.$ +$$ +\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} +$$ -### $\mathsf{x(g_d)} = a \text{ (250 bits) } || b_0 \text{ (4 bits) } || b_1 \text{ (1 bit) }$ -We check that $\mathsf{x(g_d)}$ is a canonically-encoded $255$-bit value, i.e. $\mathsf{x(g_d)} < p$. If the high bit is not set $b_1 = 0$, we are guaranteed that $\mathsf{x(g_d)} < 2^{254}$. Thus, we are only interested in cases when $b_1 = 1 \implies \mathsf{x(g_d)} \geq 2^{254}$. In these cases, we check that $\mathsf{x(g_d)}_{0..=253} < t_p < 2^{126}$: +## 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} < 2^{126}$: 1. $b_1 = 1 \implies b_0 = 0.$ -Since $b_1 = 1 \implies \mathsf{x(g_d)}_{0..=253} < 2^{126},$ we know that $\mathsf{x(g_d)}_{126..=253} = 0,$ and in particular $b_0 = \mathsf{x(g_d)}_{250..=253} = 0.$ + + Since $b_1 = 1 \implies \mathsf{x(g_d)}_{0..=253} < 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 < 2^{126}.$ -To check that $a < 2^{126}$, we use two constraints: - a) $0 \leq a < 2^{130}$. This is expressed in the custom gate as $$b_1 \cdot z_{13,a} = 0,$$ where $z_{13,a}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(a).$ + To check that $a < 2^{126}$, we use two constraints: - b) $0 \leq a + 2^{130} - t_p < 2^{130}$. To check this, we decompose $a' = a + 2^{130} - t_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_{13, a'} = 0.$$ + 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.$$ -### $\mathsf{x(pk_d)} = b_3 \text{ (4 bits) } || c \text{ (250 bits) } || d_0 \text{ (1 bit) }$ -We check that $\mathsf{x(pk_d)}$ is a canonically-encoded $255$-bit value, i.e. $\mathsf{x(pk_d)} < p$. If the high bit is not set $d_0 = 0$, we are guaranteed that $\mathsf{x(pk_d)} < 2^{254}$. Thus, we are only interested in cases when $d_0 = 1 \implies \mathsf{x(pk_d)} \geq 2^{254}$. In these cases, we check that $\mathsf{x(pk_d)}_{0..=253} < t_p < 2^{126}$: +$$ +\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} +$$ -1. $d_0 = 0 \implies 0 \leq b_3 + 2^{4} \cdot c < 2^{126}.$ -To check that $0 \leq b_3 + 2^{4} \cdot c < 2^{126},$ we use two constraints: +### $\mathsf{x(pk_d)}$ with $d_0 = 1 \implies \mathsf{x(pk_d)} \geq 2^{254}$ - a) $0 \leq b_3 + 2^{4} \cdot c < 2^{140}.$ $b_3$ is already constrained individually to be a $4$-bit value. $z_{13, c}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$d_0 \cdot z_{13,c} = 0,$$ we constrain $b_3 + 2^4 \cdot c < 2^{134} < 2^{140}.$ +In these cases, we check that $\mathsf{x(pk_d)}_{0..=253} < t_\mathbb{P} < 2^{126}$: - b) $0 \leq b_3 + 2^{4} \cdot c + 2^{140} - t_p < 2^{140}$. To check this, we decompose $b' = b_3 + 2^{4} \cdot c + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{b'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$d_0 \cdot z_{14, b'} = 0.$$ +1. $d_0 = 1 \implies 0 \leq b_3 + 2^{4} \cdot c < 2^{126}.$ -### $\rho = e_1 \text{ (4 bits) } || f \text{ (250 bits) } || g_0 \text{ (1 bit) }$ -We check that $\rho$ is a canonically-encoded $255$-bit value, i.e. $\rho < p$. If the high bit is not set $g_0 = 0$, we are guaranteed that $\rho < 2^{254}$. Thus, we are only interested in cases when $g_0 = 1 \implies \rho \geq 2^{254}$. In these cases, we check that $\rho_{0..=253} < t_p < 2^{126}$: + To check that $0 \leq b_3 + 2^{4} \cdot c < 2^{126},$ we use two constraints: -1. $g_0 = 0 \implies 0 \leq e_1 + 2^{4} \cdot f < 2^{126}.$ -To check that $0 \leq e_1 + 2^{4} \cdot f < 2^{126},$ 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}.$ - a) $0 \leq e_1 + 2^{4} \cdot f < 2^{140}.$ $e_1$ is already constrained individually to be a $4$-bit value. $z_{13, f}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$g_0 \cdot z_{13, f} = 0,$$ we constrain $e_1 + 2^4 \cdot f < 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.$$ - b) $0 \leq e_1 + 2^{4} \cdot f + 2^{140} - t_p < 2^{140}$. To check this, we decompose $e' = e_1 + 2^{4} \cdot f + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{e'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$g_0 \cdot z_{14, e'} = 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} +$$ -### $\psi = g_1 \text{ (9 bits) } || g_2 \text{ (240 bits) } || h_0 \text{ (5 bits) } || h_1 \text{ (1 bit) }$ -We check that $\psi$ is a canonically-encoded $255$-bit value, i.e. $\psi < p$. If the high bit is not set $h_1 = 0$, we are guaranteed that $\psi < 2^{254}$. Thus, we are only interested in cases when $h_1 = 1 \implies \psi \geq 2^{254}$. In these cases, we check that $\psi_{0..=253} < t_p < 2^{126}$: +### $\rho$ with $g_0 = 1 \implies \rho \geq 2^{254}$ -1. $h_1 = 0 \implies h_0 = 0.$ -Since $h_1 = 1 \implies \psi_{0..=253} < 2^{126},$ we know that $\psi_{126..=253} = 0,$ and in particular $h_0 = \psi_{249..=253} = 0.$ So, we constrain $$h_1 \cdot h_0 = 0.$$ +In these cases, we check that $\rho_{0..=253} < t_\mathbb{P} < 2^{126}$: -2. $h_1 = 0 \implies 0 \leq g_1 + 2^{9} \cdot g_2 < 2^{126}.$ -To check that $0 \leq g_1 + 2^{9} \cdot g_2 < 2^{126},$ we use two constraints: +1. $g_0 = 1 \implies 0 \leq e_1 + 2^{4} \cdot f < 2^{126}.$ - a) $0 \leq g_1 + 2^{9} \cdot g_2 < 2^{140}.$ $e_1$ is already constrained individually to be a $4$-bit value. $z_{13, f}$ is the index-13 running sum output by $\textsf{SinsemillaHash}(c).$ By constraining $$h_1 \cdot z_{13, f} = 0,$$ we constrain $e_1 + 2^4 \cdot f < 2^{134} < 2^{140}.$ + To check that $0 \leq e_1 + 2^{4} \cdot f < 2^{126},$ we use two constraints: - b) $0 \leq g_1 + 2^{9} \cdot g_2 + 2^{140} - t_p < 2^{140}$. To check this, we decompose $e' = g_1 + 2^{9} \cdot g_2 + 2^{140} - t_p$ into fourteen 10-bit words (little-endian) using a running sum $z_{e'}$, looking up each word in a $10$-bit lookup table. We then enforce in the custom gate that $$h_1 \cdot z_{14, e'} = 0.$$ \ No newline at end of file + 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} < 2^{126}$: + +1. $h_1 = 1 \implies h_0 = 0.$ + + Since $h_1 = 1 \implies \psi_{0..=253} < 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 < 2^{126}.$ + + To check that $0 \leq g_1 + 2^{9} \cdot g_2 < 2^{126},$ 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^{140}.$ + + b) $0 \leq g_1 + 2^{9} \cdot g_2 + 2^{140} - t_\mathbb{P} < 2^{140}$. To check this, + we decompose ${g_1}{g_2}' = g_1 + 2^{9} \cdot g_2 + 2^{140} - t_\mathbb{P}$ into + fourteen 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}',14} = 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^{140} - 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} +$$ From 453681f309128cbbccbc4c43d48d4b9381a1cad0 Mon Sep 17 00:00:00 2001 From: ying tong Date: Mon, 26 Jul 2021 11:09:47 +0800 Subject: [PATCH 09/12] [book] commit-ivk.md: Update region layout to use 9 advice columns. Co-authored-by: str4d --- .../design/circuit/gadgets/sinsemilla/commit-ivk.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md index 3e425194..9ca58c1c 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md +++ b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md @@ -217,13 +217,13 @@ $$ ## Region layout -The constraints controlled by the $q_\CommitIvk$ selector are arranged across all 10 +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|c} - & & & & & & & & & & q_\CommitIvk \\\hline -a & b & c & d & \AuthSignPublic & \NullifierKey & b_0 & b_1 & b_2 & d_0 & 0 \\\hline -d_1 & z_{a,13} & a' & z_{a',13} & z_{c,13} & {b_2}c' & z_{{b_2}c',14} & & & & 1 \\\hline +\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} $$ From 14b8d9b0484df665545b58baa3e12442f7dc8792 Mon Sep 17 00:00:00 2001 From: ying tong Date: Mon, 26 Jul 2021 11:12:42 +0800 Subject: [PATCH 10/12] [book] note-commit.md: 2^140 -> 2^130 in psi check. Co-authored-by: Jack Grigg --- .../design/circuit/gadgets/sinsemilla/note-commit.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md index d2921c32..a8cd53bf 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md +++ b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md @@ -339,13 +339,13 @@ In these cases, we check that $\psi_{0..=253} < t_\mathbb{P} < 2^{126}$: 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^{140}.$ + $g_1 + 2^9 \cdot g_2 < 2^{129} < 2^{130}.$ - b) $0 \leq g_1 + 2^{9} \cdot g_2 + 2^{140} - t_\mathbb{P} < 2^{140}$. To check this, - we decompose ${g_1}{g_2}' = g_1 + 2^{9} \cdot g_2 + 2^{140} - t_\mathbb{P}$ into - fourteen 10-bit words (little-endian) using a running sum $z_{{g_1}{g_2}'}$, + 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}',14} = 0.$$ + that $$h_1 \cdot z_{{g_1}{g_2}',13} = 0.$$ $$ \begin{array}{|c|l|} @@ -353,7 +353,7 @@ $$ \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^{140} - t_\mathbb{P} - {g_1}{g_2}') = 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} $$ From 3833d665de39ac54098b23a75a752c600e3cab0c Mon Sep 17 00:00:00 2001 From: ying tong Date: Mon, 26 Jul 2021 12:05:25 +0800 Subject: [PATCH 11/12] [book] Clarify upper bounds in canonicity shift constraints. --- .../circuit/gadgets/sinsemilla/commit-ivk.md | 16 +++++------ .../circuit/gadgets/sinsemilla/note-commit.md | 28 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md index 9ca58c1c..92840928 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md +++ b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md @@ -148,17 +148,17 @@ $\NullifierKey$). ### $\AuthSignPublic$ with $b_1 = 1 \implies \AuthSignPublic \geq 2^{254}$ -In these cases, we check that $\textsf{ak}_{0..=253} < t_\mathbb{P} < 2^{126}$: +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} < 2^{126},$ we know that + 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 < 2^{126}.$ +2. $b_1 = 1 \implies 0 \leq a < t_\mathbb{P}.$ - To check that $a < 2^{126}$, we use two constraints: + 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,$$ @@ -183,15 +183,15 @@ $$ ### $\NullifierKey$ with $d_1 = 1 \implies \NullifierKey \geq 2^{254}$ -In these cases, we check that $\textsf{nk}_{0..=253} < t_\mathbb{P} < 2^{126}$: +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} < 2^{126},$ we know that $\NullifierKey_{126..=253} = 0,$ and in particular $$d_0 := \NullifierKey_{245..=253} = 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 < 2^{126}.$ +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 < 2^{126}$, we use two constraints: + 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 diff --git a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md index a8cd53bf..45a6871c 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md +++ b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md @@ -232,17 +232,17 @@ below are enforced if and only if the corresponding top bit is set to 1. ### $\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} < 2^{126}$: +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} < 2^{126},$ we know that + 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 < 2^{126}.$ +2. $b_1 = 1 \implies 0 \leq a < t_\mathbb{P}.$ - To check that $a < 2^{126}$, we use two constraints: + 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,$$ @@ -267,11 +267,11 @@ $$ ### $\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} < 2^{126}$: +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 < 2^{126}.$ +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 < 2^{126},$ we use two constraints: + 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 @@ -296,11 +296,11 @@ $$ ### $\rho$ with $g_0 = 1 \implies \rho \geq 2^{254}$ -In these cases, we check that $\rho_{0..=253} < t_\mathbb{P} < 2^{126}$: +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 < 2^{126}.$ +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 < 2^{126},$ we use two constraints: + 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 @@ -325,16 +325,16 @@ $$ ### $\psi$ with $h_1 = 1 \implies \psi \geq 2^{254}$ -In these cases, we check that $\psi_{0..=253} < t_\mathbb{P} < 2^{126}$: +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} < 2^{126},$ we know that $\psi_{126..=253} = 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 < 2^{126}.$ +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 < 2^{126},$ we use two constraints: + 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 From f1ccc58d9a4775c226019eab8cbfbd8ea6ac956e Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Mon, 26 Jul 2021 18:18:19 +0800 Subject: [PATCH 12/12] [book] note-commit.md: y-coordinate canonicity constraints. Co-authored-by: Daira Hopwood --- book/src/SUMMARY.md | 1 - .../circuit/gadgets/sinsemilla/commit-ivk.md | 2 +- .../circuit/gadgets/sinsemilla/note-commit.md | 79 ++++++++++++++++++- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 82d8fee9..4a637b88 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -25,5 +25,4 @@ - [MerkleCRH](design/circuit/gadgets/sinsemilla/merkle-crh.md) - [CommitIvk](design/circuit/gadgets/sinsemilla/commit-ivk.md) - [NoteCommit](design/circuit/gadgets/sinsemilla/note-commit.md) - - [Lookup Range Check](design/circuit/gadgets/lookup_range_check.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 index 92840928..3b71d1f8 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md +++ b/book/src/design/circuit/gadgets/sinsemilla/commit-ivk.md @@ -71,7 +71,7 @@ $$ $$ where $\BoolCheck{x} = x \cdot (1 - x)$ and $\ShortLookupRangeCheck{}$ is a -[short lookup range check](../lookup_range_check.md#short-range-check). +[short lookup range check](../decomposition.md#short-range-check). ## Decomposition constraints diff --git a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md index 45a6871c..0250c46f 100644 --- a/book/src/design/circuit/gadgets/sinsemilla/note-commit.md +++ b/book/src/design/circuit/gadgets/sinsemilla/note-commit.md @@ -121,7 +121,7 @@ $$ where: - $\BoolCheck{x} = x \cdot (1 - x)$. -- $\ShortLookupRangeCheck{}$ is a [short lookup range check](../lookup_range_check.md#short-range-check). +- $\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 @@ -186,6 +186,45 @@ $$ \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)})$, @@ -265,6 +304,41 @@ $$ \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}$: @@ -294,6 +368,9 @@ $$ \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}$: