| < draft-irtf-cfrg-frost-03.txt | draft-irtf-cfrg-frost-04.txt > | |||
|---|---|---|---|---|
| CFRG D. Connolly | CFRG D. Connolly | |||
| Internet-Draft Zcash Foundation | Internet-Draft Zcash Foundation | |||
| Intended status: Informational C. Komlo | Intended status: Informational C. Komlo | |||
| Expires: 8 September 2022 University of Waterloo, Zcash Foundation | Expires: 30 September 2022 University of Waterloo, Zcash Foundation | |||
| I. Goldberg | I. Goldberg | |||
| University of Waterloo | University of Waterloo | |||
| C. A. Wood | C. A. Wood | |||
| Cloudflare | Cloudflare | |||
| 7 March 2022 | 29 March 2022 | |||
| Two-Round Threshold Schnorr Signatures with FROST | Two-Round Threshold Schnorr Signatures with FROST | |||
| draft-irtf-cfrg-frost-03 | draft-irtf-cfrg-frost-04 | |||
| Abstract | Abstract | |||
| In this draft, we present a two-round signing variant of FROST, a | In this draft, we present the two-round signing variant of FROST, a | |||
| Flexible Round-Optimized Schnorr Threshold signature scheme. FROST | Flexible Round-Optimized Schnorr Threshold signature scheme. FROST | |||
| signatures can be issued after a threshold number of entities | signatures can be issued after a threshold number of entities | |||
| cooperate to issue a signature, allowing for improved distribution of | cooperate to issue a signature, allowing for improved distribution of | |||
| trust and redundancy with respect to a secret key. Further, this | trust and redundancy with respect to a secret key. Further, this | |||
| draft specifies signatures that are compatible with [RFC8032]. | draft specifies signatures that are compatible with [RFC8032]. | |||
| However, unlike [RFC8032], the protocol for producing signatures in | However, unlike [RFC8032], the protocol for producing signatures in | |||
| this draft is not deterministic, so as to ensure protection against a | this draft is not deterministic, so as to ensure protection against a | |||
| key-recovery attack that is possible when even only one participant | key-recovery attack that is possible when even only one participant | |||
| is malicious. | is malicious. | |||
| skipping to change at page 2, line 10 ¶ | skipping to change at page 2, line 10 ¶ | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on 8 September 2022. | This Internet-Draft will expire on 30 September 2022. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2022 IETF Trust and the persons identified as the | Copyright (c) 2022 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents (https://trustee.ietf.org/ | |||
| license-info) in effect on the date of publication of this document. | license-info) in effect on the date of publication of this document. | |||
| Please review these documents carefully, as they describe your rights | Please review these documents carefully, as they describe your rights | |||
| and restrictions with respect to this document. Code Components | and restrictions with respect to this document. Code Components | |||
| extracted from this document must include Revised BSD License text as | extracted from this document must include Revised BSD License text as | |||
| described in Section 4.e of the Trust Legal Provisions and are | described in Section 4.e of the Trust Legal Provisions and are | |||
| provided without warranty as described in the Revised BSD License. | provided without warranty as described in the Revised BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 1.1. Change Log . . . . . . . . . . . . . . . . . . . . . . . 4 | 1.1. Change Log . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 5 | 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 5 | |||
| 3. Cryptographic Dependencies . . . . . . . . . . . . . . . . . 5 | 3. Cryptographic Dependencies . . . . . . . . . . . . . . . . . 6 | |||
| 3.1. Prime-Order Group . . . . . . . . . . . . . . . . . . . . 6 | 3.1. Prime-Order Group . . . . . . . . . . . . . . . . . . . . 6 | |||
| 3.2. Cryptographic Hash Function . . . . . . . . . . . . . . . 7 | 3.2. Cryptographic Hash Function . . . . . . . . . . . . . . . 7 | |||
| 4. Helper functions . . . . . . . . . . . . . . . . . . . . . . 7 | 4. Helper functions . . . . . . . . . . . . . . . . . . . . . . 7 | |||
| 4.1. Schnorr Signature Operations . . . . . . . . . . . . . . 7 | 4.1. Schnorr Signature Operations . . . . . . . . . . . . . . 8 | |||
| 4.2. Polynomial Operations . . . . . . . . . . . . . . . . . . 9 | 4.2. Polynomial Operations . . . . . . . . . . . . . . . . . . 9 | |||
| 4.2.1. Evaluation of a polynomial . . . . . . . . . . . . . 9 | 4.2.1. Evaluation of a polynomial . . . . . . . . . . . . . 9 | |||
| 4.2.2. Lagrange coefficients . . . . . . . . . . . . . . . . 9 | 4.2.2. Lagrange coefficients . . . . . . . . . . . . . . . . 10 | |||
| 4.2.3. Deriving the constant term of a polynomial . . . . . 10 | 4.2.3. Deriving the constant term of a polynomial . . . . . 11 | |||
| 4.3. Commitment List Encoding . . . . . . . . . . . . . . . . 11 | 4.3. Commitment List Encoding . . . . . . . . . . . . . . . . 12 | |||
| 4.4. Binding Factor Computation . . . . . . . . . . . . . . . 11 | 4.4. Binding Factor Computation . . . . . . . . . . . . . . . 12 | |||
| 4.5. Group Commitment Computation . . . . . . . . . . . . . . 12 | 4.5. Group Commitment Computation . . . . . . . . . . . . . . 13 | |||
| 4.6. Signature Challenge Computation . . . . . . . . . . . . . 12 | 4.6. Signature Challenge Computation . . . . . . . . . . . . . 13 | |||
| 5. Two-Round FROST . . . . . . . . . . . . . . . . . . . . . . . 13 | 5. Two-Round FROST Signing Protocol . . . . . . . . . . . . . . 14 | |||
| 5.1. Round One - Commitment . . . . . . . . . . . . . . . . . 16 | 5.1. Round One - Commitment . . . . . . . . . . . . . . . . . 17 | |||
| 5.2. Round Two - Signature Share Generation . . . . . . . . . 16 | 5.2. Round Two - Signature Share Generation . . . . . . . . . 17 | |||
| 5.3. Signature Share Verification and Aggregation . . . . . . 18 | 5.3. Signature Share Verification and Aggregation . . . . . . 19 | |||
| 6. Ciphersuites . . . . . . . . . . . . . . . . . . . . . . . . 20 | 6. Ciphersuites . . . . . . . . . . . . . . . . . . . . . . . . 21 | |||
| 6.1. FROST(Ed25519, SHA-512) . . . . . . . . . . . . . . . . . 21 | 6.1. FROST(Ed25519, SHA-512) . . . . . . . . . . . . . . . . . 22 | |||
| 6.2. FROST(ristretto255, SHA-512) . . . . . . . . . . . . . . 21 | 6.2. FROST(ristretto255, SHA-512) . . . . . . . . . . . . . . 22 | |||
| 6.3. FROST(Ed448, SHAKE256) . . . . . . . . . . . . . . . . . 22 | 6.3. FROST(Ed448, SHAKE256) . . . . . . . . . . . . . . . . . 23 | |||
| 6.4. FROST(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 23 | 6.4. FROST(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 24 | |||
| 7. Security Considerations . . . . . . . . . . . . . . . . . . . 24 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 25 | |||
| 7.1. Nonce Reuse Attacks . . . . . . . . . . . . . . . . . . . 25 | 7.1. Nonce Reuse Attacks . . . . . . . . . . . . . . . . . . . 26 | |||
| 7.2. Protocol Failures . . . . . . . . . . . . . . . . . . . . 25 | 7.2. Protocol Failures . . . . . . . . . . . . . . . . . . . . 26 | |||
| 7.3. Removing the Coordinator Role . . . . . . . . . . . . . . 25 | 7.3. Removing the Coordinator Role . . . . . . . . . . . . . . 26 | |||
| 7.4. Input Message Validation . . . . . . . . . . . . . . . . 26 | 7.4. Input Message Validation . . . . . . . . . . . . . . . . 27 | |||
| 8. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 26 | 8. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 27 | |||
| 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 26 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 | |||
| 9.1. Normative References . . . . . . . . . . . . . . . . . . 26 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 27 | |||
| 9.2. Informative References . . . . . . . . . . . . . . . . . 27 | 9.2. Informative References . . . . . . . . . . . . . . . . . 28 | |||
| Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 28 | Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 29 | |||
| Appendix B. Trusted Dealer Key Generation . . . . . . . . . . . 28 | Appendix B. Trusted Dealer Key Generation . . . . . . . . . . . 29 | |||
| B.1. Shamir Secret Sharing . . . . . . . . . . . . . . . . . . 29 | B.1. Shamir Secret Sharing . . . . . . . . . . . . . . . . . . 30 | |||
| B.2. Verifiable Secret Sharing . . . . . . . . . . . . . . . . 31 | B.2. Verifiable Secret Sharing . . . . . . . . . . . . . . . . 32 | |||
| Appendix C. Wire Format . . . . . . . . . . . . . . . . . . . . 32 | Appendix C. Wire Format . . . . . . . . . . . . . . . . . . . . 34 | |||
| C.1. Signing Commitment . . . . . . . . . . . . . . . . . . . 32 | C.1. Signing Commitment . . . . . . . . . . . . . . . . . . . 34 | |||
| C.2. Signing Packages . . . . . . . . . . . . . . . . . . . . 33 | C.2. Signing Packages . . . . . . . . . . . . . . . . . . . . 34 | |||
| C.3. Signature Share . . . . . . . . . . . . . . . . . . . . . 33 | C.3. Signature Share . . . . . . . . . . . . . . . . . . . . . 35 | |||
| Appendix D. Test Vectors . . . . . . . . . . . . . . . . . . . . 33 | Appendix D. Test Vectors . . . . . . . . . . . . . . . . . . . . 35 | |||
| D.1. FROST(Ed25519, SHA-512) . . . . . . . . . . . . . . . . . 34 | D.1. FROST(Ed25519, SHA-512) . . . . . . . . . . . . . . . . . 36 | |||
| D.2. FROST(Ed448, SHAKE256) . . . . . . . . . . . . . . . . . 36 | D.2. FROST(Ed448, SHAKE256) . . . . . . . . . . . . . . . . . 37 | |||
| D.3. FROST(ristretto255, SHA-512) . . . . . . . . . . . . . . 37 | D.3. FROST(ristretto255, SHA-512) . . . . . . . . . . . . . . 39 | |||
| D.4. FROST(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 39 | D.4. FROST(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 40 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 40 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41 | |||
| 1. Introduction | 1. Introduction | |||
| DISCLAIMER: This is a work-in-progress draft of FROST. | DISCLAIMER: This is a work-in-progress draft of FROST. | |||
| RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for this | RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for this | |||
| draft is maintained in GitHub. Suggested changes should be submitted | draft is maintained in GitHub. Suggested changes should be submitted | |||
| as pull requests at https://github.com/cfrg/draft-irtf-cfrg-frost. | as pull requests at https://github.com/cfrg/draft-irtf-cfrg-frost. | |||
| Instructions are on that page as well. | Instructions are on that page as well. | |||
| Unlike signatures in a single-party setting, threshold signatures | Unlike signatures in a single-party setting, threshold signatures | |||
| require cooperation among a threshold number of signers each holding | require cooperation among a threshold number of signers each holding | |||
| a share of a common private key. The security of threshold schemes | a share of a common private key. The security of threshold schemes | |||
| in general assume that an adversary can corrupt strictly fewer than a | in general assume that an adversary can corrupt strictly fewer than a | |||
| threshold number of participants. | threshold number of participants. | |||
| In this draft, we present a variant of FROST, a Flexible Round- | This document presents a variant of a Flexible Round-Optimized | |||
| Optimized Schnorr Threshold signature scheme. FROST reduces network | Schnorr Threshold (FROST) signature scheme originally defined in | |||
| overhead during threshold signing operations while employing a novel | [FROST20]. FROST reduces network overhead during threshold signing | |||
| technique to protect against forgery attacks applicable to prior | operations while employing a novel technique to protect against | |||
| Schnorr-based threshold signature constructions. FROST requires two | forgery attacks applicable to prior Schnorr-based threshold signature | |||
| rounds to compute a signature. | constructions. The variant of FROST presented in this document | |||
| requires two rounds to compute a signature, and implements signing | ||||
| efficiency improvements described by [Schnorr21]. Single-round | ||||
| signing with FROST is out of scope. | ||||
| For select ciphersuites, the signatures produced by this draft are | For select ciphersuites, the signatures produced by this draft are | |||
| compatible with [RFC8032]. However, unlike [RFC8032], signatures | compatible with [RFC8032]. However, unlike [RFC8032], signatures | |||
| produced by FROST are not deterministic, since deriving nonces | produced by FROST are not deterministic, since deriving nonces | |||
| deterministically, is insecure in a multi-party signature setting. | deterministically allows for a complete key-recovery attack in multi- | |||
| party discrete logarithm-based signatures, such as FROST. | ||||
| Further, this draft implements signing efficiency improvements for | Key generation for FROST signing is out of scope for this document. | |||
| FROST described by Crites, Komlo, and Maller in [Schnorr21]. | However, for completeness, key generation with a trusted dealer is | |||
| specified in Appendix B. | ||||
| 1.1. Change Log | 1.1. Change Log | |||
| draft-04 | ||||
| * Added methods to verify VSS commitments and derive group info | ||||
| (#126, #132). | ||||
| * Changed check for participants to consider only nonnegative | ||||
| numbers (#133). | ||||
| * Changed sampling for secrets and coefficients to allow the zero | ||||
| element (#130). | ||||
| * Split test vectors into separate files (#129) | ||||
| * Update wire structs to remove commitment shares where not | ||||
| necessary (#128) | ||||
| * Add failure checks (#127) | ||||
| * Update group info to include each participant's key and clarify | ||||
| how public key material is obtained (#120, #121). | ||||
| * Define cofactor checks for verification (#118) | ||||
| * Various editorial improvements and add contributors (#124, #123, | ||||
| #119, #116, #113, #109) | ||||
| draft-03 | draft-03 | |||
| * Refactor the second round to use state from the first round (#94). | * Refactor the second round to use state from the first round (#94). | |||
| * Ensure that verificaftion of signature shares from the second | * Ensure that verification of signature shares from the second round | |||
| round uses commitments from the first round (#94). | uses commitments from the first round (#94). | |||
| * Clarify RFC8032 interoperability based on PureEdDSA (#86). | * Clarify RFC8032 interoperability based on PureEdDSA (#86). | |||
| * Specify signature serialization based on element and scalar | * Specify signature serialization based on element and scalar | |||
| serialization (#85). | serialization (#85). | |||
| * Fix hash function domain separation formatting (#83). | * Fix hash function domain separation formatting (#83). | |||
| * Make trusted dealer key generation deterministic (#104). | * Make trusted dealer key generation deterministic (#104). | |||
| skipping to change at page 5, line 33 ¶ | skipping to change at page 6, line 17 ¶ | |||
| THRESHOLD_LIMIT shares must be combined to issue a valid | THRESHOLD_LIMIT shares must be combined to issue a valid | |||
| signature. | signature. | |||
| * len(x) is the length of integer input x as an 8-byte, big-endian | * len(x) is the length of integer input x as an 8-byte, big-endian | |||
| integer. | integer. | |||
| * encode_uint16(x): Convert two byte unsigned integer (uint16) x to | * encode_uint16(x): Convert two byte unsigned integer (uint16) x to | |||
| a 2-byte, big-endian byte string. For example, encode_uint16(310) | a 2-byte, big-endian byte string. For example, encode_uint16(310) | |||
| = [0x01, 0x36]. | = [0x01, 0x36]. | |||
| * || denotes contatenation, i.e., x || y = xy. | * || denotes concatenation, i.e., x || y = xy. | |||
| Unless otherwise stated, we assume that secrets are sampled uniformly | Unless otherwise stated, we assume that secrets are sampled uniformly | |||
| at random using a cryptographically secure pseudorandom number | at random using a cryptographically secure pseudorandom number | |||
| generator (CSPRNG); see [RFC4086] for additional guidance on the | generator (CSPRNG); see [RFC4086] for additional guidance on the | |||
| generation of random numbers. | generation of random numbers. | |||
| 3. Cryptographic Dependencies | 3. Cryptographic Dependencies | |||
| FROST depends on the following cryptographic constructs: | FROST signing depends on the following cryptographic constructs: | |||
| * Prime-order Group, Section 3.1; | * Prime-order Group, Section 3.1; | |||
| * Cryptographic hash function, Section 3.2; | * Cryptographic hash function, Section 3.2; | |||
| These are described in the following sections. | These are described in the following sections. | |||
| 3.1. Prime-Order Group | 3.1. Prime-Order Group | |||
| FROST depends on an abelian group G of prime order p. The | FROST depends on an abelian group G of prime order p. The | |||
| skipping to change at page 6, line 31 ¶ | skipping to change at page 7, line 13 ¶ | |||
| assignment of values by =. | assignment of values by =. | |||
| We now detail a number of member functions that can be invoked on a | We now detail a number of member functions that can be invoked on a | |||
| prime-order group G. | prime-order group G. | |||
| * Order(): Outputs the order of G (i.e. p). | * Order(): Outputs the order of G (i.e. p). | |||
| * Identity(): Outputs the identity element of the group (i.e. I). | * Identity(): Outputs the identity element of the group (i.e. I). | |||
| * RandomScalar(): A member function of G that chooses at random a | * RandomScalar(): A member function of G that chooses at random a | |||
| non-zero Scalar element in GF(p). | Scalar element in GF(p). | |||
| * RandomNonzeroScalar(): A member function of G that chooses at | ||||
| random a non-zero Scalar element in GF(p). | ||||
| * SerializeElement(A): A member function of G that maps an Element A | * SerializeElement(A): A member function of G that maps an Element A | |||
| to a unique byte array buf of fixed length Ne. | to a unique byte array buf of fixed length Ne. | |||
| * DeserializeElement(buf): A member function of G that attempts to | * DeserializeElement(buf): A member function of G that attempts to | |||
| map a byte array buf to an Element A, and fails if the input is | map a byte array buf to an Element A, and fails if the input is | |||
| not a valid byte representation of an element of the group. This | not a valid byte representation of an element of the group. This | |||
| function can raise a DeserializeError if deserialization fails or | function can raise a DeserializeError if deserialization fails or | |||
| A is the identity element of the group; see Section 6 for group- | A is the identity element of the group; see Section 6 for group- | |||
| specific input validation steps. | specific input validation steps. | |||
| skipping to change at page 8, line 26 ¶ | skipping to change at page 8, line 42 ¶ | |||
| R = G.ScalarBaseMult(k) | R = G.ScalarBaseMult(k) | |||
| comm_enc = G.SerializeElement(R) | comm_enc = G.SerializeElement(R) | |||
| pk_enc = G.SerializeElement(PK) | pk_enc = G.SerializeElement(PK) | |||
| challenge_input = comm_enc || pk_enc || msg | challenge_input = comm_enc || pk_enc || msg | |||
| c = H2(challenge_input) | c = H2(challenge_input) | |||
| z = k + (c * SK) | z = k + (c * SK) | |||
| return (R, z) | return (R, z) | |||
| The corresponding verification operation is as follows. | The corresponding verification operation is as follows. Here, h is | |||
| the cofactor for the group being operated over, e.g. h=8 for the case | ||||
| of Curve25519, h=4 for Ed448, and h=1 for groups such as ristretto255 | ||||
| and secp256k1, etc. This final scalar multiplication MUST be | ||||
| performed when h>1. | ||||
| schnorr_signature_verify(msg, sig, PK): | schnorr_signature_verify(msg, sig, PK): | |||
| Inputs: | Inputs: | |||
| - msg, signed message, an octet string | - msg, signed message, an octet string | |||
| - sig, a tuple (R, z) output from schnorr_signature_generate or FROST | - sig, a tuple (R, z) output from schnorr_signature_generate or FROST | |||
| - PK, public key, a group element | - PK, public key, a group element | |||
| Outputs: 1 if signature is valid, and 0 otherwise | Outputs: 1 if signature is valid, and 0 otherwise | |||
| def schnorr_signature_verify(msg, sig = (R, z), PK): | def schnorr_signature_verify(msg, sig = (R, z), PK): | |||
| comm_enc = G.SerializeElement(R) | comm_enc = G.SerializeElement(R) | |||
| pk_enc = G.SerializeElement(PK) | pk_enc = G.SerializeElement(PK) | |||
| challenge_input = comm_enc || pk_enc || msg | challenge_input = comm_enc || pk_enc || msg | |||
| c = H2(challenge_input) | c = H2(challenge_input) | |||
| l = G.ScalarBaseMult(z) | l = G.ScalarBaseMult(z) | |||
| r = R + (c * PK) | r = R + (c * PK) | |||
| if l == r: | check = (l - r) * h | |||
| return 1 | return check == G.Identity() | |||
| return 0 | ||||
| 4.2. Polynomial Operations | 4.2. Polynomial Operations | |||
| This section describes operations on and associated with polynomials | This section describes operations on and associated with polynomials | |||
| that are used in the main signing protocol. A polynomial of degree t | that are used in the main signing protocol. A polynomial of degree t | |||
| is represented as a sorted list of t coefficients. A point on the | is represented as a sorted list of t coefficients. A point on the | |||
| polynomial is a tuple (x, y), where y = f(x). For notational | polynomial is a tuple (x, y), where y = f(x). For notational | |||
| convenience, we refer to the x-coordinate and y-coordinate of a point | convenience, we refer to the x-coordinate and y-coordinate of a point | |||
| p as p.x and p.y, respectively. | p as p.x and p.y, respectively. | |||
| skipping to change at page 10, line 17 ¶ | skipping to change at page 11, line 17 ¶ | |||
| Inputs: | Inputs: | |||
| - x_i, an x-coordinate contained in L, a scalar | - x_i, an x-coordinate contained in L, a scalar | |||
| - L, the set of x-coordinates, each a scalar | - L, the set of x-coordinates, each a scalar | |||
| Outputs: L_i, the i-th Lagrange coefficient | Outputs: L_i, the i-th Lagrange coefficient | |||
| Errors: | Errors: | |||
| - "invalid parameters", if any coordinate is less than or equal to 0 | - "invalid parameters", if any coordinate is less than or equal to 0 | |||
| def derive_lagrange_coefficient(x_i, L): | def derive_lagrange_coefficient(x_i, L): | |||
| if x_i <= 0: | if x_i = 0: | |||
| raise "invalid parameters" | raise "invalid parameters" | |||
| for x_j in L: | for x_j in L: | |||
| if x_j <= 0: | if x_j = 0: | |||
| raise "invalid parameters" | raise "invalid parameters" | |||
| numerator = 1 | numerator = 1 | |||
| denominator = 1 | denominator = 1 | |||
| for x_j in L: | for x_j in L: | |||
| if x_j == x_i: continue | if x_j == x_i: continue | |||
| numerator *= x_j | numerator *= x_j | |||
| denominator *= x_j - x_i | denominator *= x_j - x_i | |||
| L_i = numerator / denominator | L_i = numerator / denominator | |||
| skipping to change at page 13, line 19 ¶ | skipping to change at page 14, line 19 ¶ | |||
| Outputs: a challenge Scalar value | Outputs: a challenge Scalar value | |||
| def compute_challenge(group_commitment, group_public_key, msg): | def compute_challenge(group_commitment, group_public_key, msg): | |||
| group_comm_enc = G.SerializeElement(group_commitment) | group_comm_enc = G.SerializeElement(group_commitment) | |||
| group_public_key_enc = G.SerializeElement(group_public_key) | group_public_key_enc = G.SerializeElement(group_public_key) | |||
| challenge_input = group_comm_enc || group_public_key_enc || msg | challenge_input = group_comm_enc || group_public_key_enc || msg | |||
| challenge = H2(challenge_input) | challenge = H2(challenge_input) | |||
| return challenge | return challenge | |||
| 5. Two-Round FROST | 5. Two-Round FROST Signing Protocol | |||
| FROST is a two-round threshold signature protocol for producing | We now present the two-round variant of the FROST threshold signature | |||
| Schnorr signatures. It involves signer participants and a | protocol for producing Schnorr signatures. It involves signer | |||
| coordinator. Signing participants are entities with signing key | participants and a coordinator. Signing participants are entities | |||
| shares that participate in the threshold signing protocol. The | with signing key shares that participate in the threshold signing | |||
| coordinator is a distinguished signer with the following | protocol. The coordinator is a distinguished signer with the | |||
| responsibilities: | following responsibilities: | |||
| 1. Determining which signers will participate (at least | 1. Determining which signers will participate (at least | |||
| THRESHOLD_LIMIT in number); | THRESHOLD_LIMIT in number); | |||
| 2. Coordinating rounds (receiving and forwarding inputs among | 2. Coordinating rounds (receiving and forwarding inputs among | |||
| participants); and | participants); and | |||
| 3. Aggregating signature shares output by each participant, and | 3. Aggregating signature shares output by each participant, and | |||
| publishing the resulting signature. | publishing the resulting signature. | |||
| FROST assumes the selection of all participants, including the | FROST assumes the selection of all participants, including the | |||
| dealer, signer, and Coordinator are all chosen external to the | dealer, signer, and Coordinator are all chosen external to the | |||
| protocol. Note that it is possible to deploy the protocol without a | protocol. Note that it is possible to deploy the protocol without a | |||
| distinguished Coordinator; see Section 7.3 for more information. | distinguished Coordinator; see Section 7.3 for more information. | |||
| In FROST, all signers are assumed to have the group state and their | Because key generation is not specified, all signers are assumed to | |||
| corresponding signing key shares. In particular, FROST assumes that | have the (public) group state that we refer to as "group info" below, | |||
| each signing participant P_i knows the following: | and their corresponding signing key shares. | |||
| In particular, it is assumed that the coordinator and each signing | ||||
| participant P_i knows the following group info: | ||||
| * Group public key, denoted PK = G.ScalarMultBase(s), corresponding | * Group public key, denoted PK = G.ScalarMultBase(s), corresponding | |||
| to the group secret key s. | to the group secret key s. PK is an output from the group's key | |||
| generation protocol, such as trusted_dealer_keygenor a DKG. | ||||
| * Participant is signing key, which is the i-th secret share of s. | * Public keys for each signer, denoted PK_i = | |||
| G.ScalarMultBase(sk_i), which are similarly outputs from the | ||||
| group's key generation protocol. | ||||
| And that each participant with identifier i additionally knows the | ||||
| following: | ||||
| * Participant is signing key share sk_i, which is the i-th secret | ||||
| share of s. | ||||
| The exact key generation mechanism is out of scope for this | The exact key generation mechanism is out of scope for this | |||
| specification. In general, key generation is a protocol that outputs | specification. In general, key generation is a protocol that outputs | |||
| (1) a shared, group public key PK owned by each Signer, and (2) | (1) a shared, group public key PK owned by each Signer, and (2) | |||
| individual shares of the signing key owned by each Signer. In | individual shares of the signing key owned by each Signer. In | |||
| general, two possible key generation mechanisms are possible, one | general, two possible key generation mechanisms are possible, one | |||
| that requires a single, trusted dealer, and the other which requires | that requires a single, trusted dealer, and the other which requires | |||
| performing a distributed key generation protocol. We highlight key | performing a distributed key generation protocol. We highlight key | |||
| generation mechanism by a trusted dealer in Appendix B, for | generation mechanism by a trusted dealer in Appendix B, for | |||
| reference. | reference. | |||
| There are two rounds in FROST: commitment and signature share | This signing variant of FROST requires signers to perform two network | |||
| generation. The first round serves for each participant to issue a | rounds: 1) generating and publishing commitments, and 2) signature | |||
| commitment. The second round receives commitments for all signers as | share generation and publication. The first round serves for each | |||
| well as the message, and issues a signature share. The Coordinator | participant to issue a commitment to a nonce. The second round | |||
| performs the coordination of each of these rounds. At the end of the | receives commitments for all signers as well as the message, and | |||
| second round, the Coordinator then performs an aggregation step at | issues a signature share with respect to that message. The | |||
| the end and outputs the final signature. This complete interaction | Coordinator performs the coordination of each of these rounds. At | |||
| is shown in Figure 1. | the end of the second round, the Coordinator then performs an | |||
| aggregation step and outputs the final signature. This complete | ||||
| interaction is shown in Figure 1. | ||||
| (group info) (group info, (group info, | (group info) (group info, (group info, | |||
| | signing key share) signing key share) | | signing key share) signing key share) | |||
| | | | | | | | | |||
| v v v | v v v | |||
| Coordinator Signer-1 ... Signer-n | Coordinator Signer-1 ... Signer-n | |||
| ------------------------------------------------------------ | ------------------------------------------------------------ | |||
| message | message | |||
| ------------> | ------------> | |||
| | | | | |||
| == Round 1 (Commitment) == | == Round 1 (Commitment) == | |||
| | signer commitment | | | | signer commitment | | | |||
| skipping to change at page 16, line 20 ¶ | skipping to change at page 17, line 20 ¶ | |||
| Each signer in round one generates a nonce nonce = (hiding_nonce, | Each signer in round one generates a nonce nonce = (hiding_nonce, | |||
| binding_nonce) and commitment comm = (hiding_nonce_commitment, | binding_nonce) and commitment comm = (hiding_nonce_commitment, | |||
| binding_nonce_commitment). | binding_nonce_commitment). | |||
| Inputs: None | Inputs: None | |||
| Outputs: (nonce, comm), a tuple of nonce and nonce commitment pairs. | Outputs: (nonce, comm), a tuple of nonce and nonce commitment pairs. | |||
| def commit(): | def commit(): | |||
| hiding_nonce = G.RandomScalar() | hiding_nonce = G.RandomNonzeroScalar() | |||
| binding_nonce = G.RandomScalar() | binding_nonce = G.RandomNonzeroScalar() | |||
| hiding_nonce_commitment = G.ScalarBaseMult(hiding_nonce) | hiding_nonce_commitment = G.ScalarBaseMult(hiding_nonce) | |||
| binding_nonce_commitment = G.ScalarBaseMult(binding_nonce) | binding_nonce_commitment = G.ScalarBaseMult(binding_nonce) | |||
| nonce = (hiding_nonce, binding_nonce) | nonce = (hiding_nonce, binding_nonce) | |||
| comm = (hiding_nonce_commitment, binding_nonce_commitment) | comm = (hiding_nonce_commitment, binding_nonce_commitment) | |||
| return (nonce, comm) | return (nonce, comm) | |||
| The private output nonce from Participant P_i is stored locally and | The private output nonce from Participant P_i is stored locally and | |||
| kept private for use in the second round. This nonce MUST NOT be | kept private for use in the second round. This nonce MUST NOT be | |||
| reused in more than one invocation of FROST, and it MUST be generated | reused in more than one invocation of FROST, and it MUST be generated | |||
| from a source of secure randomness. The public output comm from | from a source of secure randomness. The public output comm from | |||
| skipping to change at page 17, line 45 ¶ | skipping to change at page 18, line 45 ¶ | |||
| # Compute the per-message challenge | # Compute the per-message challenge | |||
| challenge = compute_challenge(group_commitment, group_public_key, msg) | challenge = compute_challenge(group_commitment, group_public_key, msg) | |||
| # Compute the signature share | # Compute the signature share | |||
| (hiding_nonce, binding_nonce) = nonce_i | (hiding_nonce, binding_nonce) = nonce_i | |||
| sig_share = hiding_nonce + (binding_nonce * binding_factor) + (lambda_i * sk_i * challenge) | sig_share = hiding_nonce + (binding_nonce * binding_factor) + (lambda_i * sk_i * challenge) | |||
| return sig_share | return sig_share | |||
| The output of this procedure is a signature share and group | The output of this procedure is a signature share. Each signer then | |||
| commitment share. Each signer then sends these shares back to the | sends these shares back to the collector; see Appendix C.3 for | |||
| collector; see Appendix C.3 for encoding recommendations. Each | encoding recommendations. Each signer MUST delete the nonce and | |||
| signer MUST delete the nonce and corresponding commitment after this | corresponding commitment after this round completes. | |||
| round completes. | ||||
| Upon receipt from each Signer, the Coordinator MUST validate the | Upon receipt from each Signer, the Coordinator MUST validate the | |||
| input signature and commitment shares using DeserializeElement for | input signature using DeserializeElement. If validation fails, the | |||
| each. If validation fails, the Coordinator MUST abort the protocol. | Coordinator MUST abort the protocol. If validation succeeds, the | |||
| If validation succeeds, the Coordinator then verifies the set of | Coordinator then verifies the set of signature shares using the | |||
| signature shares using the following procedure. | following procedure. | |||
| 5.3. Signature Share Verification and Aggregation | 5.3. Signature Share Verification and Aggregation | |||
| After signers perform round two and send their signature shares to | After signers perform round two and send their signature shares to | |||
| the Coordinator, the Coordinator verifies each signature share for | the Coordinator, the Coordinator verifies each signature share for | |||
| correctness. In particular, for each signer, the Coordinator uses | correctness. In particular, for each signer, the Coordinator uses | |||
| commitment pairs generated during round one and the signature share | commitment pairs generated during round one and the signature share | |||
| generated during round two, along with other group parameters, to | generated during round two, along with other group parameters, to | |||
| check that the signature share is valid using the following | check that the signature share is valid using the following | |||
| procedure. | procedure. | |||
| Inputs: | Inputs: | |||
| - index, Index `i` of the signer. Note index will never equal `0`. | - index, Index `i` of the signer. Note index will never equal `0`. | |||
| - public_key_share_i, the public key for the ith signer, where public_key_share_i = G.ScalarBaseMult(s[i]) | - PK_i, the public key for the ith signer, where `PK_i = G.ScalarBaseMult(sk_i)` | |||
| - comm_i, pair of Element values (hiding_nonce_commitment, binding_nonce_commitment) generated | - comm_i, pair of Element values (hiding_nonce_commitment, binding_nonce_commitment) generated | |||
| in round one from the ith signer. | in round one from the ith signer. | |||
| - sig_share_i, a Scalar value indicating the signature share as produced in round two from the ith signer. | - sig_share_i, a Scalar value indicating the signature share as produced in round two from the ith signer. | |||
| - commitment_list = [(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a list of commitments | - commitment_list = [(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a list of commitments | |||
| issued in Round 1 by each signer, where each element in the list indicates the signer index j and their | issued in Round 1 by each signer, where each element in the list indicates the signer index j and their | |||
| two commitment Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j). | two commitment Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j). | |||
| This list MUST be sorted in ascending order by signer index. | This list MUST be sorted in ascending order by signer index. | |||
| - participant_list, a set containing identifiers for each signer, similarly of length | - participant_list, a set containing identifiers for each signer, similarly of length | |||
| NUM_SIGNERS (sent by the Coordinator). | NUM_SIGNERS (sent by the Coordinator). | |||
| - group_public_key, the public key for the group | - group_public_key, the public key for the group | |||
| - msg, the message to be signed | - msg, the message to be signed | |||
| Outputs: True if the signature share is valid, and False otherwise. | Outputs: True if the signature share is valid, and False otherwise. | |||
| def verify_signature_share(index, public_key_share_i, comm_i, sig_share_i, commitment_list, | def verify_signature_share(index, PK_i, comm_i, sig_share_i, commitment_list, | |||
| participant_list, group_public_key, msg): | participant_list, group_public_key, msg): | |||
| # Encode the commitment list | # Encode the commitment list | |||
| encoded_commitments = encode_group_commitment_list(commitment_list) | encoded_commitments = encode_group_commitment_list(commitment_list) | |||
| # Compute the binding factor | # Compute the binding factor | |||
| binding_factor = compute_binding_factor(encoded_commitments, msg) | binding_factor = compute_binding_factor(encoded_commitments, msg) | |||
| # Compute the group commitment | # Compute the group commitment | |||
| group_commitment = compute_group_commitment(commitment_list, binding_factor) | group_commitment = compute_group_commitment(commitment_list, binding_factor) | |||
| skipping to change at page 19, line 45 ¶ | skipping to change at page 20, line 45 ¶ | |||
| comm_share = hiding_nonce_commitment + (binding_nonce_commitment * binding_factor) | comm_share = hiding_nonce_commitment + (binding_nonce_commitment * binding_factor) | |||
| # Compute the challenge | # Compute the challenge | |||
| challenge = compute_challenge(group_commitment, group_public_key, msg) | challenge = compute_challenge(group_commitment, group_public_key, msg) | |||
| # Compute Lagrange coefficient | # Compute Lagrange coefficient | |||
| lambda_i = derive_lagrange_coefficient(index, participant_list) | lambda_i = derive_lagrange_coefficient(index, participant_list) | |||
| # Compute relation values | # Compute relation values | |||
| l = G.ScalarBaseMult(sig_share_i) | l = G.ScalarBaseMult(sig_share_i) | |||
| r = comm_share + (public_key_share_i * challenge * lambda_i) | r = comm_share + (PK_i * challenge * lambda_i) | |||
| return l == r | return l == r | |||
| If any signature share fails to verify, i.e., if | If any signature share fails to verify, i.e., if | |||
| verify_signature_share returns False for any signer share, the | verify_signature_share returns False for any signer share, the | |||
| Coordinator MUST abort the protocol. Otherwise, if all signer shares | Coordinator MUST abort the protocol. Otherwise, if all signer shares | |||
| are valid, the Coordinator performs the aggregate operation and | are valid, the Coordinator performs the aggregate operation and | |||
| publishes the resulting signature. | publishes the resulting signature. | |||
| Inputs: | Inputs: | |||
| skipping to change at page 21, line 14 ¶ | skipping to change at page 22, line 14 ¶ | |||
| 6.1. FROST(Ed25519, SHA-512) | 6.1. FROST(Ed25519, SHA-512) | |||
| This ciphersuite uses edwards25519 for the Group and SHA-512 for the | This ciphersuite uses edwards25519 for the Group and SHA-512 for the | |||
| Hash function H meant to produce signatures indistinguishable from | Hash function H meant to produce signatures indistinguishable from | |||
| Ed25519 as specified in [RFC8032]. The value of the contextString | Ed25519 as specified in [RFC8032]. The value of the contextString | |||
| parameter is empty. | parameter is empty. | |||
| * Group: edwards25519 [RFC8032] | * Group: edwards25519 [RFC8032] | |||
| - Cofactor (h): 8 | ||||
| - SerializeElement: Implemented as specified in [RFC8032], | - SerializeElement: Implemented as specified in [RFC8032], | |||
| Section 5.1.2. | Section 5.1.2. | |||
| - DeserializeElement: Implemented as specified in [RFC8032], | - DeserializeElement: Implemented as specified in [RFC8032], | |||
| Section 5.1.3. Additionally, this function validates that the | Section 5.1.3. Additionally, this function validates that the | |||
| resulting element is not the group identity element. | resulting element is not the group identity element. | |||
| - SerializeScalar: Implemented by outputting the little-endian | - SerializeScalar: Implemented by outputting the little-endian | |||
| 32-byte encoding of the Scalar value. | 32-byte encoding of the Scalar value. | |||
| skipping to change at page 22, line 4 ¶ | skipping to change at page 23, line 6 ¶ | |||
| Normally H2 would also include a domain separator, but for backwards | Normally H2 would also include a domain separator, but for backwards | |||
| compatibility with [RFC8032], it is omitted. | compatibility with [RFC8032], it is omitted. | |||
| 6.2. FROST(ristretto255, SHA-512) | 6.2. FROST(ristretto255, SHA-512) | |||
| This ciphersuite uses ristretto255 for the Group and SHA-512 for the | This ciphersuite uses ristretto255 for the Group and SHA-512 for the | |||
| Hash function H. The value of the contextString parameter is "FROST- | Hash function H. The value of the contextString parameter is "FROST- | |||
| RISTRETTO255-SHA512". | RISTRETTO255-SHA512". | |||
| * Group: ristretto255 [RISTRETTO] | * Group: ristretto255 [RISTRETTO] | |||
| - Cofactor (h): 1 | ||||
| - SerializeElement: Implemented using the 'Encode' function from | - SerializeElement: Implemented using the 'Encode' function from | |||
| [RISTRETTO]. | [RISTRETTO]. | |||
| - DeserializElement: Implemented using the 'Decode' function from | - DeserializeElement: Implemented using the 'Decode' function | |||
| [RISTRETTO]. | from [RISTRETTO]. | |||
| - SerializeScalar: Implemented by outputting the little-endian | - SerializeScalar: Implemented by outputting the little-endian | |||
| 32-byte encoding of the Scalar value. | 32-byte encoding of the Scalar value. | |||
| - DeserializeScalar: Implemented by attempting to deserialize a | - DeserializeScalar: Implemented by attempting to deserialize a | |||
| Scalar from a 32-byte string. This function can fail if the | Scalar from a 32-byte string. This function can fail if the | |||
| input does not represent a Scalar between the value 0 and | input does not represent a Scalar between the value 0 and | |||
| G.Order() - 1. | G.Order() - 1. | |||
| * Hash (H): SHA-512, and Nh = 64. | * Hash (H): SHA-512, and Nh = 64. | |||
| - H1(m): Implemented by computing H(contextString || "rho" || m) | - H1(m): Implemented by computing H(contextString || "rho" || m) | |||
| and mapping the the output to a Scalar as described in | and mapping the output to a Scalar as described in [RISTRETTO], | |||
| [RISTRETTO], Section 4.4. | Section 4.4. | |||
| - H2(m): Implemented by computing H(contextString || "chal" || m) | - H2(m): Implemented by computing H(contextString || "chal" || m) | |||
| and mapping the the output to a Scalar as described in | and mapping the output to a Scalar as described in [RISTRETTO], | |||
| [RISTRETTO], Section 4.4. | Section 4.4. | |||
| - H3(m): Implemented by computing H(contextString || "digest" || | - H3(m): Implemented by computing H(contextString || "digest" || | |||
| m). | m). | |||
| 6.3. FROST(Ed448, SHAKE256) | 6.3. FROST(Ed448, SHAKE256) | |||
| This ciphersuite uses edwards448 for the Group and SHA256 for the | This ciphersuite uses edwards448 for the Group and SHA256 for the | |||
| Hash function H meant to produce signatures indistinguishable from | Hash function H meant to produce signatures indistinguishable from | |||
| Ed448 as specified in [RFC8032]. The value of the contextString | Ed448 as specified in [RFC8032]. The value of the contextString | |||
| parameter is empty. | parameter is empty. | |||
| * Group: edwards448 [RFC8032] | * Group: edwards448 [RFC8032] | |||
| - Cofactor (h): 4 | ||||
| - SerializeElement: Implemented as specified in [RFC8032], | - SerializeElement: Implemented as specified in [RFC8032], | |||
| Section 5.2.2. | Section 5.2.2. | |||
| - DeserializeElement: Implemented as specified in [RFC8032], | - DeserializeElement: Implemented as specified in [RFC8032], | |||
| Section 5.2.3. Additionally, this function validates that the | Section 5.2.3. Additionally, this function validates that the | |||
| resulting element is not the group identity element. | resulting element is not the group identity element. | |||
| - SerializeScalar: Implemented by outputting the little-endian | - SerializeScalar: Implemented by outputting the little-endian | |||
| 48-byte encoding of the Scalar value. | 48-byte encoding of the Scalar value. | |||
| skipping to change at page 23, line 35 ¶ | skipping to change at page 24, line 38 ¶ | |||
| compatibility with [RFC8032], it is omitted. | compatibility with [RFC8032], it is omitted. | |||
| 6.4. FROST(P-256, SHA-256) | 6.4. FROST(P-256, SHA-256) | |||
| This ciphersuite uses P-256 for the Group and SHA-256 for the Hash | This ciphersuite uses P-256 for the Group and SHA-256 for the Hash | |||
| function H. The value of the contextString parameter is "FROST- | function H. The value of the contextString parameter is "FROST- | |||
| P256-SHA256". | P256-SHA256". | |||
| * Group: P-256 (secp256r1) [x9.62] | * Group: P-256 (secp256r1) [x9.62] | |||
| - Cofactor (h): 1 | ||||
| - SerializeElement: Implemented using the compressed Elliptic- | - SerializeElement: Implemented using the compressed Elliptic- | |||
| Curve-Point-to-Octet-String method according to [SECG]. | Curve-Point-to-Octet-String method according to [SECG]. | |||
| - DeserializeElement: Implemented by attempting to deserialize a | - DeserializeElement: Implemented by attempting to deserialize a | |||
| public key using the compressed Octet-String-to-Elliptic-Curve- | public key using the compressed Octet-String-to-Elliptic-Curve- | |||
| Point method according to [SECG], and then performs partial | Point method according to [SECG], and then performs partial | |||
| public-key validation as defined in section 5.6.2.3.4 of | public-key validation as defined in section 5.6.2.3.4 of | |||
| [KEYAGREEMENT]. This includes checking that the coordinates of | [KEYAGREEMENT]. This includes checking that the coordinates of | |||
| the resulting point are in the correct range, that the point is | the resulting point are in the correct range, that the point is | |||
| on the curve, and that the point is not the point at infinity. | on the curve, and that the point is not the point at infinity. | |||
| skipping to change at page 24, line 25 ¶ | skipping to change at page 25, line 28 ¶ | |||
| - H2(m): Implemented using hash_to_field from [HASH-TO-CURVE], | - H2(m): Implemented using hash_to_field from [HASH-TO-CURVE], | |||
| Section 5.3 using L = 48, expand_message_xmd with SHA-256, DST | Section 5.3 using L = 48, expand_message_xmd with SHA-256, DST | |||
| = contextString || "chal", and prime modulus equal to Order(). | = contextString || "chal", and prime modulus equal to Order(). | |||
| - H3(m): Implemented by computing H(contextString || "digest" || | - H3(m): Implemented by computing H(contextString || "digest" || | |||
| m). | m). | |||
| 7. Security Considerations | 7. Security Considerations | |||
| A security analysis of FROST exists in [FROST20]. The protocol as | A security analysis of FROST exists in [FROST20] and [Schnorr21]. | |||
| specified in this document assumes the following threat model. | The protocol as specified in this document assumes the following | |||
| threat model. | ||||
| * Trusted dealer. The dealer that performs key generation is | * Trusted dealer. The dealer that performs key generation is | |||
| trusted to follow the protocol, although participants still are | trusted to follow the protocol, although participants still are | |||
| able to verify the consistency of their shares via a VSS | able to verify the consistency of their shares via a VSS | |||
| (verifiable secret sharing) step; see Appendix B.2. | (verifiable secret sharing) step; see Appendix B.2. | |||
| * Unforgeability assuming less than (t-1) corrupted signers. So | * Unforgeability assuming less than (t-1) corrupted signers. So | |||
| long as an adverary corrupts fewer than (t-1) participants, the | long as an adverary corrupts fewer than (t-1) participants, the | |||
| scheme remains secure against EUF-CMA attacks. | scheme remains secure against EUF-CMA attacks. | |||
| skipping to change at page 24, line 50 ¶ | skipping to change at page 26, line 5 ¶ | |||
| completing or causing the resulting signature to be invalid. Such | completing or causing the resulting signature to be invalid. Such | |||
| actions for the latter include sending inconsistent values to | actions for the latter include sending inconsistent values to | |||
| signing participants, such as messages or the set of individual | signing participants, such as messages or the set of individual | |||
| commitments. Note that the Coordinator is _not_ trusted with any | commitments. Note that the Coordinator is _not_ trusted with any | |||
| private information and communication at the time of signing can | private information and communication at the time of signing can | |||
| be performed over a public but reliable channel. | be performed over a public but reliable channel. | |||
| The protocol as specified in this document does not target the | The protocol as specified in this document does not target the | |||
| following goals: | following goals: | |||
| * Post quantum security. FROST, like generic Schnorr signatures, | * Post quantum security. FROST, like plain Schnorr signatures, | |||
| requires the hardness of the Discrete Logarithm Problem. | requires the hardness of the Discrete Logarithm Problem. | |||
| * Robustness. In the case of failure, FROST requires aborting the | * Robustness. In the case of failure, FROST requires aborting the | |||
| protocol. | protocol. | |||
| * Downgrade prevention. The sender and receiver are assumed to | * Downgrade prevention. The sender and receiver are assumed to | |||
| agree on what algorithms to use. | agree on what algorithms to use. | |||
| * Metadata protection. If protection for metadata is desired, a | * Metadata protection. If protection for metadata is desired, a | |||
| higher-level communication channel can be used to facilitate key | higher-level communication channel can be used to facilitate key | |||
| generation and signing. | generation and signing. | |||
| The rest of this section documents issues particular to | The rest of this section documents issues particular to | |||
| implementations or deployments. | implementations or deployments. | |||
| 7.1. Nonce Reuse Attacks | 7.1. Nonce Reuse Attacks | |||
| Nonces generated by each participant in the first round of signing | Nonces generated by each participant in the first round of signing | |||
| must be sampled uniformly at random and cannot be derived from some | must be sampled uniformly at random and cannot be derived from some | |||
| determinstic function. This is to avoid replay attacks initiated by | deterministic function. This is to avoid replay attacks initiated by | |||
| other signers, which allows for a complete key-recovery attack. | other signers, which allows for a complete key-recovery attack. | |||
| Coordinates MAY further hedge against nonce reuse attacks by tracking | Coordinates MAY further hedge against nonce reuse attacks by tracking | |||
| signer nonce commitments used for a given group key, at the cost of | signer nonce commitments used for a given group key, at the cost of | |||
| additional state. | additional state. | |||
| 7.2. Protocol Failures | 7.2. Protocol Failures | |||
| We do not specify what implementations should do when the protocol | We do not specify what implementations should do when the protocol | |||
| fails, other than requiring that the protocol abort. Examples of | fails, other than requiring that the protocol abort. Examples of | |||
| viable failure include when a verification check returns invalid or | viable failure include when a verification check returns invalid or | |||
| skipping to change at page 26, line 43 ¶ | skipping to change at page 27, line 46 ¶ | |||
| However, it is RECOMMENDED that applications take additional | However, it is RECOMMENDED that applications take additional | |||
| precautions and validate inputs so that signers do not operate as | precautions and validate inputs so that signers do not operate as | |||
| signing oracles for arbitrary messages. | signing oracles for arbitrary messages. | |||
| 8. Contributors | 8. Contributors | |||
| * Isis Lovecruft | * Isis Lovecruft | |||
| * T. Wilson-Brown | * T. Wilson-Brown | |||
| * Alden Torres | ||||
| 9. References | 9. References | |||
| 9.1. Normative References | 9.1. Normative References | |||
| [HASH-TO-CURVE] | [HASH-TO-CURVE] | |||
| Faz-Hernandez, A., Scott, S., Sullivan, N., Wahby, R. S., | Faz-Hernandez, A., Scott, S., Sullivan, N., Wahby, R. S., | |||
| and C. A. Wood, "Hashing to Elliptic Curves", Work in | and C. A. Wood, "Hashing to Elliptic Curves", Work in | |||
| Progress, Internet-Draft, draft-irtf-cfrg-hash-to-curve- | Progress, Internet-Draft, draft-irtf-cfrg-hash-to-curve- | |||
| 14, 18 February 2022, | 14, 18 February 2022, | |||
| <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg- | <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg- | |||
| skipping to change at page 28, line 42 ¶ | skipping to change at page 29, line 42 ¶ | |||
| random and uses Shamir and Verifiable Secret Sharing as described in | random and uses Shamir and Verifiable Secret Sharing as described in | |||
| Sections Appendix B.1 and Appendix B.2 to create secret shares of s | Sections Appendix B.1 and Appendix B.2 to create secret shares of s | |||
| to be sent to all other participants. We highlight at a high level | to be sent to all other participants. We highlight at a high level | |||
| how this operation can be performed. | how this operation can be performed. | |||
| Inputs: | Inputs: | |||
| - s, a group secret that MUST be derived from at least `Ns` bytes of entropy | - s, a group secret that MUST be derived from at least `Ns` bytes of entropy | |||
| - n, the number of shares to generate, an integer | - n, the number of shares to generate, an integer | |||
| - t, the threshold of the secret sharing scheme, an integer | - t, the threshold of the secret sharing scheme, an integer | |||
| Outputs: a public key Element, along with `n`shares of the secret key, each a Scalar value. | Outputs: | |||
| - signer_private_keys, `n` shares of the secret key `s`, each a Scalar value. | ||||
| - vss_commitment, a vector commitment to each of the coefficients in the polynomial defined by secret_key_shares and whose constant term is s. | ||||
| def trusted_dealer_keygen(s, n, t): | def trusted_dealer_keygen(s, n, t): | |||
| secret_key_shares = secret_share_shard(secret_key, n, t) | signer_private_keys, coefficients = secret_share_shard(secret_key, n, t) | |||
| public_key = G.ScalarBaseMult(secret_key) | vss_commitment = vss_commit(coefficients): | |||
| return public_key, secret_key_shares | PK = G.ScalarBaseMult(secret_key) | |||
| return signer_private_keys, vss_commitment | ||||
| It is assumed the dealer then sends one secret key share to each of | It is assumed the dealer then sends one secret key share to each of | |||
| the NUM_SIGNERS participants. The trusted dealer MUST delete the | the NUM_SIGNERS participants, along with C. After receiving their | |||
| secret_key and secret_key_shares upon completion. | secret key share and C each participant MUST perform | |||
| vss_verify(secret_key_share_i, C). It is assumed that all | ||||
| participant have the same view of C. The trusted dealer MUST delete | ||||
| the secret_key and secret_key_shares upon completion. | ||||
| Use of this method for key generation requires a mutually | Use of this method for key generation requires a mutually | |||
| authenticated secure channel between the dealer and participants to | authenticated secure channel between the dealer and participants to | |||
| send secret key shares, wherein the channel provides confidentiality | send secret key shares, wherein the channel provides confidentiality | |||
| and integrity. Mutually authenticated TLS is one possible deployment | and integrity. Mutually authenticated TLS is one possible deployment | |||
| option. | option. | |||
| B.1. Shamir Secret Sharing | B.1. Shamir Secret Sharing | |||
| In Shamir secret sharing, a dealer distributes a secret s to n | In Shamir secret sharing, a dealer distributes a secret s to n | |||
| participants in such a way that any cooperating subset of t | participants in such a way that any cooperating subset of t | |||
| participants can recover the secret. There are two basic steps in | participants can recover the secret. There are two basic steps in | |||
| this scheme: (1) splitting a secret into multiple shares, and (2) | this scheme: (1) splitting a secret into multiple shares, and (2) | |||
| combining shares to reveal the resulting secret. | combining shares to reveal the resulting secret. | |||
| This secret sharing scheme works over any field F. In this | This secret sharing scheme works over any field F. In this | |||
| specification, F is the scalar field of the prime-order group G. | specification, F is the scalar field of the prime-order group G. | |||
| The procedure for splitting a secret into shares is as follows. | The procedure for splitting a secret into shares is as follows. | |||
| secret_share_shard(s, n, t): | secret_share_shard(s, n, t): | |||
| Inputs: | Inputs: | |||
| - s, secret to be shared, an element of F | - s, secret to be shared, an element of F | |||
| - n, the number of shares to generate, an integer | - n, the number of shares to generate, an integer | |||
| - t, the threshold of the secret sharing scheme, an integer | - t, the threshold of the secret sharing scheme, an integer | |||
| Outputs: A list of n secret shares, each of which is an element of F | Outputs: | |||
| - secret_key_shares, A list of n secret shares, which is a tuple | ||||
| consisting of the participant identifier and the key share, each of | ||||
| which is an element of F | ||||
| - coefficients, a vector of the t coefficients which uniquely determine | ||||
| a polynomial f. | ||||
| Errors: | Errors: | |||
| - "invalid parameters", if t > n or if t is less than 2 | - "invalid parameters", if t > n or if t is less than 2 | |||
| def secret_share_shard(s, n, t): | def secret_share_shard(s, n, t): | |||
| if t > n: | if t > n: | |||
| raise "invalid parameters" | raise "invalid parameters" | |||
| if t < 2: | if t < 2: | |||
| raise "invalid parameters" | raise "invalid parameters" | |||
| # Generate random coefficients for the polynomial, yielding | # Generate random coefficients for the polynomial, yielding | |||
| # a polynomial of degree (t - 1) | # a polynomial of degree (t - 1) | |||
| coefficients = [s] | coefficients = [s] | |||
| for i in range(t - 1): | for i in range(t - 1): | |||
| coefficients.append(G.RandomScalar()) | coefficients.append(G.RandomScalar()) | |||
| # Evaluate the polynomial for each point x=1,...,n | # Evaluate the polynomial for each point x=1,...,n | |||
| points = [] | secret_key_shares = [] | |||
| for x_i in range(1, n + 1): | for x_i in range(1, n + 1): | |||
| y_i = polynomial_evaluate(x_i, coefficients) | y_i = polynomial_evaluate(x_i, coefficients) | |||
| point_i = (x_i, y_i) | secret_key_share_i = (x_i, y_i) | |||
| points.append(point_i) | secret_key_share.append(secret_key_share_i) | |||
| return points | return secret_key_shares, coefficients | |||
| Let points be the output of this function. The i-th element in | Let points be the output of this function. The i-th element in | |||
| points is the share for the i-th participant, which is the randomly | points is the share for the i-th participant, which is the randomly | |||
| generated polynomial evaluated at coordinate i. We denote a secret | generated polynomial evaluated at coordinate i. We denote a secret | |||
| share as the tuple (i, points[i]), and the list of these shares as | share as the tuple (i, points[i]), and the list of these shares as | |||
| shares. i MUST never equal 0; recall that f(0) = s, where f is the | shares. i MUST never equal 0; recall that f(0) = s, where f is the | |||
| polynomial defined in a Shamir secret sharing operation. | polynomial defined in a Shamir secret sharing operation. | |||
| The procedure for combining a shares list of length t to recover the | The procedure for combining a shares list of length t to recover the | |||
| secret s is as follows. | secret s is as follows. | |||
| skipping to change at page 31, line 28 ¶ | skipping to change at page 32, line 28 ¶ | |||
| s = polynomial_interpolation(shares) | s = polynomial_interpolation(shares) | |||
| return s | return s | |||
| B.2. Verifiable Secret Sharing | B.2. Verifiable Secret Sharing | |||
| Feldman's Verifiable Secret Sharing (VSS) builds upon Shamir secret | Feldman's Verifiable Secret Sharing (VSS) builds upon Shamir secret | |||
| sharing, adding a verification step to demonstrate the consistency of | sharing, adding a verification step to demonstrate the consistency of | |||
| a participant's share with a public commitment to the polynomial f | a participant's share with a public commitment to the polynomial f | |||
| for which the secret s is the constant term. This check ensure that | for which the secret s is the constant term. This check ensure that | |||
| all participants have a point (their share) on the same polynomial, | all participants have a point (their share) on the same polynomial, | |||
| ensuring that they can later reconstruct the correct secret. If the | ensuring that they can later reconstruct the correct secret. | |||
| validation fails, the participant can issue a complaint against the | ||||
| dealer, and take actions such as broadcasting this complaint to all | ||||
| other participants. We do not specify the complaint procedure in | ||||
| this draft, as it will be implementation-specific. | ||||
| The procedure for committing to a polynomial f of degree t-1 is as | The procedure for committing to a polynomial f of degree t-1 is as | |||
| follows. | follows. | |||
| vss_commit(coeffs): | vss_commit(coeffs): | |||
| Inputs: | Inputs: | |||
| - coeffs, a vector of the t coefficients which uniquely determine | - coeffs, a vector of the t coefficients which uniquely determine | |||
| a polynomial f. | a polynomial f. | |||
| Outputs: a commitment C, which is a vector commitment to each of the | Outputs: a commitment vss_commitment, which is a vector commitment to each of the | |||
| coefficients in coeffs. | coefficients in coeffs. | |||
| def vss_commit(coeffs): | def vss_commit(coeffs): | |||
| C = [] | vss_commitment = [] | |||
| for coeff in coeffs: | for coeff in coeffs: | |||
| A_i = ScalarBaseMult(coeff) | A_i = G.ScalarBaseMult(coeff) | |||
| C.append(A_i) | vss_commitment.append(A_i) | |||
| return C | return vss_commitment | |||
| The procedure for verification of a participant's share is as | The procedure for verification of a participant's share is as | |||
| follows. | follows. If vss_verify fails, the participant MUST abort the | |||
| protocol, and failure should be investigated out of band. | ||||
| vss_verify(sk_i, C): | vss_verify(share_i, vss_commitment): | |||
| Inputs: | Inputs: | |||
| - sk_i: A participant's secret key, the tuple sk_i = (i, s[i]), | - share_i: A tuple of the form (i, sk_i), where i indicates the participant | |||
| where s[i] is a secret share of the constant term of f. | identifier, and sk_i the participant's secret key, where sk_i is a secret share of | |||
| - C: A VSS commitment to a secret polynomial f. | the constant term of f. | |||
| - vss_commitment: A VSS commitment to a secret polynomial f. | ||||
| Outputs: 1 if s[i] is valid, and 0 otherwise | Outputs: 1 if sk_i is valid, and 0 otherwise | |||
| vss_verify(sk_i, commitment) | vss_verify(share_i, commitment) | |||
| S_i = ScalarBaseMult(s[i]) | (i, sk_i) = share_i | |||
| S_i' = SUM(commitment[0], commitment[t-1]){A_j}: A_j*(i^j) | S_i = ScalarBaseMult(sk_i) | |||
| if S_i == S_i': | S_i' = G.Identity() | |||
| return 1 | for j in range(0, THRESHOLD_LIMIT-1): | |||
| return 0 | S_i' += vss_commitment_j * i^j | |||
| if S_i == S_i': | ||||
| return 1 | ||||
| return 0 | ||||
| We now define how the coordinator and signing participants can derive | ||||
| group info, which is an input into the FROST signing protocol. | ||||
| derive_group_info(MAX_SIGNERS, THRESHOLD_LIMIT, vss_commitment): | ||||
| Inputs: | ||||
| - MAX_SIGNERS, the number of shares to generate, an integer | ||||
| - THRESHOLD_LIMIT, the threshold of the secret sharing scheme, an integer | ||||
| - vss_commitment: A VSS commitment to a secret polynomial f. | ||||
| Outputs: | ||||
| - PK, the public key representing the group | ||||
| - signer_public_keys, a list of MAX_SIGNERS public keys PK_i for i=1,...,MAX_SIGNERS, where PK_i is the public key for participant i. | ||||
| derive_group_info(MAX_SIGNERS, THRESHOLD_LIMIT, vss_commitment) | ||||
| PK = vss_commitment[0] | ||||
| signer_public_keys = [] | ||||
| for i in range(1, MAX_SIGNERS): | ||||
| PK_i = G.Identity() | ||||
| for j in range(0, THRESHOLD_LIMIT-1): | ||||
| PK_i += vss_commitment_j * i^j | ||||
| signer_public_keys.append(PK_i) | ||||
| return PK, signer_public_keys | ||||
| Appendix C. Wire Format | Appendix C. Wire Format | |||
| Applications are responsible for encoding protocol messages between | Applications are responsible for encoding protocol messages between | |||
| peers. This section contains RECOMMENDED encodings for different | peers. This section contains RECOMMENDED encodings for different | |||
| protocol messages as described in Section 5. | protocol messages as described in Section 5. | |||
| C.1. Signing Commitment | C.1. Signing Commitment | |||
| A commitment from a signer is a pair of Element values. It can be | A commitment from a signer is a pair of Element values. It can be | |||
| skipping to change at page 33, line 18 ¶ | skipping to change at page 34, line 45 ¶ | |||
| Each package contains the list of signing commitments generated | Each package contains the list of signing commitments generated | |||
| during round one along with the message to sign. This package can be | during round one along with the message to sign. This package can be | |||
| encoded in the following manner. | encoded in the following manner. | |||
| struct { | struct { | |||
| SigningCommitment signing_commitments<1..2^16-1>; | SigningCommitment signing_commitments<1..2^16-1>; | |||
| opaque msg<0..2^16-1>; | opaque msg<0..2^16-1>; | |||
| } SigningPackage; | } SigningPackage; | |||
| signing_commitments An list of SIGNING_COUNT SigningCommitment | signing_commitments An list of SIGNING_COUNT SigningCommitment | |||
| values, where THRESHOLD_LIIMT <= SIGNING_COUNT <= NUM_SIGNERS, | values, where THRESHOLD_LIMIT <= SIGNING_COUNT <= NUM_SIGNERS, | |||
| ordered in ascending order by SigningCommitment.id. This list | ordered in ascending order by SigningCommitment.id. This list | |||
| MUST NOT contain more than one SigningCommitment value | MUST NOT contain more than one SigningCommitment value | |||
| corresponding to each signer. Signers MUST ignore SigningPackage | corresponding to each signer. Signers MUST ignore SigningPackage | |||
| values with duplicate SignerIDs. | values with duplicate SignerIDs. | |||
| msg The message to be signed. | msg The message to be signed. | |||
| C.3. Signature Share | C.3. Signature Share | |||
| The output of each signer is a signature share which is sent to the | The output of each signer is a signature share which is sent to the | |||
| Coordinator. This can be constructed as follows. | Coordinator. This can be constructed as follows. | |||
| struct { | struct { | |||
| SignerID id; | SignerID id; | |||
| opaque signature_share[Ns]; | opaque signature_share[Ns]; | |||
| opaque commitment_share[Ne]; | ||||
| } SignatureShare; | } SignatureShare; | |||
| id The SignerID. | id The SignerID. | |||
| signature_share The signature share from this signer encoded as a | signature_share The signature share from this signer encoded as a | |||
| serialized scalar. | serialized scalar. | |||
| commitment_share The signature commitment share from this signer | ||||
| encoded as a serialized element. | ||||
| Appendix D. Test Vectors | Appendix D. Test Vectors | |||
| This section contains test vectors for all ciphersuites listed in | This section contains test vectors for all ciphersuites listed in | |||
| Section 6. All Element and Scalar values are represented in | Section 6. All Element and Scalar values are represented in | |||
| serialized form and encoded in hexadecimal strings. Signatures are | serialized form and encoded in hexadecimal strings. Signatures are | |||
| represented as the concatenation of their constituent parts. The | represented as the concatenation of their constituent parts. The | |||
| input message to be signed is also encoded as a hexadecimal string. | input message to be signed is also encoded as a hexadecimal string. | |||
| Each test vector consists of the following information. | Each test vector consists of the following information. | |||
| skipping to change at page 34, line 29 ¶ | skipping to change at page 36, line 7 ¶ | |||
| * Round one parameters and outputs: This lists the NUM_SIGNERS | * Round one parameters and outputs: This lists the NUM_SIGNERS | |||
| participants engaged in the protocol, identified by their integer | participants engaged in the protocol, identified by their integer | |||
| index, the hiding and binding commitment values produced in | index, the hiding and binding commitment values produced in | |||
| Section 5.1, as well as the resulting group binding factor input, | Section 5.1, as well as the resulting group binding factor input, | |||
| computed in part from the group commitment list encoded as | computed in part from the group commitment list encoded as | |||
| described in Section 4.3, and group binding factor as computed in | described in Section 4.3, and group binding factor as computed in | |||
| Section 5.2). | Section 5.2). | |||
| * Round two parameters and outputs: This lists the NUM_SIGNERS | * Round two parameters and outputs: This lists the NUM_SIGNERS | |||
| participants engaged in the protocol, identified by their integer | participants engaged in the protocol, identified by their integer | |||
| index, along with their corresponding output signature share and | index, along with their corresponding output signature share as | |||
| group commitment share as produced in Section 5.2. | produced in Section 5.2. | |||
| * Final output: This lists the aggregate signature as produced in | * Final output: This lists the aggregate signature as produced in | |||
| Section 5.3. | Section 5.3. | |||
| D.1. FROST(Ed25519, SHA-512) | D.1. FROST(Ed25519, SHA-512) | |||
| // Configuration information | // Configuration information | |||
| MAX_SIGNERS: 3 | MAX_SIGNERS: 3 | |||
| THRESHOLD_LIMIT: 2 | THRESHOLD_LIMIT: 2 | |||
| NUM_SIGNERS: 2 | NUM_SIGNERS: 2 | |||
| // Group input parameters | // Group input parameters | |||
| group_secret_key: 7c1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a7 | group_secret_key: 7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a7 | |||
| 90c6e13a98304 | 90c6e13a98304 | |||
| group_public_key: 377a6acb3b9b5f642c5ce355d23cac0568aad0da63c633d59d4 | group_public_key: 15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040 | |||
| 168bdcbce35af | d380fb9738673 | |||
| message: 74657374 | message: 74657374 | |||
| // Signer input parameters | // Signer input parameters | |||
| S1 signer_share: 949dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033 | S1 signer_share: 929dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033 | |||
| f2ec83d93509 | f2ec83d93509 | |||
| S2 signer_share: ac1e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07ee | S2 signer_share: a91e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07ee | |||
| d76bf409e80d | d76bf409e80d | |||
| S3 signer_share: d7cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8 | S3 signer_share: d3cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8 | |||
| bdea643a9a02 | bdea643a9a02 | |||
| // Round one parameters | // Round one parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| group_binding_factor_input: 000178e175d15cb5cec1257e0d84d797ba8c3dd9b | group_binding_factor_input: 000178e175d15cb5cec1257e0d84d797ba8c3dd9b | |||
| 4c7bc50f3fa527c200bcc6c4a954cdad16ae67ac5919159d655b681bd038574383bab | 4c7bc50f3fa527c200bcc6c4a954cdad16ae67ac5919159d655b681bd038574383bab | |||
| 423614f8967396ee12ca62000288a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea98 | 423614f8967396ee12ca62000288a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea98 | |||
| 981bfb25375996c5767c932bbf10c41feb17d41cc6433e69f16cceccc42a00aedf72f | 981bfb25375996c5767c932bbf10c41feb17d41cc6433e69f16cceccc42a00aedf72f | |||
| eb5f44929fdf2e2fee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a | eb5f44929fdf2e2fee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a | |||
| 5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f500 | 5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f500 | |||
| skipping to change at page 35, line 42 ¶ | skipping to change at page 37, line 20 ¶ | |||
| 5d2d5dfc5620c | 5d2d5dfc5620c | |||
| S2 hiding_nonce_commitment: 88a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea | S2 hiding_nonce_commitment: 88a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea | |||
| 98981bfb25375996c5767c9 | 98981bfb25375996c5767c9 | |||
| S2 binding_nonce_commitment: 32bbf10c41feb17d41cc6433e69f16cceccc42a0 | S2 binding_nonce_commitment: 32bbf10c41feb17d41cc6433e69f16cceccc42a0 | |||
| 0aedf72feb5f44929fdf2e2f | 0aedf72feb5f44929fdf2e2f | |||
| // Round two parameters | // Round two parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| // Signer round two outputs | // Signer round two outputs | |||
| S1 sig_share: f8bbaf924e1c90e11dec1eb679194aade084f92fbf52fdd436ba0a0 | S1 sig_share: b7e8f03a1a1149adacb96f952dbc39b6034facceafe4a70d6963592 | |||
| 7f71ab708 | fce75570c | |||
| S1 group_commitment_share: 11bb9777aa393b92e814e415039adf62687a0be543 | S2 sig_share: cd388f9aff4376397c5ad231713fe6b167bed9cc88a1cc97b0b6bbe | |||
| c2322d817e4934bc5a7cf2 | 0316a7909 | |||
| S2 sig_share: 80f589405714ca0e6adc87c2c0186a0ae4d6e352f7b248b23149a5d | ||||
| cd3fe4704 | ||||
| S2 group_commitment_share: 4af85179d17ed031b767ab579e59c7018dac09ae40 | ||||
| 0b1700623d0af1129a9c55 | ||||
| sig: ebe7efbb42c4b1c55106b5536fb5e9ac7a6d0803ea4ae9c8c629ca51e05c230e | sig: ebe7efbb42c4b1c55106b5536fb5e9ac7a6d0803ea4ae9c8c629ca51e05c230e | |||
| 78b139d3a5305af087c8a6783a32b4b7c45bdd82b60546876803b0e3ca19ff0c | 974d8a78fff1ac8e52774a24c00141536b0d869b388674a5191a151000e0d005 | |||
| D.2. FROST(Ed448, SHAKE256) | D.2. FROST(Ed448, SHAKE256) | |||
| // Configuration information | // Configuration information | |||
| MAX_SIGNERS: 3 | MAX_SIGNERS: 3 | |||
| THRESHOLD_LIMIT: 2 | THRESHOLD_LIMIT: 2 | |||
| NUM_SIGNERS: 2 | NUM_SIGNERS: 2 | |||
| // Group input parameters | // Group input parameters | |||
| group_secret_key: cef4a803a21d82fa90692e86541e08d878c9f688e5d71a2bd35 | group_secret_key: cdf4a803a21d82fa90692e86541e08d878c9f688e5d71a2bd35 | |||
| 4a9a3af62b8c7c89753055949cab8fd044c17c94211f167672b053659420b00 | 4a9a3af62b8c7c89753055949cab8fd044c17c94211f167672b053659420b00 | |||
| group_public_key: 005f23508a78131aee4d6cb027f967d89557ec5f24dc3ebeede | group_public_key: 800e9b495543b04aaebdba2813de65d1aefe78e8b219d38966b | |||
| b550466fcc1411283ff5d9c605d9a8b36e6eea36b67ceba047d57968896db80 | c0afa1d5d9d685c740c8ab720bff3c84cd9f4a701c1588e40d981f4abb19600 | |||
| message: 74657374 | message: 74657374 | |||
| // Signer input parameters | // Signer input parameters | |||
| S1 signer_share: d408a2f1d9ead0cc4b4b9b2e84a22f8e2aa2ab4ee715febe7a08 | S1 signer_share: d208a2f1d9ead0cc4b4b9b2e84a22f8e2aa2ab4ee715febe7a08 | |||
| 175d4298dd6bbe2e1c0b29aaa972c78555ea3b3d7308b248994780219e0800 | 175d4298dd6bbe2e1c0b29aaa972c78555ea3b3d7308b248994780219e0800 | |||
| S2 signer_share: da1c9bdf11b81f9f062d08d7b3265744dc7a6014e953e15222bc | S2 signer_share: d71c9bdf11b81f9f062d08d7b3265744dc7a6014e953e15222bc | |||
| 8416d5cd0210b4c5e410f90a892c91065fbdae37d51ffc29078acae9f90500 | 8416d5cd0210b4c5e410f90a892c91065fbdae37d51ffc29078acae9f90500 | |||
| S3 signer_share: e03094cd49856e71c10e757fe3aa7efa8d5315daea91c4e6c96f | S3 signer_share: dc3094cd49856e71c10e757fe3aa7efa8d5315daea91c4e6c96f | |||
| f2cf670328b4a95cad16c96b68e65a87689021323737460b75cc14b2550300 | f2cf670328b4a95cad16c96b68e65a87689021323737460b75cc14b2550300 | |||
| // Round one parameters | // Round one parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| group_binding_factor_input: 00016d8ef55145bab18c129311f1d07bef2110d0b | group_binding_factor_input: 00016d8ef55145bab18c129311f1d07bef2110d0b | |||
| 6841aae919eb6abf5e523d26f819d3695d78f8aa246c6b6d6fd6c2b8a63dd1cf8e8c8 | 6841aae919eb6abf5e523d26f819d3695d78f8aa246c6b6d6fd6c2b8a63dd1cf8e8c8 | |||
| 9a870400a0c29f750605b10c52e347fc538af0d4ebddd23a1e0300482a7d98a39d408 | 9a870400a0c29f750605b10c52e347fc538af0d4ebddd23a1e0300482a7d98a39d408 | |||
| 356b9041d5fbaa274c2dc3f248601f21cee912e2f5700c1753a80000242c2fdc11e5f | 356b9041d5fbaa274c2dc3f248601f21cee912e2f5700c1753a80000242c2fdc11e5f | |||
| 726d4c897ed118f668a27bfb0d5946b5f513e975638b7c4b0a46cf5184d4a9c1f6310 | 726d4c897ed118f668a27bfb0d5946b5f513e975638b7c4b0a46cf5184d4a9c1f6310 | |||
| fd3c10f84d9de704a33aab2af976d60804fa4ecba88458bcf7677a3952f540e20556d | fd3c10f84d9de704a33aab2af976d60804fa4ecba88458bcf7677a3952f540e20556d | |||
| skipping to change at page 37, line 22 ¶ | skipping to change at page 38, line 44 ¶ | |||
| 6b5f513e975638b7c4b0a46cf5184d4a9c1f6310fd3c10f84d9de704a33aab2af976d | 6b5f513e975638b7c4b0a46cf5184d4a9c1f6310fd3c10f84d9de704a33aab2af976d | |||
| 6080 | 6080 | |||
| S2 binding_nonce_commitment: 4fa4ecba88458bcf7677a3952f540e20556d5e90 | S2 binding_nonce_commitment: 4fa4ecba88458bcf7677a3952f540e20556d5e90 | |||
| d5aa7e8f226d303ef7b88fb33a63f6cac6a9d638089b1739a5d2564d15fb3e43e1b0b | d5aa7e8f226d303ef7b88fb33a63f6cac6a9d638089b1739a5d2564d15fb3e43e1b0b | |||
| 28a80 | 28a80 | |||
| // Round two parameters | // Round two parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| // Signer round two outputs | // Signer round two outputs | |||
| S1 sig_share: ad41cd3320c82edd20c344769bd7b250105d9d0516109b7f774c297 | S1 sig_share: c5ab0a80c561d1a616ac70f4f13d993156f65f2b44a4a90f37f0640 | |||
| faaf8b3b6065b19bbae2afb6c34cce460b40e15655fb8ad0bcc26e21e00 | 7a1b62e3940bf14199301d128358b812bef32cb4bffaf03030238772000 | |||
| S1 group_commitment_share: 086d4d2ff2555fab65afc8eb473cc708f37cdb9c5d | S2 sig_share: 15211cb96d6aa73de803d46caf2043859fd796a6282f9adb00033f1 | |||
| e74d8e12a1a9d1a086a8914175e4db77e5d281f10441913aa680fedb207c954afdd88 | 4f4827f23f8cc792c2e322a1f30631ec7690ac587e5eb9c2afd323e3300 | |||
| 380 | ||||
| S2 sig_share: 5dcc0aec7d0a71eddd5ba2dd0f185ba7990bcd39b6fc0e4b0470c35 | ||||
| 6ed0deb736d7f2652e87e932a0c176cc4bc5ba0ef756cc62081e4f51900 | ||||
| S2 group_commitment_share: 7e91f66097b6450c52c89c14400a506ee1d37f5e52 | ||||
| a8d4c3fc9733c23d0b27cd6cfce55a8aee692262e5815be341e8d0b9d240a9630c9f0 | ||||
| 600 | ||||
| sig: 4d9883057726b029d042418600abe88ad3fec06d6a48dca289482e9d51c10353 | sig: 4d9883057726b029d042418600abe88ad3fec06d6a48dca289482e9d51c10353 | |||
| 37e4d1aae5fd1c73a55701133238602f423886fc134a3c65800a0ed81f9ed29fcafe1 | 37e4d1aae5fd1c73a55701133238602f423886fc134a3c6580e787ce8da00900c1a92 | |||
| ee753abef0df8a9686a3fcc0caaca7bbcecd597069f2a74da3f0d97a98e9740e35025 | 07fd32e9c6f956597202323f8f4264ecfd99e9539ae5c388c8e45c133fb4765ee9ff2 | |||
| 716ab554d524742c4d0bd83800 | 583d90d3e49ba02dff6ab51300 | |||
| D.3. FROST(ristretto255, SHA-512) | D.3. FROST(ristretto255, SHA-512) | |||
| // Configuration information | // Configuration information | |||
| MAX_SIGNERS: 3 | MAX_SIGNERS: 3 | |||
| THRESHOLD_LIMIT: 2 | THRESHOLD_LIMIT: 2 | |||
| NUM_SIGNERS: 2 | NUM_SIGNERS: 2 | |||
| // Group input parameters | // Group input parameters | |||
| group_secret_key: b120be204b5e758960458ca9c4675b56b12a8faff2be9c94891 | group_secret_key: b020be204b5e758960458ca9c4675b56b12a8faff2be9c94891 | |||
| d5e1cd75c880e | d5e1cd75c880e | |||
| group_public_key: 563b80013f337deaa2a282af7b281bd70d2f501928a89c1aa48 | group_public_key: e22ac4850672021eac8e0a36dfc4811466fb01108c3427d2347 | |||
| b379a5ac4202b | 827467ba02a34 | |||
| message: 74657374 | message: 74657374 | |||
| // Signer input parameters | // Signer input parameters | |||
| S1 signer_share: 94ae65bb90030a89507fa00fff08dfed841cf996de5a0c574f1f | S1 signer_share: 92ae65bb90030a89507fa00fff08dfed841cf996de5a0c574f1f | |||
| 4693ddcb6705 | 4693ddcb6705 | |||
| S2 signer_share: 641003b3f00bb1e01656ac1818a4419a580e637ecaf67b191521 | S2 signer_share: 611003b3f00bb1e01656ac1818a4419a580e637ecaf67b191521 | |||
| 2e0ae43a470c | 2e0ae43a470c | |||
| S3 signer_share: 479eaa4d36b145e00690c07e5245c5312c00cd65b692ebdbda22 | S3 signer_share: 439eaa4d36b145e00690c07e5245c5312c00cd65b692ebdbda22 | |||
| 1681eaa92603 | 1681eaa92603 | |||
| // Round one parameters | // Round one parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| group_binding_factor_input: 0001824e9eddddf02b2a9caf5859825e999d791ca | group_binding_factor_input: 0001824e9eddddf02b2a9caf5859825e999d791ca | |||
| 094f65b814a8bca6013d9cc312774c7e1271d2939a84a9a867e3a06579b4d25659b42 | 094f65b814a8bca6013d9cc312774c7e1271d2939a84a9a867e3a06579b4d25659b42 | |||
| 7439ccf0d745b43f75b76600028013834ff4d48e7d6b76c2e732bc611f54720ef8933 | 7439ccf0d745b43f75b76600028013834ff4d48e7d6b76c2e732bc611f54720ef8933 | |||
| c4ca4de7eaaa77ff5cd125e056ecc4f7c4657d3a742354430d768f945db229c335d25 | c4ca4de7eaaa77ff5cd125e056ecc4f7c4657d3a742354430d768f945db229c335d25 | |||
| 8e9622ad99f3e7582d07b35bd9849ce4af6ad403090d69a7d0eb88bba669a9f985175 | 8e9622ad99f3e7582d07b35bd9849ce4af6ad403090d69a7d0eb88bba669a9f985175 | |||
| d70cd15ad5f1ef5b734c98a32b4aab7b43a57e93fc09281f2e7a207076b31e416ba63 | d70cd15ad5f1ef5b734c98a32b4aab7b43a57e93fc09281f2e7a207076b31e416ba63 | |||
| skipping to change at page 38, line 46 ¶ | skipping to change at page 40, line 14 ¶ | |||
| 19c43f48ce306 | 19c43f48ce306 | |||
| S2 hiding_nonce_commitment: 8013834ff4d48e7d6b76c2e732bc611f54720ef89 | S2 hiding_nonce_commitment: 8013834ff4d48e7d6b76c2e732bc611f54720ef89 | |||
| 33c4ca4de7eaaa77ff5cd12 | 33c4ca4de7eaaa77ff5cd12 | |||
| S2 binding_nonce_commitment: 5e056ecc4f7c4657d3a742354430d768f945db22 | S2 binding_nonce_commitment: 5e056ecc4f7c4657d3a742354430d768f945db22 | |||
| 9c335d258e9622ad99f3e758 | 9c335d258e9622ad99f3e758 | |||
| // Round two parameters | // Round two parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| // Signer round two outputs | // Signer round two outputs | |||
| S1 sig_share: ec6b075f17c5670e80b1fda8f6de1cfe3c79db06a852f8d5650fb71 | S1 sig_share: 6a539c3a4ee281879a6fb350d20d53e17473f28cd3409ffc238dafe | |||
| eaad69501 | 8d9330605 | |||
| S1 group_commitment_share: bc7e792fce347a15d547935652377c406cc721965c | S2 sig_share: 1d4e59636ee089bfaf548834b07658216649a37f87f0818d5190aa9 | |||
| 58d3003dbd947a6dfddc0c | b90957505 | |||
| S2 sig_share: 87ceccc477069aa9b751b307f25955daaf943a3abc51f214a114781 | ||||
| de0f58e03 | ||||
| S2 group_commitment_share: 92c4f352ec392ba779271dc2ed09cda37f38d8c283 | ||||
| 747d4a85b4c9ce7289cb07 | ||||
| sig: 7e92309bf40993141acd5f2c7680a302cc5aa5dd291a833906da8e35bc39b03e | sig: 7e92309bf40993141acd5f2c7680a302cc5aa5dd291a833906da8e35bc39b03e | |||
| 733ad4238fcb01b83703b1b0e83872d8ec0d164164a4eaea06242f3c8acc2405 | 87a1f59dbcc20b474ac43b858284ab02dbbc950c5b31218a751d5a846ac97b0a | |||
| D.4. FROST(P-256, SHA-256) | D.4. FROST(P-256, SHA-256) | |||
| // Configuration information | // Configuration information | |||
| MAX_SIGNERS: 3 | MAX_SIGNERS: 3 | |||
| THRESHOLD_LIMIT: 2 | THRESHOLD_LIMIT: 2 | |||
| NUM_SIGNERS: 2 | NUM_SIGNERS: 2 | |||
| // Group input parameters | // Group input parameters | |||
| group_secret_key: 6f090d1393ff53bbcbba036c00b8830ab4546c251dece199eb0 | group_secret_key: 6f090d1393ff53bbcbba036c00b8830ab4546c251dece199eb0 | |||
| 3a6a51a5a5929 | 3a6a51a5a5928 | |||
| group_public_key: 03db0945167b62e6472ad46373b6cbbca88e2a9a4883071f0b3 | group_public_key: 033a2a83f9c9fdfdab7d620f48238a5e6157a8eb1d6c382c7b0 | |||
| fde4b2b6d7b6ba6 | ba95b7c9f69679c | |||
| message: 74657374 | message: 74657374 | |||
| // Signer input parameters | // Signer input parameters | |||
| S1 signer_share: 738552e18ea4f2090597aca6c23c1666845c21c676813f9e2678 | S1 signer_share: 738552e18ea4f2090597aca6c23c1666845c21c676813f9e2678 | |||
| 6f1e410dcecf | 6f1e410dcecd | |||
| S2 signer_share: 780198af894a90563f7555e183bfa9c25463d767cf159da261ed | S2 signer_share: 780198af894a90563f7555e183bfa9c25463d767cf159da261ed | |||
| 379767c14475 | 379767c14472 | |||
| S3 signer_share: 7c7dde7d83f02ea37952ff1c45433d1e246b8d0927a9fba69d62 | S3 signer_share: 7c7dde7d83f02ea37952ff1c45433d1e246b8d0927a9fba69d62 | |||
| 00108e74ba1b | 00108e74ba17 | |||
| // Round one parameters | // Round one parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| group_binding_factor_input: 000102f34caab210d59324e12ba41f0802d9545f7 | group_binding_factor_input: 000102f34caab210d59324e12ba41f0802d9545f7 | |||
| f702906930766b86c462bb8ff7f3402b724640ea9e262469f401c9006991ba3247c2c | f702906930766b86c462bb8ff7f3402b724640ea9e262469f401c9006991ba3247c2c | |||
| 91b97cdb1f0eeab1a777e24e1e0002037f8a998dfc2e60a7ad63bc987cb27b8abf78a | 91b97cdb1f0eeab1a777e24e1e0002037f8a998dfc2e60a7ad63bc987cb27b8abf78a | |||
| 68bd924ec6adb9f251850cbe711024a4e90422a19dd8463214e997042206c39d3df56 | 68bd924ec6adb9f251850cbe711024a4e90422a19dd8463214e997042206c39d3df56 | |||
| 168b458592462090c89dbcf84efca0c54f70a585d6aae28679482b4aed03ae5d38297 | 168b458592462090c89dbcf84efca0c54f70a585d6aae28679482b4aed03ae5d38297 | |||
| b9092ab3376d46fdf55 | b9092ab3376d46fdf55 | |||
| group_binding_factor: 9df349a9f34bf01627f6b4f8b376e8c8261d55508d1cac2 | group_binding_factor: 9df349a9f34bf01627f6b4f8b376e8c8261d55508d1cac2 | |||
| skipping to change at page 40, line 17 ¶ | skipping to change at page 41, line 29 ¶ | |||
| 5a7c02f11e3e0 | 5a7c02f11e3e0 | |||
| S2 hiding_nonce_commitment: 037f8a998dfc2e60a7ad63bc987cb27b8abf78a68 | S2 hiding_nonce_commitment: 037f8a998dfc2e60a7ad63bc987cb27b8abf78a68 | |||
| bd924ec6adb9f251850cbe711 | bd924ec6adb9f251850cbe711 | |||
| S2 binding_nonce_commitment: 024a4e90422a19dd8463214e997042206c39d3df | S2 binding_nonce_commitment: 024a4e90422a19dd8463214e997042206c39d3df | |||
| 56168b458592462090c89dbcf8 | 56168b458592462090c89dbcf8 | |||
| // Round two parameters | // Round two parameters | |||
| participants: 1,2 | participants: 1,2 | |||
| // Signer round two outputs | // Signer round two outputs | |||
| S1 sig_share: 120a8ef8a5936444d8087cb10df5648629895e94582720760a10c8c | S1 sig_share: 0a658fe198caddf5ddc407ad58c4615458f02a58d0c1f7a38e25692 | |||
| 217e3417b | 98dc41df0 | |||
| S1 group_commitment_share: 0314cc3c03885953b3a15482d0ef4716eba9aca439 | S2 sig_share: e84d948cfec74b5e7540ad09fd69dcd1570f708f2d8573dbbf08cb0 | |||
| fa541a37489a146dd383d07e | 2bc872c75 | |||
| S2 sig_share: 2a7ff42d849f1bcc0e5f75d5810900a3e8f68ab717ff10d7a6da89f | ||||
| 8bb0c16aa | ||||
| S2 group_commitment_share: 034f4516676fe414883397fc5e150375c9937b3b77 | ||||
| 3c9ac57a11b2b6574e6bf452 | ||||
| sig: 035cfbd148da711bbc823455b682ed01a1be3c5415cf692f4a91b7fe22d1dec3 | sig: 035cfbd148da711bbc823455b682ed01a1be3c5415cf692f4a91b7fe22d1dec3 | |||
| 453c8a83262a328010e667f2868efe652a127fe94b7026314db0eb52bad2ef5825 | 45f2b3246e979229545304b4b7562e3e25afff9ae7fe476b7f4d2e342c4a4b4a65 | |||
| Authors' Addresses | Authors' Addresses | |||
| Deirdre Connolly | Deirdre Connolly | |||
| Zcash Foundation | Zcash Foundation | |||
| Email: durumcrustulum@gmail.com | Email: durumcrustulum@gmail.com | |||
| Chelsea Komlo | Chelsea Komlo | |||
| University of Waterloo, Zcash Foundation | University of Waterloo, Zcash Foundation | |||
| Email: ckomlo@uwaterloo.ca | Email: ckomlo@uwaterloo.ca | |||
| End of changes. 96 change blocks. | ||||
| 235 lines changed or deleted | 312 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||