Skip to content

Commit

Permalink
feat(docs): Update crypto docs (#909)
Browse files Browse the repository at this point in the history
* Slightly updated crypto document

* update Homomorphic Tally section

* fix spelling

* fix markdown

* update ZK tally proof section

* fix

* apply blue's comments

* fix spelling and markdown checks

* wip

* fix
  • Loading branch information
Mr-Leshiy authored Oct 7, 2024
1 parent 9d886f6 commit def3254
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 64 deletions.
1 change: 1 addition & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Chotivichit
chromedriver
chrono
ciphertext
ciphertexts
CIPs
COCOAPODS
codegen
Expand Down
141 changes: 77 additions & 64 deletions docs/src/architecture/08_concepts/voting_transaction/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The protocol is based around the following entities:
Or it could be defined based on their stake in the blockchain,
which is more appropriate for web3 systems.

Important to note that the protocol defined for some **one** proposal.
Important to note that the protocol defined for **single** proposal.
Obviously, it could be easily scaled for a set of proposals,
performing protocol steps in parallel.

Expand Down Expand Up @@ -86,14 +86,14 @@ the length of such vector **must** be equal to the amount of the voting options
$i$ corresponds to the proposal voting choice and
defines that the $i$-th component of the unit vector equals to $1$
and the rest components are equals to $0$.
And it stands as an identifier of the unit vector and could varies $1 \le i \le M$,
And it stands as an identifier of the unit vector and could varies $0 \le i \le M - 1$,
$M$ - amount of the voting options.
<br/>
E.g. proposal has voting options $[Yes, No, Abstain]$:

* $\mathbf{e}_1$ equals to $(1,0,0)$ corresponds to $Yes$
* $\mathbf{e}_2$ equals to $(0,1,0)$ corresponds to $No$
* $\mathbf{e}_3$ equals to $(0,0,1)$ corresponds to $Abstain$
* $\mathbf{e}_0$ equals to $(1,0,0)$ corresponds to $Yes$
* $\mathbf{e}_1$ equals to $(0,1,0)$ corresponds to $No$
* $\mathbf{e}_2$ equals to $(0,0,1)$ corresponds to $Abstain$

Lets $e_{i,j}$ denote as an each component value of the unit vector $\mathbf{e}_i$.
Where $i$ is a unit vector's identifier as it was described before,
Expand All @@ -103,35 +103,36 @@ $M$ - amount of the voting options and equals to the length of the unit vector.
Using such notation unit vector $\mathbf{e}_i$ could be defined as
<!-- markdownlint-disable emphasis-style -->
\begin{equation}
\mathbf{e}_i = (e_{i,1}, \ldots, e_{i,M})
\mathbf{e}_i = [e_{i,0}, \ldots, e_{i,M - 1}]
\end{equation}
<!-- markdownlint-enable emphasis-style -->

E.g. for the unit vector
$\mathbf{e}_1 = (1,0,0)$
$\mathbf{e}_0 = [1,0,0]$
components would be defined as follows:

* $e_{1, 1}$ equals to $1$
* $e_{1, 2}$ equals to $0$
* $e_{1, 3}$ equals to $0$
* $e_{0, 0}$ equals to $1$
* $e_{0, 1}$ equals to $0$
* $e_{0, 2}$ equals to $0$

<!-- markdownlint-enable no-inline-html -->

#### Vote encrypting
#### Vote encryption

<!-- markdownlint-disable no-inline-html -->

After the choice is done (described in [section](#voting-choice)),
vote **must** be encrypted using shared election public key $pk$.

To achieve that, Lifted ElGamal encryption algorithm is used,
noted as $ElGamalEnc(message, randomness, public \; key)$.
To achieve that, Lifted ElGamal encryption algorithm is used `ElGamalEnc`,
noted as $VoteEnc(message, randomness, public \; key)$.
More detailed description of the lifted ElGamal algorithm
you can find in the [appendix B](#b-lifted-elgamal-encryptiondecryption).
<br/>
$ElGamalEnc(message, randomness, public \; key)$ algorithm produces a ciphertext $c$ as a result.
$VoteEnc(message, randomness, public \; key)$ algorithm produces
a ciphertext $c$ with the generated randomness $r$ as a result.
\begin{equation}
c = ElGamalEnc(message, randomness, public \; key)
c, r = VoteEnc(message, public \; key)
\end{equation}

To encrypt previously generated unit vector $\mathbf{e}_i$ ($i$ - voting choice identifier),
Expand All @@ -143,15 +144,15 @@ where $j$ is the same vector component's index $j$ value, $e_{i, j} => r_j$.
Then, for each vector component $e_{i,j}$ with the corresponding randomness $r_j$,
perform encryption algorithm applying shared election public key $pk$.
\begin{equation}
c_j = ElGamalEnc(e_{i,j}, r_j, pk)
c_j, r_j = VoteEnc(e_{i,j}, pk)
\end{equation}

As a result getting a vector $\mathbf{c}$ of ciphertext values $c_f$,
with the size equals of the size $\mathbf{e}_t$ unit vector,
equals to the amount of the voting options.
Lets denote this vector as:
\begin{equation}
\mathbf{c} = (c_1, \ldots, c_{M}) = (ElGamalEnc(e_{i,j}, r_j, pk), \ldots, ElGamalEnc(e_{i,M}, r_M, pk))
\mathbf{c}, \mathbf{r} = [(c_0, r_0), \ldots, (c_{M-1}, r_{M-1})] = (VoteEnc(e_{i,j}, pk), \ldots, VoteEnc(e_{i,M - 1}, pk))
\end{equation}

where $M$ is the voting options amount and $i$ is the index of the voting choice.
Expand All @@ -163,11 +164,11 @@ This is a first part of the published vote for a specific proposal.
#### Voter's proof

After the voter's choice is generated and encrypted,
it is crucial to prove that [encoding](#voting-choice) and [encryption](#vote-encrypting) are formed correctly
it is crucial to prove that [encoding](#voting-choice) and [encryption](#vote-encryption) are formed correctly
(i.e. that the voter indeed encrypt a unit vector).

Because by the definition of the encryption algorithm $ElGamalEnc(message, randomness, public \; key)$
it is possible to encrypt an any message value,
Because by the definition of the encryption algorithm $VoteEnc(message, public \; key)$
encrypts any message value,
it is not restricted for encryption only $0$ and $1$ values
(as it was stated in the previous [section](#voting-choice),
unit vector components only could be $0$ or $1$).
Expand All @@ -180,7 +181,7 @@ noted as $VoteProof(\mathbf{c}, \mathbf{e}_i, \mathbf{r}, pk)$.
It takes an encrypted vote vector $\mathbf{c}$,
an original vote unit vector $\mathbf{e}_i$,
a randomness vector $\mathbf{r}$,
which was used during encryption algorithm $ElGamalEnc$
which was used during encryption algorithm $VoteEnc$
and an shared election public key $pk$.
As a result it generates a proof value $\pi$.
\begin{equation}
Expand Down Expand Up @@ -419,13 +420,24 @@ Tally(i, [\mathbf{c_1}, \mathbf{c_2}, \ldots, \mathbf{c_N}], [\alpha_1, \alpha_2
\end{equation}

Where $c_{j, i}$ - an encrypted corresponded $i$-th vector's component of the encrypted vote $\mathbf{c_j}$.
As it was stated in this [section](#vote-encrypting) each encrypted vote is a vector
As it was stated in this [section](#vote-encryption) each encrypted vote is a vector
$\mathbf{c_j} = (c_{j, 1}, \ldots, c_{j, M})$, $M$ - number of voting choices.

$er_i$ noted as encrypted tally result for the provided $i$-th voting choice.
As it is not an open decrypted value yet,
it needs a decryption procedure corresponded for which encryption one was made.

Important to note that the resulted value $er_i$ is a ciphertext, the same as $c_{j, i}$.
So $er_i = (er_{i, 1}, er_{i, 2})$ consists of elements $er_{i, 1}, er_{i, 2} \in \mathbb{G}$.
Operations which are applied for pair $c_{j, i} \circ c_{j+1, i}$, actually means the following:

\begin{equation}
c_{j, i} \circ c_{j+1, i} = (c_{j, i, 1} \circ c_{j+1, i, 1},\quad c_{j, i, 2} \circ c_{j+1, i, 2})
\end{equation}

So $\circ$ operation applied separately for each corresponding items of the ciphertexts $c_{j, i}, c_{j+1, i}$
and in the result we are getting a new ciphertext.

<!-- markdownlint-enable no-inline-html -->

## D: Non-Interactive ZK Vote Proof
Expand Down Expand Up @@ -456,7 +468,7 @@ The prover algorithm takes as arguments:

So basically here is the relation between all these values:
\begin{equation}
\mathbf{c} = (c_1, \ldots, c_M) = (ElGamalEnc(e_{i,1}, r_1, pk), \ldots, ElGamalEnc(e_{i,M}, r_M, pk))
\mathbf{c} = (c_1, \ldots, c_M) = (VoteEnc(e_{i,1}, r_1, pk), \ldots, VoteEnc(e_{i,M}, r_M, pk))
\end{equation}

\begin{equation}
Expand All @@ -470,23 +482,23 @@ $\pi$ is the final proof.
To compute it, prover needs to perform the next steps:

1. If the number of voting options $M$ is not a perfect power of $2$,
extend the vector $\mathbf{c}$ with $c_j = ElGamalEnc(0, 0, pk)$,
extend the vector $\mathbf{c}$ with $c_j = VoteEnc(0, 0, pk)$,
where $N$ is a perfect power of $2$, $j \in [M, \ldots, N - 1]$.
So the resulted $\mathbf{c} = (c_1, \ldots, c_M, \{c_j\})$.
2. Generate a commitment key $ck \in \mathbb{G}$.
3. Let $i_k$ is a bit value of the $i$-th binary representation,
3. Let $i_k$ is a bit value of the $i$-th binary representation (little-endian order),
where $k \in [0, log_2(N) - 1]$.
E.g. $i=3$ and $N=8, log_2(N) = 3$,
its binary representation $i=011$,
$i_0=0, i_1=1, i_2=1$.
$i_0=1, i_1=1, i_2=0$.
4. For $l \in [0, \ldots, log_2(N)-1]$ generate a random values
$\alpha_l, \beta_l, \gamma_l, \delta_l, \in \mathbb{Z}_q$.
5. For $l \in [0, \ldots, log_2(N)-1]$ calculate, where $g$ is the group generator:
* $I_l = g^{i_l} \circ ck^{\alpha_l}, I_l \in \mathbb{G}$.
* $B_l = g^{\beta_l} \circ ck^{\gamma_l}, B_l \in \mathbb{G}$.
* $A_l = g^{i_l * \beta_l} \circ ck^{\delta_l}, A_l \in \mathbb{G}$.
6. Calculate a first verifier challenge
$com_1 = H(ck, pk, \{c_j\}, \{I_l\}, \{B_l\}, \{A_l\})$,
$ch_1 = H(ck, pk, \{c_j\}, \{I_l\}, \{B_l\}, \{A_l\})$,
where $H$ is a hash function,
$j \in [0, \ldots, N-1]$
and $l \in [0, \ldots, log_2(N)-1]$.
Expand All @@ -498,19 +510,19 @@ To compute it, prover needs to perform the next steps:
* Calculate the polynomial itself $p_j(x) = \prod_{l=0}^{log_2(N)-1} z_l^{j_l}$
8. For $l \in [0, \ldots, log_2(N)-1]$ generate a random $R_l \in \mathbb{Z}_q$.
9. For $l \in [0, \ldots, log_2(N)-1]$ compute
$D_l = ElGamalEnc(sum_l, R_l, pk)$,
where $sum_l = \sum_{j=0}^{N-1}(p_{j,l} * com_1^j)$
$D_l = VoteEnc(sum_l, R_l, pk)$,
where $sum_l = \sum_{j=0}^{N-1}(p_{j,l} * ch_1^j)$
and $p_{j,l}$ - corresponding coefficients of the polynomial $p_j(x)$ calculated on step `7`.
10. Calculate a second verifier challenge
$com_2 = H(com_1, \{D_l\})$,
$ch_2 = H(ch_1, \{D_l\})$,
where $H$ is a hash function
and $l \in [0, \ldots, log_2(N)-1]$.
11. For $l \in [0, \ldots, log_2(N)-1]$ calculate:
* $z_l = i_l * com_2 + \beta_l, z_l \in \mathbb{Z}_q$.
* $w_l = \alpha_l * com_2 + \gamma_l, w_l \in \mathbb{Z}_q$.
* $v_l = \alpha_l * (com_2 - z_l) + \delta_l, v_l \in \mathbb{Z}_q$.
* $z_l = i_l * ch_2 + \beta_l, z_l \in \mathbb{Z}_q$.
* $w_l = \alpha_l * ch_2 + \gamma_l, w_l \in \mathbb{Z}_q$.
* $v_l = \alpha_l * (ch_2 - z_l) + \delta_l, v_l \in \mathbb{Z}_q$.
12. Calculate
$R=\sum_{j=0}^{N-1}(r_j * (com_2)^{log_2(N)} * (com_1)^j) + \sum_{l=0}^{log_2(N)-1}(R_l * (com_2)^l)$,
$R=\sum_{j=0}^{N-1}(r_j * (ch_2)^{log_2(N)} * (ch_1)^j) + \sum_{l=0}^{log_2(N)-1}(R_l * (ch_2)^l)$,
where $r_j$ original random values which was used to encrypt $c_j$
and $R_l$ random values generated in step `8`.

Expand All @@ -537,42 +549,42 @@ Knowing that $\pi$ equals to $(ck, \{I_l\}, \{B_l\}, \{A_l\}, \{D_l\}, \{z_l\},
verifier needs to perform the next steps:

1. If the number of voting options $M$ is not a perfect power of $2$,
extend the vector $\mathbf{c}$ with $c_j = ElGamalEnc(0, 0, pk)$,
extend the vector $\mathbf{c}$ with $c_j = VoteEnc(0, 0, pk)$,
where $N$ is a perfect power of $2$, $j \in [M, \ldots, N - 1]$.
So the resulted $\mathbf{c} = (c_1, \ldots, c_M, \{c_j\})$.
2. Calculate the first verifier challenge
$com_1 = H(ck, pk, \{c_j\}, \{I_l\}, \{B_l\}, \{A_l\})$,
$ch_1 = H(ck, pk, \{c_j\}, \{I_l\}, \{B_l\}, \{A_l\})$,
where $H$ is a hash function,
$j \in [0, \ldots, N-1]$
and $l \in [0, \ldots, log_2(N)-1]$.
3. Calculate a second verifier challenge
$com_2 = H(com_1, \{D_l\})$,
$ch_2 = H(ch_1, \{D_l\})$,
where $H$ is a hash function
and $l \in [0, \ldots, log_2(N)-1]$.
4. For $l \in [0, \ldots, log_2(N)-1]$ verify that the following statements are `true`,
where $g$ is the group generator:
* $(I_l)^{com_2} \circ B_l == g^{z_l} \circ ck^{w_l}$.
* $(I_l)^{com_2 - z_l} \circ A_l == g^{0} \circ ck^{v_l}$.
5. Calculate the following $Left = ElGamalEnc(0, R, pk)$.
* $(I_l)^{ch_2} \circ B_l == g^{z_l} \circ ck^{w_l}$.
* $(I_l)^{ch_2 - z_l} \circ A_l == g^{0} \circ ck^{v_l}$.
5. Calculate the following $Left = VoteEnc(0, R, pk)$.
Note that the $Left$ is a ciphertext, $Left = (Left_1, Left_2)$.
6. Note that $D_l$ is a ciphertext,
$D_l = (D_{l,1}, D_{l,2})$, for $l \in [0, \ldots, log_2(N)-1]$
calculate the following:
* $Right2_1 = (D_{0,1})^{0} \circ \ldots \circ (D_{log_2(N) - 1,1})^{log_2(N) - 1}$.
* $Right2_2 = (D_{0,2})^{0} \circ \ldots \circ (D_{log_2(N) - 1,2})^{log_2(N) - 1}$.
7. For $j \in [0, \ldots, N-1]$ calculate the $p_j(com_2)$,
* $Right2_1 = (D_{0,1})^{ch_2^{0}} \circ \ldots \circ (D_{log_2(N) - 1,1})^{ch_2^{log_2(N) - 1}}$.
* $Right2_2 = (D_{0,2})^{ch_2^{0}} \circ \ldots \circ (D_{log_2(N) - 1,2})^{ch_2^{log_2(N) - 1}}$.
7. For $j \in [0, \ldots, N-1]$ calculate the $p_j(ch_2)$,
where $p_j$ is a prover's defined polynomial defined in step `7`:
* $j_l$ is a bit value of the $j$-th binary representation.
* $z_l^1 = z_j$.
* $z_l^0 = com_2 - z_j^1$.
* $p_j(com_2) = \prod_l^{log_2(N)-1} z_l^{j_l}$.
8. For $j \in [0, \ldots, N-1]$ calculate the $P_j = ElGamalEnc(-p_j(com_2), 0, pk)$.
* $z_l^0 = ch_2 - z_j^1$.
* $p_j(ch_2) = \prod_l^{log_2(N)-1} z_l^{j_l}$.
8. For $j \in [0, \ldots, N-1]$ calculate the $P_j = VoteEnc(-p_j(ch_2), 0, pk)$.
Note that the $P_j$ is a ciphertext, $P_j = (P_{j,1}, P_{j,2})$.
9. Note that $C_j$ is a ciphertext,
$C_j = (C_{j,1}, C_{j,2})$, for $j \in [0, \ldots, N-1]$
calculate:
* $Right1_{j,1} = (C_{j,1})^{com_2^{log_2(N)}} \circ (P_{j,1})^{com_1^{j}}$.
* $Right1_{j,2} = (C_{j,2})^{com_2^{log_2(N)}} \circ (P_{j,2})^{com_1^{j}}$.
* $Right1_{j,1} = (C_{j,1})^{ch_2^{log_2(N)}} \circ (P_{j,1})^{ch_1^{j}}$.
* $Right1_{j,2} = (C_{j,2})^{ch_2^{log_2(N)}} \circ (P_{j,2})^{ch_1^{j}}$.
* $Right1_{1} = Right1_{j,1} \circ \ldots \circ Right1_{N - 1, 1}$.
* $Right1_{2} = Right1_{j,2} \circ \ldots \circ Right1_{N - 1, 2}$.
10. Verify that the following statements are `true`:
Expand All @@ -589,8 +601,8 @@ using exactly that secret key,
which is corresponds to the some shared public key.

<!-- markdownlint-disable max-one-sentence-per-line -->
A more detailed and formal description
you can find in the sections *Fig. 10* and *2.1.5* of this [paper][treasury_system_spec].
It is a slightly modified version of the algorithm described in the sections
*Fig. 10* and *2.1.5* of this [paper][treasury_system_spec].
<!-- markdownlint-enable max-one-sentence-per-line -->

It is assumed that the original encryption and decryption is performing by ElGamal scheme.
Expand All @@ -611,16 +623,16 @@ TallyProof(enc, sk) = \pi
$\pi$ is the final proof.
To compute it, prover needs to perform the next steps:

1. Take the first element of the ciphertext $enc = (enc_1, enc_2)$
and calculate $d = enc_1^{sk}$.
2. Generate a random value $\mu, \quad \mu \in \mathbb{Z}_q$.
3. Compute $A_1 = g^{\mu}$, where $g$ is the group generator ($A_1 \in \mathbb{G}$).
4. Compute $A_2 = (enc_1)^{\mu}, \quad A_2 \in \mathbb{G}$.
5. Compute $e = H(pk, d, g, enc_1, A_1, A_2 )$,
1. Take the first element of the ciphertext $enc = (enc_1, enc_2)$.
2. Calculate $d = enc_1^{sk}, \quad d \in \mathbb{G}$.
3. Generate a random value $\mu, \quad \mu \in \mathbb{Z}_q$.
4. Compute $A_1 = g^{\mu}$, where $g$ is the group generator ($A_1 \in \mathbb{G}$).
5. Compute $A_2 = (enc_1)^{\mu}, \quad A_2 \in \mathbb{G}$.
6. Compute $с = H(pk, d, g, enc_1, A_1, A_2)$,
where $pk$ is a corresponding public key of $sk$, $H$ is a hash function.
6. Compute $z = sk * e + \mu, \quad z \in \mathbb{Z}_q$.
7. Compute $z = sk * с + \mu, \quad z \in \mathbb{Z}_q$.

Finally, the proof is $\pi = (A_1, A_2, z)$.
Finally, the proof is $\pi = (с, z)$.

### Verifier

Expand All @@ -639,17 +651,18 @@ TallyCheck(enc, dec, pk, \pi) = true | false
As a result algorithm will return `true` or `false`,
is the verification was succeeded or not respectively.

Knowing that $\pi$ equals to $(A_1, A_2, z)$,
Knowing that $\pi$ equals to $(с, z)$,
verifier needs to perform the next steps:

1. Take the first and second elements $enc_1, enc_2$
of the ciphertext $enc = (enc_1, enc_2)$.
2. Calculate $d = g^{dec} \circ (-enc_2), \quad d \in \mathbb{G}$.
3. Compute $e = H(pk, d, g, enc_1, A_1, A_2 )$, where $g$ is the group generator.
4. Verify $g^z == pk^e \circ A_1$.
5. Verify $enc_1^z == d^e \circ A_2$.
2. Calculate $d = enc_2 \circ g^{-dec}, \quad d \in \mathbb{G}$.
3. Calculate $A_1 = g^{z} \circ pk^{-c}, \quad A_1 \in \mathbb{G}$.
4. Calculate $A_2 = enc_1^{z} \circ d^{-c}, \quad A_2 \in \mathbb{G}$.
5. Compute $с2 = H(pk, d, g, enc_1, A_1, A_2)$, where $g$ is the group generator.
6. Verify $с == с2$.

If step `3` and `4` returns `true` so the final result is `true` otherwise return `false`.
If step `6` returns `true` so the final result is `true` otherwise return `false`.

## Rationale

Expand Down

0 comments on commit def3254

Please sign in to comment.