Skip to content

Commit

Permalink
Publicly verifiable secret sharing
Browse files Browse the repository at this point in the history
Signed-off-by: lovesh <lovesh.bond@gmail.com>
  • Loading branch information
lovesh committed May 31, 2024
1 parent d932a3e commit a1f322a
Show file tree
Hide file tree
Showing 20 changed files with 1,356 additions and 24 deletions.
7 changes: 1 addition & 6 deletions saver/src/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ use dock_crypto_utils::{msm::multiply_field_elems_with_same_group_elem, serde_ut
/// ```
///
/// Since `b`, `n` and `G` are public, it can be ensured that `G_i`s are correctly created.
///
/// CAVEAT: Since the same blinding `r'` is used for `H` in both the chunked commitment `J` and the commitment
/// to the full message, they can be divided to get a value that is unique to the message and thus can
/// be used to link 2 different proofs created for the same message. One solution to this is to generate a
/// different `G` for each proof by hashing an agreed upon string appended with a counter.
#[serde_as]
#[derive(
Clone, PartialEq, Eq, Debug, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
Expand All @@ -52,7 +47,7 @@ pub struct ChunkedCommitment<G: AffineRepr>(
impl<G: AffineRepr> ChunkedCommitment<G> {
/// Decompose a given field element `message` to `chunks_count` chunks each of size `chunk_bit_size` and
/// create a Pedersen commitment to those chunks. say `m` is decomposed as `m_1`, `m_2`, .. `m_n`.
/// Create commitment key as multiples of `g` as `g_n, g_{n-1}, ..., g_2, g_1` using `create_gs`. Now commit as `m_1 * g_1 + m_2 * g_2 + ... + m_n * g_n + r * h`
/// Create commitment key as multiples of `g` as `g_n, g_{n-1}, ..., g_2, g_1` using `Self::commitment_key`. Now commit as `m_1 * g_1 + m_2 * g_2 + ... + m_n * g_n + r * h`
/// Return the commitment and commitment key
pub fn new(
message: &G::ScalarField,
Expand Down
10 changes: 9 additions & 1 deletion schnorr_pok/src/discrete_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ pub struct PokDiscreteLogProtocol<G: AffineRepr> {
/// Proof of knowledge of discrete log
#[serde_as]
#[derive(
Clone, PartialEq, Eq, Debug, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
Default,
Clone,
PartialEq,
Eq,
Debug,
CanonicalSerialize,
CanonicalDeserialize,
Serialize,
Deserialize,
)]
pub struct PokDiscreteLog<G: AffineRepr> {
#[serde_as(as = "ArkObjectBytes")]
Expand Down
2 changes: 1 addition & 1 deletion schnorr_pok/src/discrete_log_pairing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ macro_rules! impl_protocol {

#[serde_as]
#[derive(
Clone, PartialEq, Eq, Debug, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
Default, Clone, PartialEq, Eq, Debug, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
)]
pub struct $proof<E: Pairing> {
#[serde_as(as = "ArkObjectBytes")]
Expand Down
26 changes: 26 additions & 0 deletions secret_sharing_and_dkg/src/bagheri_pvss/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Publicly verifiable secret sharing protocols

These allow a dealer to share commitments to the secret shares (`commitment_key * secret_share`) with a group such that a threshold number of group
members can get commitment to the secret. This sharing can happen on a public bulletin board as the dealer's
shares are encrypted for the corresponding party and anyone can verify that the shares are created correctly because the dealer
also outputs a proof. This primitive is useful for sharing secrets on a blockchain as the blockchain can verify the proof.

Based on Fig. 7 of the paper [A Unified Framework for Verifiable Secret Sharing](https://eprint.iacr.org/2023/1669).
Implements the protocol in the paper and a variation.

The dealer in the protocol in Fig 7. wants to share commitments to the shares of secrets of `k` - (`k_1`, `k_2`, ..., `k_n`) as (`g * k_1`, `g * k_2`, ..., `g * k_n`)
to `n` parties with secret and public keys (`s_i`, `h_i = g * s_i`) such that any `t` parties can reconstruct commitment to the secret `g * k`.
Notice the base `g` is the same in the public keys, the share commitments and the reconstructed commitment to the secret. This is implemented in [same_base](./same_base.rs)

Let's say the dealer wants to share `j * k` where base `j` is also a group generator and discrete log of `j` wrt. `g` is not known
such that party `i` gets `j * k_i`
The dealer follows a similar protocol as above and broadcasts `y'_i = j * k_i . g * k_i = (j + g) * k_i` in addition
to `y_i = h_i * k_i` and a proof that `k_i` is the same in both `y'_i` and `y_i`. Then each party can
compute `g * k_i` as described in the paper and compute `j * k_i = y'_i - g * k_i`. Essentially, `y'_i` is
an Elgamal ciphertext, `g * k_i` is the ephemeral secret key (between the dealer and party `i`) and
`j * k_i` is the message. This is implemented in [different_base](./different_base.rs). Note that both `j` and `g` must be in the same group.

The proof in the protocol described in the paper contains a polynomial of degree `t-1`. This adds to the proof `t` field
elements (polynomial coefficients) and requires evaluation of a `t-1` degree polynomial during proving and verification.
An alternate implementation is to have the proof contain `n` fields elements and avoid the polynomial evaluation during
proving and verification making these faster but the proofs bigger. These are implemented in [same_base_alt](./same_base_alt.rs) and [different_base_alt](./different_base_alt.rs)
Loading

0 comments on commit a1f322a

Please sign in to comment.