BIP445: FROST Signing Protocol for BIP340 Signatures - #2070
Conversation
|
I'll fix the typos check soon |
|
I can see that GitHub's file changes view shows only one file at a time due to the large number of changes. This is because the reference implementation includes dependencies and auxiliary materials:
|
murchandamus
left a comment
There was a problem hiding this comment.
This is just a first glance, but I noticed a few issues:
murchandamus
left a comment
There was a problem hiding this comment.
Thanks for the quick turn-around. It’s on my todo list to give this a more thorough look, but it might take a bit. If you can motivate some other reviewers meanwhile, that would also be welcome.
I've shared it with most of the Bitcoin cryptographers I know and will post it on Twitter and the Bitcoin dev groups I'm part of. Hopefully that will bring in more reviewers! |
DarkWindman
left a comment
There was a problem hiding this comment.
Hi! Quite a remarkable job! We found a few minor issues, and correcting them would improve the overall specification of the BIP.
Christewart
left a comment
There was a problem hiding this comment.
As I mentioned on X i'm working on this, so you will likely see more comments in the future. Another nice-to-have would be a table of contents (example) as most other BIPs have this. Perhaps this is a limitation of the .md document vs .mediawiki. Not sure.
Yes, it's a |
Click there. ;)
|
Thank you! TIL :-) |
DarkWindman
left a comment
There was a problem hiding this comment.
A few additional minor issues and questions.
|
@DarkWindman thanks a lot for the review! I've addressed most of your review comments in a88f033. |
There was a problem hiding this comment.
From an editorial standpoint, it looks pretty good and like all the required sections are present. I have read the proposal only partially, and do not have the expertise to fully understand all aspects, so I cannot comment on the technical soundness and whether the Specification is complete and sufficient.
|
Let’s call this BIP 445. Please add an entry for your proposal in the README table, in the preamble update the BIP header to 445 and Assigned header to 2026-01-30, and update your documents file name as well as the auxiliary file directory. |
dc8729a to
289286c
Compare
|
@siv2r: Version 1.0.0 is usually reserved for the stage of the BIP that is advanced to Complete. You can find more guidance on Changelog Section and Version Header in BIP3. |
murchandamus
left a comment
There was a problem hiding this comment.
I gave this another fast read. From an editorial perspective, this looks properly formatted and complete (when considering the footnotes and "Remarks on Security and Correctness" the stand-in for the Rationale section). I did not spend the time to fully understand the scheme and only skimmed the algorithm sections. I saw that there was a reference implementation included and that it had some tests. Given the many review comments, and extensive Changelog, it seems to have been read much more carefully by multiple other more qualified reviewers.
From an editorial perspective, I’d be happy to publish this whenever the author and reviewers indicate that the proposal is clear, comprehensive, and mature enough to do so.
|
@siv2r: It sounds like you think it’s ready for publication, some reviewers have indicated the same. Let’s merge this in a week (on or after July 6th) unless more things crop up. Or if you want it published before then, please let me know. |
Sounds good! I'll do one final review this week, and will update here if anything comes up. Else we can merge on July 6th. |
DarkWindman
left a comment
There was a problem hiding this comment.
Minor nit; everything else looks good to me!
|
Sorry for being late with a comment of this kind, but I think this should somehow take into account the "plausible attack on adaptive security of threshold Schnorr signatures" by Elizabeth Crites and Alistair Stewart (paper, talk). tl;dr of the paper:
The big question, of course, is what to do. I think there are two reasonable options:
I tend to think that option 1 is better. Of course, that's a restriction in practice, but we can't just move on and pretend that everything will be fine. If someone wants to ignore the restriction, they can still do this, but then they're on their own. |
|
Given these new review comments, I expect that we will not publish today. I’ll wait for your input, @siv2r. |
|
After consulting with @elizabeth-crites, I have a clearer understanding now, and I should have mentioned also a second paper of her with Jonathan Katz, Chelsea Komlo, Stefano Tessaro, and Chenzhi Zhu (talk; immediately after the other talk in the same video). In fact, the situation is better than I mentioned. It's not just that we don't know whether an attack exist. The new paper defines a computational problem LDVR and proves that FROST is adaptively secure when LDVR is hard in addition to the discrete logarithm problem DL (or strictly speaking, its variant AOMDL). Then the paper proves that LDVR is – at least for parameters we're interested in (i.e., small enough n) – so hard that it's better for the attacker to attack DL instead. Here's improved script that estimates the bit security (function from math import log2, perm
BITS_GROUP_ORDER = 256
def myperm(n: int, k: int):
if k >= 1:
return perm(n, k)
else:
return 1
def table1(n: int, t: int, t_c: int | None = None):
if t_c is None:
t_c = t # worst case
return log2(myperm(n, 2 * t_c - t)/myperm(t_c, 2 * t_c - t))
# Check some numbers from Table 1 in https://eprint.iacr.org/2025/1061
assert table1(128, 96, round(0.9 * 96)) - 79.24 <= 0.01
assert table1(256, 64, 64 ) - 203.57 <= 0.01
assert table1(1024, 512, round(0.6 * 512)) - 197.18 <= 0.01
def effort(n: int, t: int | None = None, t_c: int | None = None):
if t is None:
t = n // 2 # worst case
return -(table1(n, t, t_c) - BITS_GROUP_ORDER)DL has an (assumed) bit security of ~128, and to be on the safe side, we want that breaking LDVR is at least as hard, i.e., There's a cruder but much simpler restriction: As long as n <= 131, we'll always have effort >= 128. So a simple restriction (or recommendation) for the BIP could be simply to require n <= 131 (or maybe n <= 128 to be on the safe side and have a nicer looking number). I'm pretty sure that 128 parties will be enough for all envisioned currently envisioned use cases of FROST. |
|
@siv2r: Please let me know whether you want to go forward with the publication or are still making further updates. The recent review comments could also be addressed in a follow-up authored by another contributor. |
|
I'm working on fixing the recent review comments. Let's not publish until they're fixed. |
| This signing protocol is compatible with any key generation protocol that produces valid FROST keys. | ||
| Valid keys satisfy: (1) each *secret share* is a Shamir share of the *threshold secret key*, and (2) each *public share* equals the scalar multiplication *secshare \* G*. | ||
| Before signing, the signers context must pass *ValidateSignersCtx*, which rejects duplicate identifiers and confirms the key material reproduces the threshold public key. The signing algorithms (*Sign*, *PartialSigVerify*, and *PartialSigAgg*) include this check for clarity, so an implementation can instead validate a context once and skip the repeated checks in later calls. | ||
| For comprehensive validation of the entire key material, *ValidateSignersCtx* can be run on all possible *u* signing participants. |
There was a problem hiding this comment.
nit: Do you mean "on the full set of n participants (u = n)" here? Could be clarified.
edit: On a further look, this is much more sublte. Moved the discussion to the dev repo at siv2r/bip-frost-signing#43 (comment).
|
I completed a full pass on the text. Nothing substantial and sorry again that my comments arrive that late in the process. edit: Forgot to mention a "global" nit: The text uses "signer" and "participant" interchangeable. Sticking to one term would make things a tiny bit clearer (but this may be an annoying change to make at this stage). |
|
Tysm for the detailed review.
This was fixed in the development repo recently. "Participants" refers to anyone involved in key generation, and "signers" to those participating in the current signing session. Will pull in the latest changes once the other review comments are resolved. |

This PR adds a BIP for the FROST (Flexible Round-Optimized Schnorr Threshold) signing protocol. The development repository is at https://github.com/siv2r/bip-frost-signing.
There already exists RFC 9591, which standardizes the two-round FROST signing protocol, but it is incompatible with Bitcoin's BIP340 X-only public keys. This BIP bridges that gap by providing a BIP340-compatible variant of FROST.
This BIP standardizes the FROST3 variant (Section 2.3 of the ROAST paper). This variant shares significant similarities with the MuSig2 signing protocol (BIP327). Accordingly, this BIP follows the core design principles of BIP327, and many sections have been directly adapted from it.
FROST key generation is out of scope for this BIP. There are sister BIPs such as ChillDKG and Trusted Dealer Generation that specify key generation mechanisms. This BIP must be used in conjunction with either of those for the full workflow from key generation to signature creation. Careful consideration has been taken to ensure the terminology in this BIP matches that of ChillDKG.
There are multiple (experimental) implementations of this specification:
FROST-BIP340TODO: verify if this impl is compatible with our test vectorssecp256kfun (implements ChillDKG with FROST signing)TODO: verify if this impl is compatible with our test vectorsDisclosure: AI has been used to rephrase paragraphs for clarity, refactor certain sections of the reference code, and review pull requests made to the development repository.
Feedback is appreciated! Please comment on this pull request or open an issue at https://github.com/siv2r/bip-frost-signing for any feedback. Thank you!
cc @jonasnick @real-or-random @jesseposner