diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic index 281fc2fb13..d145a4877e 100644 --- a/.config/dictionaries/project.dic +++ b/.config/dictionaries/project.dic @@ -43,6 +43,7 @@ Chotivichit chromedriver chrono ciphertext +ciphertexts CIPs COCOAPODS codegen diff --git a/docs/src/architecture/08_concepts/voting_transaction/crypto.md b/docs/src/architecture/08_concepts/voting_transaction/crypto.md index 5ae02eeaa1..0b4db24a3f 100644 --- a/docs/src/architecture/08_concepts/voting_transaction/crypto.md +++ b/docs/src/architecture/08_concepts/voting_transaction/crypto.md @@ -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. @@ -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.
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, @@ -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 \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} 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$ -#### Vote encrypting +#### Vote encryption 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).
-$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), @@ -143,7 +144,7 @@ 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$, @@ -151,7 +152,7 @@ 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. @@ -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$). @@ -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} @@ -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. + ## D: Non-Interactive ZK Vote Proof @@ -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} @@ -470,15 +482,15 @@ $\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: @@ -486,7 +498,7 @@ To compute it, prover needs to perform the next steps: * $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]$. @@ -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`. @@ -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`: @@ -589,8 +601,8 @@ using exactly that secret key, which is corresponds to the some shared public key. -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]. It is assumed that the original encryption and decryption is performing by ElGamal scheme. @@ -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 @@ -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