Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Engagement notes 2023 #118

Merged
merged 13 commits into from
Mar 7, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl ValidatorKeysUpdatesGadget {
&GingerMHTParams::ZERO_NODE_CST.unwrap().nodes[0],
);

let mut validator_mktree_leaves_g = Vec::with_capacity(max_pks);
let mut validator_mktree_leaves_g = Vec::with_capacity(max_pks*2);

for (i, (signing_key_g, master_key_g)) in sig_keys_g.iter().zip(master_keys_g).enumerate() {
// Enforce signing key hash
Expand Down
47 changes: 16 additions & 31 deletions doc/GenericThresholdCircuit.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
# Generic Threshold Circuit for Schnorr Signatures

We describe a generic counting and threshold comparison procedure for Schnorr signatures (as in [ginger-lib's SchnorrSignature.pdf](https://github.com/HorizenOfficial/ginger-lib/blob/development/doc/SchnorrSignature.pdf)) formulated as circuit over the 'SNARK field' $F$ with modulus bit length denoted by $len|F|$. As a fixed circuit it should be able to treat up to
$$
N < L=len|F|,
$$
We describe a generic counting and threshold comparison procedure for Schnorr signatures (as in [ginger-lib's SchnorrSignature.pdf](https://github.com/HorizenOfficial/ginger-lib/blob/development/doc/SchnorrSignature.pdf)) formulated as circuit over the 'SNARK field' $F$ with modulus bit length denoted by $len|F|$. As a fixed circuit it should be able to treat up to
$$N < L=len|F|,$$
public keys,
$$
pk_1,pk_2,\ldots, pk_N,
$$
$$pk_1,pk_2,\ldots, pk_N,$$
arranged in a linearly ordered list, with *Null keys* $pk_{NULL}$ to fill up to the maximum number $N$, if there a less signer.

#### Normative notes

For our purpose, we assume $pk_{NULL}\in \mathbb G$ to be a *phantom key*, i.e. an arbitrary fixed element from the group $\mathbb G= MNT4-753=EC(F)$ (as used by the signature scheme) to which nobody knows the secret key. A simple way to do this in a publicly verifiable manner is by choosing it as hash of some public data, for example
$$
pk_{NULL} = H(\text{"magic string")},
$$
For our purpose, we assume $pk_{NULL} \in \mathbb G$ to be a *phantom key*, i.e. an arbitrary fixed element from the group $\mathbb G= MNT4-753=EC(F)$ (as used by the signature scheme) to which nobody knows the secret key. A simple way to do this in a publicly verifiable manner is by choosing it as hash of some public data, for example
$$pk_{NULL} = H(\text{"magic string")},$$
where $H$ is any hash-to-curve algorithm and some publicly declared "magic string" (e.g. $\text{"Strontium Sr 90"}$).

Notice that the upper bound for $N$ is quite arbitrarily chosen to satisfy
$$
d = len(N) < len|F|-1,
$$
$$d = len(N) < len|F|-1,$$
as needed for the threshold enforcer described below, and not too large anyway for performance. However, any other $N$ the bit length of which satisfies the above inequality is fine.

## The Generic Threshold Gadget
Expand All @@ -34,7 +26,7 @@ Our gadget $Threshold(m,h)$ is as follows.
- Private input / witnesses:
- the threshold $t\in F$,
- the public keys $pk_1,\ldots, pk_{N}$ (including possible null keys) in the same order as done for the computation of $h$,
- Schnorr signatures $\sigma_1,\ldots,\sigma_{N}$, including arbitrarily chosen null signatures $\sigma_{NULL}$ (e.g., $\sigma_{NULL}=(0,0)$) to fill up to full length,
- Schnorr signatures $\sigma_1,\ldots,\sigma_{N}$, including arbitrarily chosen null signatures $\sigma_{NULL}$ (e.g., $\sigma_{NULL}=\left( 1,1\right) \phantom{}$) to fill up to full length,
- Boolean variables $b_0,\ldots,b_{d-1}$ for the threshold comparison.

It's circuit is based on three components, as depicted below:
Expand All @@ -52,31 +44,24 @@ is as described in [ginger-lib's Poseidon.pdf](https://github.com/HorizenOfficia
### Threshold enforcer

To guarantee that two integers $x$, $t$ from $I=\left[0,2^d-1\right]$ as subset of $F$ satisfy $x\geq t$, we take $x-t$ in $F$ and force it to be in the same interval $I$ simply by demanding an at most $d$ bit integer representation
$$
\begin{align*}
x &= \sum_{k=0}^{d-1} b_k\cdot 2^k.
\\
0 &= b_k\cdot (b_k-1), &k=0,\ldots,d-1.
\end{align*}
$$
```math
\begin{align*} x &= \sum_{k=0}^{d-1}b_k \cdot 2^k \\ 0 &= b_k \cdot (b_k-1), &k=0, \ldots ,d-1\end{align*}
```
Note that $d$ needs to be smaller than the length $L$ of the field modulus (In practice it is much smaller, e.g. $d=4$), so that $2^{d+1}< |F|$.

<img src="./pics/ThresholdEnforcer.svg.png" style="zoom:30%;" />

Notice that this gadget comes almost for free, demanding only $d+1$ rank one constraints.

Comment, or why it works although risking modular reduction at any point during the calculation: any integer solution $(b_i)$ of
$$
\begin{align*}x &= b_0+ b_1 \cdot 2 + ... + b_d\cdot 2^{d-1} \bmod r,\\0 &= b_i\cdot(1-b_i) \bmod r, &i=0,\ldots,d-1.\end{align*}
$$
```math
\begin{align*} x &= b_0+b_1 \cdot 2 + \dots + b_d\cdot 2^{d-1} \bmod r,\\ 0 &= b_i \cdot (1-b_i) \bmod r, &i=0,\ldots,d-1 \end{align*}
```
is forced by the Boolean constraints $0=b_i\cdot(1-b_i)$ to be of the form
$$
b_i = \epsilon_i + k\cdot r, \quad \epsilon_i\in\{0,1\},
$$
$$b_i = \epsilon_i + k\cdot r, \quad \epsilon_i\in\{0,1\},$$
where $k\cdot r$ is a (positive or negative) multiple of the modulus $r$. Hence, by the first equation, $x$ and
$$
\sum_{i=0}^{d-1} \epsilon_i\cdot 2^i
$$
$$\sum_{i=0}^{d-1} \epsilon_i\cdot 2^i$$

can still only differ by a multiple of $r$. But this means that $x$ has a representation (mod $r$) as an integer from $I$.


Expand Down
Binary file modified doc/GenericThresholdCircuit.pdf
Binary file not shown.