11 KiB
Fixed-base scalar multiplication
There are 6
fixed bases in the Orchard protocol:
\mathcal{K}^{\mathsf{Orchard}}
, used in deriving the nullifier;\mathcal{G}^{\mathsf{Orchard}}
, used in spend authorization;\mathcal{R}
base for\mathsf{NoteCommit}^{\mathsf{Orchard}}
;\mathcal{V}
and\mathcal{R}
bases for\mathsf{ValueCommit}^{\mathsf{Orchard}}
; and\mathcal{R}
base for\mathsf{Commit}^{\mathsf{ivk}}
.
Decompose scalar
We support fixed-base scalar multiplication with three types of scalars:
Full-width scalar
A 255
-bit scalar from \mathbb{F}_q
. We decompose a full-width scalar \alpha
into 85
3
-bit windows:
\alpha = k_0 + k_1 \cdot (2^3)^1 + \cdots + k_{84} \cdot (2^3)^{84}, k_i \in [0..2^3).
The scalar multiplication will be computed correctly for k_{0..84}
representing any
integer in the range [0, 2^{255})
- that is, the scalar is allowed to be non-canonical.
We range-constrain each 3
-bit word of the scalar decomposition using a polynomial range-check constraint:
\begin{array}{|c|l|}
\hline
\text{Degree} & \text{Constraint} \\\hline
9 & q_\texttt{mul\_fixed\_full} \cdot \RangeCheck{\text{word}}{2^3} = 0 \\\hline
\end{array}
where \RangeCheck{\text{word}}{\texttt{range}} = \text{word} \cdot (1 - \text{word}) \cdots (\texttt{range} - 1 - \text{word}).
Base field element
We support using a base field element as the scalar in fixed-base multiplication. This occurs, for example, in the scalar multiplication for the nullifier computation of the Action circuit \mathsf{DeriveNullifier_{nk}} = \mathsf{Extract}_\mathbb{P}\left(\left[(\mathsf{PRF_{nk}^{nfOrchard}}(\rho) + \psi) \bmod{q_\mathbb{P}}\right]\mathcal{K}^\mathsf{Orchard} + \mathsf{cm}\right)
: here, the scalar \left[(\mathsf{PRF_{nk}^{nfOrchard}}(\rho) + \psi) \bmod{q_\mathbb{P}}\right]
is the result of a base field addition.
Decompose the base field element \alpha
into three-bit windows, and range-constrain each window, using the short range decomposition gadget in strict mode, with W = 85, K = 3.
If k_{0..84}
is witnessed directly then no issue of canonicity arises. However, because the scalar is given as a base field element here, care must be taken to ensure a canonical representation, since 2^{255} > p
. That is, we must check that 0 \leq \alpha < p,
where p
the is Pallas base field modulus $p = 2^{254} + t_p = 2^{254} + 45560315531419706090280762371685220353.
Note that $t_p < 2^{130}.
To do this, we decompose \alpha
into three pieces: \alpha = \alpha_0 \text{ (252 bits) } ,||, \alpha_1 \text{ (2 bits) } ,||, \alpha_2 \text{ (1 bit) }.
We check the correctness of this decomposition by:
\begin{array}{|c|l|}
\hline
\text{Degree} & \text{Constraint} \\\hline
5 & q_\text{canon-base-field} \cdot \RangeCheck{\alpha_1}{2^2} = 0 \\\hline
3 & q_\text{canon-base-field} \cdot \BoolCheck{\alpha_2} = 0 \\\hline
2 & q_\text{canon-base-field} \cdot \left(z_{84} - (\alpha_1 + \alpha_2 \cdot 2^2)\right) = 0 \\\hline
\end{array}
If the MSB \alpha_2 = 0
is not set, then \alpha < 2^{254} < p.
However, in the case where \alpha_2 = 1
, we must check:
\alpha_2 = 1 \implies \alpha_1 = 0;
\alpha_2 = 1 \implies \alpha_0 < t_p
:\alpha_2 = 1 \implies 0 \leq \alpha_0 < 2^{130}
,\alpha_2 = 1 \implies 0 \leq \alpha_0 + 2^{130} - t_p < 2^{130}
To check that 0 \leq \alpha_0 < 2^{130},
we make use of the three-bit running sum decomposition:
- Firstly, we constrain
\alpha_0
to be a132
-bit value by enforcing its high120
bits to be all-zero. We can get\textsf{alpha\_0\_hi\_120}
from the decomposition:
\begin{aligned}
z_{44} &= k_{44} + 2^3 k_{45} + \cdots + 2^{3 \cdot (84 - 44)} k_{84}\\
\implies \textsf{alpha\_0\_hi\_120} &= z_{44} - 2^{3 \cdot (84 - 44)} k_{84}\\
&= z_{44} - 2^{3 \cdot (40)} z_{84}.
\end{aligned}
- Then, we constrain bits
130..\!\!=\!\!131
of\alpha_0
to be zeroes; in other words, we constrain the three-bit wordk_{43} = \alpha[129..\!\!=\!\!131] = \alpha_0[129..\!\!=\!\!131] \in \{0, 1\}.
We make use of the running sum decomposition to obtaink_{43} = z_{43} - z_{44} \cdot 2^3.
Define \alpha'_0 = \alpha_0 + 2^{130} - t_p
. To check that 0 \leq \alpha'_0 < 2^{130},
we use 13 ten-bit lookups, where we constrain the z_{13}
running sum output of the lookup to be 0
if \alpha_2 = 1.
\begin{array}{|c|l|l|}
\hline
\text{Degree} & \text{Constraint} & \text{Comment} \\\hline
2 & q_\text{canon-base-field} \cdot (\alpha_0' - (\alpha_0 + 2^{130} - t_\mathbb{P})) = 0 \\\hline
3 & q_\text{canon-base-field} \cdot \alpha_2 \cdot \alpha_1 = 0 & \alpha_2 = 1 \implies \alpha_1 = 0 \\\hline
3 & q_\text{canon-base-field} \cdot \alpha_2 \cdot \textsf{alpha\_0\_hi\_120} = 0 & \text{Constrain $\alpha_0$ to be a $132$-bit value} \\\hline
4 & q_\text{canon-base-field} \cdot \alpha_2 \cdot \BoolCheck{k_{43}} = 0 & \text{Constrain $\alpha_0[130..\!\!=\!\!131]$ to $0$} \\\hline
3 & q_\text{canon-base-field} \cdot \alpha_2 \cdot z_{13}(\texttt{lookup}(\alpha_0', 13)) = 0 & \alpha_2 = 1 \implies 0 \leq \alpha'_0 < 2^{130}\\\hline
\end{array}
Short signed scalar
A short signed scalar is witnessed as a magnitude m
and sign s
such that
s \in \{-1, 1\} \\
m \in [0, 2^{64}) \\
\mathsf{v^{old}} - \mathsf{v^{new}} = s \cdot m.
This is used for \mathsf{ValueCommit^{Orchard}}
. We want to compute \mathsf{ValueCommit^{Orchard}_{rcv}}(\mathsf{v^{old}} - \mathsf{v^{new}}) = [\mathsf{v^{old}} - \mathsf{v^{new}}] \mathcal{V} + [\mathsf{rcv}] \mathcal{R}
, where
-(2^{64}-1) \leq \mathsf{v^{old}} - \mathsf{v^{new}} \leq 2^{64}-1
\mathsf{v^{old}}
and \mathsf{v^{new}}
are each already constrained to 64
bits (by their use as inputs to \mathsf{NoteCommit^{Orchard}}
).
Decompose the magnitude m
into three-bit windows, and range-constrain each window, using the short range decomposition gadget in strict mode, with W = 22, K = 3.
We have two additional constraints:
\begin{array}{|c|l|l|}
\hline
\text{Degree} & \text{Constraint} & \text{Comment} \\\hline
3 & q_\texttt{mul\_fixed\_short} \cdot \BoolCheck{k_{21}} = 0 & \text{The last window must be a single bit.}\\\hline
3 & q_\texttt{mul\_fixed\_short} \cdot \left(s^2 - 1\right) = 0 &\text{The sign must be $1$ or $-1$.}\\\hline
\end{array}
where \BoolCheck{x} = x \cdot (1 - x)
.
Load fixed base
Then, we precompute multiples of the fixed base B
for each window. This takes the form of a window table: M[0..W)[0..8)
such that:
- for the first (W-1) rows
M[0..(W-1))[0..8)
:$M[w][k] = [(k+2) \cdot (2^3)^w]B
$ - in the last row
M[W-1][0..8)
:$M[w][k] = [k \cdot (2^3)^w - \sum\limits_{j=0}^{83} 2^{3j+1}]B
$
The additional (k + 2)
term lets us avoid adding the point at infinity in the case k = 0
. We offset these accumulated terms by subtracting them in the final window, i.e. we subtract \sum\limits_{j=0}^{W-2} 2^{3j+1}
.
Note: Although an offset of
(k + 1)
would naively suffice, it introduces an edge case whenk_0 = 7, k_1= 0
. In this case, the window table entries evaluate to the same point:
M[0][k_0] = [(7+1)*(2^3)^0]B = [8]B,
M[1][k_1] = [(0+1)*(2^3)^1]B = [8]B.
In fixed-base scalar multiplication, we sum the multiples of
B
at each window (except the last) using incomplete addition. Since the point doubling case is not handled by incomplete addition, we avoid it by using an offset of(k+2).
For each window of fixed-base multiples M[w] = (M[w][0], \cdots, M[w][7]), w \in [0..(W-1))
:
- Define a Lagrange interpolation polynomial
\mathcal{L}_x(k)
that mapsk \in [0..8)
to thex
-coordinate of the multipleM[w][k]
, i.e.\mathcal{L}_x(k) = \begin{cases} ([(k + 2) \cdot (2^3)^w] B)_x &\text{for } w \in [0..(W-1)); \\ ([k \cdot (2^3)^w - \sum\limits_{j=0}^{83} 2^{3j+1}] B)_x &\text{for } w = 84; \text{ and} \end{cases}
- Find a value
z_w
such thatz_w + (M[w][k])_y
is a squareu^2
in the field, but the wrong-signy
-coordinatez_w - (M[w][k])_y
does not produce a square.
- Find a value
Repeating this for all W
windows, we end up with:
- an
W \times 8
table\mathcal{L}_x
storing8
coefficients interpolating thex-$coordinate for each window. Each $x
-coordinate interpolation polynomial will be of the form
\mathcal{L}_x[w](k) = c_0 + c_1 \cdot k + c_2 \cdot k^2 + \cdots + c_7 \cdot k^7,
where k \in [0..8), w \in [0..85)
and c_k
's are the coefficients for each power of k
; and
- a length-
W
arrayZ
ofz_w
's.
We load these precomputed values into fixed columns whenever we do fixed-base scalar multiplication in the circuit.
Fixed-base scalar multiplication
Given a decomposed scalar \alpha
and a fixed base B
, we compute [\alpha]B
as follows:
- For each
k_w, w \in [0..85), k_w \in [0..8)
in the scalar decomposition, witness thex
- andy
-coordinates(x_w,y_w) = M[w][k_w].
- Check that
(x_w, y_w)
is on the curve:y_w^2 = x_w^3 + b
. - Witness
u_w
such thaty_w + z_w = u_w^2
. - For all windows but the last, use incomplete addition to sum the
M[w][k_w]
's, resulting in[\alpha - k_{84} \cdot (2^3)^{84} + \sum\limits_{j=0}^{83} 2^{3j+1}]B
. - For the last window, use complete addition
M[83][k_{83}] + M[84][k_{84}]
and return the final result.
Note: complete addition is required in the final step to correctly map
[0]B
to a representation of the point at infinity,(0,0)
; and also to handle a corner case for which the last step is a doubling.
\begin{array}{|c|l|}
\hline
\text{Degree} & \text{Constraint} \\\hline
8 & q_\text{mul-fixed} \cdot \left( \mathcal{L}_x[w](k_w) - x_w \right) = 0 \\\hline
4 & q_\text{mul-fixed} \cdot \left( y_w^2 - x_w^3 - b \right) = 0 \\\hline
3 & q_\text{mul-fixed} \cdot \left( u_w^2 - y_w - Z[w] \right) = 0 \\\hline
\end{array}
where b = 5
(from the Pallas curve equation).
Signed short exponent
Recall that the signed short exponent is witnessed as a 64-$bit magnitude $m
, and a sign s \in {1, -1}.
Using the above algorithm, we compute P = [m] \mathcal{B}
. Then, to get the final result P',
we conditionally negate P
using (x, y) \mapsto (x, s \cdot y)
.
\begin{array}{|c|l|}
\hline
\text{Degree} & \text{Constraint} \\\hline
3 & q_\texttt{mul\_fixed\_short} \cdot \left(P'_y - P_y\right) \cdot \left(P'_y + P_y\right) = 0 \\\hline
3 & q_\texttt{mul\_fixed\_short} \cdot \left(s \cdot P'_y - P_y\right) = 0 \\\hline
\end{array}
Layout
\begin{array}{|c|c|c|c|c|c|c|c|}
\hline
x_P & y_P & x_{QR} & y_{QR} & u & \text{window} & L_{0..=7} & \textsf{fixed\_z} \\\hline
x_{P,0} & y_{P,0} & & & u_0 & \text{window}_0 & L_{0..=7,0} & \textsf{fixed\_z}_0 \\\hline
x_{P,1} & y_{P,1} & x_{Q,1} = x_{P,0} & y_{Q,1} = y_{P,0} & u_1 & \text{window}_1 & L_{0..=7,1} & \textsf{fixed\_z}_1 \\\hline
x_{P,2} & y_{P,2} & x_{Q,2} = x_{R,1} & y_{Q,2} = y_{R,1} & u_2 & \text{window}_2 & L_{0..=7,1} & \textsf{fixed\_z}_2 \\\hline
\vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\\hline
\end{array}
Note: this doesn't include the last row that uses complete addition. In the implementation this is allocated in a different region.