From 368fe17d424c6cc9dbdd82a4afbeb2754c3ed1e9 Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Fri, 18 Oct 2024 13:18:52 +0300 Subject: [PATCH 1/3] move docs from catalyst-voices repo --- .../08_concepts/catalyst_voting/.pages | 4 + .../08_concepts/catalyst_voting/crypto.md | 685 ++++++++++++++++++ .../catalyst_voting/transaction.md | 136 ++++ .../08_concepts/catalyst_voting/tx_v1.abnf | 70 ++ 4 files changed, 895 insertions(+) create mode 100644 docs/src/architecture/08_concepts/catalyst_voting/.pages create mode 100644 docs/src/architecture/08_concepts/catalyst_voting/crypto.md create mode 100644 docs/src/architecture/08_concepts/catalyst_voting/transaction.md create mode 100644 docs/src/architecture/08_concepts/catalyst_voting/tx_v1.abnf diff --git a/docs/src/architecture/08_concepts/catalyst_voting/.pages b/docs/src/architecture/08_concepts/catalyst_voting/.pages new file mode 100644 index 0000000000..b3e6a7370e --- /dev/null +++ b/docs/src/architecture/08_concepts/catalyst_voting/.pages @@ -0,0 +1,4 @@ +title: Catalyst Voting +arrange: + - crypto.md + - transaction.md diff --git a/docs/src/architecture/08_concepts/catalyst_voting/crypto.md b/docs/src/architecture/08_concepts/catalyst_voting/crypto.md new file mode 100644 index 0000000000..04c6f5d8d4 --- /dev/null +++ b/docs/src/architecture/08_concepts/catalyst_voting/crypto.md @@ -0,0 +1,685 @@ + + +# Cryptography Schema + +--- + +Title: Voting Protocol Cryptography Schema + +Status: Proposed + +Authors: + - Alex Pozhylenkov + +Created: 2024-09-06 + +--- + +## Abstract + +This voting protocol is based on this [paper][treasury_system_paper] and on this [specification][treasury_system_spec], +so all formal definitions described in this document you can find there. +It provides a fully anonymous, secured, verifiable schema of casting votes +and performing tally process for executing "Catalyst" fund events. + +## Motivation + +## Specification + +### Preliminaries + +The protocol is based around the following entities: + +* **Proposal** - + voting subject on which each voter will be cast their votes. +* **Proposal voting options** - + a proposal options array, e.g. $[Yes, No, Abstain]$. +* **Voting committee** - + a special **trusted** entity, which perform tally process and revealing the results of the tallying. + Such committee consists of the 1 person. +* **Voters** - + actors who actually performing the voting by posting ballots with their voting choices. +* **Election public key** $pk$ - committees generated public key, + which is shared across all voters + and used for vote's encryption and tallying processes. +* **Voter's voting power** - + an integer value which defines a voting power for a specific voter. + This value could be equals to $1$ for every voter, + so everyone would be equal in their voting rights. + 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 **single** proposal. +Obviously, it could be easily scaled for a set of proposals, +performing protocol steps in parallel. + +### Initial setup + +Before any voting will start an initial setup procedure should be performed. + +* Define an array of voting options/choices for a proposal, e.g. $[Yes, No, Abstain]$. +* Voting committee must generate a shared election public key $pk$ and distribute it among voters. + A corresponding private key (secret share) $sk$ will be used to perform tally. +* Define for each voter their own voting power. + Basically this step could be done at any point of time, but before the tally. +* As most of the crypto algorithms are group dependent + (more about this you can read in [appendix A](#a-group-definition)), + it is needed to specifically define which cryptographically secure group would be used. +* Define a hash function which will be used by the underlying crypto algorithms. +* Define a commitment key $ck$, + which will be used during the voter proof generation and verification procedures. + +### Vote + +A voter could cast a vote for some proposal. +To do that, obviously, a voting choice should be made and encoded in specific format. +For achieving anonymity this voting choice must be homomorphically encrypted, +using the specific election public key $pk$, so afterwards voting committee could perform tally. +It is also important for the voter to generate a cryptographically secured proof, +that he has generated and encrypted a vote correctly and according to the protocol, +and everyone would be able to verify it. +So we will preserve anonymity without lacking transparency and correctness. + +#### Voting choice + + +For some proposal, voter generates a unit vector $\mathbf{e}_i$, +the length of such vector **must** be equal to the amount of the voting options of the proposal. +
+$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 $0 \le i \le M - 1$, +$M$ - amount of the voting options. +
+E.g. proposal has voting options $[Yes, No, 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, +$j$ index of the unit vector's component, which could varies $1 \le j \le M$, +$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,0}, \ldots, e_{i,M - 1}] +\end{equation} + + +E.g. for the unit vector +$\mathbf{e}_0 = [1,0,0]$ +components would be defined as follows: + +* $e_{0, 0}$ equals to $1$ +* $e_{0, 1}$ equals to $0$ +* $e_{0, 2}$ equals to $0$ + + + +#### 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 `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). +
+$VoteEnc(message, randomness, public \; key)$ algorithm produces +a ciphertext $c$ with the generated randomness $r$ as a result. +\begin{equation} +c, r = VoteEnc(message, public \; key) +\end{equation} + +To encrypt previously generated unit vector $\mathbf{e}_i$ ($i$ - voting choice identifier), +for each vector component value $e_{i,j}$ generate a corresponding randomness. +
+Lets denote randomness value as $r_j$, +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, 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}, \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. + +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-encryption) are formed correctly +(i.e. that the voter indeed encrypt a unit vector). + +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$). +That's why it is needed to generate such a proof, +so everyone could validate a correctness of the encrypted vote data, +without revealing a voting choice itself. + +To achieve that a some sophisticated ZK (Zero Knowledge) algorithm is used, +noted as $VoteProof(\mathbf{c}, \mathbf{e}_i, \mathbf{r}, pk, ck)$. +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 $VoteEnc$ +a shared election public key $pk$ and a commitment key $ck$. +As a result it generates a proof value $\pi$. +\begin{equation} +\pi = VoteProof(\mathbf{c}, \mathbf{e}_i, \mathbf{r}, pk, ck) +\end{equation} + +So to validate a $VoteCheck(\mathbf{c}, \pi, pk, ck)$ procedure should be used, +which takes an encrypted vote $\mathbf{c}$, corresponded proof $\pi$, +the same shared election public key $pk$ and a commitment key $ck$ +as arguments and returns `true` or `false`, +is it valid or not. +\begin{equation} +true | false = VoteCheck(\mathbf{c}, \pi, pk, ck) +\end{equation} + +A more detailed description of how $VoteProof$, $VoteCheck$ work +you can find in the [appendix D](#d-non-interactive-zk-vote-proof). + +#### Vote publishing + +After all these procedures are done, +a final step is to publish an encrypted vote $\mathbf{c}$ +and voter's proof $\pi$ corresponded to this choice. +It could be published using any public channel, e.g. blockchain, ipfs or through p2p network. + +### Tally + + + +After voters performed voting procedure and encrypted votes are published, +tally could be executed by the voting committee. +Important to note, voting committee doing tally does not revealing personal voting choices. + +By the result of tally procedure means +an accumulated sum of voting power for each voting option of the proposal, +based on published votes. +
+E.g.: + + +* proposal with voting options $[Yes, No, Abstain]$ +* two different voters with their voting power: + * "Alice" with voting power $10$ + * "Bob" with voting power $30$ +* these voter's published their choices on this proposal: + * "Alice" voted $Yes$ + * "Bob" voted $No$ +* final result would be the following: + * $Yes$ accumulated $10$ + * $No$ accumulated $30$ + * $Abstain$ accumulated $0$ + + +So to replicate the same process but securely, +based on the set of encrypted votes $\mathbf{c}$, +a special $Tally$, $TallyDec$ and $TallyProof$ algorithms are used. + + + +#### Homomorphic tally + +To perform homomorphic tally of the encrypted set of votes, +$Tally$ algorithm is used which described in [appendix C](#c-homomorphic-tally). +It takes as an input the following: + +* $[\mathbf{c_1}, \mathbf{c_2}, \ldots, \mathbf{c}_{N}]$ - + an array of all published encrypted vote's. +* $[\alpha_1, \alpha_2, \ldots, \alpha_N]$ - an array of corresponded voter's voting power. +* $i$ - voting option index. + +Where $N$ - votes amount. + +And produce an encrypted tally result for voting option $i$. +\begin{equation} +er_i = Tally(i, [\mathbf{c_1}, \mathbf{c_2}, \ldots, \mathbf{c_N}], [\alpha_1, \alpha_2, \ldots, \alpha_N]) +\end{equation} + +E.g. a proposal with voting choices $[Yes, No]$, +votes $[\mathbf{c_1}, \mathbf{c_2}]$, +voting powers $[\alpha_1, \alpha_2]$ +and election secret key $sk$. + +* Encrypted result for option $Yes$: $er_1 = Tally(1, [\mathbf{c_1}, \mathbf{c_2}], [\alpha_1, \alpha_2])$. +* Encrypted result for option $No$: $er_2 = Tally(2, [\mathbf{c_1}, \mathbf{c_2}], [\alpha_1, \alpha_2])$ + +#### Tally decryption + +To decrypt each calculated tally result from the previous [step](#homomorphic-tally), +$TallyDec$ is used, +which is technically a common $ElGamalDec$ algorithm described in [appendix B](#b-lifted-elgamal-encryptiondecryption). +It takes as an input the following: + +* $sk$ - an election private key held by voting committee. +* $er_i$ - an encrypted tally result for the specific voting option defined for a proposal. + +It produces a decrypted tally result for the voting option of a proposal. +\begin{equation} +r_i = ElGamalDec(er_i, sk) = TallyDec(er_i, sk) +\end{equation} + +This decrypted tally result is an exact result of the voting procedure, +which represents an outcome of the election process. + +E.g. a proposal with voting choices $[Yes, No]$, +encrypted tally results $[er_1, er_2]$ +and election secret key $sk$. + +* Decrypted result for option $Yes$: $r_1 = TallyDec(er_1, sk)$. +* Decrypted result for option $No$: $r_2 = TallyDec(er_2, sk)$ + +#### Tally proof + +An important step for bringing transparency and exclude misbehaving from the voting committee, +a corresponded proof for each decrypted tally result **must** be generated. + +It is necessary to verify that encrypted tally was decrypted exactly by using committee secret key, +and not any other. +So the publicly published decrypted tally result (a final tally result) actually is correct and +represents a proper election outcome. + +To do that, a sophisticated ZK (Zero Knowledge) $TallyProof$ algorithm is used. +Which proofs that a provided encrypted tally result value $er$ was decrypted into tally result $r$ +using the exact secret key $sk$, +which is corresponded to the already known shared election public key $pk$. +\begin{equation} +\pi = TallyProof(er, sk) +\end{equation} + +So to validate a $TallyCheck(er, r, pk, \pi)$ procedure should be used, +which takes an encrypted tally result $er$, decrypted tally result $r$, +election public key $pk$ and corresponded proof $\pi$ +as arguments and returns `true` or `false`, +is it valid or not. +\begin{equation} +true | false = TallyCheck(er, r, pk, \pi) +\end{equation} + +A more detailed description of how $TallyProof$, $TallyCheck$ work +you can find in the [appendix E](#e-non-interactive-zk-tally-proof). + +#### Tally publishing + +After all these procedures are done, +a final step is to publish an encrypted tally results $er_i$, +decrypted tally results $r_i$ +and tally proofs $\pi_i$ +corresponded for each voting option of some proposal. +It could be published using any public channel, e.g. blockchain, ipfs or through p2p network. + +## A: Group Definition + + + +Important to note that some crypto algorithms, which are described below, are group $\mathbb{G}$ dependant. +More detailed about groups you can find at section *8.2.1* section on this [book][crypto_book]. +
+Therefore, the generalized notation of the group operation used - $\circ$. +And defined as follows: + +* For all $a, b \in \mathbb{G}$, $a \circ b = c$, where $c \in \mathbb{G}$. +* For all $a \in \mathbb{G}$, and $n \in \mathbb{Z}$, $a^n = a \circ a \ldots \circ a$ ($n$ - times). +* There is an element noted as $1$, called *neutral* element, + such that $a \circ 1 = a$, for all $a \in \mathbb{G}$. +* For each element $a \in \mathbb{G}$ exists $a^{-1} \in \mathbb{G}$, + called the inversed of $a$, such that $a \circ a^{-1} = a^{-1} \circ a = 1$. + + + +## B: Lifted ElGamal Encryption/Decryption + + + +Lifted ElGamal encryption schema is defined over +any cyclic group $\mathbb{G}$ of order $q$ with group generator $g$ ($g \in \mathbb{G}$). +It could be multiplicative group of integers modulo $n$ or some elliptic curve over the finite field group. +
+More detailed how group operations are defined, described in [appendix A](#a-group-definition). + +### Encryption + +Lifted ElGamal encryption algorithm +takes as arguments: + +* $m$ - message ($m \in \mathbb{Z}_q$) +* $r$ - randomness ($r \in \mathbb{Z}_q$) +* $pk$ - public key ($pk \in \mathbb{G}$) + +\begin{equation} +ElGamalEnc(m, r, pk) = (c_1, c_2) = c, +\end{equation} + +\begin{equation} +c_1 = g^r, \quad c_2 = g^m \circ pk^r +\end{equation} + +$c$ - is a resulted ciphertext which consists of two elements $c_1, c_2 \in \mathbb{G}$. + +### Decryption + +Lifted ElGamal decryption algorithm takes as arguments: + +* $c$ - ciphertext, +* $sk$ - secret key ($sk \in \mathbb{Z}_q$) + +\begin{equation} +ElGamalDec(c, sk) = Dlog(c_2 \circ c_1^{-sk}) = m +\end{equation} + +$m$ - an original message which was encrypted on the previous step, +$Dlog(x)$ is a discrete logarithm of $x$. +Note that since $Dlog$ is not efficient, +the message space should be a small set, +say $m \in \{0,1\}^{\xi}$, for $\xi \le 30$. + + + +## C: Homomorphic Tally + + + +Homomorphic tally schema is defined over any cyclic group $\mathbb{G}$ of order $q$ with group generator $g$ ($g \in \mathbb{G}$). +
+More detailed how group operations are defined, described in [appendix A](#a-group-definition). + +Homomorphic tally algorithm takes as arguments: + +* $i$ - voting choice index +* $[\mathbf{c_1}, \mathbf{c_2}, \ldots, \mathbf{c_N}]$ - an array of encrypted votes vector's, + where $N$ - votes amount +* $[\alpha_1, \alpha_2, \ldots, \alpha_N]$ - an array of corresponded voter's voting power, + where $N$ - votes amount + +\begin{equation} +Tally(i, [\mathbf{c_1}, \mathbf{c_2}, \ldots, \mathbf{c_N}], [\alpha_1, \alpha_2, \ldots, \alpha_N]) += c_{1, i}^{\alpha_1} \circ c_{2, i}^{\alpha_2} \circ \ldots \circ c_{N, i}^{\alpha_N} = er_i +\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-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 + +Non-Interactive ZK (Zero Knowledge) Vote Proof algorithm helps to solve only one problem, +to prove that the encrypted voting choice is exactly a some unit vector, +which consists of **only one** is $1$ value and others are $0$. + +A more detailed and formal description +you can find in the section *2.4* of this [paper][treasury_system_spec]. + +It is assumed that the original encryption and decryption is performing by ElGamal scheme. +It means that all described operations is also group dependent +(more about groups described in [appendix A](#a-group-definition)). + +### Prover + +The prover algorithm takes as arguments: + +* $\mathbf{c} = (c_0, \ldots, c_{M-1})$ - encrypted vote (a vector of ciphertext), + where $M$ is amount of voting options. +* $\mathbf{e}_i = (e_{i,0},\ldots, e_{i,M-1})$ - original voting choice, a unit vector, + where $M$ is amount of voting options + and $i$ is an index of the voting choice. +* $\mathbf{r} = (r_0, \ldots, r_{M-1})$ - a vector of randomnesses, + which was used during encryption. +* $pk$ - is a public key, which was used to encrypt a unit vector. +* $ck \in \mathbb{G}$ - a commitment key. + +So basically here is the relation between all these values: +\begin{equation} +\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} +VoteProof(\mathbf{c}, \mathbf{e}_i, \mathbf{r}, pk, ck) = \pi +\end{equation} + +Important to note that the following notation would be used +$\{a_i\}$ - which is a set of some elements $a_i$. + +$\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 = 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. 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=1, i_1=1, i_2=0$. +3. 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$. +4. 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}$. +5. Calculate a first verifier challenge + $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]$. +6. For $j \in [0, \ldots, N-1]$ calculate polynomials + in the following form $p_j(x) = e_{i, j}*x^{log_2(N)} + \sum_{l=0}^{log_2(N)-1} p_{j,l} * x^l$: + * $j_l$ is a bit value of the $j$-th binary representation (same as was described in step `2`). + * $z_l^{1} = i_l * x + \beta_l$. + * $z_l^{0} = x - z_l^{1} = (1 - i_l)*x - \beta_l$. + * Calculate the polynomial itself $p_j(x) = \prod_{l=0}^{log_2(N)-1} z_l^{j_l}$ +7. For $l \in [0, \ldots, log_2(N)-1]$ generate a random $R_l \in \mathbb{Z}_q$. +8. For $l \in [0, \ldots, log_2(N)-1]$ compute + $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`. +9. Calculate a second verifier challenge + $ch_2 = H(ch_1, \{D_l\})$, + where $H$ is a hash function + and $l \in [0, \ldots, log_2(N)-1]$. +10. For $l \in [0, \ldots, log_2(N)-1]$ calculate: + * $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$. +11. Calculate + $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`. + +Finally, the proof is $\pi = (\{I_l\}, \{B_l\}, \{A_l\}, \{D_l\}, \{z_l\}, \{w_l\}, \{v_l\}, R)$, +where $l \in [0, \ldots, log_2(N)-1]$. + +### Verifier + +The verifier algorithm takes as arguments: + +* $\mathbf{c} = (c_0, \ldots, c_{M-1})$ - encrypted vote (a vector of ciphertext), + where $M$ is amount of voting options. +* $\pi$ - a prover's proof generated on the [previous step](#prover) +* $pk$ - is a public key, which was used to encrypt a unit vector. +* $ck \in \mathbb{G}$ - a commitment key, same which was used by the prover. + +\begin{equation} +VoteCheck(\mathbf{c}, \pi, pk, ck) = true | false +\end{equation} + +As a result algorithm will return `true` or `false`, +is the verification was succeeded or not respectively. + +Knowing that $\pi$ equals to $(\{I_l\}, \{B_l\}, \{A_l\}, \{D_l\}, \{z_l\}, \{w_l\}, \{v_l\}, R)$, +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 = 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 + $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 + $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)^{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})^{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 = 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})^{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`: + * $Right1_{1} \circ Right2_1 == Left_1$. + * $Right1_{2} \circ Right2_2 == Left_2$. + +If step `4` and `10` returns `true` so the final result is `true` otherwise return `false`. + +## E: Non-Interactive ZK Tally Proof + +Non-Interactive ZK (Zero Knowledge) Tally Proof algorithm helps to solve only one problem, +to prove that the specific encrypted message was decrypted into the specific resulted value, +using exactly that secret key, +which is corresponds to the some shared public key. + + +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. +It means that all described operations is also group dependent +(more about groups described in [appendix A](#a-group-definition)). + +### Prover + +The prover algorithm takes as arguments: + +* $enc$ - an encrypted message (ciphertext). +* $sk$ - a secret key which was used to decrypt a message $enc$. + +\begin{equation} +TallyProof(enc, sk) = \pi +\end{equation} + +$\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)$. +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. +7. Compute $z = sk * с + \mu, \quad z \in \mathbb{Z}_q$. + +Finally, the proof is $\pi = (с, z)$. + +### Verifier + +The verifier algorithm takes as arguments: + +* $enc$ - an encrypted message (ciphertext). +* $dec$ - a decrypted message from the encrypted ciphertext $enc$. +* $pk$ - a public key corresponded to the $sk$ + which was supposedly used to decrypt a message $enc$. +* $\pi$ - a prover's proof generated on the [previous step](#prover-1). + +\begin{equation} +TallyCheck(enc, dec, pk, \pi) = true | false +\end{equation} + +As a result algorithm will return `true` or `false`, +is the verification was succeeded or not respectively. + +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 = 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 `6` returns `true` so the final result is `true` otherwise return `false`. + +## Rationale + +## Path to Active + +### Acceptance Criteria + + +### Implementation Plan + + + + +[treasury_system_paper]: https://eprint.iacr.org/2018/435.pdf +[treasury_system_spec]: https://github.com/input-output-hk/treasury-crypto/blob/master/docs/voting_protocol_spec/Treasury_voting_protocol_spec.pdf +[crypto_book]: https://gnanavelrec.wordpress.com/wp-content/uploads/2019/06/2.understanding-cryptography-by-christof-paar-.pdf diff --git a/docs/src/architecture/08_concepts/catalyst_voting/transaction.md b/docs/src/architecture/08_concepts/catalyst_voting/transaction.md new file mode 100644 index 0000000000..fa60732db1 --- /dev/null +++ b/docs/src/architecture/08_concepts/catalyst_voting/transaction.md @@ -0,0 +1,136 @@ +# Transaction + +--- + +Title: Voting Transaction + +Status: Proposed + +Authors: + - Alex Pozhylenkov + +Created: 2024-09-04 + +--- + +## Abstract + +This document describes a specification of the different versions "Catalyst" voting transaction structure. +From the old one (Jörmungandr) to the newest. + +## Motivation + +Project "Catalyst" requires a structure to keep people vote's data in the secure way, anonymous and verifiable way. + +## Specification + +### v1 (Jörmungandr) + + +??? note "V1 vote transaction definition: `tx_v1.abnf`" + + ```abnf + {{ include_file('src/architecture/08_concepts/catalyst_voting/tx_v1.abnf', indent=4) }} + ``` + + +#### Example + +V1 transaction representation in hex: + + +```hex +0000037e000b36ad42885189a0ac3438cdb57bc8ac7f6542e05a59d1f2e4d1d38194c9d4ac7b000203f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6fb0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6fc8f58976fc0e951ba284a24f3fc190d914ae53aebcc523e7a4a330c8655b4908f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6fb0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846021c76d0a50054ef7205cb95c1fd3f928f224fab8a8d70feaf4f5db90630c3845a06df2f11c881e396318bd8f9e9f135c2477e923c3decfd6be5466d6166fb3c702edd0d1d0a201fb8c51a91d01328da257971ca78cc566d4b518cb2cd261f96644067a7359a745fe239db8e73059883aece4d506be71c1262b137e295ce5f8a0aac22c1d8d343e5c8b5be652573b85cba8f4dcb46cfa4aafd8d59974e2eb65f480cf85ab522e23203c4f2faa9f95ebc0cd75b04f04fef5d4001d349d1307bb5570af4a91d8af4a489297a3f5255c1e12948787271275c50386ab2ef3980d882228e5f3c82d386e6a4ccf7663df5f6bbd9cbbadd6b2fea2668a8bf5603be29546152902a35fc44aae80d9dcd85fad6cde5b47a6bdc6257c5937f8de877d5ca0356ee9f12a061e03b99ab9dfea56295485cb5ce38cd37f56c396949f58b0627f455d26e4c5ff0bc61ab0ff05ffa07880d0e5c540bc45b527e8e85bb1da469935e0d3ada75d7d41d785d67d1d0732d7d6cbb12b23bfc21dfb4bbe3d933eaa1e5190a85d6e028706ab18d262375dd22a7c1a0e7efa11851ea29b4c92739aaabfee40353453ece16bda2f4a2c2f86e6b37f6de92dc45dba2eb811413c4af2c89f5fc0859718d7cd9888cd8d813da2e93726484ea5ce5be8ecf1e1490b874bd897ccd0cbc33db0a1751f813683724b7f5cf750f2497953607d1e82fb5d1429cbfd7a40ccbdba04fb648203c91e0809e497e80e9fad7895b844ba6da6ac690c7ce49c10e00000000000000000100ff00000000000000036d2ac8ddbf6eaac95401f91baca7f068e3c237386d7c9a271f5187ed909155870200000000e6c8aa48925e37fdab75db13aca7c4f39068e12eeb3af8fd1f342005cae5ab9a1ef5344fab2374e9436a67f57041899693d333610dfe785d329988736797950d +``` + + + +1. Transaction size (u32): `0000037e` +2. `00` +3. Jörmungandr specific tag (u8): `0b` +4. Vote plan id (32 byte hash): `36ad42885189a0ac3438cdb57bc8ac7f6542e05a59d1f2e4d1d38194c9d4ac7b` +5. Proposal index (u8): `00` +6. Payload type tag (u8): `02` +7. Encrypted vote: +`03|f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6f|b0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846|f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6f|c8f58976fc0e951ba284a24f3fc190d914ae53aebcc523e7a4a330c8655b4908|f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6f|b0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846` + * size (u8): `03` + * ciphertext (group element (32 byte), group element (32 byte)): `f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6f|b0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846|f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6f|c8f58976fc0e951ba284a24f3fc190d914ae53aebcc523e7a4a330c8655b4908|f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6f|b0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846` +8. Proof: `02|1c76d0a50054ef7205cb95c1fd3f928f224fab8a8d70feaf4f5db90630c3845a|06df2f11c881e396318bd8f9e9f135c2477e923c3decfd6be5466d6166fb3c70|2edd0d1d0a201fb8c51a91d01328da257971ca78cc566d4b518cb2cd261f9664|4067a7359a745fe239db8e73059883aece4d506be71c1262b137e295ce5f8a0a|ac22c1d8d343e5c8b5be652573b85cba8f4dcb46cfa4aafd8d59974e2eb65f48|0cf85ab522e23203c4f2faa9f95ebc0cd75b04f04fef5d4001d349d1307bb557|0af4a91d8af4a489297a3f5255c1e12948787271275c50386ab2ef3980d88222|8e5f3c82d386e6a4ccf7663df5f6bbd9cbbadd6b2fea2668a8bf5603be295461|52902a35fc44aae80d9dcd85fad6cde5b47a6bdc6257c5937f8de877d5ca0356|ee9f12a061e03b99ab9dfea56295485cb5ce38cd37f56c396949f58b0627f455|d26e4c5ff0bc61ab0ff05ffa07880d0e5c540bc45b527e8e85bb1da469935e0d|3ada75d7d41d785d67d1d0732d7d6cbb12b23bfc21dfb4bbe3d933eaa1e5190a|85d6e028706ab18d262375dd22a7c1a0e7efa11851ea29b4c92739aaabfee403|53453ece16bda2f4a2c2f86e6b37f6de92dc45dba2eb811413c4af2c89f5fc08|59718d7cd9888cd8d813da2e93726484ea5ce5be8ecf1e1490b874bd897ccd0c|bc33db0a1751f813683724b7f5cf750f2497953607d1e82fb5d1429cbfd7a40c|cbdba04fb648203c91e0809e497e80e9fad7895b844ba6da6ac690c7ce49c10e` + * size (u8): `02` + * announcements (group element (32 byte), group element (32 byte), group element (32 byte)): `1c76d0a50054ef7205cb95c1fd3f928f224fab8a8d70feaf4f5db90630c3845a|06df2f11c881e396318bd8f9e9f135c2477e923c3decfd6be5466d6166fb3c70|2edd0d1d0a201fb8c51a91d01328da257971ca78cc566d4b518cb2cd261f9664|4067a7359a745fe239db8e73059883aece4d506be71c1262b137e295ce5f8a0a|ac22c1d8d343e5c8b5be652573b85cba8f4dcb46cfa4aafd8d59974e2eb65f48|0cf85ab522e23203c4f2faa9f95ebc0cd75b04f04fef5d4001d349d1307bb557` + * ciphertext (group element (32 byte), group element (32 byte)): `0af4a91d8af4a489297a3f5255c1e12948787271275c50386ab2ef3980d88222|8e5f3c82d386e6a4ccf7663df5f6bbd9cbbadd6b2fea2668a8bf5603be295461|52902a35fc44aae80d9dcd85fad6cde5b47a6bdc6257c5937f8de877d5ca0356|ee9f12a061e03b99ab9dfea56295485cb5ce38cd37f56c396949f58b0627f455` + * response randomness (scalar (32 byte), scalar (32 byte), scalar (32 byte)): `d26e4c5ff0bc61ab0ff05ffa07880d0e5c540bc45b527e8e85bb1da469935e0d|3ada75d7d41d785d67d1d0732d7d6cbb12b23bfc21dfb4bbe3d933eaa1e5190a|85d6e028706ab18d262375dd22a7c1a0e7efa11851ea29b4c92739aaabfee403|53453ece16bda2f4a2c2f86e6b37f6de92dc45dba2eb811413c4af2c89f5fc08|59718d7cd9888cd8d813da2e93726484ea5ce5be8ecf1e1490b874bd897ccd0c|bc33db0a1751f813683724b7f5cf750f2497953607d1e82fb5d1429cbfd7a40c` + * scalar (32 byte): `cbdba04fb648203c91e0809e497e80e9fad7895b844ba6da6ac690c7ce49c10e` +9. `IOW` stand for Inputs-Outputs-Witnesses: `00000000000000000100ff00000000000000036d2ac8ddbf6eaac95401f91baca7f068e3c237386d7c9a271f5187ed909155870200000000e6c8aa48925e37fdab75db13aca7c4f39068e12eeb3af8fd1f342005cae5ab9a1ef5344fab2374e9436a67f57041899693d333610dfe785d329988736797950d` + * Jörmungandr specific block date (epoch (u32), slot (u32)) + (*could be anything, not processed anymore*): `00000000|00000000` + * number of inputs and witnesses (u8) (**always** `1`): `01` + * number of outputs (u8) (**always** `0`): `00` + * Inputs + 1. + * Jörmungandr specific tag: `ff` + * Jörmungandr specific value (u64) (*could be anything, not processed anymore*): `0000000000000003` + * input pointer (32 byte): `6d2ac8ddbf6eaac95401f91baca7f068e3c237386d7c9a271f5187ed90915587` + * Witnesses + 1. + * Jörmungandr specific tag (u8): `02` + * Jörmungandr specific nonce (u32) (*could be anything, not processed anymore*): `00000000` + * legacy signature (64 byte): `e6c8aa48925e37fdab75db13aca7c4f39068e12eeb3af8fd1f342005cae5ab9a1ef5344fab2374e9436a67f57041899693d333610dfe785d329988736797950d` + + +#### Transaction vote generation + +To generate a cryptographically secured `ENCRYPTED-VOTE` and `PROOF-VOTE` parts you can follow this [spec](./crypto.md#vote). +Important to note, +that as part of [*initial setup*](./crypto.md#initial-setup) of the voting procedure, +the following properties are used: + +1. Each proposal, defined by the "Vote plan id" and "Proposal index", defines a number of possible options. +2. [ristretto255] as a backend cryptographic group. +3. [BLAKE2b-512] hash function. +4. A commitment key $ck$ defined as a [BLAKE2b-512] hash of the "Vote plan id" bytes. + +#### Transaction signing (witness generation) + +Signature generated from the [BLAKE2b-256] hashed `VOTE-PAYLOAD` bytes except of the `WITNESS` part +(the last part from the bytes array): + +1. `CAST-CERT` bytes +2. `BLOCK-DATE` bytes +3. `%x01` +4. `%x00` +5. `INPUT` bytes + +Based on the on the transaction example, data to sign: + + +```hex +36ad42885189a0ac3438cdb57bc8ac7f6542e05a59d1f2e4d1d38194c9d4ac7b000203f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6fb0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6fc8f58976fc0e951ba284a24f3fc190d914ae53aebcc523e7a4a330c8655b4908f6639bdbc9235103825a9f025eae5cff3bd9c9dcc0f5a4b286909744746c8b6fb0018773d3b4308344d2e90599cd03749658561787eab714b542a5ccaf078846021c76d0a50054ef7205cb95c1fd3f928f224fab8a8d70feaf4f5db90630c3845a06df2f11c881e396318bd8f9e9f135c2477e923c3decfd6be5466d6166fb3c702edd0d1d0a201fb8c51a91d01328da257971ca78cc566d4b518cb2cd261f96644067a7359a745fe239db8e73059883aece4d506be71c1262b137e295ce5f8a0aac22c1d8d343e5c8b5be652573b85cba8f4dcb46cfa4aafd8d59974e2eb65f480cf85ab522e23203c4f2faa9f95ebc0cd75b04f04fef5d4001d349d1307bb5570af4a91d8af4a489297a3f5255c1e12948787271275c50386ab2ef3980d882228e5f3c82d386e6a4ccf7663df5f6bbd9cbbadd6b2fea2668a8bf5603be29546152902a35fc44aae80d9dcd85fad6cde5b47a6bdc6257c5937f8de877d5ca0356ee9f12a061e03b99ab9dfea56295485cb5ce38cd37f56c396949f58b0627f455d26e4c5ff0bc61ab0ff05ffa07880d0e5c540bc45b527e8e85bb1da469935e0d3ada75d7d41d785d67d1d0732d7d6cbb12b23bfc21dfb4bbe3d933eaa1e5190a85d6e028706ab18d262375dd22a7c1a0e7efa11851ea29b4c92739aaabfee40353453ece16bda2f4a2c2f86e6b37f6de92dc45dba2eb811413c4af2c89f5fc0859718d7cd9888cd8d813da2e93726484ea5ce5be8ecf1e1490b874bd897ccd0cbc33db0a1751f813683724b7f5cf750f2497953607d1e82fb5d1429cbfd7a40ccbdba04fb648203c91e0809e497e80e9fad7895b844ba6da6ac690c7ce49c10e00000000000000000100ff00000000000000036d2ac8ddbf6eaac95401f91baca7f068e3c237386d7c9a271f5187ed90915587 +``` + + +[BLAKE2b-256] hash of the transaction data to sign equals to `f51473df863be3e0383ce5a8da79c7ff51b3d98dadbbefbf9f042e8601901269` + +Expected witness (includes signature) + + +```hex + 0200000000e6c8aa48925e37fdab75db13aca7c4f39068e12eeb3af8fd1f342005cae5ab9a1ef5344fab2374e9436a67f57041899693d333610dfe785d329988736797950d +``` + + +## Rationale + +## Path to Active + +### Acceptance Criteria + + +### Implementation Plan + + + + +[BLAKE2b-256]: https://www.blake2.net/blake2.pdf\ +[BLAKE2b-512]: https://www.blake2.net/blake2.pdf\ +[ristretto255]: https://ristretto.group diff --git a/docs/src/architecture/08_concepts/catalyst_voting/tx_v1.abnf b/docs/src/architecture/08_concepts/catalyst_voting/tx_v1.abnf new file mode 100644 index 0000000000..d582d096db --- /dev/null +++ b/docs/src/architecture/08_concepts/catalyst_voting/tx_v1.abnf @@ -0,0 +1,70 @@ +VOTE-TX = SIZE-BYTES-32BIT %x00 %x0b VOTE-PAYLOAD + +VOTE-PAYLOAD = CAST-CERT IOW +CAST-CERT = VOTE-PLAN-ID PROPOSAL-INDEX CAST-PAYLOAD + +VOTE-PLAN-ID = SIZE-BYTES-32BYTE ; Jörmungandr specific vote plan identifier, Blake2b hash of the vote plan bytes +PROPOSAL-INDEX = U8 ; Jörmungandr specific proposal identifier +CAST-PAYLOAD = %x01 CHOICE ; Public payload + / %x02 ENCRYPTED-VOTE PROOF-VOTE ; Private payload + +CHOICE = U8 +ENCRYPTED-VOTE = SIZE-BYTES-8BIT *CIPHERTEXT +PROOF-VOTE = SIZE-BYTES-8BIT *ANNOUNCEMENT *CIPHERTEXT *R-RESPONSE SCALAR ; size of the *ANNOUNCEMENT, *CIPHERTEXT, *R-RESPONSE are equal to SIZE-BYTES-8BIT value + +CIPHERTEXT = E1 E2 +ANNOUNCEMENT = I A B +R-RESPONSE = 3 * SCALAR +I = GROUP-ELEMENT +A = GROUP-ELEMENT +B = GROUP-ELEMENT +E1 = GROUP-ELEMENT +E2 = GROUP-ELEMENT + +; #################### +; IOW stand for Inputs-Outputs-Witnesses +; #################### + +IOW = BLOCK-DATE + %x01 ; number of inputs and witness + %x00 ; number of outputs + INPUT ; one input + WITNESS ; one witness + +INPUT = %xff + VALUE + ED25519-PUBLICKEY + +WITNESS = %x02 + NONCE + ED25519-SIGNATURE + +VALUE = U64 ; could be anything, not processed anymore, recommended set to zero +NONCE = U32 ; could be anything, not processed anymore, recommended set to zero +BLOCK-DATE = BLOCK-EPOCH BLOCK-SLOT ; expiration date, could be anything, not processed anymore, recommended set to zeros +BLOCK-EPOCH = U32 +BLOCK-SLOT = U32 + +; #################### +; CRYPTO +; #################### + +ED25519-PUBLICKEY = SIZE-BYTES-32BYTE +ED25519-SIGNATURE = SIZE-BYTES-64BYTE + +; #################### +; PRIMITIVES +; #################### + +SIZE-BYTES-8BIT = U8 ; size in elements (8 bits) +SIZE-BYTES-16BIT = U16 ; size in bytes (16 bits) +SIZE-BYTES-32BIT = U32 ; size in bytes (32 bits) +U8 = OCTET ; unsigned integer 8 bit +U16 = 2OCTET ; unsigned integer 16 bit (BE) +U32 = 4OCTET ; unsigned integer 32 bit (BE) +U64 = 8OCTET ; unsigned integer 64 bit (BE) +SIZE-BYTES-32BYTE = 32OCTET ; unsigned integer 256 bit (32 bytes) (BE) +SIZE-BYTES-64BYTE = 64OCTET ; unsigned integer 512 bit (64 bytes) (BE) +SIZE-BYTES-65BYTE = 65OCTET ; unsigned integer 520 bit (65 bytes) (BE) +SCALAR = SIZE-BYTES-32BYTE +GROUP-ELEMENT = SIZE-BYTES-32BYTE ; ristretto255 group element From 733dab50fd51d50a8b652f88fc0218143e2e9c4e Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Fri, 18 Oct 2024 13:28:18 +0300 Subject: [PATCH 2/3] fix spelling --- .config/dictionaries/project.dic | 2 ++ rust/catalyst-voting/src/crypto/zk_dl_equality.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic index 1925830991..02052bab53 100644 --- a/.config/dictionaries/project.dic +++ b/.config/dictionaries/project.dic @@ -55,6 +55,7 @@ dcbor decompressor delegators dleq +dlog dockerhub Dominik dotenv @@ -105,6 +106,7 @@ ideascale idents IFMT Intellij +inversed ioerr iohk ipfs diff --git a/rust/catalyst-voting/src/crypto/zk_dl_equality.rs b/rust/catalyst-voting/src/crypto/zk_dl_equality.rs index b388445814..2c904532b6 100644 --- a/rust/catalyst-voting/src/crypto/zk_dl_equality.rs +++ b/rust/catalyst-voting/src/crypto/zk_dl_equality.rs @@ -10,7 +10,7 @@ //! points `point_1` and `point_2`. The witness, on the other hand //! is the discrete logarithm, `dlog`. -// cspell: words NIZK dlog +// cspell: words NIZK use crate::crypto::{ group::{GroupElement, Scalar}, From 5efeaa60aaba2912d46a792865b576d082252b7b Mon Sep 17 00:00:00 2001 From: Mr-Leshiy Date: Fri, 18 Oct 2024 14:49:04 +0300 Subject: [PATCH 3/3] update crate links --- rust/catalyst-voting/src/crypto/group/mod.rs | 2 +- rust/catalyst-voting/src/crypto/zk_unit_vector/mod.rs | 2 +- .../catalyst-voting/src/crypto/zk_unit_vector/polynomial.rs | 2 +- rust/catalyst-voting/src/txs/v1/mod.rs | 2 +- rust/catalyst-voting/src/vote_protocol/mod.rs | 2 +- rust/catalyst-voting/src/vote_protocol/tally/mod.rs | 4 ++-- rust/catalyst-voting/src/vote_protocol/tally/proof.rs | 6 +++--- rust/catalyst-voting/src/vote_protocol/voter/mod.rs | 6 +++--- rust/catalyst-voting/src/vote_protocol/voter/proof.rs | 6 +++--- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/rust/catalyst-voting/src/crypto/group/mod.rs b/rust/catalyst-voting/src/crypto/group/mod.rs index d76e332903..eaa33b6fed 100644 --- a/rust/catalyst-voting/src/crypto/group/mod.rs +++ b/rust/catalyst-voting/src/crypto/group/mod.rs @@ -1,5 +1,5 @@ //! Group definitions used in voting protocol. -//! For more information, see: +//! For more information, see: mod ristretto255; diff --git a/rust/catalyst-voting/src/crypto/zk_unit_vector/mod.rs b/rust/catalyst-voting/src/crypto/zk_unit_vector/mod.rs index 1e85ad2dd7..2cb0686c6b 100644 --- a/rust/catalyst-voting/src/crypto/zk_unit_vector/mod.rs +++ b/rust/catalyst-voting/src/crypto/zk_unit_vector/mod.rs @@ -2,7 +2,7 @@ //! Zhang, Oliynykov and Balogum in //! [`A Treasury System for Cryptocurrencies: Enabling Better Collaborative Intelligence`](https://www.ndss-symposium.org/wp-content/uploads/2019/02/ndss2019_02A-2_Zhang_paper.pdf). //! -//! This implementation follows this [specification](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#d-non-interactive-zk-vote-proof) +//! This implementation follows this [specification](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#d-non-interactive-zk-vote-proof) // cspell: words Zhang, Oliynykov, Balogum diff --git a/rust/catalyst-voting/src/crypto/zk_unit_vector/polynomial.rs b/rust/catalyst-voting/src/crypto/zk_unit_vector/polynomial.rs index 0eb67f3650..2d33680763 100644 --- a/rust/catalyst-voting/src/crypto/zk_unit_vector/polynomial.rs +++ b/rust/catalyst-voting/src/crypto/zk_unit_vector/polynomial.rs @@ -39,7 +39,7 @@ impl Polynomial { } } -/// Generate the polynomial according to the step 7 of this [spec](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#prover) +/// Generate the polynomial according to the step 7 of this [spec](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#prover) pub(crate) fn generate_polynomial( i: usize, j: usize, randomness: &[BlindingRandomness], ) -> Polynomial { diff --git a/rust/catalyst-voting/src/txs/v1/mod.rs b/rust/catalyst-voting/src/txs/v1/mod.rs index c9672225dd..c98bfe2835 100644 --- a/rust/catalyst-voting/src/txs/v1/mod.rs +++ b/rust/catalyst-voting/src/txs/v1/mod.rs @@ -1,4 +1,4 @@ -//! A Jörmungandr transaction object structured following this [spec](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/transaction/#v1-jormungandr) +//! A Jörmungandr transaction object structured following this [spec](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/transaction/#v1-jormungandr) //! //! ```rust //! use catalyst_voting::{ diff --git a/rust/catalyst-voting/src/vote_protocol/mod.rs b/rust/catalyst-voting/src/vote_protocol/mod.rs index 7c2ab504a3..1856d50082 100644 --- a/rust/catalyst-voting/src/vote_protocol/mod.rs +++ b/rust/catalyst-voting/src/vote_protocol/mod.rs @@ -1,4 +1,4 @@ -//! An implementation of the voting protocol described in this [spec](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/) +//! An implementation of the voting protocol described in this [spec](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/) //! //! ```rust //! use catalyst_voting::vote_protocol::{ diff --git a/rust/catalyst-voting/src/vote_protocol/tally/mod.rs b/rust/catalyst-voting/src/vote_protocol/tally/mod.rs index 33ee9269d9..b6781575e4 100644 --- a/rust/catalyst-voting/src/vote_protocol/tally/mod.rs +++ b/rust/catalyst-voting/src/vote_protocol/tally/mod.rs @@ -47,7 +47,7 @@ impl DecryptionTallySetup { } /// Tally function. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#homomorphic-tally) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#homomorphic-tally) /// /// # Errors /// - Votes and voting power length mismatch. @@ -86,7 +86,7 @@ pub fn tally( } /// Decrypts the encrypted tally result. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#tally-decryption) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#tally-decryption) /// /// # Errors /// - Cannot decrypt tally result. Provided an invalid secret key or invalid encrypted diff --git a/rust/catalyst-voting/src/vote_protocol/tally/proof.rs b/rust/catalyst-voting/src/vote_protocol/tally/proof.rs index e043e5d158..46d89844b1 100644 --- a/rust/catalyst-voting/src/vote_protocol/tally/proof.rs +++ b/rust/catalyst-voting/src/vote_protocol/tally/proof.rs @@ -21,7 +21,7 @@ use crate::{ pub struct TallyProof(DleqProof); /// Generates a tally proof. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#tally-proof) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#tally-proof) #[allow(clippy::module_name_repetitions)] pub fn generate_tally_proof( encrypted_tally: &EncryptedTally, secret_key: &ElectionSecretKey, rng: &mut R, @@ -43,7 +43,7 @@ pub fn generate_tally_proof( } /// Generates a tally proof with `crypto::default_rng`. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#tally-proof) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#tally-proof) #[allow(clippy::module_name_repetitions)] pub fn generate_tally_proof_with_default_rng( encrypted_tally: &EncryptedTally, secret_key: &ElectionSecretKey, @@ -52,7 +52,7 @@ pub fn generate_tally_proof_with_default_rng( } /// Verifies a tally proof. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#tally-proof) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#tally-proof) #[must_use] #[allow(clippy::module_name_repetitions)] pub fn verify_tally_proof( diff --git a/rust/catalyst-voting/src/vote_protocol/voter/mod.rs b/rust/catalyst-voting/src/vote_protocol/voter/mod.rs index bb267a6253..5635db536c 100644 --- a/rust/catalyst-voting/src/vote_protocol/voter/mod.rs +++ b/rust/catalyst-voting/src/vote_protocol/voter/mod.rs @@ -50,7 +50,7 @@ impl EncryptedVote { impl Vote { /// Generate a vote. - /// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#voting-choice) + /// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#voting-choice) /// /// # Errors /// - Invalid voting choice, the value of `choice`, should be less than the number @@ -85,7 +85,7 @@ impl Vote { } /// Create a new encrypted vote from the given vote and public key with with the -/// `crypto::default_rng`. More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#vote-encryption) +/// `crypto::default_rng`. More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#vote-encryption) /// /// # Errors /// - `EncryptedVoteError` @@ -106,7 +106,7 @@ pub fn encrypt_vote( } /// Create a new encrypted vote from the given vote and public key. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#vote-encryption) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#vote-encryption) #[must_use] pub fn encrypt_vote_with_default_rng( vote: &Vote, public_key: &ElectionPublicKey, diff --git a/rust/catalyst-voting/src/vote_protocol/voter/proof.rs b/rust/catalyst-voting/src/vote_protocol/voter/proof.rs index 7e669ab25a..2f74a4ac01 100644 --- a/rust/catalyst-voting/src/vote_protocol/voter/proof.rs +++ b/rust/catalyst-voting/src/vote_protocol/voter/proof.rs @@ -46,7 +46,7 @@ impl VoterProofCommitment { } /// Generates a voter proof. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#voters-proof) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#voters-proof) /// /// # Errors /// - Provided arguments mismatch. Size of the provided `vote`, `encrypted_vote` and @@ -77,7 +77,7 @@ pub fn generate_voter_proof( } /// Generates a voter proof with `crypto::default_rng`. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#voters-proof) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#voters-proof) /// /// # Errors /// - Provided arguments mismatch. Size of the provided `vote`, `encrypted_vote` and @@ -98,7 +98,7 @@ pub fn generate_voter_proof_with_default_rng( } /// Verifies a voter proof. -/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#voters-proof) +/// More detailed described [here](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/catalyst_voting/crypto/#voters-proof) #[must_use] #[allow(clippy::module_name_repetitions)] pub fn verify_voter_proof(