Skip to content

BIP445: FROST Signing Protocol for BIP340 Signatures#2070

Open
siv2r wants to merge 10 commits intobitcoin:masterfrom
siv2r:bip-frost-signing
Open

BIP445: FROST Signing Protocol for BIP340 Signatures#2070
siv2r wants to merge 10 commits intobitcoin:masterfrom
siv2r:bip-frost-signing

Conversation

@siv2r
Copy link
Copy Markdown
Contributor

@siv2r siv2r commented Jan 3, 2026

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:

  • The reference Python implementation included in this PR
  • secp256k1-zkp FROST module (yet to implement the test vectors)
  • FROST-BIP340 TODO: verify if this impl is compatible with our test vectors
  • secp256kfun (implements ChillDKG with FROST signing) TODO: verify if this impl is compatible with our test vectors

Disclosure: 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

@siv2r
Copy link
Copy Markdown
Contributor Author

siv2r commented Jan 3, 2026

I'll fix the typos check soon

@siv2r
Copy link
Copy Markdown
Contributor Author

siv2r commented Jan 3, 2026

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:

  • The reference code uses secp256k1lab python library (vendored as a git subtree, ~20 files) for scalar and group arithmetic. I can remove this from the PR when the library is integrated into this repository (RFC: Integrate secp256k1lab v1.0.0 as subtree, use it for BIP-374 #1855).
  • Auxiliary files include docs/partialsig_forgery.md (which I can move to a gist if preferred) and a test vector generation script (~1400 lines). I can exclude these if necessary.

@murchandamus murchandamus changed the title Add BIP: FROST Signing for BIP340-compatible Threshold Signatures BIP Draft: FROST Signing Protocol for BIP340 Schnorr Signatures Jan 6, 2026
Copy link
Copy Markdown
Member

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

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

This is just a first glance, but I noticed a few issues:

Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
@murchandamus murchandamus changed the title BIP Draft: FROST Signing Protocol for BIP340 Schnorr Signatures BIP Draft: FROST Signing Protocol for BIP340 Signatures Jan 8, 2026
Copy link
Copy Markdown
Member

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

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

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.

Comment thread bip-frost-signing.md Outdated
@siv2r
Copy link
Copy Markdown
Contributor Author

siv2r commented Jan 9, 2026

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!

Copy link
Copy Markdown

@DarkWindman DarkWindman left a comment

Choose a reason for hiding this comment

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

Hi! Quite a remarkable job! We found a few minor issues, and correcting them would improve the overall specification of the BIP.

Comment thread bip-0445.md
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-0445.md
Comment thread bip-frost-signing.md Outdated
Comment thread bip-0445.md
Comment thread bip-0445.md
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Copy link
Copy Markdown
Contributor

@Christewart Christewart left a comment

Choose a reason for hiding this comment

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

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.

Comment thread bip-0445.md
Comment thread bip-0445.md
@siv2r
Copy link
Copy Markdown
Contributor Author

siv2r commented Jan 21, 2026

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 .md issue, this bip initially had a manually written table of contents but was removed after #2070 (comment)

@murchandamus
Copy link
Copy Markdown
Member

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.

Click there. ;)

image

@Christewart
Copy link
Copy Markdown
Contributor

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.

Click there. ;)

Thank you! TIL :-)

Copy link
Copy Markdown

@DarkWindman DarkWindman left a comment

Choose a reason for hiding this comment

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

A few additional minor issues and questions.

Comment thread bip-0445.md
Comment thread bip-frost-signing.md Outdated
Comment thread bip-0445.md
- If the optional argument *extra_in* is not present:
- Let *extra_in = empty_bytestring*
- Let *k<sub>i</sub> = scalar_from_bytes_wrapping(hash<sub>FROST/nonce</sub>(rand || bytes(1, len(pubshare)) || pubshare || bytes(1, len(thresh_pk)) || thresh_pk || m_prefixed || bytes(4, len(extra_in)) || extra_in || bytes(1, i - 1)))* for *i = 1,2*
- Fail if *k<sub>1</sub> = Scalar(0)* or *k<sub>2</sub> = Scalar(0)*
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

While reading the implementation, I noticed that it includes a check ensuring that k_1 != k_2. At first glance, omitting this check does not appear to introduce any vulnerabilities, and we have verified this. However, I would appreciate hearing your opinion on this point.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Which function are you referring to? I don't see a k_1 != k_2 check in the nonce_gen_internal or deterministic_sign functions.

This is an interesting question though. I never considered adding this check, primarily because BIP327's reference implementation doesn't have it either.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Which function are you referring to? I don't see a k_1 != k_2 check in the nonce_gen_internal or deterministic_sign functions.

I apologize for not mentioning which implementation I was referring to. I meant the secp256k1-zkp FROST module, where the secp256k1_frost_nonce_gen() function performs this check. However, I think this verification is redundant, as I have not found any paper or specification that requires it. At first glance, it may seem that manipulation with Wagner attacks could apply, but I do not see any concrete attack vectors.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh, I was not aware of this. Thank you! I checked the Olaf paper as well, and it didn't have this requirement. I haven't thought about this from security proof perspective. Will keep this open till then :)

Comment thread bip-0445.md
Comment thread bip-0445.md
@siv2r
Copy link
Copy Markdown
Contributor Author

siv2r commented Jan 25, 2026

@DarkWindman thanks a lot for the review! I've addressed most of your review comments in a88f033.

Copy link
Copy Markdown
Member

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

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

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.

Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
@murchandamus murchandamus added the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Jan 27, 2026
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-0445/python/vectors/sign_verify_vectors.json Outdated
@murchandamus
Copy link
Copy Markdown
Member

murchandamus commented Jan 30, 2026

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.

@murchandamus murchandamus changed the title BIP Draft: FROST Signing Protocol for BIP340 Signatures BIP445: FROST Signing Protocol for BIP340 Signatures Jan 30, 2026
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-frost-signing.md Outdated
Comment thread bip-0445/python/vectors/det_sign_vectors.json
Comment thread bip-0445.md

[^t-edge-cases]: While *t = n* and *t = 1* are in principle supported, simpler alternatives are available in these cases. In the case *t = n*, using a dedicated *n-of-n* multi-signature scheme such as MuSig2 (see [BIP327][bip327]) instead of FROST avoids the need for an interactive DKG. The case *t = 1* can be realized by letting one signer generate an ordinary [BIP340][bip340] key pair and transmitting the key pair to every other signer, who can check its consistency and then simply use the ordinary [BIP340][bip340] signing algorithm. Signers still need to ensure that they agree on a key pair.

The IRTF has published [RFC 9591][rfc9591], which specifies the FROST signing protocol for several elliptic curve and hash function combinations, including secp256k1 with SHA-256, the cryptographic primitives used in Bitcoin. However, the signatures produced by RFC 9591 are incompatible with BIP340 Schnorr signatures due to the X-only public keys introduced in BIP340. Additionally, RFC 9591 does not specify key tweaking mechanisms, which are essential for Bitcoin applications such as [BIP32][bip32] key derivation and [BIP341][bip341] Taproot. This document addresses these limitations by specifying a BIP340-compatible variant of FROST signing protocol that supports key tweaking.
Copy link
Copy Markdown
Contributor

@Christewart Christewart Feb 2, 2026

Choose a reason for hiding this comment

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

I'm not sure where to best recommend putting this (here, or the tweaking section?) but I think it could be a good idea to mention that this BIP (AFAICT) follows the tweak handling of BIP327.

This would give people a heads up that you may be able to reuse code from your existing MuSig implementation if you have one.

We call it the "Tweak Context" in this BIP. In BIP327, they call it the "KeyAgg Context". At minimum, it seems preferable to use the same nomenclature.

I would guess that this data structure is gonna become more popular as taproot native protocols will have to handle x-only keys - perhaps its worth having a BIP of its own 🤷‍♂️ .

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The BIP has the following paragraph in the motivation section:

The FROST3 signing protocol shares substantial similarities with the MuSig2 signing protocol specified in [BIP327][bip327]. Accordingly, this specification adopts several design principles from BIP327, including support for key tweaking, partial signature verification, and identifiable abort mechanisms.

It specifies the key tweaking is adopted from BIP327. I'll now add a note in the algorithms section, about the potential to reuse code from exisiting MuSig2 implementation. This should suffice, right?

We call it the "Tweak Context" in this BIP. In BIP327, they call it the "KeyAgg Context". At minimum, it seems preferable to use the same nomenclature.

Yes, TweakContext is basically the renamed version of KeyAgg Context. It would be incorrect to use the same name here because in BIP327, this struct was the output of the KeyAgg function (a key generation protocol). However, key generation for this BIP is out of scope, and TweakContext is only needed when the user wants to tweak their threshold public key. It's not needed otherwise. Hence, I prefer the TweakContext name.

I would guess that this data structure is gonna become more popular as taproot native protocols will have to handle x-only keys - perhaps its worth having a BIP of its own 🤷‍♂️ .

I agree this structure will become popular. It's already used in BIP 89. As for standardizing it in a BIP, I think it could be done. Whenever this struct appears, it's usually accompanied by Tweak Context, TweakCtxInit, and ApplyTweak. However, I'm not sure every BIP would follow this exact structure, they may modify it depending on their needs. For instance, this BIP renamed KeyAggContext. There's also the possibility of "agnostic tweaking" in FROST, which if adopted would completely eliminate this data structure and would follow a different tweaking approach.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The "agnostic tweaking" approach is essentially what is described in Re-Randomized FROST. You can see in the game in Figure 4 that the attacker provides tweak alpha to the signing oracle, which then tweaks the secret share and public key ("randomize" with alpha) and runs the normal FROST signing algorithm with the tweaked keys.

Btw, this approach does not work with MuSig2. In FROST where ell_i and x_i denote the lagrange coefficient and share of signer i and t denote the tweak, tweaking-agnostic signing relies on

sum(ell_i(x_i + t)) = sum(ell_i x_i) + t

which follows from sum(ell_i) = 1. In MuSig2 we'd multiply the tweaked secret key with key aggregation coefficient a_i:

sum(a_i(x_i + t))

which is generally not identical to sum(a_i x_i) + t.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah yes, this sums up agnostic tweaking accurately. I only knew this as a trick: that shifting every shamir secshare by t would result in the threshold public key being shifted by g^t, when reviewing this ChillDKG function. I wasn't aware of the paper. Just went through it and it describes the algorithm exactly. Thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agnostic tweaking issue is tracked here: siv2r/bip-frost-signing#41.

I'll now add a note in the algorithms section, about the potential to reuse code from exisiting MuSig2 implementation. This should suffice, right?

Added a note in TweakContext data structure introduction about potential BIP327 code reuse.

Comment thread bip-0445.md Outdated
@Christewart
Copy link
Copy Markdown
Contributor

tACK test vectors on 289286c

@murchandamus
Copy link
Copy Markdown
Member

murchandamus commented Feb 3, 2026

As I’m not involved in the technical review here, I’m gonna tune out here for the time being.
Please feel free to mention me by nickname when you reach a point where you’d like an editor to take a look again, or when you think you are reaching a point where your document should be published.

@jonasnick
Copy link
Copy Markdown
Contributor

There are a few REVIEW comments in the python implementation that would need to be addressed because they appear to be relevant to security.

Copy link
Copy Markdown

@disnocen disnocen left a comment

Choose a reason for hiding this comment

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

Nonce generation review

b = Scalar.from_bytes_wrapping(
tagged_hash("FROST/noncecoef", ser_ids + aggnonce + Q.to_bytes_xonly() + msg)
)
assert b != 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I reviewed the nonce generation functions (NonceGen, CounterNonceGen,DeterministicSign) and the nonce coefficient computation.

  1. Nonce reuse is prevented by secnonce zeroing and defense-in-depth hash inputs
  2. RNG failures are mitigated by secret share blinding and alternative generation modes
  3. Nonce bias is negligible due to proper modular reduction of hash outputs
  4. Domain separation is thorough via tagged hashing
  5. Multi-user concerns are addressed by including signer-specific inputs in the nonce hash
  6. Nonce aggregation integrity is ensured by binding the nonce coefficient b to all session parameters (signer set, aggregate nonce, public key, message), preventing algebraic attacks across signing sessions

Comment thread bip-0445.md Outdated
Comment thread bip-0445/python/frost_ref/signing.py Outdated
Comment thread bip-0445/python/frost_ref/signing.py Outdated
Comment thread bip-0445/python/frost_ref/signing.py Outdated
raise ValueError(
"The signer's pubshare must be included in the list of pubshares."
)
# REVIEW: do we actually need this check?
Copy link
Copy Markdown

@disnocen disnocen Feb 19, 2026

Choose a reason for hiding this comment

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

Note: The comment is for line 344, and the subsequent check, not the previous one. Sorry, from the wrong highlight. I can not change that.

I do think we need this check. Without this check, a malicious coordinator could achieve signature disruption and make signing session fail by manipulating the Lagrange interpolation process. This in turn breaks the identifiable aborts property of ROAST/FROST3, since now the signer is apparently responsible for the failure, while in reality the problem lies in the wrong data fed by the coordinator

Note that the assert in derive_interpolating_value is not sufficient, since Python assert statements are removed entirely when Python is run with the -O (optimize) flag or PYTHONOPTIMIZE=1is set

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should you also check that the ids are unique for identifiable aborts?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I see that get_session_values (line 321) calls validate_signers_ctx, which already checks uniqueness of ids at line 103-104. It raises a generic ValueError though: I don't know if this kind of error is sufficient for identifiable aborts, or if aInvalidContributionError would be better

Copy link
Copy Markdown
Contributor Author

@siv2r siv2r Feb 27, 2026

Choose a reason for hiding this comment

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

I agree. I'd like to keep this check as well.

I don't know if this kind of error is sufficient for identifiable aborts, or if aInvalidContributionError would be better

SignersContext is external, pre-protocol setup data, agreed upon by all parties before signing begins. It is not a runtime protocol contribution from any single signer or coordinator. InvalidContributionError is semantically for in-protocol misbehavior, so I don't think it's appropriate here. Maybe we could define a new error for invalid protocol input data like ProtocolInputError or ProtocolSetupError.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should you also check that the ids are unique for identifiable aborts?

Duplicate ids in SignersContext means the protocol setup is broken and should be rejected upfront. Now that you mention it, the BIP says validate_signers_context is an "optional" API that implementations can run to check the compatibility of keygen and signing. We should mandate it since we obviously want to avoid duplicate IDs during signing.

Side note: For identifiable abort to work, it requires the coordinator to be trusted (peform honest aggregation): siv2r/bip-frost-signing#42

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

validate_signers_ctx is updated to return only ValueError, removed the existing InvalidContributionError

Maybe we could define a new error for invalid protocol input data like ProtocolInputError or ProtocolSetupError.

Discussions in siv2r/bip-frost-signing#43 suggests introducing new error type isn't required.

Comment thread bip-0445/python/frost_ref/signing.py Outdated
return psig


# REVIEW should we hash the signer set (or pubshares) too? Otherwise same nonce will be generate even if the signer set changes
Copy link
Copy Markdown

@disnocen disnocen Feb 19, 2026

Choose a reason for hiding this comment

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

Note: The comment is for line 364, and the subsequent function. Sorry, from the wrong highlight. I can not change that.

I think we should include serialize_ids(ids) in the det_nonce_hash input.

The current implementation hashes secshare, aggothernonce, tweaked_tpk, msg, and the index i, but not the signer set (ids). Since deterministic_sign is used by the last participant (the one who waits for everyone else's nonces), a malicious coordinator can replay the same aggothernonce across multiple sessions with different signer subsets while keeping everything else constant. This produces identical nonces for the victim across sessions, but the Lagrange interpolation coefficients differ because the signer set changed. Three such sessions give three linear equations in three unknowns (k_1, k_2, d'), which is enough to extract the victim's secret share.

MuSig2's DeterministicSign doesn't need this because it's always n-of-n (the signer set never varies), but in FROST the variable signer subsets make it necessary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you think about adding my_id as well? I don't think it's required (if key generation was done correctly) but it doesn't hurt.

Copy link
Copy Markdown
Contributor Author

@siv2r siv2r Apr 14, 2026

Choose a reason for hiding this comment

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

Added the signer set to det_nonce_hash and noted the attack in a footnote. Included my_id too. Skipped adding my_id to the regular randomized nonce_hash as it'd increase the NonceGen's public API for a defense-in-depth hedge that pubshare already gives. See c408401.

Comment thread bip-0445.md
Comment thread bip-0445.md
Comment thread bip-0445/python/frost_ref/signing.py
Comment thread bip-0445/python/frost_ref/signing.py Outdated
Comment thread bip-0445/python/frost_ref/signing.py Outdated
Comment thread bip-0445/python/frost_ref/signing.py Outdated
return psig


# REVIEW should we hash the signer set (or pubshares) too? Otherwise same nonce will be generate even if the signer set changes
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you think about adding my_id as well? I don't think it's required (if key generation was done correctly) but it doesn't hurt.

@siv2r siv2r force-pushed the bip-frost-signing branch from ad69a7c to 63748eb Compare April 13, 2026 15:19
@mllwchrry
Copy link
Copy Markdown

I reviewed test vectors and found a few gaps worth addressing:

  1. The coverage would benefit from testing different threshold settings (different t and n values).
  2. No vector attempts signing with fewer than t participants. validate_signers_ctx explicitly raises ValueError("The number of signers must be between t and n.") for this case, but it is never triggered by the existing vectors.
  3. The check if not 0 < d_ < GE.ORDER exists in sign but no vector exercises it.
  4. Need to cover the second half of secnonce all-zeros path. The existing nonce-reuse vector uses a fully zeroed 64-byte secnonce, which fails on the first half check and never reaches the second half (k_2) validation.
  5. apply_tweak has two uncovered error paths: if Q_.infinity: raise ValueError("The result of tweaking cannot be infinity.") and if len(tweak) != 32: raise ValueError("The tweak must be a 32-byte array.").
  6. validate_signers_ctx checks if not 0 <= i <= n - 1: raise ValueError(f"The participant identifier {i} is out of range.") but no vector passes an out-of-range identifier.

Please let me know if I missed anything or misunderstood some of the cases.

- bind signer_ids to det_nonce_hash
- raise only value erros inside validate_signers_ctx
- fix spec vs python mismatch, and some typos
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New BIP PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants