Skip to content

Commit

Permalink
DKG notes (#6)
Browse files Browse the repository at this point in the history
* added up to pedersen dkg

* added og refs

* finalized dkg notes
  • Loading branch information
trbritt authored Jul 11, 2024
1 parent 0ea33b6 commit 414f14d
Showing 1 changed file with 131 additions and 0 deletions.
131 changes: 131 additions & 0 deletions notebooks/secret_sharing.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d6771199-ac12-47c1-af3c-4cc23313f6f2",
"metadata": {},
"source": [
"# Distributed Keys\n",
"\n",
"When dealing with cryptography in general, the source of truth you use for encrypting your secrets is usually a single point of failure, in any naïve implementations. This could be the private key used to generate / verify signatures for example. Also, when decentralizing cryptography protocols, traditional ideas of verification must be extended to encompass many parties, with the intention of removing single point failures, not adding more. This goes over the basics of related distribution protocols for secret sharing and validation.\n",
"\n",
"## Shamir's Secret Sharing\n",
"\n",
"[This](https://dl.acm.org/doi/pdf/10.1145/359168.359176) is the foundation on which many distributed key generation (DKG) protocols are based. The punchline is that it allows for $t$ individuals, out of $n$ total, to verify a signature. Not only does this allow for fault tolerance (e.g. node in the network goes down), but allows for a quorum of attestations, improving trustlessness. Maximum security would require $n>\\lfloor 2t - 1\\rfloor$.\n",
"\n",
"At the core of this concept is the following truth. Given a set $\\{(x_i,y_i)\\in\\mathbb{R}_2\\,|\\, i\\in[0, t]\\}$, there exists a UNIQUE polynomial $q(x)$ of degree $t-1$ such that $q(x_i)=y_i$. We then express this polynomial as:\n",
"$$\n",
"q(x) = a_0 + a_1x+\\cdots+a_{t-1}x^{t-1}\n",
"$$\n",
"where $a_0$ is the secret to be shared. Discretization is then done as $s_i = q(i)$, where $s_i$ is the partial shared secret. The partial signature is therefore $s_iH(m)$, where $H(m)$ is the hashed message in the group $\\mathbb{G}_1$. The uniqueness of polynomial interoplation requires knowledge of exactly $t$ of these partial shares to recover the shared secret. Knowledge of only $t-1$ means that, of the candidate $a_0^\\prime\\in[0,p)$, there will be again only a unique polynomial fitting $(0, a_0^\\prime)$ and $(i, a_i)$, each of these $p$ unique polynomials being equally likely, thus maintaining security of the shared secret.\n",
"\n",
"Recovery of the shared secret is done via Lagrange interpolation:\n",
"$$\n",
"a_0 = q(0) = \\sum_{j=0}^{t-1}y_t\\prod_{m=0,m\\neq j}^{t-1}\\frac{x_m}{x_m-x_j}$$\n",
"\n",
"The problems with this, while admittedly simple and extensible, is that it assumes honesty of the participants (at no point is there an ability to verify partial shares), and further that the shared secret is known singuarly at some point in space-time, both at instantiation of the sharing and at the recovery of the shares. To address these issues, we move beyond to ...\n",
"\n",
"## Feldman's VSS\n",
"\n",
"This is a new approach to secret sharing that addresses the concern that the partials are not verifiable by the council. We again now generate $q(x)$, with $q(0)=a_0$ which is the secret, and transmit to all $i$ participants a partial share $s_i = f(i)$. The dealer also sends a committment $\\{A_k=g^{a_k}\\}_{k=0,t}$, with $g$ a generator of $\\mathbb{Z}_p^\\ast$. This allows for verification (that the partials form a secret) by checking:\n",
"$$\n",
"g^{s_i}\\stackrel{?}{=}\\prod_{k=0}^t\\left(A_k\\right)^{i^k}\n",
"$$\n",
"performed in the field (aka mod $p$). If participant $i$ does not satisfy the above, a complaint is made publically against the dealer, who is required to then reveal $s_i$ that satisfy the above, else they're fired! \n",
"\n",
"The biggest issue is that this protocol leaks $A_0=g^{a_0}=g^{\\rm secret}\\mod p$. However, assume the bad actor knows $t$ or less shares $s_i$ and $g_{a_0}$. They can then compute $\\{A_k\\}_{k=1,t}$ via $A_k=g^{a_k}=\\prod_{i=0}^t(g^{s_i})^{\\lambda_{ki}}$, where $\\lambda$ satisfies $a_k=\\sum_{i=0}^t\\lambda_{ki}f(i)$, which is still not enough to learn about $a_0$ anymore than what you could learn from $g^{a_0}$. \n",
"\n",
"## pedersen vss\n",
"\n",
"To address the concern of the secret's secrecy, we move to pedersen dkg. Now in this [scheme](https://link.springer.com/chapter/10.1007/3-540-46416-6_47), each participant generates coefficients, and the cooperation of participants is what allows for the collective generation of a secret. The public parameters in this setup are a large prime $p$, a generator $g$ of a subgroup of $\\mathbb{Z}_p^\\ast$, and another element in the subgroup of $\\mathbb{Z}_p$ generated by $g$, $h$, where no one knows $\\log_g h$. Therefore, the cost of information-theoretic secrecy of the shared secret is the hard assumption that the bad actor, or a cheating dealer, cannot solve the DL problem. \n",
"\n",
"The dealer generates two random polynomials of degree $t$, $q(x)=\\sum_k a_kx^k,\\tilde{q}(x)=\\sum_k b_kx^k\\in\\mathbb{Z}_p[x]$, with again $q(0)=a_0$ the shared secret. The dealer then transmits to each participant $i$ their share $(s_i=q(i), \\tilde{s}_i=\\tilde{q}(i))$, and broadcasts the values $\\{C_k = g^{a_k}g^{b_k}\\mod p\\}_{k=0,t}$. Verification of the shared secret follows by:\n",
"$$\n",
"g^{s_i}h^{\\tilde{s}_i}\\stackrel{?}{=} \\prod_{k=0}^t\\left(C_k\\right)^{i^k}\\mod p\n",
"$$\n",
"\n",
"As before, complaints against the dealer are made public, and are rectified by the dealer transmitting $(s_i, \\tilde{s}_i)$ satisfying the above lest they face disqualification.\n",
"\n",
"### feldman dkg\n",
"\n",
"feldman dkg is built on top of the idea's above to create distribution of the process among participants. Each participant $i$ is now a dealer running a version of Feldman vss, and glued together according to the following. .\n",
"\n",
"Firstly, each participant $i$ chooses a secret value $a_i\\sim U(0, p)\\in\\mathbb{Z}_p$, as well as a random polynomial $q_i(x)$ of degree $t$ in $\\mathbb{Z}_p[x]$:\n",
"$$\n",
"q_i(x) = a_{i0} + a_{i1}x + a_{i2}x^2 + \\cdots + a_{it}x^t\n",
"$$\n",
"The participant then computes and broadcasts $C_{ij} = g^{a_{ij}}$ for $j\\in[0, t]$\n",
"\n",
"Then, everyone computes the shares of $1,\\ldots,n$ of their secret polynomial $s_{ij} = q_i(j)$, and sends them secretly to participants $j=1,\\ldots,n$. \n",
"\n",
"A participant is able to verify that a share received from $j$ is consistent by assuring:\n",
"$$\n",
"g^{s_{ij}} = \\prod_{k=0}^{t}C^{j^k}_{ik}\n",
"$$\n",
"\n",
"If this fails, then participant $i$ complains publically. If there are $t$ complaints against $j$, they're automatically kicked out. If there are less than $t$ complaints, the accused participant must broadcast the correct share (and random value if used). If this fails, they're booted (you're fired!). In this way, we can remove the assumption in Shamir's secret sharing of honesty of the participants, because we can verify when they're lying.\n",
"\n",
"Finally, participant $i$ determines their share as $s_i = \\sum_{j\\in\\rm qualified} s_{ji}$, and the public key is now $y=\\prod_{i\\in\\rm qualified}C_{i0}$, and the public verification values are $C_k = \\prod_{i\\in\\rm qualified} C_{ik}$. The shared secret value $s$ itself is not computed by anyone since they don't know all the parts, but can be seen as $s=\\sum_i a_{i0}$. \n",
"\n",
"### pedersen dkg\n",
"\n",
"We now finally move onto secure distributed key generation that is verified to be secure enough for threshold signaturing (see [this](https://link.springer.com/content/pdf/10.1007/3-540-48910-X_21.pdf)). \n",
"\n",
"We now buil don topof the pedersen vss and feldman vss.\n",
"\n",
"#### Generating s:\n",
"\n",
"Each player $P_i$ performs a Pedersen-VSS of a random value $z_i$ as a dealer:\n",
"1. $P_i$ chooses two random polynomials $q_i(z), q_i^\\prime(z)$ over $\\mathbb{Z}_q[z]$ of degree $t$:\n",
"$$q_i(z) = a_{i0} + a_{i1}z + \\ldots + a_{it}z^t$$\n",
"\n",
"$$q_i'(z) = b_{i0} + b_{i1}z + \\ldots + b_{it}z^t$$\n",
"\n",
"Let $z_i = a_{i0} = q_i(0)$. $P_i$ broadcasts $C_{ik} = g^{a_{ik}}h^{b_{ik}} \\mod p$ for $k = 0,\\ldots,t$. $P_i$ computes the shares $s_{ij} = q_i(j), s_{ij}^\\prime = q_i^\\prime(j) \\mod q$ for $j = 1,\\ldots,n$ and sends $s_{ij}, s_{ij}^\\prime$ to player $P_j$.\n",
"\n",
"3. Each player $P_j$ verifies the shares he received from the other players. For each $i = 1,\\ldots,n$, $P_j$ checks if\n",
"$$g^{s_{ij}}h^{s_{ij}'} = \\prod_{k=0}^t (C_{ik})^{j^k} \\mod p$$ \n",
"If the check fails for an index $i$, $P_j$ broadcasts a complaint against $P_i$.\n",
"\n",
"4. Each player $P_i$ who, as a dealer, received a complaint from player $P_j$ broadcasts the values $s_{ij}, s_{ij}'$ that satisfy the above.\n",
"5. Each player marks as disqualified any player that either\n",
"- received more than $t$ complaints in Step 1b, or\n",
"- answered to a complaint in Step 1c with values that falsify the relation above.\n",
" \n",
"Each player then builds the set of non-disqualified players QUAL. The distributed secret value $s$ is not explicitly computed by any party, but it equals $s = \\sum_{i \\in QUAL} z_i \\mod q$. Each player $P_i$ sets his share of the secret as $s_i = \\sum_{j \\in QUAL} s_{ji} \\mod q$ and the value $s_i' = \\sum_{j \\in QUAL} s_{ji}' \\mod q$.\n",
"\n",
"#### Extracting $y = g^s \\mod p$:\n",
"\n",
"Each player $i \\in QUAL$ exposes $y_i = g^{z_i} \\mod p$ via Feldman VSS:\n",
"\n",
"1. Each player $P_i$, $i \\in QUAL$, broadcasts $A_{ik} = g^{a_{ik}} \\mod p$ for $k = 0,\\ldots,t$.\n",
"2. Each player $P_j$ verifies the values broadcast by the other players in QUAL, namely, for each $i \\in QUAL$, $P_j$ checks if\n",
"$$g^{s_{ij}} = \\prod_{k=0}^t (A_{ik})^{j^k} \\mod p$$\n",
"If the check fails for an index $i$, $P_j$ complains against $P_i$ by broadcasting the values $s_{ij}, s_{ij}'$ that satisfy the relation in part 1 but do not satisfy the relation immediately above.\n",
"3. For players $P_i$ who receive at least one valid complaint, i.e. values which satisfy the equation in part 1 and not the equation above, the other players run the reconstruction phase of Pedersen-VSS to compute $z_i$, $q_i(z)$, $A_{ik}$ for $k = 0,\\ldots,t$ in the clear. For all players in QUAL, set $y_i = A_{i0} = g^{z_i} \\mod p$. Compute $y = \\prod_{i \\in QUAL} y_i \\mod p$.\n",
"\n",
"What might this look like? I'd recommend looking at the implementation [here](https://docs.rs/secret_sharing_and_dkg/latest/src/secret_sharing_and_dkg/pedersen_dvss.rs.html#1-341) for the basics. The idea is that the reduction of single point failures via the secret generation requires a more secure protocol like pedersen dkg, which allows later steps to be less secure and more efficient, namely by using feldman instead.\n",
"\n",
"However, [it was shown](https://www.researchgate.net/publication/2558744_Revisiting_the_Distributed_Key_Generation_for_Discrete-Log_Based_Cryptosystems) that using Feldman vss for both stages is actually secure enough when subsequently used in a thresholding signature scheme! This is why cloudflare uses it, and saves them the pain of implementing two different VSS schemes.\n",
"\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Rust",
"language": "rust",
"name": "rust"
},
"language_info": {
"codemirror_mode": "rust",
"file_extension": ".rs",
"mimetype": "text/rust",
"name": "Rust",
"pygment_lexer": "rust",
"version": ""
}
},
"nbformat": 4,
"nbformat_minor": 5
}

0 comments on commit 414f14d

Please sign in to comment.