idnits 2.17.00 (12 Aug 2021) /tmp/idnits6842/draft-irtf-cfrg-frost-04.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** There are 47 instances of too long lines in the document, the longest one being 72 characters in excess of 72. ** The abstract seems to contain references ([RFC8032]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- -- The document date (29 March 2022) is 46 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Informational ---------------------------------------------------------------------------- == Missing Reference: '0x01' is mentioned on line 250, but not defined == Missing Reference: '0x36' is mentioned on line 250, but not defined == Missing Reference: 'Ne' is mentioned on line 1450, but not defined == Missing Reference: 'Ns' is mentioned on line 1489, but not defined -- Looks like a reference, but probably isn't: '0' on line 1425 Summary: 3 errors (**), 0 flaws (~~), 4 warnings (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 CFRG D. Connolly 3 Internet-Draft Zcash Foundation 4 Intended status: Informational C. Komlo 5 Expires: 30 September 2022 University of Waterloo, Zcash Foundation 6 I. Goldberg 7 University of Waterloo 8 C. A. Wood 9 Cloudflare 10 29 March 2022 12 Two-Round Threshold Schnorr Signatures with FROST 13 draft-irtf-cfrg-frost-04 15 Abstract 17 In this draft, we present the two-round signing variant of FROST, a 18 Flexible Round-Optimized Schnorr Threshold signature scheme. FROST 19 signatures can be issued after a threshold number of entities 20 cooperate to issue a signature, allowing for improved distribution of 21 trust and redundancy with respect to a secret key. Further, this 22 draft specifies signatures that are compatible with [RFC8032]. 23 However, unlike [RFC8032], the protocol for producing signatures in 24 this draft is not deterministic, so as to ensure protection against a 25 key-recovery attack that is possible when even only one participant 26 is malicious. 28 Discussion Venues 30 This note is to be removed before publishing as an RFC. 32 Discussion of this document takes place on the Crypto Forum Research 33 Group mailing list (cfrg@ietf.org), which is archived at 34 https://mailarchive.ietf.org/arch/search/?email_list=cfrg. 36 Source for this draft and an issue tracker can be found at 37 https://github.com/cfrg/draft-irtf-cfrg-frost. 39 Status of This Memo 41 This Internet-Draft is submitted in full conformance with the 42 provisions of BCP 78 and BCP 79. 44 Internet-Drafts are working documents of the Internet Engineering 45 Task Force (IETF). Note that other groups may also distribute 46 working documents as Internet-Drafts. The list of current Internet- 47 Drafts is at https://datatracker.ietf.org/drafts/current/. 49 Internet-Drafts are draft documents valid for a maximum of six months 50 and may be updated, replaced, or obsoleted by other documents at any 51 time. It is inappropriate to use Internet-Drafts as reference 52 material or to cite them other than as "work in progress." 54 This Internet-Draft will expire on 30 September 2022. 56 Copyright Notice 58 Copyright (c) 2022 IETF Trust and the persons identified as the 59 document authors. All rights reserved. 61 This document is subject to BCP 78 and the IETF Trust's Legal 62 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 63 license-info) in effect on the date of publication of this document. 64 Please review these documents carefully, as they describe your rights 65 and restrictions with respect to this document. Code Components 66 extracted from this document must include Revised BSD License text as 67 described in Section 4.e of the Trust Legal Provisions and are 68 provided without warranty as described in the Revised BSD License. 70 Table of Contents 72 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 73 1.1. Change Log . . . . . . . . . . . . . . . . . . . . . . . 4 74 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 5 75 3. Cryptographic Dependencies . . . . . . . . . . . . . . . . . 6 76 3.1. Prime-Order Group . . . . . . . . . . . . . . . . . . . . 6 77 3.2. Cryptographic Hash Function . . . . . . . . . . . . . . . 7 78 4. Helper functions . . . . . . . . . . . . . . . . . . . . . . 7 79 4.1. Schnorr Signature Operations . . . . . . . . . . . . . . 8 80 4.2. Polynomial Operations . . . . . . . . . . . . . . . . . . 9 81 4.2.1. Evaluation of a polynomial . . . . . . . . . . . . . 9 82 4.2.2. Lagrange coefficients . . . . . . . . . . . . . . . . 10 83 4.2.3. Deriving the constant term of a polynomial . . . . . 11 84 4.3. Commitment List Encoding . . . . . . . . . . . . . . . . 12 85 4.4. Binding Factor Computation . . . . . . . . . . . . . . . 12 86 4.5. Group Commitment Computation . . . . . . . . . . . . . . 13 87 4.6. Signature Challenge Computation . . . . . . . . . . . . . 13 88 5. Two-Round FROST Signing Protocol . . . . . . . . . . . . . . 14 89 5.1. Round One - Commitment . . . . . . . . . . . . . . . . . 17 90 5.2. Round Two - Signature Share Generation . . . . . . . . . 17 91 5.3. Signature Share Verification and Aggregation . . . . . . 19 92 6. Ciphersuites . . . . . . . . . . . . . . . . . . . . . . . . 21 93 6.1. FROST(Ed25519, SHA-512) . . . . . . . . . . . . . . . . . 22 94 6.2. FROST(ristretto255, SHA-512) . . . . . . . . . . . . . . 22 95 6.3. FROST(Ed448, SHAKE256) . . . . . . . . . . . . . . . . . 23 96 6.4. FROST(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 24 98 7. Security Considerations . . . . . . . . . . . . . . . . . . . 25 99 7.1. Nonce Reuse Attacks . . . . . . . . . . . . . . . . . . . 26 100 7.2. Protocol Failures . . . . . . . . . . . . . . . . . . . . 26 101 7.3. Removing the Coordinator Role . . . . . . . . . . . . . . 26 102 7.4. Input Message Validation . . . . . . . . . . . . . . . . 27 103 8. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 27 104 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 105 9.1. Normative References . . . . . . . . . . . . . . . . . . 27 106 9.2. Informative References . . . . . . . . . . . . . . . . . 28 107 Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 29 108 Appendix B. Trusted Dealer Key Generation . . . . . . . . . . . 29 109 B.1. Shamir Secret Sharing . . . . . . . . . . . . . . . . . . 30 110 B.2. Verifiable Secret Sharing . . . . . . . . . . . . . . . . 32 111 Appendix C. Wire Format . . . . . . . . . . . . . . . . . . . . 34 112 C.1. Signing Commitment . . . . . . . . . . . . . . . . . . . 34 113 C.2. Signing Packages . . . . . . . . . . . . . . . . . . . . 34 114 C.3. Signature Share . . . . . . . . . . . . . . . . . . . . . 35 115 Appendix D. Test Vectors . . . . . . . . . . . . . . . . . . . . 35 116 D.1. FROST(Ed25519, SHA-512) . . . . . . . . . . . . . . . . . 36 117 D.2. FROST(Ed448, SHAKE256) . . . . . . . . . . . . . . . . . 37 118 D.3. FROST(ristretto255, SHA-512) . . . . . . . . . . . . . . 39 119 D.4. FROST(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 40 120 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41 122 1. Introduction 124 DISCLAIMER: This is a work-in-progress draft of FROST. 126 RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for this 127 draft is maintained in GitHub. Suggested changes should be submitted 128 as pull requests at https://github.com/cfrg/draft-irtf-cfrg-frost. 129 Instructions are on that page as well. 131 Unlike signatures in a single-party setting, threshold signatures 132 require cooperation among a threshold number of signers each holding 133 a share of a common private key. The security of threshold schemes 134 in general assume that an adversary can corrupt strictly fewer than a 135 threshold number of participants. 137 This document presents a variant of a Flexible Round-Optimized 138 Schnorr Threshold (FROST) signature scheme originally defined in 139 [FROST20]. FROST reduces network overhead during threshold signing 140 operations while employing a novel technique to protect against 141 forgery attacks applicable to prior Schnorr-based threshold signature 142 constructions. The variant of FROST presented in this document 143 requires two rounds to compute a signature, and implements signing 144 efficiency improvements described by [Schnorr21]. Single-round 145 signing with FROST is out of scope. 147 For select ciphersuites, the signatures produced by this draft are 148 compatible with [RFC8032]. However, unlike [RFC8032], signatures 149 produced by FROST are not deterministic, since deriving nonces 150 deterministically allows for a complete key-recovery attack in multi- 151 party discrete logarithm-based signatures, such as FROST. 153 Key generation for FROST signing is out of scope for this document. 154 However, for completeness, key generation with a trusted dealer is 155 specified in Appendix B. 157 1.1. Change Log 159 draft-04 161 * Added methods to verify VSS commitments and derive group info 162 (#126, #132). 164 * Changed check for participants to consider only nonnegative 165 numbers (#133). 167 * Changed sampling for secrets and coefficients to allow the zero 168 element (#130). 170 * Split test vectors into separate files (#129) 172 * Update wire structs to remove commitment shares where not 173 necessary (#128) 175 * Add failure checks (#127) 177 * Update group info to include each participant's key and clarify 178 how public key material is obtained (#120, #121). 180 * Define cofactor checks for verification (#118) 182 * Various editorial improvements and add contributors (#124, #123, 183 #119, #116, #113, #109) 185 draft-03 187 * Refactor the second round to use state from the first round (#94). 189 * Ensure that verification of signature shares from the second round 190 uses commitments from the first round (#94). 192 * Clarify RFC8032 interoperability based on PureEdDSA (#86). 194 * Specify signature serialization based on element and scalar 195 serialization (#85). 197 * Fix hash function domain separation formatting (#83). 199 * Make trusted dealer key generation deterministic (#104). 201 * Add additional constraints on participant indexes and nonce usage 202 (#105, #103, #98, #97). 204 * Apply various editorial improvements. 206 draft-02 208 * Fully specify both rounds of FROST, as well as trusted dealer key 209 generation. 211 * Add ciphersuites and corresponding test vectors, including suites 212 for RFC8032 compatibility. 214 * Refactor document for editorial clarity. 216 draft-01 218 * Specify operations, notation and cryptographic dependencies. 220 draft-00 222 * Outline CFRG draft based on draft-komlo-frost. 224 2. Conventions and Definitions 226 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 227 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 228 "OPTIONAL" in this document are to be interpreted as described in 229 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 230 capitals, as shown here. 232 The following notation and terminology are used throughout this 233 document. 235 * A participant is an entity that is trusted to hold a secret share. 237 * NUM_SIGNERS denotes the number of participants, and the number of 238 shares that s is split into. This value MUST NOT exceed 2^16-1. 240 * THRESHOLD_LIMIT denotes the threshold number of participants 241 required to issue a signature. More specifically, at least 242 THRESHOLD_LIMIT shares must be combined to issue a valid 243 signature. 245 * len(x) is the length of integer input x as an 8-byte, big-endian 246 integer. 248 * encode_uint16(x): Convert two byte unsigned integer (uint16) x to 249 a 2-byte, big-endian byte string. For example, encode_uint16(310) 250 = [0x01, 0x36]. 252 * || denotes concatenation, i.e., x || y = xy. 254 Unless otherwise stated, we assume that secrets are sampled uniformly 255 at random using a cryptographically secure pseudorandom number 256 generator (CSPRNG); see [RFC4086] for additional guidance on the 257 generation of random numbers. 259 3. Cryptographic Dependencies 261 FROST signing depends on the following cryptographic constructs: 263 * Prime-order Group, Section 3.1; 265 * Cryptographic hash function, Section 3.2; 267 These are described in the following sections. 269 3.1. Prime-Order Group 271 FROST depends on an abelian group G of prime order p. The 272 fundamental group operation is addition + with identity element I. 273 For any elements A and B of the group G, A + B = B + A is also a 274 member of G. Also, for any A in GG, there exists an element -A such 275 that A + (-A) = (-A) + A = I. Scalar multiplication is equivalent to 276 the repeated application of the group operation on an element A with 277 itself r-1 times, this is denoted as r*A = A + ... + A. For any 278 element A, p * A = I. We denote B as the fixed generator of the 279 group. Scalar base multiplication is equivalent to the repeated 280 application of the group operation B with itself r-1 times, this is 281 denoted as ScalarBaseMult(r). The set of scalars corresponds to 282 GF(p), which refer to as the scalar field. This document uses types 283 Element and Scalar to denote elements of the group G and its set of 284 scalars, respectively. We denote equality comparison as == and 285 assignment of values by =. 287 We now detail a number of member functions that can be invoked on a 288 prime-order group G. 290 * Order(): Outputs the order of G (i.e. p). 292 * Identity(): Outputs the identity element of the group (i.e. I). 294 * RandomScalar(): A member function of G that chooses at random a 295 Scalar element in GF(p). 297 * RandomNonzeroScalar(): A member function of G that chooses at 298 random a non-zero Scalar element in GF(p). 300 * SerializeElement(A): A member function of G that maps an Element A 301 to a unique byte array buf of fixed length Ne. 303 * DeserializeElement(buf): A member function of G that attempts to 304 map a byte array buf to an Element A, and fails if the input is 305 not a valid byte representation of an element of the group. This 306 function can raise a DeserializeError if deserialization fails or 307 A is the identity element of the group; see Section 6 for group- 308 specific input validation steps. 310 * SerializeScalar(s): A member function of G that maps a Scalar s to 311 a unique byte array buf of fixed length Ns. 313 * DeserializeScalar(buf): A member function of G that attempts to 314 map a byte array buf to a Scalar s. This function can raise a 315 DeserializeError if deserialization fails; see Section 6 for 316 group-specific input validation steps. 318 3.2. Cryptographic Hash Function 320 FROST requires the use of a cryptographically secure hash function, 321 generically written as H, which functions effectively as a random 322 oracle. For concrete recommendations on hash functions which SHOULD 323 BE used in practice, see Section 6. Using H, we introduce three 324 separate domain-separated hashes, H1, H2, and H3, where H1 and H2 map 325 arbitrary inputs to non-zero Scalar elements of the prime-order group 326 scalar field, and H3 is an alias for H with domain separation 327 applied. The details of H1, H2, and H3 vary based on ciphersuite. 328 See Section 6 for more details about each. 330 4. Helper functions 332 Beyond the core dependencies, the protocol in this document depends 333 on the following helper operations: 335 * Schnorr signatures, Section 4.1; 337 * Polynomial operations, Section 4.2; 339 * Encoding operations, Section 4.3; 341 * Signature binding Section 4.4, group commitment Section 4.5, and 342 challenge computation Section 4.6 344 This sections describes these operations in more detail. 346 4.1. Schnorr Signature Operations 348 In the single-party setting, a Schnorr signature is generated with 349 the following operation. 351 schnorr_signature_generate(msg, SK): 353 Inputs: 354 - msg, message to be signed, an octet string 355 - SK, private key, a scalar 357 Outputs: signature (R, z), a pair of scalar values 359 def schnorr_signature_generate(msg, SK): 360 PK = G.ScalarBaseMult(SK) 361 k = G.RandomScalar() 362 R = G.ScalarBaseMult(k) 364 comm_enc = G.SerializeElement(R) 365 pk_enc = G.SerializeElement(PK) 366 challenge_input = comm_enc || pk_enc || msg 367 c = H2(challenge_input) 369 z = k + (c * SK) 370 return (R, z) 372 The corresponding verification operation is as follows. Here, h is 373 the cofactor for the group being operated over, e.g. h=8 for the case 374 of Curve25519, h=4 for Ed448, and h=1 for groups such as ristretto255 375 and secp256k1, etc. This final scalar multiplication MUST be 376 performed when h>1. 378 schnorr_signature_verify(msg, sig, PK): 380 Inputs: 381 - msg, signed message, an octet string 382 - sig, a tuple (R, z) output from schnorr_signature_generate or FROST 383 - PK, public key, a group element 385 Outputs: 1 if signature is valid, and 0 otherwise 387 def schnorr_signature_verify(msg, sig = (R, z), PK): 388 comm_enc = G.SerializeElement(R) 389 pk_enc = G.SerializeElement(PK) 390 challenge_input = comm_enc || pk_enc || msg 391 c = H2(challenge_input) 393 l = G.ScalarBaseMult(z) 394 r = R + (c * PK) 395 check = (l - r) * h 396 return check == G.Identity() 398 4.2. Polynomial Operations 400 This section describes operations on and associated with polynomials 401 that are used in the main signing protocol. A polynomial of degree t 402 is represented as a sorted list of t coefficients. A point on the 403 polynomial is a tuple (x, y), where y = f(x). For notational 404 convenience, we refer to the x-coordinate and y-coordinate of a point 405 p as p.x and p.y, respectively. 407 4.2.1. Evaluation of a polynomial 409 This section describes a method for evaluating a polynomial f at a 410 particular input x, i.e., y = f(x) using Horner's method. 412 polynomial_evaluate(x, coeffs): 414 Inputs: 415 - x, input at which to evaluate the polynomial, a scalar 416 - coeffs, the polynomial coefficients, a list of scalars 418 Outputs: Scalar result of the polynomial evaluated at input x 420 def polynomial_evaluate(x, coeffs): 421 value = 0 422 for (counter, coeff) in coeffs.reverse(): 423 if counter == coeffs.len() - 1: 424 value += coeff // add the constant term 425 else: 426 value += coeff 427 value *= x 429 return value 431 4.2.2. Lagrange coefficients 433 Lagrange coefficients are used in FROST to evaluate a polynomial f at 434 f(0), given a set of t other points, where f is represented as a set 435 of coefficients. 437 derive_lagrange_coefficient(x_i, L): 439 Inputs: 440 - x_i, an x-coordinate contained in L, a scalar 441 - L, the set of x-coordinates, each a scalar 443 Outputs: L_i, the i-th Lagrange coefficient 445 Errors: 446 - "invalid parameters", if any coordinate is less than or equal to 0 448 def derive_lagrange_coefficient(x_i, L): 449 if x_i = 0: 450 raise "invalid parameters" 451 for x_j in L: 452 if x_j = 0: 453 raise "invalid parameters" 455 numerator = 1 456 denominator = 1 457 for x_j in L: 458 if x_j == x_i: continue 459 numerator *= x_j 460 denominator *= x_j - x_i 462 L_i = numerator / denominator 463 return L_i 465 4.2.3. Deriving the constant term of a polynomial 467 Secret sharing requires "splitting" a secret, which is represented as 468 a constant term of some polynomial f of degree t. Recovering the 469 constant term occurs with a set of t points using polynomial 470 interpolation, defined as follows. 472 Inputs: 473 - points, a set of `t` points on a polynomial f, each a tuple of two 474 scalar values representing the x and y coordinates 476 Outputs: The constant term of f, i.e., f(0) 478 def polynomial_interpolation(points): 479 L = [] 480 for point in points: 481 L.append(point.x) 483 f_zero = F(0) 484 for point in points: 485 delta = point.y * derive_lagrange_coefficient(point.x, L) 486 f_zero = f_zero + delta 488 return f_zero 490 4.3. Commitment List Encoding 492 This section describes the subroutine used for encoding a list of 493 signer commitments into a bytestring that is used in the FROST 494 protocol. 496 Inputs: 497 - commitment_list = [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...], a list of commitments issued by each signer, 498 where each element in the list indicates the signer index i and their 499 two commitment Element values (hiding_nonce_commitment_i, binding_nonce_commitment_i). This list MUST be sorted in ascending order 500 by signer index. 502 Outputs: A byte string containing the serialized representation of commitment_list. 504 def encode_group_commitment_list(commitment_list): 505 encoded_group_commitment = nil 506 for (index, hiding_nonce_commitment, binding_nonce_commitment) in commitment_list: 507 encoded_commitment = encode_uint16(index) || 508 G.SerializeElement(hiding_nonce_commitment) || 509 G.SerializeElement(binding_nonce_commitment) 510 encoded_group_commitment = encoded_group_commitment || encoded_commitment 511 return encoded_group_commitment 513 4.4. Binding Factor Computation 515 This section describes the subroutine for computing the binding 516 factor based on the signer commitment list and message to be signed. 518 Inputs: 519 - encoded_commitment_list, an encoded commitment list (as computed 520 by encode_group_commitment_list) 521 - msg, the message to be signed (sent by the Coordinator). 523 Outputs: binding_factor, a Scalar representing the binding factor 525 def compute_binding_factor(encoded_commitment_list, msg): 526 msg_hash = H3(msg) 527 rho_input = encoded_commitment_list || msg_hash 528 binding_factor = H1(rho_input) 529 return binding_factor 531 4.5. Group Commitment Computation 533 This section describes the subroutine for creating the group 534 commitment from a commitment list. 536 Inputs: 537 - commitment_list = [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...], a list of 538 commitments issued by each signer, where each element in the list indicates the signer index i and their 539 two commitment Element values (hiding_nonce_commitment_i, binding_nonce_commitment_i). 540 This list MUST be sorted in ascending order by signer index. 541 - binding_factor, a Scalar 543 Outputs: An Element representing the group commitment 545 def compute_group_commitment(commitment_list, binding_factor): 546 group_commitment = G.Identity() 547 for (_, hiding_nonce_commitment, binding_nonce_commitment) in commitment_list: 548 group_commitment = group_commitment + (hiding_nonce_commitment + (binding_nonce_commitment * binding_factor)) 549 return group_commitment 551 4.6. Signature Challenge Computation 553 This section describes the subroutine for creating the per-message 554 challenge. 556 Inputs: 557 - group_commitment, an Element representing the group commitment 558 - group_public_key, public key corresponding to the signer secret key share. 559 - msg, the message to be signed (sent by the Coordinator). 561 Outputs: a challenge Scalar value 563 def compute_challenge(group_commitment, group_public_key, msg): 564 group_comm_enc = G.SerializeElement(group_commitment) 565 group_public_key_enc = G.SerializeElement(group_public_key) 566 challenge_input = group_comm_enc || group_public_key_enc || msg 567 challenge = H2(challenge_input) 568 return challenge 570 5. Two-Round FROST Signing Protocol 572 We now present the two-round variant of the FROST threshold signature 573 protocol for producing Schnorr signatures. It involves signer 574 participants and a coordinator. Signing participants are entities 575 with signing key shares that participate in the threshold signing 576 protocol. The coordinator is a distinguished signer with the 577 following responsibilities: 579 1. Determining which signers will participate (at least 580 THRESHOLD_LIMIT in number); 582 2. Coordinating rounds (receiving and forwarding inputs among 583 participants); and 585 3. Aggregating signature shares output by each participant, and 586 publishing the resulting signature. 588 FROST assumes the selection of all participants, including the 589 dealer, signer, and Coordinator are all chosen external to the 590 protocol. Note that it is possible to deploy the protocol without a 591 distinguished Coordinator; see Section 7.3 for more information. 593 Because key generation is not specified, all signers are assumed to 594 have the (public) group state that we refer to as "group info" below, 595 and their corresponding signing key shares. 597 In particular, it is assumed that the coordinator and each signing 598 participant P_i knows the following group info: 600 * Group public key, denoted PK = G.ScalarMultBase(s), corresponding 601 to the group secret key s. PK is an output from the group's key 602 generation protocol, such as trusted_dealer_keygenor a DKG. 604 * Public keys for each signer, denoted PK_i = 605 G.ScalarMultBase(sk_i), which are similarly outputs from the 606 group's key generation protocol. 608 And that each participant with identifier i additionally knows the 609 following: 611 * Participant is signing key share sk_i, which is the i-th secret 612 share of s. 614 The exact key generation mechanism is out of scope for this 615 specification. In general, key generation is a protocol that outputs 616 (1) a shared, group public key PK owned by each Signer, and (2) 617 individual shares of the signing key owned by each Signer. In 618 general, two possible key generation mechanisms are possible, one 619 that requires a single, trusted dealer, and the other which requires 620 performing a distributed key generation protocol. We highlight key 621 generation mechanism by a trusted dealer in Appendix B, for 622 reference. 624 This signing variant of FROST requires signers to perform two network 625 rounds: 1) generating and publishing commitments, and 2) signature 626 share generation and publication. The first round serves for each 627 participant to issue a commitment to a nonce. The second round 628 receives commitments for all signers as well as the message, and 629 issues a signature share with respect to that message. The 630 Coordinator performs the coordination of each of these rounds. At 631 the end of the second round, the Coordinator then performs an 632 aggregation step and outputs the final signature. This complete 633 interaction is shown in Figure 1. 635 (group info) (group info, (group info, 636 | signing key share) signing key share) 637 | | | 638 v v v 639 Coordinator Signer-1 ... Signer-n 640 ------------------------------------------------------------ 641 message 642 ------------> 643 | 644 == Round 1 (Commitment) == 645 | signer commitment | | 646 |<-----------------------+ | 647 | ... | 648 | signer commitment | 649 |<-----------------------------------------+ 651 == Round 2 (Signature Share Generation) == 652 | 653 | signer input | | 654 +------------------------> | 655 | signature share | | 656 |<-----------------------+ | 657 | ... | 658 | signer input | 659 +------------------------------------------> 660 | signature share | 661 <------------------------------------------+ 662 | 663 == Aggregation == 664 | 665 signature | 666 <-----------+ 668 Figure 1: FROST signature overview 670 Details for round one are described in Section 5.1, and details for 671 round two are described in Section 5.2. The final Aggregation step 672 is described in Section 5.3. 674 FROST assumes reliable message delivery between Coordinator and 675 signing participants in order for the protocol to complete. Messages 676 exchanged during signing operations are all within the public domain. 677 An attacker masquerading as another participant will result only in 678 an invalid signature; see Section 7. 680 5.1. Round One - Commitment 682 Round one involves each signer generating a pair of nonces and their 683 corresponding public commitments. A nonce is a pair of Scalar 684 values, and a commitment is a pair of Element values. 686 Each signer in round one generates a nonce nonce = (hiding_nonce, 687 binding_nonce) and commitment comm = (hiding_nonce_commitment, 688 binding_nonce_commitment). 690 Inputs: None 692 Outputs: (nonce, comm), a tuple of nonce and nonce commitment pairs. 694 def commit(): 695 hiding_nonce = G.RandomNonzeroScalar() 696 binding_nonce = G.RandomNonzeroScalar() 697 hiding_nonce_commitment = G.ScalarBaseMult(hiding_nonce) 698 binding_nonce_commitment = G.ScalarBaseMult(binding_nonce) 699 nonce = (hiding_nonce, binding_nonce) 700 comm = (hiding_nonce_commitment, binding_nonce_commitment) 701 return (nonce, comm) 703 The private output nonce from Participant P_i is stored locally and 704 kept private for use in the second round. This nonce MUST NOT be 705 reused in more than one invocation of FROST, and it MUST be generated 706 from a source of secure randomness. The public output comm from 707 Participant P_i is sent to the Coordinator; see Appendix C.1 for 708 encoding recommendations. 710 5.2. Round Two - Signature Share Generation 712 In round two, the Coordinator is responsible for sending the message 713 to be signed, and for choosing which signers will participate (of 714 number at least THRESHOLD_LIMIT). Signers additionally require 715 locally held data; specifically, their private key and the nonces 716 corresponding to their commitment issued in round one. 718 The Coordinator begins by sending each signer the message to be 719 signed along with the set of signing commitments for other signers in 720 the participant list. Each signer MUST validate the inputs before 721 processing the Coordinator's request. In particular, the Signer MUST 722 validate commitment_list, deserializing each group Element in the 723 list using DeserializeElement from Section 3.1. If deserialization 724 fails, the Signer MUST abort the protocol. Applications which 725 require that signers not process arbitrary input messages are also 726 required to also perform relevant application-layer input validation 727 checks; see Section 7.4 for more details. 729 Upon receipt and successful input validation, each Signer then runs 730 the following procedure to produce its own signature share. 732 Inputs: 733 - index, Index `i` of the signer. Note index will never equal `0`. 734 - sk_i, Signer secret key share. 735 - group_public_key, public key corresponding to the signer secret key share. 736 - nonce_i, pair of Scalar values (hiding_nonce, binding_nonce) generated in round one. 737 - msg, the message to be signed (sent by the Coordinator). 738 - commitment_list = [(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a 739 list of commitments issued in Round 1 by each signer, where each element in the list indicates the signer index j and their 740 two commitment Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j). 741 This list MUST be sorted in ascending order by signer index. 742 - participant_list, a set containing identifiers for each signer, similarly of length 743 NUM_SIGNERS (sent by the Coordinator). 745 Outputs: a Scalar value representing the signature share 747 def sign(index, sk_i, group_public_key, nonce_i, msg, commitment_list, participant_list): 748 # Encode the commitment list 749 encoded_commitments = encode_group_commitment_list(commitment_list) 751 # Compute the binding factor 752 binding_factor = compute_binding_factor(encoded_commitments, msg) 754 # Compute the group commitment 755 group_commitment = compute_group_commitment(commitment_list, binding_factor) 757 # Compute Lagrange coefficient 758 lambda_i = derive_lagrange_coefficient(index, participant_list) 760 # Compute the per-message challenge 761 challenge = compute_challenge(group_commitment, group_public_key, msg) 763 # Compute the signature share 764 (hiding_nonce, binding_nonce) = nonce_i 765 sig_share = hiding_nonce + (binding_nonce * binding_factor) + (lambda_i * sk_i * challenge) 767 return sig_share 769 The output of this procedure is a signature share. Each signer then 770 sends these shares back to the collector; see Appendix C.3 for 771 encoding recommendations. Each signer MUST delete the nonce and 772 corresponding commitment after this round completes. 774 Upon receipt from each Signer, the Coordinator MUST validate the 775 input signature using DeserializeElement. If validation fails, the 776 Coordinator MUST abort the protocol. If validation succeeds, the 777 Coordinator then verifies the set of signature shares using the 778 following procedure. 780 5.3. Signature Share Verification and Aggregation 782 After signers perform round two and send their signature shares to 783 the Coordinator, the Coordinator verifies each signature share for 784 correctness. In particular, for each signer, the Coordinator uses 785 commitment pairs generated during round one and the signature share 786 generated during round two, along with other group parameters, to 787 check that the signature share is valid using the following 788 procedure. 790 Inputs: 791 - index, Index `i` of the signer. Note index will never equal `0`. 792 - PK_i, the public key for the ith signer, where `PK_i = G.ScalarBaseMult(sk_i)` 793 - comm_i, pair of Element values (hiding_nonce_commitment, binding_nonce_commitment) generated 794 in round one from the ith signer. 795 - sig_share_i, a Scalar value indicating the signature share as produced in round two from the ith signer. 796 - commitment_list = [(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a list of commitments 797 issued in Round 1 by each signer, where each element in the list indicates the signer index j and their 798 two commitment Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j). 799 This list MUST be sorted in ascending order by signer index. 800 - participant_list, a set containing identifiers for each signer, similarly of length 801 NUM_SIGNERS (sent by the Coordinator). 802 - group_public_key, the public key for the group 803 - msg, the message to be signed 805 Outputs: True if the signature share is valid, and False otherwise. 807 def verify_signature_share(index, PK_i, comm_i, sig_share_i, commitment_list, 808 participant_list, group_public_key, msg): 809 # Encode the commitment list 810 encoded_commitments = encode_group_commitment_list(commitment_list) 812 # Compute the binding factor 813 binding_factor = compute_binding_factor(encoded_commitments, msg) 815 # Compute the group commitment 816 group_commitment = compute_group_commitment(commitment_list, binding_factor) 818 # Compute the commitment share 819 (hiding_nonce_commitment, binding_nonce_commitment) = comm_i 820 comm_share = hiding_nonce_commitment + (binding_nonce_commitment * binding_factor) 822 # Compute the challenge 823 challenge = compute_challenge(group_commitment, group_public_key, msg) 825 # Compute Lagrange coefficient 826 lambda_i = derive_lagrange_coefficient(index, participant_list) 828 # Compute relation values 829 l = G.ScalarBaseMult(sig_share_i) 830 r = comm_share + (PK_i * challenge * lambda_i) 832 return l == r 834 If any signature share fails to verify, i.e., if 835 verify_signature_share returns False for any signer share, the 836 Coordinator MUST abort the protocol. Otherwise, if all signer shares 837 are valid, the Coordinator performs the aggregate operation and 838 publishes the resulting signature. 840 Inputs: 841 - group_commitment, the group commitment returned by compute_group_commitment 842 - sig_shares, a set of signature shares z_i for each signer, of length NUM_SIGNERS, 843 where THRESHOLD_LIMIT <= NUM_SIGNERS <= MAX_SIGNERS. 845 Outputs: (R, z), a Schnorr signature consisting of an Element and Scalar value. 847 def frost_aggregate(group_commitment, sig_shares): 848 z = 0 849 for z_i in sig_shares: 850 z = z + z_i 851 return (group_commitment, z) 853 The output signature (R, z) from the aggregation step MUST be encoded 854 as follows: 856 struct { 857 opaque R_encoded[Ne]; 858 opaque z_encoded[Ns]; 859 } Signature; 861 Where Signature.R_encoded is G.SerializeElement(R) and 862 Signature.z_encoded is G.SerializeScalar(z). 864 6. Ciphersuites 866 A FROST ciphersuite must specify the underlying prime-order group 867 details and cryptographic hash function. Each ciphersuite is denoted 868 as (Group, Hash), e.g., (ristretto255, SHA-512). This section 869 contains some ciphersuites. 871 The RECOMMENDED ciphersuite is (ristretto255, SHA-512) Section 6.2. 872 The (Ed25519, SHA-512) ciphersuite is included for backwards 873 compatibility with [RFC8032]. 875 The DeserializeElement and DeserializeScalar functions instantiated 876 for a particular prime-order group corresponding to a ciphersuite 877 MUST adhere to the description in Section 3.1. Validation steps for 878 these functions are described for each the ciphersuites below. 879 Future ciphersuites MUST describe how input validation is done for 880 DeserializeElement and DeserializeScalar. 882 6.1. FROST(Ed25519, SHA-512) 884 This ciphersuite uses edwards25519 for the Group and SHA-512 for the 885 Hash function H meant to produce signatures indistinguishable from 886 Ed25519 as specified in [RFC8032]. The value of the contextString 887 parameter is empty. 889 * Group: edwards25519 [RFC8032] 891 - Cofactor (h): 8 893 - SerializeElement: Implemented as specified in [RFC8032], 894 Section 5.1.2. 896 - DeserializeElement: Implemented as specified in [RFC8032], 897 Section 5.1.3. Additionally, this function validates that the 898 resulting element is not the group identity element. 900 - SerializeScalar: Implemented by outputting the little-endian 901 32-byte encoding of the Scalar value. 903 - DeserializeScalar: Implemented by attempting to deserialize a 904 Scalar from a 32-byte string. This function can fail if the 905 input does not represent a Scalar between the value 0 and 906 G.Order() - 1. 908 * Hash (H): SHA-512, and Nh = 64. 910 - H1(m): Implemented by computing H("rho" || m), interpreting the 911 lower 32 bytes as a little-endian integer, and reducing the 912 resulting integer modulo L = 913 2^252+27742317777372353535851937790883648493. 915 - H2(m): Implemented by computing H(m), interpreting the lower 32 916 bytes as a little-endian integer, and reducing the resulting 917 integer modulo L = 918 2^252+27742317777372353535851937790883648493. 920 - H3(m): Implemented as an alias for H, i.e., H(m). 922 Normally H2 would also include a domain separator, but for backwards 923 compatibility with [RFC8032], it is omitted. 925 6.2. FROST(ristretto255, SHA-512) 927 This ciphersuite uses ristretto255 for the Group and SHA-512 for the 928 Hash function H. The value of the contextString parameter is "FROST- 929 RISTRETTO255-SHA512". 931 * Group: ristretto255 [RISTRETTO] 933 - Cofactor (h): 1 935 - SerializeElement: Implemented using the 'Encode' function from 936 [RISTRETTO]. 938 - DeserializeElement: Implemented using the 'Decode' function 939 from [RISTRETTO]. 941 - SerializeScalar: Implemented by outputting the little-endian 942 32-byte encoding of the Scalar value. 944 - DeserializeScalar: Implemented by attempting to deserialize a 945 Scalar from a 32-byte string. This function can fail if the 946 input does not represent a Scalar between the value 0 and 947 G.Order() - 1. 949 * Hash (H): SHA-512, and Nh = 64. 951 - H1(m): Implemented by computing H(contextString || "rho" || m) 952 and mapping the output to a Scalar as described in [RISTRETTO], 953 Section 4.4. 955 - H2(m): Implemented by computing H(contextString || "chal" || m) 956 and mapping the output to a Scalar as described in [RISTRETTO], 957 Section 4.4. 959 - H3(m): Implemented by computing H(contextString || "digest" || 960 m). 962 6.3. FROST(Ed448, SHAKE256) 964 This ciphersuite uses edwards448 for the Group and SHA256 for the 965 Hash function H meant to produce signatures indistinguishable from 966 Ed448 as specified in [RFC8032]. The value of the contextString 967 parameter is empty. 969 * Group: edwards448 [RFC8032] 971 - Cofactor (h): 4 973 - SerializeElement: Implemented as specified in [RFC8032], 974 Section 5.2.2. 976 - DeserializeElement: Implemented as specified in [RFC8032], 977 Section 5.2.3. Additionally, this function validates that the 978 resulting element is not the group identity element. 980 - SerializeScalar: Implemented by outputting the little-endian 981 48-byte encoding of the Scalar value. 983 - DeserializeScalar: Implemented by attempting to deserialize a 984 Scalar from a 48-byte string. This function can fail if the 985 input does not represent a Scalar between the value 0 and 986 G.Order() - 1. 988 * Hash (H): SHAKE256, and Nh = 117. 990 - H1(m): Implemented by computing H("rho" || m), interpreting the 991 lower 57 bytes as a little-endian integer, and reducing the 992 resulting integer modulo L = 2^446 - 13818066809895115352007386 993 748515426880336692474882178609894547503885. 995 - H2(m): Implemented by computing H(m), interpreting the lower 57 996 bytes as a little-endian integer, and reducing the resulting 997 integer modulo L = 2^446 - 138180668098951153520073867485154268 998 80336692474882178609894547503885. 1000 - H3(m): Implemented as an alias for H, i.e., H(m). 1002 Normally H2 would also include a domain separator, but for backwards 1003 compatibility with [RFC8032], it is omitted. 1005 6.4. FROST(P-256, SHA-256) 1007 This ciphersuite uses P-256 for the Group and SHA-256 for the Hash 1008 function H. The value of the contextString parameter is "FROST- 1009 P256-SHA256". 1011 * Group: P-256 (secp256r1) [x9.62] 1013 - Cofactor (h): 1 1015 - SerializeElement: Implemented using the compressed Elliptic- 1016 Curve-Point-to-Octet-String method according to [SECG]. 1018 - DeserializeElement: Implemented by attempting to deserialize a 1019 public key using the compressed Octet-String-to-Elliptic-Curve- 1020 Point method according to [SECG], and then performs partial 1021 public-key validation as defined in section 5.6.2.3.4 of 1022 [KEYAGREEMENT]. This includes checking that the coordinates of 1023 the resulting point are in the correct range, that the point is 1024 on the curve, and that the point is not the point at infinity. 1025 Additionally, this function validates that the resulting 1026 element is not the group identity element. If these checks 1027 fail, deserialization returns an error. 1029 - SerializeScalar: Implemented using the Field-Element-to-Octet- 1030 String conversion according to [SECG]. 1032 - DeserializeScalar: Implemented by attempting to deserialize a 1033 Scalar from a 32-byte string using Octet-String-to-Field- 1034 Element from [SECG]. This function can fail if the input does 1035 not represent a Scalar between the value 0 and G.Order() - 1. 1037 * Hash (H): SHA-256, and Nh = 32. 1039 - H1(m): Implemented using hash_to_field from [HASH-TO-CURVE], 1040 Section 5.3 using L = 48, expand_message_xmd with SHA-256, DST 1041 = contextString || "rho", and prime modulus equal to Order(). 1043 - H2(m): Implemented using hash_to_field from [HASH-TO-CURVE], 1044 Section 5.3 using L = 48, expand_message_xmd with SHA-256, DST 1045 = contextString || "chal", and prime modulus equal to Order(). 1047 - H3(m): Implemented by computing H(contextString || "digest" || 1048 m). 1050 7. Security Considerations 1052 A security analysis of FROST exists in [FROST20] and [Schnorr21]. 1053 The protocol as specified in this document assumes the following 1054 threat model. 1056 * Trusted dealer. The dealer that performs key generation is 1057 trusted to follow the protocol, although participants still are 1058 able to verify the consistency of their shares via a VSS 1059 (verifiable secret sharing) step; see Appendix B.2. 1061 * Unforgeability assuming less than (t-1) corrupted signers. So 1062 long as an adverary corrupts fewer than (t-1) participants, the 1063 scheme remains secure against EUF-CMA attacks. 1065 * Coordinator. We assume the Coordinator at the time of signing 1066 does not perform a denial of service attack. A denial of service 1067 would include any action which either prevents the protocol from 1068 completing or causing the resulting signature to be invalid. Such 1069 actions for the latter include sending inconsistent values to 1070 signing participants, such as messages or the set of individual 1071 commitments. Note that the Coordinator is _not_ trusted with any 1072 private information and communication at the time of signing can 1073 be performed over a public but reliable channel. 1075 The protocol as specified in this document does not target the 1076 following goals: 1078 * Post quantum security. FROST, like plain Schnorr signatures, 1079 requires the hardness of the Discrete Logarithm Problem. 1081 * Robustness. In the case of failure, FROST requires aborting the 1082 protocol. 1084 * Downgrade prevention. The sender and receiver are assumed to 1085 agree on what algorithms to use. 1087 * Metadata protection. If protection for metadata is desired, a 1088 higher-level communication channel can be used to facilitate key 1089 generation and signing. 1091 The rest of this section documents issues particular to 1092 implementations or deployments. 1094 7.1. Nonce Reuse Attacks 1096 Nonces generated by each participant in the first round of signing 1097 must be sampled uniformly at random and cannot be derived from some 1098 deterministic function. This is to avoid replay attacks initiated by 1099 other signers, which allows for a complete key-recovery attack. 1100 Coordinates MAY further hedge against nonce reuse attacks by tracking 1101 signer nonce commitments used for a given group key, at the cost of 1102 additional state. 1104 7.2. Protocol Failures 1106 We do not specify what implementations should do when the protocol 1107 fails, other than requiring that the protocol abort. Examples of 1108 viable failure include when a verification check returns invalid or 1109 if the underlying transport failed to deliver the required messages. 1111 7.3. Removing the Coordinator Role 1113 In some settings, it may be desirable to omit the role of the 1114 coordinator entirely. Doing so does not change the security 1115 implications of FROST, but instead simply requires each participant 1116 to communicate with all other participants. We loosely describe how 1117 to perform FROST signing among signers without this coordinator role. 1118 We assume that every participant receives as input from an external 1119 source the message to be signed prior to performing the protocol. 1121 Every participant begins by performing frost_commit() as is done in 1122 the setting where a coordinator is used. However, instead of sending 1123 the commitment SigningCommitment to the coordinator, every 1124 participant instead will publish this commitment to every other 1125 participant. Then, in the second round, instead of receiving a 1126 SigningPackage from the coordinator, signers will already have 1127 sufficient information to perform signing. They will directly 1128 perform frost_sign. All participants will then publish a 1129 SignatureShare to one another. After having received all signature 1130 shares from all other signers, each signer will then perform 1131 frost_verify and then frost_aggregate directly. 1133 The requirements for the underlying network channel remain the same 1134 in the setting where all participants play the role of the 1135 coordinator, in that all messages that are exchanged are public and 1136 so the channel simply must be reliable. However, in the setting that 1137 a player attempts to split the view of all other players by sending 1138 disjoint values to a subset of players, the signing operation will 1139 output an invalid signature. To avoid this denial of service, 1140 implementations may wish to define a mechanism where messages are 1141 authenticated, so that cheating players can be identified and 1142 excluded. 1144 7.4. Input Message Validation 1146 Some applications may require that signers only process messages of a 1147 certain structure. For example, in digital currency applications 1148 wherein multiple signers may collectively sign a transaction, it is 1149 reasonable to require that each signer check the input message to be 1150 a syntactically valid transaction. As another example, use of 1151 threshold signatures in TLS [TLS] to produce signatures of transcript 1152 hashes might require that signers check that the input message is a 1153 valid TLS transcript from which the corresponding transcript hash can 1154 be derived. 1156 In general, input message validation is an application-specific 1157 consideration that varies based on the use case and threat model. 1158 However, it is RECOMMENDED that applications take additional 1159 precautions and validate inputs so that signers do not operate as 1160 signing oracles for arbitrary messages. 1162 8. Contributors 1164 * Isis Lovecruft 1166 * T. Wilson-Brown 1168 * Alden Torres 1170 9. References 1172 9.1. Normative References 1174 [HASH-TO-CURVE] 1175 Faz-Hernandez, A., Scott, S., Sullivan, N., Wahby, R. S., 1176 and C. A. Wood, "Hashing to Elliptic Curves", Work in 1177 Progress, Internet-Draft, draft-irtf-cfrg-hash-to-curve- 1178 14, 18 February 2022, 1179 . 1182 [KEYAGREEMENT] 1183 Barker, E., Chen, L., Roginsky, A., Vassilev, A., and R. 1184 Davis, "Recommendation for pair-wise key-establishment 1185 schemes using discrete logarithm cryptography", National 1186 Institute of Standards and Technology report, 1187 DOI 10.6028/nist.sp.800-56ar3, April 2018, 1188 . 1190 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1191 Requirement Levels", BCP 14, RFC 2119, 1192 DOI 10.17487/RFC2119, March 1997, 1193 . 1195 [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital 1196 Signature Algorithm (EdDSA)", RFC 8032, 1197 DOI 10.17487/RFC8032, January 2017, 1198 . 1200 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1201 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1202 May 2017, . 1204 [RISTRETTO] 1205 Valence, H. D., Grigg, J., Hamburg, M., Lovecruft, I., 1206 Tankersley, G., and F. Valsorda, "The ristretto255 and 1207 decaf448 Groups", Work in Progress, Internet-Draft, draft- 1208 irtf-cfrg-ristretto255-decaf448-03, 25 February 2022, 1209 . 1212 [SECG] "Elliptic Curve Cryptography, Standards for Efficient 1213 Cryptography Group, ver. 2", 2009, 1214 . 1216 [x9.62] ANSI, "Public Key Cryptography for the Financial Services 1217 Industry: the Elliptic Curve Digital Signature Algorithm 1218 (ECDSA)", ANSI X9.62-1998, September 1998. 1220 9.2. Informative References 1222 [FROST20] Komlo, C. and I. Goldberg, "Two-Round Threshold Signatures 1223 with FROST", 22 December 2020, 1224 . 1226 [RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker, 1227 "Randomness Requirements for Security", BCP 106, RFC 4086, 1228 DOI 10.17487/RFC4086, June 2005, 1229 . 1231 [Schnorr21] 1232 Crites, E., Komlo, C., and M. Maller, "How to Prove 1233 Schnorr Assuming Schnorr", 11 October 2021, 1234 . 1236 [TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol 1237 Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, 1238 . 1240 Appendix A. Acknowledgments 1242 The Zcash Foundation engineering team designed a serialization format 1243 for FROST messages which we employ a slightly adapted version here. 1245 Appendix B. Trusted Dealer Key Generation 1247 One possible key generation mechanism is to depend on a trusted 1248 dealer, wherein the dealer generates a group secret s uniformly at 1249 random and uses Shamir and Verifiable Secret Sharing as described in 1250 Sections Appendix B.1 and Appendix B.2 to create secret shares of s 1251 to be sent to all other participants. We highlight at a high level 1252 how this operation can be performed. 1254 Inputs: 1255 - s, a group secret that MUST be derived from at least `Ns` bytes of entropy 1256 - n, the number of shares to generate, an integer 1257 - t, the threshold of the secret sharing scheme, an integer 1259 Outputs: 1260 - signer_private_keys, `n` shares of the secret key `s`, each a Scalar value. 1261 - vss_commitment, a vector commitment to each of the coefficients in the polynomial defined by secret_key_shares and whose constant term is s. 1263 def trusted_dealer_keygen(s, n, t): 1264 signer_private_keys, coefficients = secret_share_shard(secret_key, n, t) 1265 vss_commitment = vss_commit(coefficients): 1266 PK = G.ScalarBaseMult(secret_key) 1267 return signer_private_keys, vss_commitment 1269 It is assumed the dealer then sends one secret key share to each of 1270 the NUM_SIGNERS participants, along with C. After receiving their 1271 secret key share and C each participant MUST perform 1272 vss_verify(secret_key_share_i, C). It is assumed that all 1273 participant have the same view of C. The trusted dealer MUST delete 1274 the secret_key and secret_key_shares upon completion. 1276 Use of this method for key generation requires a mutually 1277 authenticated secure channel between the dealer and participants to 1278 send secret key shares, wherein the channel provides confidentiality 1279 and integrity. Mutually authenticated TLS is one possible deployment 1280 option. 1282 B.1. Shamir Secret Sharing 1284 In Shamir secret sharing, a dealer distributes a secret s to n 1285 participants in such a way that any cooperating subset of t 1286 participants can recover the secret. There are two basic steps in 1287 this scheme: (1) splitting a secret into multiple shares, and (2) 1288 combining shares to reveal the resulting secret. 1290 This secret sharing scheme works over any field F. In this 1291 specification, F is the scalar field of the prime-order group G. 1293 The procedure for splitting a secret into shares is as follows. 1295 secret_share_shard(s, n, t): 1297 Inputs: 1298 - s, secret to be shared, an element of F 1299 - n, the number of shares to generate, an integer 1300 - t, the threshold of the secret sharing scheme, an integer 1302 Outputs: 1303 - secret_key_shares, A list of n secret shares, which is a tuple 1304 consisting of the participant identifier and the key share, each of 1305 which is an element of F 1306 - coefficients, a vector of the t coefficients which uniquely determine 1307 a polynomial f. 1309 Errors: 1310 - "invalid parameters", if t > n or if t is less than 2 1312 def secret_share_shard(s, n, t): 1313 if t > n: 1314 raise "invalid parameters" 1315 if t < 2: 1316 raise "invalid parameters" 1318 # Generate random coefficients for the polynomial, yielding 1319 # a polynomial of degree (t - 1) 1320 coefficients = [s] 1321 for i in range(t - 1): 1322 coefficients.append(G.RandomScalar()) 1324 # Evaluate the polynomial for each point x=1,...,n 1325 secret_key_shares = [] 1326 for x_i in range(1, n + 1): 1327 y_i = polynomial_evaluate(x_i, coefficients) 1328 secret_key_share_i = (x_i, y_i) 1329 secret_key_share.append(secret_key_share_i) 1330 return secret_key_shares, coefficients 1332 Let points be the output of this function. The i-th element in 1333 points is the share for the i-th participant, which is the randomly 1334 generated polynomial evaluated at coordinate i. We denote a secret 1335 share as the tuple (i, points[i]), and the list of these shares as 1336 shares. i MUST never equal 0; recall that f(0) = s, where f is the 1337 polynomial defined in a Shamir secret sharing operation. 1339 The procedure for combining a shares list of length t to recover the 1340 secret s is as follows. 1342 secret_share_combine(shares): 1344 Inputs: 1345 - shares, a list of t secret shares, each a tuple (i, f(i)) 1347 Outputs: The resulting secret s, that was previously split into shares 1349 Errors: 1350 - "invalid parameters", if less than t input shares are provided 1352 def secret_share_combine(shares): 1353 if len(shares) < t: 1354 raise "invalid parameters" 1355 s = polynomial_interpolation(shares) 1356 return s 1358 B.2. Verifiable Secret Sharing 1360 Feldman's Verifiable Secret Sharing (VSS) builds upon Shamir secret 1361 sharing, adding a verification step to demonstrate the consistency of 1362 a participant's share with a public commitment to the polynomial f 1363 for which the secret s is the constant term. This check ensure that 1364 all participants have a point (their share) on the same polynomial, 1365 ensuring that they can later reconstruct the correct secret. 1367 The procedure for committing to a polynomial f of degree t-1 is as 1368 follows. 1370 vss_commit(coeffs): 1372 Inputs: 1373 - coeffs, a vector of the t coefficients which uniquely determine 1374 a polynomial f. 1376 Outputs: a commitment vss_commitment, which is a vector commitment to each of the 1377 coefficients in coeffs. 1379 def vss_commit(coeffs): 1380 vss_commitment = [] 1381 for coeff in coeffs: 1382 A_i = G.ScalarBaseMult(coeff) 1383 vss_commitment.append(A_i) 1384 return vss_commitment 1386 The procedure for verification of a participant's share is as 1387 follows. If vss_verify fails, the participant MUST abort the 1388 protocol, and failure should be investigated out of band. 1390 vss_verify(share_i, vss_commitment): 1392 Inputs: 1393 - share_i: A tuple of the form (i, sk_i), where i indicates the participant 1394 identifier, and sk_i the participant's secret key, where sk_i is a secret share of 1395 the constant term of f. 1396 - vss_commitment: A VSS commitment to a secret polynomial f. 1398 Outputs: 1 if sk_i is valid, and 0 otherwise 1400 vss_verify(share_i, commitment) 1401 (i, sk_i) = share_i 1402 S_i = ScalarBaseMult(sk_i) 1403 S_i' = G.Identity() 1404 for j in range(0, THRESHOLD_LIMIT-1): 1405 S_i' += vss_commitment_j * i^j 1406 if S_i == S_i': 1407 return 1 1408 return 0 1410 We now define how the coordinator and signing participants can derive 1411 group info, which is an input into the FROST signing protocol. 1413 derive_group_info(MAX_SIGNERS, THRESHOLD_LIMIT, vss_commitment): 1415 Inputs: 1416 - MAX_SIGNERS, the number of shares to generate, an integer 1417 - THRESHOLD_LIMIT, the threshold of the secret sharing scheme, an integer 1418 - vss_commitment: A VSS commitment to a secret polynomial f. 1420 Outputs: 1421 - PK, the public key representing the group 1422 - 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. 1424 derive_group_info(MAX_SIGNERS, THRESHOLD_LIMIT, vss_commitment) 1425 PK = vss_commitment[0] 1426 signer_public_keys = [] 1427 for i in range(1, MAX_SIGNERS): 1428 PK_i = G.Identity() 1429 for j in range(0, THRESHOLD_LIMIT-1): 1430 PK_i += vss_commitment_j * i^j 1431 signer_public_keys.append(PK_i) 1432 return PK, signer_public_keys 1434 Appendix C. Wire Format 1436 Applications are responsible for encoding protocol messages between 1437 peers. This section contains RECOMMENDED encodings for different 1438 protocol messages as described in Section 5. 1440 C.1. Signing Commitment 1442 A commitment from a signer is a pair of Element values. It can be 1443 encoded in the following manner. 1445 SignerID uint64; 1447 struct { 1448 SignerID id; 1449 opaque D[Ne]; 1450 opaque E[Ne]; 1451 } SigningCommitment; 1453 id The SignerID. 1455 D The commitment hiding factor encoded as a serialized group 1456 element. 1458 E The commitment binding factor encoded as a serialized group 1459 element. 1461 C.2. Signing Packages 1463 The Coordinator sends "signing packages" to each Signer in Round two. 1464 Each package contains the list of signing commitments generated 1465 during round one along with the message to sign. This package can be 1466 encoded in the following manner. 1468 struct { 1469 SigningCommitment signing_commitments<1..2^16-1>; 1470 opaque msg<0..2^16-1>; 1471 } SigningPackage; 1473 signing_commitments An list of SIGNING_COUNT SigningCommitment 1474 values, where THRESHOLD_LIMIT <= SIGNING_COUNT <= NUM_SIGNERS, 1475 ordered in ascending order by SigningCommitment.id. This list 1476 MUST NOT contain more than one SigningCommitment value 1477 corresponding to each signer. Signers MUST ignore SigningPackage 1478 values with duplicate SignerIDs. 1480 msg The message to be signed. 1482 C.3. Signature Share 1484 The output of each signer is a signature share which is sent to the 1485 Coordinator. This can be constructed as follows. 1487 struct { 1488 SignerID id; 1489 opaque signature_share[Ns]; 1490 } SignatureShare; 1492 id The SignerID. 1494 signature_share The signature share from this signer encoded as a 1495 serialized scalar. 1497 Appendix D. Test Vectors 1499 This section contains test vectors for all ciphersuites listed in 1500 Section 6. All Element and Scalar values are represented in 1501 serialized form and encoded in hexadecimal strings. Signatures are 1502 represented as the concatenation of their constituent parts. The 1503 input message to be signed is also encoded as a hexadecimal string. 1505 Each test vector consists of the following information. 1507 * Configuration: This lists the fixed parameters for the particular 1508 instantiation of FROST, including MAX_SIGNERS, THRESHOLD_LIMIT, 1509 and NUM_SIGNERS. 1511 * Group input parameters: This lists the group secret key and shared 1512 public key, generated by a trusted dealer as described in 1513 Appendix B, as well as the input message to be signed. All values 1514 are encoded as hexadecimal strings. 1516 * Signer input parameters: This lists the signing key share for each 1517 of the NUM_SIGNERS signers. 1519 * Round one parameters and outputs: This lists the NUM_SIGNERS 1520 participants engaged in the protocol, identified by their integer 1521 index, the hiding and binding commitment values produced in 1522 Section 5.1, as well as the resulting group binding factor input, 1523 computed in part from the group commitment list encoded as 1524 described in Section 4.3, and group binding factor as computed in 1525 Section 5.2). 1527 * Round two parameters and outputs: This lists the NUM_SIGNERS 1528 participants engaged in the protocol, identified by their integer 1529 index, along with their corresponding output signature share as 1530 produced in Section 5.2. 1532 * Final output: This lists the aggregate signature as produced in 1533 Section 5.3. 1535 D.1. FROST(Ed25519, SHA-512) 1537 // Configuration information 1538 MAX_SIGNERS: 3 1539 THRESHOLD_LIMIT: 2 1540 NUM_SIGNERS: 2 1542 // Group input parameters 1543 group_secret_key: 7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a7 1544 90c6e13a98304 1545 group_public_key: 15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040 1546 d380fb9738673 1547 message: 74657374 1549 // Signer input parameters 1550 S1 signer_share: 929dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033 1551 f2ec83d93509 1552 S2 signer_share: a91e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07ee 1553 d76bf409e80d 1554 S3 signer_share: d3cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8 1555 bdea643a9a02 1557 // Round one parameters 1558 participants: 1,2 1559 group_binding_factor_input: 000178e175d15cb5cec1257e0d84d797ba8c3dd9b 1560 4c7bc50f3fa527c200bcc6c4a954cdad16ae67ac5919159d655b681bd038574383bab 1561 423614f8967396ee12ca62000288a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea98 1562 981bfb25375996c5767c932bbf10c41feb17d41cc6433e69f16cceccc42a00aedf72f 1563 eb5f44929fdf2e2fee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a 1564 5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f500 1565 28a8ff 1566 group_binding_factor: c4d7668d793ff4c6ec424fb493cdab3ef5b625eefffe775 1567 71ff28a345e5f700a 1569 // Signer round one outputs 1570 S1 hiding_nonce: 570f27bfd808ade115a701eeee997a488662bca8c2a073143e66 1571 2318f1ed8308 1572 S1 binding_nonce: 6720f0436bd135fe8dddc3fadd6e0d13dbd58a1981e587d377d 1573 48e0b8f1c3c01 1574 S1 hiding_nonce_commitment: 78e175d15cb5cec1257e0d84d797ba8c3dd9b4c7b 1575 c50f3fa527c200bcc6c4a95 1576 S1 binding_nonce_commitment: 4cdad16ae67ac5919159d655b681bd038574383b 1577 ab423614f8967396ee12ca62 1578 S2 hiding_nonce: 2a67c5e85884d0275a7a740ba8f53617527148418797345071dd 1579 cf1a1bd37206 1580 S2 binding_nonce: a0609158eeb448abe5b0df27f5ece96196df5722c01a999e8a4 1581 5d2d5dfc5620c 1582 S2 hiding_nonce_commitment: 88a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea 1583 98981bfb25375996c5767c9 1584 S2 binding_nonce_commitment: 32bbf10c41feb17d41cc6433e69f16cceccc42a0 1585 0aedf72feb5f44929fdf2e2f 1587 // Round two parameters 1588 participants: 1,2 1590 // Signer round two outputs 1591 S1 sig_share: b7e8f03a1a1149adacb96f952dbc39b6034facceafe4a70d6963592 1592 fce75570c 1593 S2 sig_share: cd388f9aff4376397c5ad231713fe6b167bed9cc88a1cc97b0b6bbe 1594 0316a7909 1596 sig: ebe7efbb42c4b1c55106b5536fb5e9ac7a6d0803ea4ae9c8c629ca51e05c230e 1597 974d8a78fff1ac8e52774a24c00141536b0d869b388674a5191a151000e0d005 1599 D.2. FROST(Ed448, SHAKE256) 1601 // Configuration information 1602 MAX_SIGNERS: 3 1603 THRESHOLD_LIMIT: 2 1604 NUM_SIGNERS: 2 1606 // Group input parameters 1607 group_secret_key: cdf4a803a21d82fa90692e86541e08d878c9f688e5d71a2bd35 1608 4a9a3af62b8c7c89753055949cab8fd044c17c94211f167672b053659420b00 1609 group_public_key: 800e9b495543b04aaebdba2813de65d1aefe78e8b219d38966b 1610 c0afa1d5d9d685c740c8ab720bff3c84cd9f4a701c1588e40d981f4abb19600 1611 message: 74657374 1613 // Signer input parameters 1614 S1 signer_share: d208a2f1d9ead0cc4b4b9b2e84a22f8e2aa2ab4ee715febe7a08 1615 175d4298dd6bbe2e1c0b29aaa972c78555ea3b3d7308b248994780219e0800 1616 S2 signer_share: d71c9bdf11b81f9f062d08d7b3265744dc7a6014e953e15222bc 1617 8416d5cd0210b4c5e410f90a892c91065fbdae37d51ffc29078acae9f90500 1618 S3 signer_share: dc3094cd49856e71c10e757fe3aa7efa8d5315daea91c4e6c96f 1619 f2cf670328b4a95cad16c96b68e65a87689021323737460b75cc14b2550300 1621 // Round one parameters 1622 participants: 1,2 1623 group_binding_factor_input: 00016d8ef55145bab18c129311f1d07bef2110d0b 1624 6841aae919eb6abf5e523d26f819d3695d78f8aa246c6b6d6fd6c2b8a63dd1cf8e8c8 1625 9a870400a0c29f750605b10c52e347fc538af0d4ebddd23a1e0300482a7d98a39d408 1626 356b9041d5fbaa274c2dc3f248601f21cee912e2f5700c1753a80000242c2fdc11e5f 1627 726d4c897ed118f668a27bfb0d5946b5f513e975638b7c4b0a46cf5184d4a9c1f6310 1628 fd3c10f84d9de704a33aab2af976d60804fa4ecba88458bcf7677a3952f540e20556d 1629 5e90d5aa7e8f226d303ef7b88fb33a63f6cac6a9d638089b1739a5d2564d15fb3e43e 1630 1b0b28a80b54ff7255705a71ee2925e4a3e30e41aed489a579d5595e0df13e32e1e4d 1631 d202a7c7f68b31d6418d9845eb4d757adda6ab189e1bb340db818e5b3bc725d992faf 1632 63e9b0500db10517fe09d3f566fba3a80e46a403e0c7d41548fbf75cf2662b00225b5 1633 02961f98d8c9ff937de0b24c231845 1634 group_binding_factor: 2716e157c3da80b65149b1c2cb546723516272ccf75e111 1635 334533e2840a9bf85f3c71478ade11be26d26d8e4b9a1667af88f7df61670f60a00 1637 // Signer round one outputs 1638 S1 hiding_nonce: 04eccfe12348a5a2e4b30e95efcf4e494ce64b89f6504de46b3d 1639 67a5341baaa931e455c57c6c5c81f4895e333da9d71f7d119fcfbd0d7d2000 1640 S1 binding_nonce: 80bcd1b09e82d7d2ff6dd433b0f81e012cadd4661011c44d929 1641 1269cf24820f5c5086d4363dc67450f24ebe560eb4c2059883545d54aa43a00 1642 S1 hiding_nonce_commitment: 6d8ef55145bab18c129311f1d07bef2110d0b6841 1643 aae919eb6abf5e523d26f819d3695d78f8aa246c6b6d6fd6c2b8a63dd1cf8e8c89a87 1644 0400 1645 S1 binding_nonce_commitment: a0c29f750605b10c52e347fc538af0d4ebddd23a 1646 1e0300482a7d98a39d408356b9041d5fbaa274c2dc3f248601f21cee912e2f5700c17 1647 53a80 1648 S2 hiding_nonce: 3b3bbe82babf2a67ded81b308ba45f73b88f6cf3f6aaa4442256 1649 b7a0354d1567478cfde0a2bba98ba4c3e65645e1b77386eb4063f925e00700 1650 S2 binding_nonce: bcbd112a88bebf463e3509076c5ef280304cb4f1b3a7499cca1 1651 d5e282cc2010a92ff56a3bdcf5ba352e0f4241ba2e54c1431a895c19fff0600 1652 S2 hiding_nonce_commitment: 42c2fdc11e5f726d4c897ed118f668a27bfb0d594 1653 6b5f513e975638b7c4b0a46cf5184d4a9c1f6310fd3c10f84d9de704a33aab2af976d 1654 6080 1655 S2 binding_nonce_commitment: 4fa4ecba88458bcf7677a3952f540e20556d5e90 1656 d5aa7e8f226d303ef7b88fb33a63f6cac6a9d638089b1739a5d2564d15fb3e43e1b0b 1657 28a80 1659 // Round two parameters 1660 participants: 1,2 1662 // Signer round two outputs 1663 S1 sig_share: c5ab0a80c561d1a616ac70f4f13d993156f65f2b44a4a90f37f0640 1664 7a1b62e3940bf14199301d128358b812bef32cb4bffaf03030238772000 1665 S2 sig_share: 15211cb96d6aa73de803d46caf2043859fd796a6282f9adb00033f1 1666 4f4827f23f8cc792c2e322a1f30631ec7690ac587e5eb9c2afd323e3300 1668 sig: 4d9883057726b029d042418600abe88ad3fec06d6a48dca289482e9d51c10353 1669 37e4d1aae5fd1c73a55701133238602f423886fc134a3c6580e787ce8da00900c1a92 1670 07fd32e9c6f956597202323f8f4264ecfd99e9539ae5c388c8e45c133fb4765ee9ff2 1671 583d90d3e49ba02dff6ab51300 1673 D.3. FROST(ristretto255, SHA-512) 1675 // Configuration information 1676 MAX_SIGNERS: 3 1677 THRESHOLD_LIMIT: 2 1678 NUM_SIGNERS: 2 1680 // Group input parameters 1681 group_secret_key: b020be204b5e758960458ca9c4675b56b12a8faff2be9c94891 1682 d5e1cd75c880e 1683 group_public_key: e22ac4850672021eac8e0a36dfc4811466fb01108c3427d2347 1684 827467ba02a34 1685 message: 74657374 1687 // Signer input parameters 1688 S1 signer_share: 92ae65bb90030a89507fa00fff08dfed841cf996de5a0c574f1f 1689 4693ddcb6705 1690 S2 signer_share: 611003b3f00bb1e01656ac1818a4419a580e637ecaf67b191521 1691 2e0ae43a470c 1692 S3 signer_share: 439eaa4d36b145e00690c07e5245c5312c00cd65b692ebdbda22 1693 1681eaa92603 1695 // Round one parameters 1696 participants: 1,2 1697 group_binding_factor_input: 0001824e9eddddf02b2a9caf5859825e999d791ca 1698 094f65b814a8bca6013d9cc312774c7e1271d2939a84a9a867e3a06579b4d25659b42 1699 7439ccf0d745b43f75b76600028013834ff4d48e7d6b76c2e732bc611f54720ef8933 1700 c4ca4de7eaaa77ff5cd125e056ecc4f7c4657d3a742354430d768f945db229c335d25 1701 8e9622ad99f3e7582d07b35bd9849ce4af6ad403090d69a7d0eb88bba669a9f985175 1702 d70cd15ad5f1ef5b734c98a32b4aab7b43a57e93fc09281f2e7a207076b31e416ba63 1703 f53d9d 1704 group_binding_factor: f00ae6007f2d74a1507c962cf30006be77596106db28f2d 1705 5443fd66d755e780c 1707 // Signer round one outputs 1708 S1 hiding_nonce: 349b3bb8464a1d87f7d6b56f4559a3f9a6335261a3266089a9b1 1709 2d9d6f6ce209 1710 S1 binding_nonce: ce7406016a854be4291f03e7d24fe30e77994c3465de031515a 1711 4c116f22ca901 1712 S1 hiding_nonce_commitment: 824e9eddddf02b2a9caf5859825e999d791ca094f 1713 65b814a8bca6013d9cc3127 1714 S1 binding_nonce_commitment: 74c7e1271d2939a84a9a867e3a06579b4d25659b 1715 427439ccf0d745b43f75b766 1716 S2 hiding_nonce: 4d66d319f20a728ec3d491cbf260cc6be687bd87cc2b5fdb4d5f 1717 528f65fd650d 1718 S2 binding_nonce: 278b9b1e04632e6af3f1a3c144d07922ffcf5efd3a341b47abc 1719 19c43f48ce306 1720 S2 hiding_nonce_commitment: 8013834ff4d48e7d6b76c2e732bc611f54720ef89 1721 33c4ca4de7eaaa77ff5cd12 1722 S2 binding_nonce_commitment: 5e056ecc4f7c4657d3a742354430d768f945db22 1723 9c335d258e9622ad99f3e758 1725 // Round two parameters 1726 participants: 1,2 1728 // Signer round two outputs 1729 S1 sig_share: 6a539c3a4ee281879a6fb350d20d53e17473f28cd3409ffc238dafe 1730 8d9330605 1731 S2 sig_share: 1d4e59636ee089bfaf548834b07658216649a37f87f0818d5190aa9 1732 b90957505 1734 sig: 7e92309bf40993141acd5f2c7680a302cc5aa5dd291a833906da8e35bc39b03e 1735 87a1f59dbcc20b474ac43b858284ab02dbbc950c5b31218a751d5a846ac97b0a 1737 D.4. FROST(P-256, SHA-256) 1739 // Configuration information 1740 MAX_SIGNERS: 3 1741 THRESHOLD_LIMIT: 2 1742 NUM_SIGNERS: 2 1744 // Group input parameters 1745 group_secret_key: 6f090d1393ff53bbcbba036c00b8830ab4546c251dece199eb0 1746 3a6a51a5a5928 1747 group_public_key: 033a2a83f9c9fdfdab7d620f48238a5e6157a8eb1d6c382c7b0 1748 ba95b7c9f69679c 1749 message: 74657374 1751 // Signer input parameters 1752 S1 signer_share: 738552e18ea4f2090597aca6c23c1666845c21c676813f9e2678 1753 6f1e410dcecd 1754 S2 signer_share: 780198af894a90563f7555e183bfa9c25463d767cf159da261ed 1755 379767c14472 1756 S3 signer_share: 7c7dde7d83f02ea37952ff1c45433d1e246b8d0927a9fba69d62 1757 00108e74ba17 1759 // Round one parameters 1760 participants: 1,2 1761 group_binding_factor_input: 000102f34caab210d59324e12ba41f0802d9545f7 1762 f702906930766b86c462bb8ff7f3402b724640ea9e262469f401c9006991ba3247c2c 1763 91b97cdb1f0eeab1a777e24e1e0002037f8a998dfc2e60a7ad63bc987cb27b8abf78a 1764 68bd924ec6adb9f251850cbe711024a4e90422a19dd8463214e997042206c39d3df56 1765 168b458592462090c89dbcf84efca0c54f70a585d6aae28679482b4aed03ae5d38297 1766 b9092ab3376d46fdf55 1767 group_binding_factor: 9df349a9f34bf01627f6b4f8b376e8c8261d55508d1cac2 1768 919cdaf7f9cb20e70 1770 // Signer round one outputs 1771 S1 hiding_nonce: 3da92a503cf7e3f72f62dabedbb3ffcc9f555f1c1e78527940fe 1772 3fed6d45e56f 1773 S1 binding_nonce: ec97c41fc77ae7e795067976b2edd8b679f792abb062e4d0c33 1774 f0f37d2e363eb 1775 S1 hiding_nonce_commitment: 02f34caab210d59324e12ba41f0802d9545f7f702 1776 906930766b86c462bb8ff7f34 1777 S1 binding_nonce_commitment: 02b724640ea9e262469f401c9006991ba3247c2c 1778 91b97cdb1f0eeab1a777e24e1e 1779 S2 hiding_nonce: 06cb4425031e695d1f8ac61320717d63918d3edc7a02fcd3f23a 1780 de47532b1fd9 1781 S2 binding_nonce: 2d965a4ea73115b8065c98c1d95c7085db247168012a834d828 1782 5a7c02f11e3e0 1783 S2 hiding_nonce_commitment: 037f8a998dfc2e60a7ad63bc987cb27b8abf78a68 1784 bd924ec6adb9f251850cbe711 1785 S2 binding_nonce_commitment: 024a4e90422a19dd8463214e997042206c39d3df 1786 56168b458592462090c89dbcf8 1788 // Round two parameters 1789 participants: 1,2 1791 // Signer round two outputs 1792 S1 sig_share: 0a658fe198caddf5ddc407ad58c4615458f02a58d0c1f7a38e25692 1793 98dc41df0 1794 S2 sig_share: e84d948cfec74b5e7540ad09fd69dcd1570f708f2d8573dbbf08cb0 1795 2bc872c75 1797 sig: 035cfbd148da711bbc823455b682ed01a1be3c5415cf692f4a91b7fe22d1dec3 1798 45f2b3246e979229545304b4b7562e3e25afff9ae7fe476b7f4d2e342c4a4b4a65 1800 Authors' Addresses 1802 Deirdre Connolly 1803 Zcash Foundation 1804 Email: durumcrustulum@gmail.com 1806 Chelsea Komlo 1807 University of Waterloo, Zcash Foundation 1808 Email: ckomlo@uwaterloo.ca 1810 Ian Goldberg 1811 University of Waterloo 1812 Email: iang@uwaterloo.ca 1813 Christopher A. Wood 1814 Cloudflare 1815 Email: caw@heapingbits.net