Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[llfourn] Rapid fire comments #1

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ To instantiate a DKG there are many possible schemes which differ by the guarant
Since DKGs are difficult to implement correctly in practice, this document describes DKGs that are relatively *simple*, namely SimplPedPop and SecPedPop.
However, the DKG can be swapped out for another one if desired.

<!-- Can it though? I understood the claim of the "practical" paper was that the keygen and signing must be proved secure together. Is there some way of checking whether a DKG can be replaced with another. Is there some functionality we can simulate or a game we can reduce to? -->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the sentence to

However, the DKG can be swapped out for a different one provided it is proven to be secure when used in FROST.

But it's a good question. Why are the modifications we make to SimplPedPop compared to the paper secure?


The DKG outputs the shared public key and a secret share for each signer.
It is extremely important that both outputs are securely backed up because losing the share will render the signer incapable of producing signatures.
In order to reduce the chance of losing the backup, it is possible to encrypt the backup and send it to every other signer.
If a signer loses the local backup, as long as there's at least one other signer that cooperates and sends back the encrypted backup, the signer can restore (see also [repairable threshold signatures](https://github.com/chelseakomlo/talks/blob/master/2019-combinatorial-schemes/A_Survey_and_Refinement_of_Repairable_Threshold_Schemes.pdf).

<!-- But then one must back up the deryption key? I think we should clear this up by explaining what your options are in "backup and recover section". This is an option where you have a long lived secret you can encrypt to. The other solution that is always available to you is to use MPC to recover the share with a threshold of parties. This also allows issuing a new share i.e. enrollment. Not suggesting we should specify that here but for our project at least this is a more appropriate solution. -->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you must back up the decryption key. But at least that one can be derived from some 24 words.

Good idea to add a dedicated "backup and recover" section. I did that and moved the sentence over there, mentioned the encryption key and the MPC method (although I don't know the specifics of how this would work).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MPC in this context I just mean something like the "repair algorithm" scheme on page 18 on the wonderful slides above i.e. each party splits up their share to other parties and then you do some linear computation on them. Here we Lagrange interpolate and evaluate at a new point on the polynomial to produce a new share which can all be done with additions a multiplication by public scalar.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I actually skimmed the slides now ;) This is pretty useful indeed; I updated the section.

How does the repairing user know that they actually have the right share? Is this it the same share as before? If so, maybe the cert can be reused?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm maybe you can create a cert for it in the scheme you gave but you'd have to restrict the cert to just the public polynomial and your index in it because the artifacts from this protocol are a bit different to the keygen (e.g. no PoPs).

I'd say you convince the new/repaired user of the t public shares of the parties who will create the new share somehow. From that you can Lagrange interpolate the implied public polynomial and from there you can verify that the image of your secret share matches the public polynomial evaluated at your index.

Copy link
Collaborator

@jonasnick jonasnick Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, don't you need a long term secret also for Enrolment RTS, in particular to authorize the enrolment? Without it, anyone could ask for a share.

Copy link
Author

@LLFourn LLFourn Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting point. I actually handn't thought about this workflow even in our context too much yet. To identify the t parties providing input, the secret shares themselves are a natural choice. You can assign the image of the secret share as the public encryption key to create secure channel in the RTS. I am brushing aside composability issues here which would need to be analyzed a bit (intuitively it should be fine).

For the receiver I guess you just have to verify their public key out of band somehow.

A safe way to do it would be to have a session string that consists of the [t share images + indices, index + public key of the receiver] which all parties (including the intended receiver) must agree on before starting the protocol. How you verify that all parties have the same string before starting is context specific (like keygen except you must verify this before starting rather than after!).


Once the DKG concludes successfully, it is recommended to rule out basic mistakes in the setup by having all signers create a FROST signature for some test message.

<!-- Nice idea. I'd soften the recommendation to "Applications should consider..". -->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


### SimplPedPop

We specify the SimplPedPop scheme as described in [Practical Schnorr Threshold Signatures
Expand All @@ -32,6 +38,8 @@ Without the Algebraic Group Model, section 4](https://eprint.iacr.org/2023/899.p
- Very rudimentary ability to identify misbehaving signers in some situations.
- The proof-of-knowledge in the setup does not commit to the prover's id. This is slightly simpler because it doesn't require the setup algorithm to know take the id as input.

<!-- This is indeed what we do atm but there's a good reason to using small integer indicies: You can ask a user to etch a number onto a 24 seed word backup plate. Also something like BIP93 for when you can backup a short bech32 string. Like bip93 we'd wanna keep the index to ≤ 2⁵ -->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would you need to back up the ID? Is this for the enrolment scheme? And if you have the ability to back up seed words, couldn't you derive the ID from the seed? The ID can even be fixed across multiple threshold setups, the index cannot, I think.

Copy link
Collaborator

@jonasnick jonasnick Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As real-or-random pointed out to me in private conversation, you need the ID - your own and those of the other signers - for signing. The current writeup does not forbid using low-entropy IDs such as indices.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we talking about seed words that back up your secret share? You certainly can't derive your ID from those.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the scenario I had mainly considered is existing wallets integrating threshold signatures. They support single signatures and typically have a seed backup. Is your scenario is pure threshold wallets without a backed up master key?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see SimplPedPop has since been updated to not take IDs as input

Is your scenario is pure threshold wallets without a backed up master key?

Yes. While we do have a key on each device for our secure channel and device "pairing", we were looking to avoid using these keys for device indexes and needing to back them up


SimplPedPop requires SECURE point-to-point channels between the participants, i.e., channels that are ENCRYPTED and AUTHENTICATED.
The messages can be relayed through a coordinator who is responsible to pass the messages to the participants as long as the coordinator does not interfere with the secure channels between the participants.

Expand Down Expand Up @@ -83,7 +91,7 @@ def simplpedpop_finalize(ids, my_id, vss_commits, shares, eta = ()):
throw BadParticipant(ids[i])
if not verify_sig(vss_commits[i].sig, vss_commits[i][0], "")
throw BadParticipant(ids[i])
eta += (sig, vss_commit[i])
eta += (sig, vss_commit[i])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

if not Eq(eta):
return False
# helper_compute_pk computes the individual pubkey of participant with the given id
Expand All @@ -104,7 +112,7 @@ def secpedpop_round1(seckey):
return individual_pk(seckey)
```

The public keys are set to each other.
The public keys are sent to each other.
Comment on lines -107 to +115
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Every participant stores the received public keys in the `pubkeys` array.

```python
Expand Down Expand Up @@ -221,3 +229,23 @@ TODO Consider a variant based on MuSig2
If the participants run a BFT-style consensus protocol (e.g., as part of a federated protocol), they can use consensus to check whether they agree on `x`.

TODO: Explain more here. This can also achieve termination but consensus is hard (e.g., honest majority, network assumptions...)


<!-- An important question here is how many parties need to give input of polynomial commitments for the key generation? -->
<!-- It would be prohibitive to require that the number of input parties is the same number as those receiving shares (which would be every consensus node). The spec implicitly implies this invariant atm. -->


<!-- If we have n = 3T + 1 (where T is number of corrupted parties) and `n` is the consensus nodes -->
<!-- I claim you only need T + 1 parties to be involved in keygen for it to be secure (i.e. only one -->
<!-- honest party). This means if we get consensus on the need to generate key then there will be at -->
<!-- least T+1 nodes who provide input in the next epoch in an atomic broadcast consensus algo like -->
<!-- HoneyBadgerBFT (https://eprint.iacr.org/2016/199.pdf) so it can be done in one round. -->

<!-- So I think we have to allow the number of parties receiving shares be different from the number that receive shares. Also these two groups can be totally disjoint. On one extreme you can have a trusted party who generates key shares for a bunch of other parties for example. On the other you can have a group of `N` parties contribute polynomial commitments for a smaller group of `n` nodes where `N ⊃ n`. We are doing this in frostsnap so that we have extra randomness go into the key generation. -->

<!-- On the other hand, I'm not sure we should recommend this protocol for honest majority settings. There are elegant, efficient and information theoretically secure protocols that can do sharings in batch. -->
<!-- These slides have the closest thing to what I have in mind (but they are not for key specifically but secret sharing sharing): -->

<!-- https://tcc.iacr.org/2020/workshop/tcc-tot-2020.pdf (see "Random Sharings with HIM") -->
<!-- There's also this more sophisticated schemes like https://eprint.iacr.org/2023/1175 that I still haven't finished understanding yet. -->
-
4 changes: 4 additions & 0 deletions notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@
- Need to document that we shouldn't throw away data until we're sure that the DKG either failed or succeeded. Otherwise, the DKG may end up succeeding after throwing away and someone sends funds to the address.
- How modular do we want to design this? Do we support plugging in other DKGs?
- Do we want to support some sort of share backup scheme (see also [repairable threshold sigs](https://github.com/chelseakomlo/talks/blob/master/2019-combinatorial-schemes/A_Survey_and_Refinement_of_Repairable_Threshold_Schemes.pdf))that sends share encrypted-to-self to other signers? As long as one other signer cooperates we can restore.
<!-- I 'd not use the self-encrypted one. The enrollment scheme is nicer because it doesn't store extra data. Just having the shares is enough. If we agree on this we can just specify a bech32 format like BIP93 for shares and leave this stuff for future work. In addition we should specify how to generate the public keys from a threshold number of share images. -->
- Are we able to get rid of indices entirely? SimplPedPop uses indices, JessePedPop doesn't. It uses public keys instead.
- use unique identifier instead of pubkey?
<!-- No. Indicies are useful for backups. Otherwise you have to back up the index as well. -->
- Into how many functions should we split up the DKG. Jesse claims that splitting up has the advantage that "it's more flexible because with the proposed API the VSS can be generated prior to knowing the public keys of any participants"
- Should it be possible to assign weights for weighted threshold sigs?
<!-- I wouldn't unless we want to specify how to sign with multiple shares at once in a single signature. Easy to derive a correct protocol for this dunno about security. -->
- Do we need to include the signature in the vss_hash? Probably not, but depending on how the rest is set up, it may not hurt.
- Should the scheme support deterministic key derivation?
- Not sure if that's actually that useful. And it only works as long as the code does not change, which we may not want to guarantee.
<!-- After a lot of thought on this: no it shouldn't. Everything can reproduced with a threshold of shares via MPC. Polynomials should use runtime randomness and deleted after share generation. -->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain some of your thought process? Deterministic seed derivation may allow backups that only rely on a single cooperating signer instead of a threshold.

Copy link
Author

@LLFourn LLFourn Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I didn't interpret what you said properly. You shouldn't use deterministic derivation to derive your input polynomial for they key generation is what I meant. I am not certain what key you are referring to that we should generate deterministically?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't use deterministic derivation to derive your input polynomial for they key generation is what I meant.

My question is why you concluded that you shouldn't do that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because there is little value in reproducing the secret polynomial at a later time. The polynomial can only help you recover if you have n-of-n polynomials. But this is strictly worse than recovery schemes that just require t-of-n.

Copy link

@nickfarrow nickfarrow Nov 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree backing up methods described in dkg and repairing make sense for our purposes and more generally.

allow backups that only rely on a single cooperating signer instead of a threshold

Couldn't it at this point be easier to encrypt one's secret share to oneself and sign under a key from the seed, and share this among other parties?

Perhaps other FROST users could want deterministic keygen if it allows them to lazily recover the key with all n preexisting seed phrases.. Or even use a single seed in a number of DKGs, all with this lazy backup method.

edit: ah catching up on https://github.com/jonasnick/bip-frost-dkg/issues/6

- Is it impossible to sign if the `Eq` check fails? If not, we may want to tweak the public key by `eta` to make sure that signing fails.


Expand Down