<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.16 (Ruby 3.1.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-frost-08" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.14.0 -->
  <front>
    <title abbrev="FROST">Two-Round Threshold Schnorr Signatures with FROST</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-frost-08"/>
    <author initials="D." surname="Connolly" fullname="Deirdre Connolly">
      <organization>Zcash Foundation</organization>
      <address>
        <email>durumcrustulum@gmail.com</email>
      </address>
    </author>
    <author initials="C." surname="Komlo" fullname="Chelsea Komlo">
      <organization>University of Waterloo, Zcash Foundation</organization>
      <address>
        <email>ckomlo@uwaterloo.ca</email>
      </address>
    </author>
    <author initials="I." surname="Goldberg" fullname="Ian Goldberg">
      <organization>University of Waterloo</organization>
      <address>
        <email>iang@uwaterloo.ca</email>
      </address>
    </author>
    <author initials="C. A." surname="Wood" fullname="Christopher A. Wood">
      <organization>Cloudflare</organization>
      <address>
        <email>caw@heapingbits.net</email>
      </address>
    </author>
    <date year="2022" month="August" day="19"/>
    <area>General</area>
    <workgroup>CFRG</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <t>In this draft, we present the two-round signing variant of FROST, a Flexible Round-Optimized
Schnorr Threshold signature scheme. FROST signatures can be issued after a threshold number
of entities cooperate to issue a signature, allowing for improved distribution of trust and
redundancy with respect to a secret key. Further, this draft specifies signatures that are
compatible with <xref target="RFC8032"/>. However, unlike <xref target="RFC8032"/>, the protocol for producing
signatures in this draft is not deterministic, so as to ensure protection against a
key-recovery attack that is possible when even only one participant is malicious.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
    Crypto Forum Research Group mailing list (cfrg@ietf.org),
    which is archived at <eref target="https://mailarchive.ietf.org/arch/search/?email_list=cfrg"/>.</t>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/cfrg/draft-irtf-cfrg-frost"/>.</t>
    </note>
  </front>
  <middle>
    <section anchor="introduction">
      <name>Introduction</name>
      <t>DISCLAIMER: This is a work-in-progress draft of FROST.</t>
      <t>RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for this draft is
maintained in GitHub. Suggested changes should be submitted as pull requests
at https://github.com/cfrg/draft-irtf-cfrg-frost. Instructions are on that page as
well.</t>
      <t>Unlike signatures in a single-party setting, threshold signatures
require cooperation among a threshold number of signers each holding a share
of a common private key. The security of threshold schemes in general assume
that an adversary can corrupt strictly fewer than a threshold number of participants.</t>
      <t>This document presents a variant of a Flexible Round-Optimized Schnorr Threshold (FROST)
signature scheme originally defined in <xref target="FROST20"/>. FROST reduces network overhead during
threshold signing operations while employing a novel technique to protect against forgery
attacks applicable to prior Schnorr-based threshold signature constructions. The variant of
FROST presented in this document requires two rounds to compute a signature. Single-round
signing with FROST is out of scope.</t>
      <t>For select ciphersuites, the signatures produced by this draft are compatible with
<xref target="RFC8032"/>. However, unlike <xref target="RFC8032"/>, signatures produced by FROST are not
deterministic, since deriving nonces deterministically allows for a complete key-recovery
attack in multi-party discrete logarithm-based signatures, such as FROST.</t>
      <t>While an optimization to FROST was shown in <xref target="Schnorr21"/> that reduces scalar multiplications
from linear in the number of signers to constant, this draft does not specify that optimization
due to the malleability that this optimization introduces, as shown in <xref target="StrongerSec22"/>.
Specifically, this optimization removes the guarantee that the set of signers that started
round one of the protocol is the same set of signers that produced the signature output by
round two.</t>
      <t>Key generation for FROST signing is out of scope for this document. However, for completeness,
key generation with a trusted dealer is specified in <xref target="dep-dealer"/>.</t>
      <section anchor="change-log">
        <name>Change Log</name>
        <t>draft-08</t>
        <ul spacing="normal">
          <li>Add notation for Scalar multiplication (#237)</li>
          <li>Add secp2561k1 ciphersuite (#223)</li>
          <li>Remove RandomScalar implementation details (#231)</li>
          <li>Add domain separation for message and commitment digests (#228)</li>
        </ul>
        <t>draft-07</t>
        <ul spacing="normal">
          <li>Fix bug in per-rho signer computation (#222)</li>
        </ul>
        <t>draft-06</t>
        <ul spacing="normal">
          <li>Make verification a per-ciphersuite functionality (#219)</li>
          <li>Use per-signer values of rho to mitigate protocol malleability (#217)</li>
          <li>Correct prime-order subgroup checks (#215, #211)</li>
          <li>Fix bug in ed25519 ciphersuite description (#205)</li>
          <li>Various editorial improvements (#208, #209, #210, #218)</li>
        </ul>
        <t>draft-05</t>
        <ul spacing="normal">
          <li>Update test vectors to include version string (#202, #203)</li>
          <li>Rename THRESHOLD_LIMIT to MIN_SIGNERS (#192)</li>
          <li>Use non-contiguous signers for the test vectors (#187)</li>
          <li>Add more reasoning why the coordinator MUST abort (#183)</li>
          <li>Add a function to generate nonces (#182)</li>
          <li>Add MUST that all participants have the same view of VSS commitment (#174)</li>
          <li>Use THRESHOLD_LIMIT instead of t and MAX_SIGNERS instead of n (#171)</li>
          <li>Specify what the dealer is trusted to do (#166)</li>
          <li>Clarify types of NUM_SIGNERS and THRESHOLD_LIMIT (#165)</li>
          <li>Assert that the network channel used for signing should be authenticated (#163)</li>
          <li>Remove wire format section (#156)</li>
          <li>Update group commitment derivation to have a single scalarmul (#150)</li>
          <li>Use RandomNonzeroScalar for single-party Schnorr example (#148)</li>
          <li>Fix group notation and clarify member functions (#145)</li>
          <li>Update existing implementations table (#136)</li>
          <li>Various editorial improvements (#135, #143, #147, #149, #153, #158, #162, #167, #168, #169, #170, #175, #176, #177, #178, #184, #186, #193, #198, #199)</li>
        </ul>
        <t>draft-04</t>
        <ul spacing="normal">
          <li>Added methods to verify VSS commitments and derive group info (#126, #132).</li>
          <li>Changed check for participants to consider only nonnegative numbers (#133).</li>
          <li>Changed sampling for secrets and coefficients to allow the zero element (#130).</li>
          <li>Split test vectors into separate files (#129)</li>
          <li>Update wire structs to remove commitment shares where not necessary (#128)</li>
          <li>Add failure checks (#127)</li>
          <li>Update group info to include each participant's key and clarify how public key material is obtained (#120, #121).</li>
          <li>Define cofactor checks for verification (#118)</li>
          <li>Various editorial improvements and add contributors (#124, #123, #119, #116, #113, #109)</li>
        </ul>
        <t>draft-03</t>
        <ul spacing="normal">
          <li>Refactor the second round to use state from the first round (#94).</li>
          <li>Ensure that verification of signature shares from the second round uses commitments from the first round (#94).</li>
          <li>Clarify RFC8032 interoperability based on PureEdDSA (#86).</li>
          <li>Specify signature serialization based on element and scalar serialization (#85).</li>
          <li>Fix hash function domain separation formatting (#83).</li>
          <li>Make trusted dealer key generation deterministic (#104).</li>
          <li>Add additional constraints on participant indexes and nonce usage (#105, #103, #98, #97).</li>
          <li>Apply various editorial improvements.</li>
        </ul>
        <t>draft-02</t>
        <ul spacing="normal">
          <li>Fully specify both rounds of FROST, as well as trusted dealer key generation.</li>
          <li>Add ciphersuites and corresponding test vectors, including suites for RFC8032 compatibility.</li>
          <li>Refactor document for editorial clarity.</li>
        </ul>
        <t>draft-01</t>
        <ul spacing="normal">
          <li>Specify operations, notation and cryptographic dependencies.</li>
        </ul>
        <t>draft-00</t>
        <ul spacing="normal">
          <li>Outline CFRG draft based on draft-komlo-frost.</li>
        </ul>
      </section>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
"MAY", and "OPTIONAL" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <t>The following terminology is used throughout this document.</t>
      <ul spacing="normal">
        <li>A participant is an entity that is trusted to hold and use a signing key share.</li>
        <li>
          <tt>MAX_SIGNERS</tt> denotes the number of participants, and the number of shares that <tt>s</tt> is split into. This value MUST NOT exceed 2^16-1.</li>
        <li>
          <tt>MIN_SIGNERS</tt> denotes the threshold number of participants required to issue a signature, where MIN_SIGNERS &lt;= MAX_SIGNERS.</li>
        <li>
          <tt>NUM_SIGNERS</tt> denotes the number of signers that participate in an invocation of FROST signing, where
MIN_SIGNERS &lt;= NUM_SIGNERS &lt;= MAX_SIGNERS.</li>
        <li>An identifier is an integer value associated with a participant, or signer,
and is a value in the range [1, MAX_SIGNERS].</li>
      </ul>
      <t>Additionally, the following notation is used throughout the document.</t>
      <ul spacing="normal">
        <li>
          <tt>encode_uint16(x)</tt>: Convert two byte unsigned integer (uint16) <tt>x</tt> to a 2-byte,
big-endian byte string. For example, <tt>encode_uint16(310) = [0x01, 0x36]</tt>.</li>
        <li>
          <tt>random_bytes(n)</tt>: Outputs <tt>n</tt> bytes, sampled uniformly at random
using a cryptographically secure pseudorandom number generator (CSPRNG).</li>
        <li>
          <tt>len(l)</tt>: Outputs the length of input list <tt>l</tt>, e.g., <tt>len([1,2,3]) = 3)</tt>.</li>
        <li>
          <tt>reverse(l)</tt>: Outputs the list <tt>l</tt> in reverse order, e.g., <tt>reverse([1,2,3]) = [3,2,1]</tt>.</li>
        <li>
          <tt>range(a, b)</tt>: Outputs a list of integers from <tt>a</tt> to <tt>b-1</tt> in ascending order, e.g., <tt>range(1, 4) = [1,2,3]</tt>.</li>
        <li>
          <tt>pow(a, b)</tt>: Output the integer result of <tt>a</tt> to the power of <tt>b</tt>, e.g., <tt>pow(2, 3) = 8</tt>.</li>
        <li>|| denotes concatenation, i.e., x || y = xy.</li>
        <li>nil denotes an empty byte string.</li>
      </ul>
      <t>Unless otherwise stated, we assume that secrets are sampled uniformly at random
using a cryptographically secure pseudorandom number generator (CSPRNG); see
<xref target="RFC4086"/> for additional guidance on the generation of random numbers.</t>
    </section>
    <section anchor="cryptographic-dependencies">
      <name>Cryptographic Dependencies</name>
      <t>FROST signing depends on the following cryptographic constructs:</t>
      <ul spacing="normal">
        <li>Prime-order Group, <xref target="dep-pog"/>;</li>
        <li>Cryptographic hash function, <xref target="dep-hash"/>;</li>
      </ul>
      <t>These are described in the following sections.</t>
      <section anchor="dep-pog">
        <name>Prime-Order Group</name>
        <t>FROST depends on an abelian group of prime order <tt>p</tt>. We represent this
group as the object <tt>G</tt> that additionally defines helper functions described below. The group operation
for <tt>G</tt> is addition <tt>+</tt> with identity element <tt>I</tt>. For any elements <tt>A</tt> and <tt>B</tt> of the group <tt>G</tt>,
<tt>A + B = B + A</tt> is also a member of <tt>G</tt>. Also, for any <tt>A</tt> in <tt>G</tt>, there exists an element
<tt>-A</tt> such that <tt>A + (-A) = (-A) + A = I</tt>. For convenience, we use <tt>-</tt> to denote
subtraction, e.g., <tt>A - B = A + (-B)</tt>. Scalar multiplication is equivalent to the repeated
application of the group operation on an element <tt>A</tt> with itself <tt>r-1</tt> times, denoted as
<tt>ScalarBaseMult(A, r)</tt>. We denote the sum, difference, and product of two scalars using the <tt>+</tt>, <tt>-</tt>,
and <tt>*</tt> operators, respectively. (Note that this means <tt>+</tt> may refer to group element addition or
scalar addition, depending on types of the operands.) For any element <tt>A</tt>, <tt>ScalarBaseMult(A, p) = I</tt>.
We denote <tt>B</tt> as a fixed generator of the group. Scalar base multiplication is equivalent to the repeated application
of the group operation <tt>B</tt> with itself <tt>r-1</tt> times, this is denoted as <tt>ScalarBaseMult(r)</tt>. The set of
scalars corresponds to <tt>GF(p)</tt>, which we refer to as the scalar field. This document uses types
<tt>Element</tt> and <tt>Scalar</tt> to denote elements of the group <tt>G</tt> and its set of scalars, respectively.
We denote Scalar(x) as the conversion of integer input <tt>x</tt> to the corresponding Scalar value with
the same numeric value. For example, Scalar(1) yields a Scalar representing the value 1.
We denote equality comparison as <tt>==</tt> and assignment of values by <tt>=</tt>.</t>
        <t>We now detail a number of member functions that can be invoked on <tt>G</tt>.</t>
        <ul spacing="normal">
          <li>Order(): Outputs the order of <tt>G</tt> (i.e. <tt>p</tt>).</li>
          <li>Identity(): Outputs the identity <tt>Element</tt> of the group (i.e. <tt>I</tt>).</li>
          <li>RandomScalar(): Outputs a random <tt>Scalar</tt> element in GF(p).</li>
          <li>ScalarMult(A, k): Output the scalar multiplication between Element <tt>A</tt> and Scalar <tt>k</tt>.</li>
          <li>ScalarBaseMult(A): Output the scalar multiplication between Element <tt>A</tt> and the group generator <tt>B</tt>.</li>
          <li>SerializeElement(A): Maps an <tt>Element</tt> <tt>A</tt> to a unique byte array <tt>buf</tt> of fixed length <tt>Ne</tt>.</li>
          <li>DeserializeElement(buf): Attempts to map a byte array <tt>buf</tt> to an <tt>Element</tt> <tt>A</tt>,
and fails if the input is not a valid byte representation of an element of
the group. This function can raise a DeserializeError if deserialization fails
or <tt>A</tt> is the identity element of the group; see <xref target="ciphersuites"/> for group-specific
input validation steps.</li>
          <li>SerializeScalar(s): Maps a Scalar <tt>s</tt> to a unique byte array <tt>buf</tt> of fixed length <tt>Ns</tt>.</li>
          <li>DeserializeScalar(buf): Attempts to map a byte array <tt>buf</tt> to a <tt>Scalar</tt> <tt>s</tt>.
This function can raise a DeserializeError if deserialization fails; see
<xref target="ciphersuites"/> for group-specific input validation steps.</li>
        </ul>
      </section>
      <section anchor="dep-hash">
        <name>Cryptographic Hash Function</name>
        <t>FROST requires the use of a cryptographically secure hash function, generically
written as H, which functions effectively as a random oracle. For concrete
recommendations on hash functions which SHOULD be used in practice, see
<xref target="ciphersuites"/>. Using H, we introduce separate domain-separated hashes,
H1, H2, H3, H4, and H5:</t>
        <ul spacing="normal">
          <li>H1, H2, and H3 map arbitrary byte strings to Scalar elements of the prime-order group scalar field.</li>
          <li>H4 and H5 are aliases for H with distinct domain separators.</li>
        </ul>
        <t>The details of H1, H2, H3, H4, and H5 vary based on ciphersuite. See <xref target="ciphersuites"/>
for more details about each.</t>
      </section>
    </section>
    <section anchor="helpers">
      <name>Helper functions</name>
      <t>Beyond the core dependencies, the protocol in this document depends on the
following helper operations:</t>
      <ul spacing="normal">
        <li>Nonce generation, <xref target="dep-nonces"/></li>
        <li>Polynomial operations, <xref target="dep-polynomial"/>;</li>
        <li>Encoding operations, <xref target="dep-encoding"/>;</li>
        <li>Signature binding <xref target="dep-binding-factor"/>, group commitment <xref target="dep-group-commit"/>, and challenge computation <xref target="dep-sig-challenge"/></li>
      </ul>
      <t>These sections describes these operations in more detail.</t>
      <section anchor="dep-nonces">
        <name>Nonce generation</name>
        <t>To hedge against a bad RNG that outputs predictable values, we generate
nonces by sourcing fresh randomness and combine with the secret key,
to create a domain-separated hash function from the ciphersuite hash
function <tt>H</tt>, <tt>H3</tt>:</t>
        <artwork><![CDATA[
  nonce_generate(secret):

  Inputs:
  - secret, a Scalar

  Outputs: nonce, a Scalar

  def nonce_generate(secret):
    k_enc = random_bytes(32)
    secret_enc = G.SerializeScalar(secret)
    return H3(k_enc || secret_enc)
]]></artwork>
      </section>
      <section anchor="dep-polynomial">
        <name>Polynomial Operations</name>
        <t>This section describes operations on and associated with polynomials over Scalars
that are used in the main signing protocol. A polynomial of maximum degree t
is represented as a list of t coefficients, where the constant term of the polynomial
is in the first position and the highest-degree coefficient is in the last position.
A point on the polynomial is a tuple (x, y), where <tt>y = f(x)</tt>. For notational
convenience, we refer to the x-coordinate and y-coordinate of a
point p as <tt>p.x</tt> and <tt>p.y</tt>, respectively.</t>
        <section anchor="evaluation-of-a-polynomial">
          <name>Evaluation of a polynomial</name>
          <t>This section describes a method for evaluating a polynomial <tt>f</tt> at a
particular input <tt>x</tt>, i.e., <tt>y = f(x)</tt> using Horner's method.</t>
          <artwork><![CDATA[
  polynomial_evaluate(x, coeffs):

  Inputs:
  - x, input at which to evaluate the polynomial, a Scalar
  - coeffs, the polynomial coefficients, a list of Scalars

  Outputs: Scalar result of the polynomial evaluated at input x

  def polynomial_evaluate(x, coeffs):
    value = 0
    for coeff in reverse(coeffs):
      value *= x
      value += coeff
    return value
]]></artwork>
        </section>
        <section anchor="lagrange-coefficients">
          <name>Lagrange coefficients</name>
          <t>The function <tt>derive_lagrange_coefficient</tt> derives a Lagrange coefficient
to later perform polynomial interpolation, and is provided a list of x-coordinates
as input. Note that <tt>derive_lagrange_coefficient</tt> does not permit any x-coordinate
to equal 0. Lagrange coefficients are used in FROST to evaluate a polynomial <tt>f</tt>
at x-coordinate 0, i.e., <tt>f(0)</tt>, given a list of <tt>t</tt> other x-coordinates.</t>
          <artwork><![CDATA[
  derive_lagrange_coefficient(x_i, L):

  Inputs:
  - x_i, an x-coordinate contained in L, a Scalar
  - L, the set of x-coordinates, each a Scalar

  Outputs: L_i, the i-th Lagrange coefficient

  Errors:
  - "invalid parameters", if any x-coordinate is equal to 0 or if x_i
    is not in L

  def derive_lagrange_coefficient(x_i, L):
    if x_i == 0:
      raise "invalid parameters"
    for x_j in L:
      if x_j == 0:
        raise "invalid parameters"
    if x_i not in L:
      raise "invalid parameters"

    numerator = Scalar(1)
    denominator = Scalar(1)
    for x_j in L:
      if x_j == x_i: continue
      numerator *= x_j
      denominator *= x_j - x_i

    L_i = numerator / denominator
    return L_i
]]></artwork>
        </section>
        <section anchor="deriving-the-constant-term-of-a-polynomial">
          <name>Deriving the constant term of a polynomial</name>
          <t>Secret sharing requires "splitting" a secret, which is represented as
a constant term of some polynomial <tt>f</tt> of degree <tt>t-1</tt>. Recovering the
constant term occurs with a set of <tt>t</tt> points using polynomial
interpolation, defined as follows.</t>
          <artwork><![CDATA[
  Inputs:
  - points, a set of t points on a polynomial f, each a tuple of two
    Scalar values representing the x and y coordinates

  Outputs: The constant term of f, i.e., f(0)

  def polynomial_interpolation(points):
    L = []
    for point in points:
      L.append(point.x)

    f_zero = Scalar(0)
    for point in points:
      delta = point.y * derive_lagrange_coefficient(point.x, L)
      f_zero = f_zero + delta

    return f_zero
]]></artwork>
        </section>
      </section>
      <section anchor="dep-encoding">
        <name>List Operations</name>
        <t>This section describes helper functions that work on lists of values produced
during the FROST protocol. The following function encodes a list of signer
commitments into a bytestring for use in the FROST protocol.</t>
        <artwork><![CDATA[
  Inputs:
  - commitment_list = [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...],
    a list of commitments issued by each signer, where each element in the list
    indicates the signer identifier i and their two commitment Element values
    (hiding_nonce_commitment_i, binding_nonce_commitment_i). This list MUST be sorted
    in ascending order by signer identifier.

  Outputs: A byte string containing the serialized representation of commitment_list

  def encode_group_commitment_list(commitment_list):
    encoded_group_commitment = nil
    for (identifier, hiding_nonce_commitment, binding_nonce_commitment) in commitment_list:
      encoded_commitment = encode_uint16(identifier) ||
                           G.SerializeElement(hiding_nonce_commitment) ||
                           G.SerializeElement(binding_nonce_commitment)
      encoded_group_commitment = encoded_group_commitment || encoded_commitment
    return encoded_group_commitment
]]></artwork>
        <t>The following function is used to extract participant identifiers from a commitment
list.</t>
        <artwork><![CDATA[
  Inputs:
  - commitment_list = [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...],
    a list of commitments issued by each signer, where each element in the list
    indicates the signer identifier i and their two commitment Element values
    (hiding_nonce_commitment_i, binding_nonce_commitment_i). This list MUST be sorted
    in ascending order by signer identifier.

  Outputs: A list of signer participant identifiers

def participants_from_commitment_list(commitment_list):
  identifiers = []
  for (identifier, _, _) in commitment_list:
    identifiers.append(identifier)
  return identifiers
]]></artwork>
        <t>The following function is used to extract a binding factor from a list of binding factors.</t>
        <artwork><![CDATA[
  Inputs:
  - binding_factor_list = [(i, binding_factor), ...],
    a list of binding factors for each signer, where each element in the list
    indicates the signer identifier i and their binding factor. This list MUST be sorted
    in ascending order by signer identifier.
  - identifier, Identifier i of the signer.

  Outputs: A Scalar value.

  Errors: "invalid participant", when the designated participant is not known

def binding_factor_for_participant(binding_factor_list, identifier):
  binding_factors = []
  for (i, binding_factor) in commitment_list:
    if identifier == i:
      return binding_factor
  raise "invalid participant"
]]></artwork>
      </section>
      <section anchor="dep-binding-factor">
        <name>Binding Factors Computation</name>
        <t>This section describes the subroutine for computing binding factors based
on the signer commitment list and message to be signed.</t>
        <artwork><![CDATA[
  Inputs:
  - commitment_list = [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...],
    a list of commitments issued by each signer, where each element in the list
    indicates the signer identifier i and their two commitment Element values
    (hiding_nonce_commitment_i, binding_nonce_commitment_i). This list MUST be sorted
    in ascending order by signer identifier.
  - msg, the message to be signed.

  Outputs: A list of (identifier, Scalar) tuples representing the binding factors.

  def compute_binding_factors(commitment_list, msg):
    msg_hash = H4(msg)
    encoded_commitment_hash = H5(encode_group_commitment_list(commitment_list))
    rho_input_prefix = msg_hash || encoded_commitment_hash

    binding_factor_list = []
    for (identifier, hiding_nonce_commitment, binding_nonce_commitment) in commitment_list:
      rho_input = rho_input_prefix || encode_uint16(identifier)
      binding_factor = H1(rho_input)
      binding_factor_list.append((identifier, binding_factor))
    return binding_factor_list
]]></artwork>
      </section>
      <section anchor="dep-group-commit">
        <name>Group Commitment Computation</name>
        <t>This section describes the subroutine for creating the group commitment
from a commitment list.</t>
        <artwork><![CDATA[
  Inputs:
  - commitment_list =
     [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...], a list
    of commitments issued by each signer, where each element in the list
    indicates the signer identifier i and their two commitment Element values
    (hiding_nonce_commitment_i, binding_nonce_commitment_i). This list MUST be
    sorted in ascending order by signer identifier.
  - binding_factor_list = [(i, binding_factor), ...],
    a list of (identifier, Scalar) tuples representing the binding factor Scalar
    for the given identifier. This list MUST be sorted in ascending order by identifier.

  Outputs: An Element in G representing the group commitment

  def compute_group_commitment(commitment_list, binding_factor_list):
    group_commitment = G.Identity()
    for (identifier, hiding_nonce_commitment, binding_nonce_commitment) in commitment_list:
      binding_factor = binding_factor_for_participant(binding_factors, identifier)
      group_commitment = group_commitment +
        hiding_nonce_commitment + G.ScalarMult(binding_nonce_commitment, binding_factor)
    return group_commitment
]]></artwork>
      </section>
      <section anchor="dep-sig-challenge">
        <name>Signature Challenge Computation</name>
        <t>This section describes the subroutine for creating the per-message challenge.</t>
        <artwork><![CDATA[
  Inputs:
  - group_commitment, an Element in G representing the group commitment
  - group_public_key, public key corresponding to the group signing key, an
    Element in G.
  - msg, the message to be signed.

  Outputs: A Scalar representing the challenge

  def compute_challenge(group_commitment, group_public_key, msg):
    group_comm_enc = G.SerializeElement(group_commitment)
    group_public_key_enc = G.SerializeElement(group_public_key)
    challenge_input = group_comm_enc || group_public_key_enc || msg
    challenge = H2(challenge_input)
    return challenge
]]></artwork>
      </section>
    </section>
    <section anchor="frost-spec">
      <name>Two-Round FROST Signing Protocol</name>
      <t>We now present the two-round variant of the FROST threshold signature protocol for producing Schnorr signatures.
It involves signer participants and a Coordinator. Signer participants are
entities with signing key shares that participate in the threshold signing
protocol. The Coordinator is an entity with the following responsibilities:</t>
      <ol spacing="normal" type="1"><li>Determining which signers will participate (at least MIN_SIGNERS in number);</li>
        <li>Coordinating rounds (receiving and forwarding inputs among participants); and</li>
        <li>Aggregating signature shares output by each participant, and publishing the resulting signature.</li>
      </ol>
      <t>FROST assumes the selection of all participants, including Coordinator and set of
signers, are all chosen external to the protocol. Note that it is possible to
deploy the protocol without a distinguished Coordinator; see <xref target="no-coordinator"/>
for more information.</t>
      <t>Because key generation is not specified, all signers are assumed to have the
(public) group state that we refer to as "group info" below, and their corresponding
signing key shares.</t>
      <t>In particular, it is assumed that the Coordinator and each signer participant <tt>P_i</tt> knows the following
group info:</t>
      <ul spacing="normal">
        <li>Group public key, an <tt>Element</tt> in <tt>G</tt>, denoted <tt>PK</tt>, corresponding
to the group secret key <tt>s</tt>, which is a <tt>Scalar</tt>. <tt>PK</tt> is an output from the
group's key generation protocol, such as <tt>trusted_dealer_keygen</tt> or a DKG.</li>
        <li>Public keys for each signer, denoted <tt>PK_i</tt>, which are similarly outputs
from the group's key generation protocol, <tt>Element</tt> values in <tt>G</tt>.</li>
      </ul>
      <t>And that each participant with identifier <tt>i</tt> additionally knows the following:</t>
      <ul spacing="normal">
        <li>Participant <tt>i</tt>s signing key share <tt>sk_i</tt>, which is the i-th secret share of <tt>s</tt>, a <tt>Scalar</tt>.</li>
      </ul>
      <t>By construction, <tt>PK = G.ScalarBaseMult(s)</tt> and <tt>PK_i = G.ScalarMultBase(sk_i)</tt> for each participant <tt>i</tt>.</t>
      <t>The exact key generation mechanism is out of scope for this specification. In general,
key generation is a protocol that outputs (1) a shared, group public key PK owned
by each Signer, and (2) individual shares of the signing key owned by each Signer.
In general, two possible key generation mechanisms are possible, one that requires
a single, trusted dealer, and the other which requires performing a distributed
key generation protocol. We highlight key generation mechanism by a trusted dealer
in <xref target="dep-dealer"/>, for reference.</t>
      <t>This signing variant of FROST requires signers to perform two network rounds:
1) generating and publishing commitments, and 2) signature share generation and
publication. The first round serves for each participant to issue a commitment to
a nonce. The second round receives commitments for all signers as well as the message,
and issues a signature share with respect to that message. The Coordinator performs
the coordination of each of these rounds. At the end of the second round, the
Coordinator then performs an aggregation step and outputs the final signature.
This complete interaction is shown in <xref target="fig-frost"/>.</t>
      <figure anchor="fig-frost">
        <name>FROST signature overview</name>
        <artwork><![CDATA[
        (group info)            (group info,     (group info,
            |               signing key share)   signing key share)
            |                         |                |
            v                         v                v
        Coordinator               Signer-1   ...   Signer-n
    ------------------------------------------------------------
   message
------------>
            |
      == Round 1 (Commitment) ==
            |    signer commitment   |                 |
            |<-----------------------+                 |
            |          ...                             |
            |    signer commitment              (commit state) ==\
            |<-----------------------------------------+         |
                                                                 |
      == Round 2 (Signature Share Generation) ==                 |
            |                                                    |
            |     signer input       |                 |         |
            +------------------------>                 |         |
            |     signature share    |                 |         |
            |<-----------------------+                 |         |
            |          ...                             |         |
            |     signer input                         |         |
            +------------------------------------------>         /
            |     signature share                      |<=======/
            <------------------------------------------+
            |
      == Aggregation ==
            |
  signature |
<-----------+
]]></artwork>
      </figure>
      <t>Details for round one are described in <xref target="frost-round-one"/>, and details for round two
are described in <xref target="frost-round-two"/>. Note that each signer persists some state between
both rounds, and this state is deleted as described in <xref target="frost-round-two"/>. The final
Aggregation step is described in <xref target="frost-aggregation"/>.</t>
      <t>FROST assumes that all inputs to each round, especially those of which are received
over the network, are validated before use. In particular, this means that any value
of type Element or Scalar is deserialized using DeserializeElement and DeserializeScalar,
respectively, as these functions perform the necessary input validation steps.</t>
      <t>FROST assumes reliable message delivery between the Coordinator and signer participants in
order for the protocol to complete. An attacker masquerading as another participant
will result only in an invalid signature; see <xref target="sec-considerations"/>. However, in order
to identify any participant which has misbehaved (resulting in the protocol aborting)
to take actions such as excluding them from future signing operations, we assume that
the network channel is additionally authenticated; confidentiality is not required.</t>
      <section anchor="frost-round-one">
        <name>Round One - Commitment</name>
        <t>Round one involves each signer generating nonces and their corresponding public commitments.
A nonce is a pair of Scalar values, and a commitment is a pair of Element values.</t>
        <t>Each signer in round one generates a nonce <tt>nonce = (hiding_nonce, binding_nonce)</tt> and commitment
<tt>comm = (hiding_nonce_commitment, binding_nonce_commitment)</tt>.</t>
        <artwork><![CDATA[
  Inputs: sk_i, the secret key share, a Scalar

  Outputs: (nonce, comm), a tuple of nonce and nonce commitment pairs,
    where each value in the nonce pair is a Scalar and each value in
    the nonce commitment pair is an Element

  def commit(sk_i):
    hiding_nonce = nonce_generate(sk_i)
    binding_nonce = nonce_generate(sk_i)
    hiding_nonce_commitment = G.ScalarBaseMult(hiding_nonce)
    binding_nonce_commitment = G.ScalarBaseMult(binding_nonce)
    nonce = (hiding_nonce, binding_nonce)
    comm = (hiding_nonce_commitment, binding_nonce_commitment)
    return (nonce, comm)
]]></artwork>
        <t>The private output <tt>nonce</tt> from Participant <tt>P_i</tt> is stored locally and 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 from a source of secure randomness. The public output
<tt>comm</tt> from Participant <tt>P_i</tt> is sent to the Coordinator.</t>
        <!-- The Coordinator must not get confused about which commitments come from which signers, do we need to say more about how this is done? -->

</section>
      <section anchor="frost-round-two">
        <name>Round Two - Signature Share Generation</name>
        <t>In round two, the Coordinator is responsible for sending the message to be signed, and
for choosing which signers will participate (of number at least MIN_SIGNERS). Signers
additionally require locally held data; specifically, their private key and the
nonces corresponding to their commitment issued in round one.</t>
        <t>The Coordinator begins by sending each signer the message to be signed along with the
set of signing commitments for all signers in the participant list. Each signer
MUST validate the inputs before processing the Coordinator's request. In particular,
the Signer MUST validate commitment_list, deserializing each group Element in the
list using DeserializeElement from <xref target="dep-pog"/>. If deserialization fails, the Signer
MUST abort the protocol. Moreover, each signer MUST ensure that their identifier as well as their commitment as from the first round appears in commitment_list.
Applications which require that signers not process arbitrary
input messages are also required to also perform relevant application-layer input
validation checks; see <xref target="message-validation"/> for more details.</t>
        <t>Upon receipt and successful input validation, each Signer then runs the following
procedure to produce its own signature share.</t>
        <artwork><![CDATA[
  Inputs:
  - identifier, Identifier i of the signer. Note identifier will never equal 0.
  - sk_i, Signer secret key share, a Scalar.
  - group_public_key, public key corresponding to the group signing key,
    an Element in G.
  - nonce_i, pair of Scalar values (hiding_nonce, binding_nonce) generated in
    round one.
  - msg, the message to be signed (sent by the Coordinator).
  - commitment_list =
      [(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a
    list of commitments issued in Round 1 by each signer and sent by the Coordinator.
    Each element in the list indicates the signer identifier j and their two commitment
    Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
    This list MUST be sorted in ascending order by signer identifier.

  Outputs: a Scalar value representing the signature share

  def sign(identifier, sk_i, group_public_key, nonce_i, msg, commitment_list):
    # Compute the binding factor(s)
    binding_factor_list = compute_binding_factors(commitment_list, msg)
    binding_factor = binding_factor_for_participant(binding_factor_list, identifier)

    # Compute the group commitment
    group_commitment = compute_group_commitment(commitment_list, binding_factor_list)

    # Compute Lagrange coefficient
    participant_list = participants_from_commitment_list(commitment_list)
    lambda_i = derive_lagrange_coefficient(Scalar(identifier), participant_list)

    # Compute the per-message challenge
    challenge = compute_challenge(group_commitment, group_public_key, msg)

    # Compute the signature share
    (hiding_nonce, binding_nonce) = nonce_i
    sig_share = hiding_nonce + (binding_nonce * binding_factor) + (lambda_i * sk_i * challenge)

    return sig_share
]]></artwork>
        <t>The output of this procedure is a signature share. Each signer then sends
these shares back to the Coordinator. Each signer MUST delete the nonce and
corresponding commitment after this round completes, and MUST use the nonce
to generate at most one signature share.</t>
        <t>Note that the <tt>lambda_i</tt> value derived during this procedure does not change
across FROST signing operations for the same signing group. As such, signers
can compute it once and store it for reuse across signing sessions.</t>
        <t>Upon receipt from each Signer, the Coordinator MUST validate the input
signature share using DeserializeElement. If validation fails, the Coordinator MUST abort
the protocol. If validation succeeds, the Coordinator then verifies the set of
signature shares using the following procedure.</t>
      </section>
      <section anchor="frost-aggregation">
        <name>Signature Share Verification and Aggregation</name>
        <t>After signers perform round two and send their signature shares to the Coordinator,
the Coordinator verifies each signature share for correctness. In particular,
for each signer, the Coordinator uses commitment pairs generated during round
one and the signature share generated during round two, along with other group
parameters, to check that the signature share is valid using the following procedure.</t>
        <artwork><![CDATA[
  Inputs:
  - identifier, Identifier i of the signer. Note: identifier MUST never equal 0.
  - PK_i, the public key for the ith signer, where PK_i = G.ScalarBaseMult(sk_i),
    an Element in G
  - comm_i, pair of Element values in G (hiding_nonce_commitment, binding_nonce_commitment)
    generated 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.
  - 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 identifier j and their two commitment
    Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
    This list MUST be sorted in ascending order by signer identifier.
  - group_public_key, public key corresponding to the group signing key,
    an Element in G.
  - msg, the message to be signed.

  Outputs: True if the signature share is valid, and False otherwise.

  def verify_signature_share(identifier, PK_i, comm_i, sig_share_i, commitment_list,
                             group_public_key, msg):
    # Compute the binding factors
    binding_factor_list = compute_binding_factors(commitment_list, msg)
    binding_factor = binding_factor_for_participant(binding_factor_list, identifier)

    # Compute the group commitment
    group_commitment = compute_group_commitment(commitment_list, binding_factor_list)

    # Compute the commitment share
    (hiding_nonce_commitment, binding_nonce_commitment) = comm_i
    comm_share = hiding_nonce_commitment + G.ScalarMult(binding_nonce_commitment, binding_factor)

    # Compute the challenge
    challenge = compute_challenge(group_commitment, group_public_key, msg)

    # Compute Lagrange coefficient
    participant_list = participants_from_commitment_list(commitment_list)
    lambda_i = derive_lagrange_coefficient(Scalar(identifier), participant_list)

    # Compute relation values
    l = G.ScalarBaseMult(sig_share_i)
    r = comm_share + G.ScalarMult(PK_i, challenge * lambda_i)

    return l == r
]]></artwork>
        <t>If any signature share fails to verify, i.e., if verify_signature_share returns False for
any signer share, the Coordinator MUST abort the protocol for correctness reasons.
Excluding one signer means that their nonce will not be included in the joint response <tt>z</tt>
and consequently the output signature will not verify.</t>
        <t>Otherwise, if all shares from signers that participated in Rounds 1 and 2 are valid, the Coordinator
performs the <tt>aggregate</tt> operation and publishes the resulting signature.</t>
        <artwork><![CDATA[
  Inputs:
  - group_commitment, the group commitment returned by compute_group_commitment,
    an Element in G.
  - sig_shares, a set of signature shares z_i, Scalar values, for each signer,
    of length NUM_SIGNERS, where MIN_SIGNERS <= NUM_SIGNERS <= MAX_SIGNERS.

  Outputs: (R, z), a Schnorr signature consisting of an Element R and Scalar z.

  def aggregate(group_commitment, sig_shares):
    z = 0
    for z_i in sig_shares:
      z = z + z_i
    return (group_commitment, z)
]]></artwork>
        <t>The output signature (R, z) from the aggregation step MUST be encoded as follows
(using notation from <xref section="3" sectionFormat="of" target="TLS"/>):</t>
        <artwork><![CDATA[
  struct {
    opaque R_encoded[Ne];
    opaque z_encoded[Ns];
  } Signature;
]]></artwork>
        <t>Where Signature.R_encoded is <tt>G.SerializeElement(R)</tt> and Signature.z_encoded is
<tt>G.SerializeScalar(z)</tt>.</t>
      </section>
    </section>
    <section anchor="ciphersuites">
      <name>Ciphersuites</name>
      <t>A FROST ciphersuite must specify the underlying prime-order group details
and cryptographic hash function. Each ciphersuite is denoted as (Group, Hash),
e.g., (ristretto255, SHA-512). This section contains some ciphersuites.</t>
      <t>The RECOMMENDED ciphersuite is (ristretto255, SHA-512) <xref target="recommended-suite"/>.
The (Ed25519, SHA-512) ciphersuite is included for backwards compatibility
with <xref target="RFC8032"/>.</t>
      <t>The DeserializeElement and DeserializeScalar functions instantiated for a
particular prime-order group corresponding to a ciphersuite MUST adhere
to the description in <xref target="dep-pog"/>. Validation steps for these functions
are described for each the ciphersuites below. Future ciphersuites MUST
describe how input validation is done for DeserializeElement and DeserializeScalar.</t>
      <t>Each ciphersuite includes explicit instructions for verifying signatures produced
by FROST. Note that these instructions are equivalent to those produced by a single
signer.</t>
      <section anchor="frosted25519-sha-512">
        <name>FROST(Ed25519, SHA-512)</name>
        <t>This ciphersuite uses edwards25519 for the Group and SHA-512 for the Hash function <tt>H</tt>
meant to produce signatures indistinguishable from Ed25519 as specified in <xref target="RFC8032"/>.
The value of the contextString parameter is "FROST-ED25519-SHA512-v8".</t>
        <ul spacing="normal">
          <li>
            <t>Group: edwards25519 <xref target="RFC8032"/>
            </t>
            <ul spacing="normal">
              <li>Order(): Return 2^252 + 27742317777372353535851937790883648493 (see <xref target="RFC7748"/>)</li>
              <li>Identity(): As defined in <xref target="RFC7748"/>.</li>
              <li>RandomScalar(): Implemented by returning a uniformly random Scalar in the range
[0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for implementation guidance.</li>
              <li>SerializeElement(A): Implemented as specified in <xref section="5.1.2" sectionFormat="comma" target="RFC8032"/>.</li>
              <li>DeserializeElement(buf): Implemented as specified in <xref section="5.1.3" sectionFormat="comma" target="RFC8032"/>.
Additionally, this function validates that the resulting element is not the group
identity element and is in the prime-order subgroup. The latter check can
be implemented by multiplying the resulting point by the order of the group and
checking that the result is the identity element.</li>
              <li>SerializeScalar(s): Implemented by outputting the little-endian 32-byte encoding of
the Scalar value.</li>
              <li>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar from a
little-endian 32-byte string. This function can fail if the input does not
represent a Scalar in the range [0, <tt>G.Order()</tt> - 1].</li>
            </ul>
          </li>
          <li>
            <t>Hash (<tt>H</tt>): SHA-512, and Nh = 64.
            </t>
            <ul spacing="normal">
              <li>H1(m): Implemented by computing H(contextString || "rho" || m), interpreting the 64-byte digest
as a little-endian integer, and reducing the resulting integer modulo
L = 2^252+27742317777372353535851937790883648493.</li>
              <li>H2(m): Implemented by computing H(m), interpreting the 64-byte digest
as a little-endian integer, and reducing the resulting integer modulo
L = 2^252+27742317777372353535851937790883648493.</li>
              <li>H3(m): Implemented by computing H(contextString || "nonce" || m), interpreting the 64-byte digest
as a little-endian integer, and reducing the resulting integer modulo
L = 2^252+27742317777372353535851937790883648493.</li>
              <li>H4(m): Implemented by computing H(contextString || "msg" || m).</li>
              <li>H5(m): Implemented by computing H(contextString || "com" || m).</li>
            </ul>
          </li>
        </ul>
        <t>Normally H2 would also include a domain separator, but for backwards compatibility
with <xref target="RFC8032"/>, it is omitted.</t>
        <t>Signature verification is as specified in <xref section="5.1.7" sectionFormat="of" target="RFC8032"/> with the
constraint that implementations MUST check the group equation [8][S]B = [8]R + [8][k]A'.
The alternative check [S]B = R + [k]A' is not safe or interoperable in practice.</t>
      </section>
      <section anchor="recommended-suite">
        <name>FROST(ristretto255, SHA-512)</name>
        <t>This ciphersuite uses ristretto255 for the Group and SHA-512 for the Hash function <tt>H</tt>.
The value of the contextString parameter is "FROST-RISTRETTO255-SHA512-v8".</t>
        <ul spacing="normal">
          <li>
            <t>Group: ristretto255 <xref target="RISTRETTO"/>
            </t>
            <ul spacing="normal">
              <li>Order(): Return 2^252 + 27742317777372353535851937790883648493 (see <xref target="RISTRETTO"/>)</li>
              <li>Identity(): As defined in <xref target="RISTRETTO"/>.</li>
              <li>RandomScalar(): Implemented by returning a uniformly random Scalar in the range
[0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for implementation guidance.</li>
              <li>SerializeElement(A): Implemented using the 'Encode' function from <xref target="RISTRETTO"/>.</li>
              <li>DeserializeElement(buf): Implemented using the 'Decode' function from <xref target="RISTRETTO"/>.</li>
              <li>SerializeScalar(s): Implemented by outputting the little-endian 32-byte encoding of
the Scalar value.</li>
              <li>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar from a
little-endian 32-byte string. This function can fail if the input does not
represent a Scalar in the range [0, <tt>G.Order()</tt> - 1].</li>
            </ul>
          </li>
          <li>
            <t>Hash (<tt>H</tt>): SHA-512, and Nh = 64.
            </t>
            <ul spacing="normal">
              <li>H1(m): Implemented by computing H(contextString || "rho" || m) and mapping the
output to a Scalar as described in <xref section="4.4" sectionFormat="comma" target="RISTRETTO"/>.</li>
              <li>H2(m): Implemented by computing H(contextString || "chal" || m) and mapping the
output to a Scalar as described in <xref section="4.4" sectionFormat="comma" target="RISTRETTO"/>.</li>
              <li>H3(m): Implemented by computing H(contextString || "nonce" || m) and mapping the
output to a Scalar as described in <xref section="4.4" sectionFormat="comma" target="RISTRETTO"/>.</li>
              <li>H4(m): Implemented by computing H(contextString || "msg" || m).</li>
              <li>H5(m): Implemented by computing H(contextString || "com" || m).</li>
            </ul>
          </li>
        </ul>
        <t>Signature verification is as specified in <xref target="prime-order-verify"/>.</t>
      </section>
      <section anchor="frosted448-shake256">
        <name>FROST(Ed448, SHAKE256)</name>
        <t>This ciphersuite uses edwards448 for the Group and SHAKE256 for the Hash function <tt>H</tt>
meant to produce signatures indistinguishable from Ed448 as specified in <xref target="RFC8032"/>.
The value of the contextString parameter is "FROST-ED448-SHAKE256-v8".</t>
        <ul spacing="normal">
          <li>
            <t>Group: edwards448 <xref target="RFC8032"/>
            </t>
            <ul spacing="normal">
              <li>Order(): Return 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885</li>
              <li>Identity(): As defined in <xref target="RFC7748"/>.</li>
              <li>RandomScalar(): Implemented by returning a uniformly random Scalar in the range
[0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for implementation guidance.</li>
              <li>SerializeElement(A): Implemented as specified in <xref section="5.2.2" sectionFormat="comma" target="RFC8032"/>.</li>
              <li>DeserializeElement(buf): Implemented as specified in <xref section="5.2.3" sectionFormat="comma" target="RFC8032"/>.
Additionally, this function validates that the resulting element is not the group
identity element.</li>
              <li>SerializeScalar(s): Implemented by outputting the little-endian 48-byte encoding of
the Scalar value.</li>
              <li>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar from a
little-endian 48-byte string. This function can fail if the input does not
represent a Scalar in the range [0, <tt>G.Order()</tt> - 1].</li>
            </ul>
          </li>
          <li>
            <t>Hash (<tt>H</tt>): SHAKE256, and Nh = 114.
            </t>
            <ul spacing="normal">
              <li>H1(m): Implemented by computing H(contextString || "rho" || m), interpreting the lower
57 bytes as a little-endian integer, and reducing the resulting integer modulo
L = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885.</li>
              <li>H2(m): Implemented by computing H(m), interpreting the lower 57 bytes
as a little-endian integer, and reducing the resulting integer modulo
L = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885.</li>
              <li>H3(m): Implemented by computing H(contextString || "nonce" || m), interpreting the lower
57 bytes as a little-endian integer, and reducing the resulting integer modulo
L = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885.</li>
              <li>H4(m): Implemented by computing H(contextString || "msg" || m).</li>
              <li>H5(m): Implemented by computing H(contextString || "com" || m).</li>
            </ul>
          </li>
        </ul>
        <t>Normally H2 would also include a domain separator, but for backwards compatibility
with <xref target="RFC8032"/>, it is omitted.</t>
        <t>Signature verification is as specified in <xref section="5.2.7" sectionFormat="of" target="RFC8032"/> with the
constraint that implementations MUST check the group equation [4][S]B = [4]R + [4][k]A'.
The alternative check [S]B = R + [k]A' is not safe or interoperable in practice.</t>
      </section>
      <section anchor="frostp-256-sha-256">
        <name>FROST(P-256, SHA-256)</name>
        <t>This ciphersuite uses P-256 for the Group and SHA-256 for the Hash function <tt>H</tt>.
The value of the contextString parameter is "FROST-P256-SHA256-v8".</t>
        <ul spacing="normal">
          <li>
            <t>Group: P-256 (secp256r1) <xref target="x9.62"/>
            </t>
            <ul spacing="normal">
              <li>Order(): Return 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551</li>
              <li>Identity(): As defined in <xref target="x9.62"/>.</li>
              <li>RandomScalar(): Implemented by returning a uniformly random Scalar in the range
[0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for implementation guidance.</li>
              <li>SerializeElement(A): Implemented using the compressed Elliptic-Curve-Point-to-Octet-String
method according to <xref target="SEC1"/>.</li>
              <li>DeserializeElement(buf): Implemented by attempting to deserialize a public key using
the compressed Octet-String-to-Elliptic-Curve-Point method according to <xref target="SEC1"/>,
and then performs partial public-key validation as defined in section 5.6.2.3.4 of
<xref target="KEYAGREEMENT"/>. This includes checking that the
coordinates of 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. Additionally, this function
validates that the resulting element is not the group identity element.
If these checks fail, deserialization returns an error.</li>
              <li>SerializeScalar(s): Implemented using the Field-Element-to-Octet-String conversion
according to <xref target="SEC1"/>.</li>
              <li>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar from a 32-byte
string using Octet-String-to-Field-Element from <xref target="SEC1"/>. This function can fail if the
input does not represent a Scalar in the range [0, <tt>G.Order()</tt> - 1].</li>
            </ul>
          </li>
          <li>
            <t>Hash (<tt>H</tt>): SHA-256, and Nh = 32.
            </t>
            <ul spacing="normal">
              <li>H1(m): Implemented using hash_to_field from <xref section="5.3" sectionFormat="comma" target="HASH-TO-CURVE"/>
using L = 48, <tt>expand_message_xmd</tt> with SHA-256, DST = contextString || "rho", and
prime modulus equal to <tt>Order()</tt>.</li>
              <li>H2(m): Implemented using hash_to_field from <xref section="5.3" sectionFormat="comma" target="HASH-TO-CURVE"/>
using L = 48, <tt>expand_message_xmd</tt> with SHA-256, DST = contextString || "chal", and
prime modulus equal to <tt>Order()</tt>.</li>
              <li>H3(m): Implemented using hash_to_field from <xref section="5.3" sectionFormat="comma" target="HASH-TO-CURVE"/>
using L = 48, <tt>expand_message_xmd</tt> with SHA-256, DST = contextString || "nonce", and
prime modulus equal to <tt>Order()</tt>.</li>
              <li>H4(m): Implemented by computing H(contextString || "msg" || m).</li>
              <li>H5(m): Implemented by computing H(contextString || "com" || m).</li>
            </ul>
          </li>
        </ul>
        <t>Signature verification is as specified in <xref target="prime-order-verify"/>.</t>
      </section>
      <section anchor="frostsecp256k1-sha-256">
        <name>FROST(secp256k1, SHA-256)</name>
        <t>This ciphersuite uses secp256k1 for the Group and SHA-256 for the Hash function <tt>H</tt>.
The value of the contextString parameter is "FROST-secp256k1-SHA256-v8".</t>
        <ul spacing="normal">
          <li>
            <t>Group: secp256k1 <xref target="SEC2"/>
            </t>
            <ul spacing="normal">
              <li>Order(): Return 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551</li>
              <li>Identity(): As defined in <xref target="SEC2"/>.</li>
              <li>RandomScalar(): Implemented by returning a uniformly random Scalar in the range
[0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for implementation guidance.</li>
              <li>SerializeElement(A): Implemented using the compressed Elliptic-Curve-Point-to-Octet-String
method according to <xref target="SEC1"/>.</li>
              <li>DeserializeElement(buf): Implemented by attempting to deserialize a public key using
the compressed Octet-String-to-Elliptic-Curve-Point method according to <xref target="SEC1"/>,
and then performs partial public-key validation as defined in section 3.2.2.1 of
<xref target="SEC1"/>. This includes checking that the coordinates of 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. Additionally, this function validates that the resulting
element is not the group identity element. If these checks fail, deserialization
returns an error.</li>
              <li>SerializeScalar(s): Implemented using the Field-Element-to-Octet-String conversion
according to <xref target="SEC1"/>.</li>
              <li>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar from a 32-byte
string using Octet-String-to-Field-Element from <xref target="SEC1"/>. This function can fail if the
input does not represent a Scalar in the range [0, <tt>G.Order()</tt> - 1].</li>
            </ul>
          </li>
          <li>
            <t>Hash (<tt>H</tt>): SHA-256, and Nh = 32.
            </t>
            <ul spacing="normal">
              <li>H1(m): Implemented using hash_to_field from <xref section="5.3" sectionFormat="comma" target="HASH-TO-CURVE"/>
using L = 48, <tt>expand_message_xmd</tt> with SHA-256, DST = contextString || "rho", and
prime modulus equal to <tt>Order()</tt>.</li>
              <li>H2(m): Implemented using hash_to_field from <xref section="5.3" sectionFormat="comma" target="HASH-TO-CURVE"/>
using L = 48, <tt>expand_message_xmd</tt> with SHA-256, DST = contextString || "chal", and
prime modulus equal to <tt>Order()</tt>.</li>
              <li>H3(m): Implemented using hash_to_field from <xref section="5.3" sectionFormat="comma" target="HASH-TO-CURVE"/>
using L = 48, <tt>expand_message_xmd</tt> with SHA-256, DST = contextString || "nonce", and
prime modulus equal to <tt>Order()</tt>.</li>
              <li>H4(m): Implemented by computing H(contextString || "msg" || m).</li>
              <li>H5(m): Implemented by computing H(contextString || "com" || m).</li>
            </ul>
          </li>
        </ul>
        <t>Signature verification is as specified in <xref target="prime-order-verify"/>.</t>
      </section>
    </section>
    <section anchor="sec-considerations">
      <name>Security Considerations</name>
      <t>A security analysis of FROST exists in <xref target="FROST20"/> and <xref target="Schnorr21"/>. The protocol as specified
in this document assumes the following threat model.</t>
      <ul spacing="normal">
        <li>Trusted dealer. The dealer that performs key generation is trusted to follow
the protocol, although participants still are able to verify the consistency of their
shares via a VSS (verifiable secret sharing) step; see <xref target="dep-vss"/>.</li>
        <li>Unforgeability assuming at most <tt>(MIN_SIGNERS-1)</tt> corrupted signers. So long as an adversary
corrupts fewer than <tt>MIN_SIGNERS</tt> participants, the scheme remains secure against Existential
Unforgeability Under Chosen Message Attack (EUF-CMA) attacks, as defined in <xref target="BonehShoup"/>,
Definition 13.2.</li>
        <li>Coordinator. We assume the Coordinator at the time of signing does not perform a
denial of service attack. A denial of service would include any action which either
prevents the protocol from completing or causing the resulting signature to be invalid.
Such actions for the latter include sending inconsistent values to signer participants,
such as messages or the set of individual commitments. Note that the Coordinator
is <em>not</em> trusted with any private information and communication at the time of signing
can be performed over a public but reliable channel.</li>
      </ul>
      <t>The protocol as specified in this document does not target the following goals:</t>
      <ul spacing="normal">
        <li>Post quantum security. FROST, like plain Schnorr signatures, requires the hardness of the Discrete Logarithm Problem.</li>
        <li>Robustness. In the case of failure, FROST requires aborting the protocol.</li>
        <li>Downgrade prevention. All participants in the protocol are assumed to agree on what algorithms to use.</li>
        <li>Metadata protection. If protection for metadata is desired, a higher-level communication
channel can be used to facilitate key generation and signing.</li>
      </ul>
      <t>The rest of this section documents issues particular to implementations or deployments.</t>
      <section anchor="nonce-reuse-attacks">
        <name>Nonce Reuse Attacks</name>
        <t><xref target="dep-nonces"/> describes the procedure that signers use to produce nonces during
the first round of singing. The randomness produced in this procedure MUST be sampled
uniformly at random. The resulting nonces produced via <tt>nonce_generate</tt> are indistinguishable
from values sampled uniformly at random. This requirement is necessary to avoid
replay attacks initiated by other signers, which allows for a complete key-recovery attack.
The Coordinator MAY further hedge against nonce reuse attacks by tracking signer nonce
commitments used for a given group key, at the cost of additional state.</t>
      </section>
      <section anchor="protocol-failures">
        <name>Protocol Failures</name>
        <t>We do not specify what implementations should do when the protocol fails, other than requiring that
the protocol abort. Examples of viable failure include when a verification check returns invalid or
if the underlying transport failed to deliver the required messages.</t>
      </section>
      <section anchor="no-coordinator">
        <name>Removing the Coordinator Role</name>
        <t>In some settings, it may be desirable to omit the role of the Coordinator entirely.
Doing so does not change the security implications of FROST, but instead simply
requires each participant to communicate with all other participants. We loosely
describe how to perform FROST signing among signers without this coordinator role.
We assume that every participant receives as input from an external source the
message to be signed prior to performing the protocol.</t>
        <t>Every participant begins by performing <tt>commit()</tt> as is done in the setting
where a Coordinator is used. However, instead of sending the commitment
to the Coordinator, every participant instead will publish
this commitment to every other participant. Then, in the second round, signers will already have
sufficient information to perform signing. They will directly perform <tt>sign</tt>.
All participants will then publish their signature shares to one another. After having
received all signature shares from all other signers, each signer will then perform
<tt>verify_signature_share</tt> and then <tt>aggregate</tt> directly.</t>
        <t>The requirements for the underlying network channel remain the same in the setting
where all participants play the role of the Coordinator, in that all messages that
are exchanged are public and so the channel simply must be reliable. However, in
the setting that a player attempts to split the view of all other players by
sending disjoint values to a subset of players, the signing operation will output
an invalid signature. To avoid this denial of service, implementations may wish
to define a mechanism where messages are authenticated, so that cheating players
can be identified and excluded.</t>
      </section>
      <section anchor="message-validation">
        <name>Input Message Validation</name>
        <t>Some applications may require that signers only process messages of a certain
structure. For example, in digital currency applications wherein multiple
signers may collectively sign a transaction, it is reasonable to require that
each signer check the input message to be a syntactically valid transaction.
As another example, use of threshold signatures in TLS <xref target="TLS"/> to produce
signatures of transcript hashes might require that signers check that the input
message is a valid TLS transcript from which the corresponding transcript hash
can be derived.</t>
        <t>In general, input message validation is an application-specific consideration
that varies based on the use case and threat model. However, it is RECOMMENDED
that applications take additional precautions and validate inputs so that signers
do not operate as signing oracles for arbitrary messages.</t>
      </section>
    </section>
    <section anchor="contributors">
      <name>Contributors</name>
      <ul spacing="normal">
        <li>Isis Lovecruft</li>
        <li>Alden Torres</li>
        <li>T. Wilson-Brown</li>
        <li>Conrado Gouvea</li>
      </ul>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="x9.62">
          <front>
            <title>Public Key Cryptography for the Financial Services Industry: the Elliptic Curve Digital Signature Algorithm (ECDSA)</title>
            <author>
              <organization>ANSI</organization>
            </author>
            <date year="1998" month="September"/>
          </front>
          <seriesInfo name="ANSI" value="X9.62-1998"/>
        </reference>
        <reference anchor="SEC1" target="https://secg.org/sec1-v2.pdf">
          <front>
            <title>Elliptic Curve Cryptography, Standards for Efficient Cryptography Group, ver. 2</title>
            <author>
              <organization/>
            </author>
            <date year="2009"/>
          </front>
        </reference>
        <reference anchor="SEC2" target="https://secg.org/sec2-v2.pdf">
          <front>
            <title>Recommended Elliptic Curve Domain Parameters, Standards for Efficient Cryptography Group, ver. 2</title>
            <author>
              <organization/>
            </author>
            <date year="2010"/>
          </front>
        </reference>
        <reference anchor="RFC8032">
          <front>
            <title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson">
              <organization/>
            </author>
            <author fullname="I. Liusvaara" initials="I." surname="Liusvaara">
              <organization/>
            </author>
            <date month="January" year="2017"/>
            <abstract>
              <t>This document describes elliptic curve signature scheme Edwards-curve Digital Signature Algorithm (EdDSA).  The algorithm is instantiated with recommended parameters for the edwards25519 and edwards448 curves.  An example implementation and test vectors are provided.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8032"/>
          <seriesInfo name="DOI" value="10.17487/RFC8032"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner">
              <organization/>
            </author>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba">
              <organization/>
            </author>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol  specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the  defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RISTRETTO">
          <front>
            <title>The ristretto255 and decaf448 Groups</title>
            <author fullname="Henry de Valence">
	 </author>
            <author fullname="Jack Grigg">
	 </author>
            <author fullname="Mike Hamburg">
	 </author>
            <author fullname="Isis Lovecruft">
	 </author>
            <author fullname="George Tankersley">
	 </author>
            <author fullname="Filippo Valsorda">
	 </author>
            <date day="25" month="February" year="2022"/>
            <abstract>
              <t>   This memo specifies two prime-order groups, ristretto255 and
   decaf448, suitable for safely implementing higher-level and complex
   cryptographic protocols.  The ristretto255 group can be implemented
   using Curve25519, allowing existing Curve25519 implementations to be
   reused and extended to provide a prime-order group.  Likewise, the
   decaf448 group can be implemented using edwards448.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-ristretto255-decaf448-03"/>
        </reference>
        <reference anchor="KEYAGREEMENT">
          <front>
            <title>Recommendation for pair-wise key-establishment schemes using discrete logarithm cryptography</title>
            <author fullname="Elaine Barker" initials="E." surname="Barker">
              <organization/>
            </author>
            <author fullname="Lily Chen" initials="L." surname="Chen">
              <organization/>
            </author>
            <author fullname="Allen Roginsky" initials="A." surname="Roginsky">
              <organization/>
            </author>
            <author fullname="Apostol Vassilev" initials="A." surname="Vassilev">
              <organization/>
            </author>
            <author fullname="Richard Davis" initials="R." surname="Davis">
              <organization/>
            </author>
            <date month="April" year="2018"/>
          </front>
          <seriesInfo name="National Institute of Standards and Technology" value="report"/>
          <seriesInfo name="DOI" value="10.6028/nist.sp.800-56ar3"/>
        </reference>
        <reference anchor="HASH-TO-CURVE">
          <front>
            <title>Hashing to Elliptic Curves</title>
            <author fullname="Armando Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Sam Scott">
              <organization>Cornell Tech</organization>
            </author>
            <author fullname="Nick Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Riad S. Wahby">
              <organization>Stanford University</organization>
            </author>
            <author fullname="Christopher A. Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="15" month="June" year="2022"/>
            <abstract>
              <t>   This document specifies a number of algorithms for encoding or
   hashing an arbitrary string to a point on an elliptic curve.  This
   document is a product of the Crypto Forum Research Group (CFRG) in
   the IRTF.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-hash-to-curve-16"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="FROST20" target="https://eprint.iacr.org/2020/852.pdf">
          <front>
            <title>Two-Round Threshold Signatures with FROST</title>
            <author initials="C." surname="Komlo" fullname="Chelsea Komlo">
              <organization/>
            </author>
            <author initials="I." surname="Goldberg" fullname="Ian Goldberg">
              <organization/>
            </author>
            <date year="2020" month="December" day="22"/>
          </front>
        </reference>
        <reference anchor="Schnorr21" target="https://eprint.iacr.org/2021/1375">
          <front>
            <title>How to Prove Schnorr Assuming Schnorr</title>
            <author initials="E." surname="Crites" fullname="Elizabeth Crites">
              <organization/>
            </author>
            <author initials="C." surname="Komlo" fullname="Chelsea Komlo">
              <organization/>
            </author>
            <author initials="M." surname="Maller" fullname="Mary Maller">
              <organization/>
            </author>
            <date year="2021" month="October" day="11"/>
          </front>
        </reference>
        <reference anchor="StrongerSec22" target="https://eprint.iacr.org/2022/833">
          <front>
            <title>Stronger Security for Non-Interactive Threshold Signatures: BLS and FROST</title>
            <author initials="M." surname="Bellare" fullname="Mihir Bellare">
              <organization/>
            </author>
            <author initials="S." surname="Tessaro" fullname="Stefano Tessaro">
              <organization/>
            </author>
            <author initials="C." surname="Zhu" fullname="Chenzhi Zhu">
              <organization/>
            </author>
            <date year="2022" month="June" day="01"/>
          </front>
        </reference>
        <reference anchor="BonehShoup" target="http://toc.cryptobook.us/book.pdf">
          <front>
            <title>A Graduate Course in Applied Cryptography</title>
            <author initials="D." surname="Boneh" fullname="Dan Boneh">
              <organization/>
            </author>
            <author initials="V." surname="Shoup" fullname="Victor Shoup">
              <organization/>
            </author>
            <date year="2020" month="January"/>
          </front>
        </reference>
        <reference anchor="RFC4086">
          <front>
            <title>Randomness Requirements for Security</title>
            <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd">
              <organization/>
            </author>
            <author fullname="J. Schiller" initials="J." surname="Schiller">
              <organization/>
            </author>
            <author fullname="S. Crocker" initials="S." surname="Crocker">
              <organization/>
            </author>
            <date month="June" year="2005"/>
            <abstract>
              <t>Security systems are built on strong cryptographic algorithms that foil pattern analysis attempts.  However, the security of these systems is dependent on generating secret quantities for passwords, cryptographic keys, and similar quantities.  The use of pseudo-random processes to generate secret quantities can result in pseudo-security. A sophisticated attacker may find it easier to reproduce the environment that produced the secret quantities and to search the resulting small set of possibilities than to locate the quantities in the whole of the potential number space.</t>
              <t>Choosing random quantities to foil a resourceful and motivated adversary is surprisingly difficult.  This document points out many pitfalls in using poor entropy sources or traditional pseudo-random number generation techniques for generating such quantities.  It recommends the use of truly random hardware techniques and shows that the existing hardware on many systems can be used for this purpose. It provides suggestions to ameliorate the problem when a hardware solution is not available, and it gives examples of how large such quantities need to be for some applications.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="106"/>
          <seriesInfo name="RFC" value="4086"/>
          <seriesInfo name="DOI" value="10.17487/RFC4086"/>
        </reference>
        <reference anchor="RFC7748">
          <front>
            <title>Elliptic Curves for Security</title>
            <author fullname="A. Langley" initials="A." surname="Langley">
              <organization/>
            </author>
            <author fullname="M. Hamburg" initials="M." surname="Hamburg">
              <organization/>
            </author>
            <author fullname="S. Turner" initials="S." surname="Turner">
              <organization/>
            </author>
            <date month="January" year="2016"/>
            <abstract>
              <t>This memo specifies two elliptic curves over prime fields that offer a high level of practical security in cryptographic applications, including Transport Layer Security (TLS).  These curves are intended to operate at the ~128-bit and ~224-bit security level, respectively, and are generated deterministically based on a list of required properties.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7748"/>
          <seriesInfo name="DOI" value="10.17487/RFC7748"/>
        </reference>
        <reference anchor="TLS">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla">
              <organization/>
            </author>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol.  TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961.  This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
      </references>
    </references>
    <section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>This document was improved based on input and contributions by the Zcash Foundation engineering team.</t>
    </section>
    <section anchor="prime-order-verify">
      <name>Schnorr Signature Verification for Prime-Order Groups</name>
      <t>This section contains a routine for verifying Schnorr signatures with validated inputs.
Specifically, it assumes that signature R component and public key belong to the
prime-order group.</t>
      <artwork><![CDATA[
  prime_order_verify(msg, sig, PK):

  Inputs:
  - msg, signed message, a byte string
  - sig, a tuple (R, z) output from signature generation
  - PK, public key, an Element

  Outputs: 1 if signature is valid, and 0 otherwise

  def prime_order_verify(msg, sig = (R, z), PK):
    comm_enc = G.SerializeElement(R)
    pk_enc = G.SerializeElement(PK)
    challenge_input = comm_enc || pk_enc || msg
    c = H2(challenge_input)

    l = G.ScalarBaseMult(z)
    r = R + G.ScalarMult(PK, c)
    return l == r
]]></artwork>
    </section>
    <section anchor="dep-dealer">
      <name>Trusted Dealer Key Generation</name>
      <t>One possible key generation mechanism is to depend on a trusted dealer, wherein the
dealer generates a group secret <tt>s</tt> uniformly at random and uses Shamir and Verifiable
Secret Sharing as described in <xref target="dep-shamir"/> and <xref target="dep-vss"/> to create secret
shares of <tt>s</tt> to be sent to all other participants. We highlight at a high level how this
operation can be performed.</t>
      <t>The dealer is trusted to 1) generate good randomness, and 2) delete secret values after distributing shares to each participant,
and 3) keep secret values confidential.</t>
      <artwork><![CDATA[
  Inputs:
  - s, a group secret, Scalar, that MUST be derived from at least Ns bytes of entropy
  - MAX_SIGNERS, the number of shares to generate, an integer
  - MIN_SIGNERS, the threshold of the secret sharing scheme, an integer

  Outputs:
  - signer_private_keys, MAX_SIGNERS shares of the secret key s, each a tuple
    consisting of the participant identifier and the key share (a Scalar).
  - vss_commitment, a vector commitment of Elements in G, to each of the coefficients
    in the polynomial defined by secret_key_shares and whose first element is
    G.ScalarBaseMult(s).

  def trusted_dealer_keygen(s, MAX_SIGNERS, MIN_SIGNERS):
    signer_private_keys, coefficients = secret_share_shard(secret_key, MAX_SIGNERS, MIN_SIGNERS)
    vss_commitment = vss_commit(coefficients):
    PK = G.ScalarBaseMult(secret_key)
    return signer_private_keys, vss_commitment
]]></artwork>
      <t>It is assumed the dealer then sends one secret key share to each of the NUM_SIGNERS participants, along with <tt>vss_commitment</tt>.
After receiving their secret key share and <tt>vss_commitment</tt>, participants MUST abort if they do not have the same view of <tt>vss_commitment</tt>.
Otherwise, each participant MUST perform <tt>vss_verify(secret_key_share_i, vss_commitment)</tt>, and abort if the check fails.
The trusted dealer MUST delete the secret_key and secret_key_shares upon completion.</t>
      <t>Use of this method for key generation requires a mutually authenticated secure channel
between the dealer and participants to send secret key shares, wherein the channel provides confidentiality
and integrity. Mutually authenticated TLS is one possible deployment option.</t>
      <section anchor="dep-shamir">
        <name>Shamir Secret Sharing</name>
        <t>In Shamir secret sharing, a dealer distributes a secret <tt>Scalar</tt> <tt>s</tt> to <tt>n</tt> participants
in such a way that any cooperating subset of <tt>MIN_SIGNERS</tt> participants can recover the
secret. There are two basic steps in this scheme: (1) splitting a secret into
multiple shares, and (2) combining shares to reveal the resulting secret.</t>
        <t>This secret sharing scheme works over any field <tt>F</tt>. In this specification, <tt>F</tt> is
the scalar field of the prime-order group <tt>G</tt>.</t>
        <t>The procedure for splitting a secret into shares is as follows.</t>
        <artwork><![CDATA[
  secret_share_shard(s, MAX_SIGNERS, MIN_SIGNERS):

  Inputs:
  - s, secret value to be shared, a Scalar
  - MAX_SIGNERS, the number of shares to generate, an integer
  - MIN_SIGNERS, the threshold of the secret sharing scheme, an integer

  Outputs:
  - secret_key_shares, A list of MAX_SIGNERS number of secret shares, each a tuple
    consisting of the participant identifier and the key share (a Scalar)
  - coefficients, a vector of the t coefficients which uniquely determine
    a polynomial f.

  Errors:
  - "invalid parameters", if MIN_SIGNERS > MAX_SIGNERS or if MIN_SIGNERS is less than 2

  def secret_share_shard(s, MAX_SIGNERS, MIN_SIGNERS):
    if MIN_SIGNERS > MAX_SIGNERS:
      raise "invalid parameters"
    if MIN_SIGNERS < 2:
      raise "invalid parameters"

    # Generate random coefficients for the polynomial, yielding
    # a polynomial of degree (MIN_SIGNERS - 1)
    coefficients = [s]
    for i in range(1, MIN_SIGNERS):
      coefficients.append(G.RandomScalar())

    # Evaluate the polynomial for each point x=1,...,n
    secret_key_shares = []
    for x_i in range(1, MAX_SIGNERS + 1):
      y_i = polynomial_evaluate(Scalar(x_i), coefficients)
      secret_key_share_i = (x_i, y_i)
      secret_key_share.append(secret_key_share_i)
    return secret_key_shares, coefficients
]]></artwork>
        <t>Let <tt>points</tt> be the output of this function. The i-th element in <tt>points</tt> is
the share for the i-th participant, which is the randomly generated polynomial
evaluated at coordinate <tt>i</tt>. We denote a secret share as the tuple <tt>(i, points[i])</tt>,
and the list of these shares as <tt>shares</tt>.
<tt>i</tt> MUST never equal <tt>0</tt>; recall that <tt>f(0) = s</tt>, where <tt>f</tt> is the polynomial defined in a Shamir secret sharing operation.</t>
        <t>The procedure for combining a <tt>shares</tt> list of length <tt>MIN_SIGNERS</tt> to recover the
secret <tt>s</tt> is as follows.</t>
        <artwork><![CDATA[
  secret_share_combine(shares):

  Inputs:
  - shares, a list of at minimum MIN_SIGNERS secret shares, each a tuple (i, f(i))
    where i is an identifier and f(i) is a Scalar

  Outputs: The resulting secret s, a Scalar, that was previously split into shares

  Errors:
  - "invalid parameters", if less than MIN_SIGNERS input shares are provided

  def secret_share_combine(shares):
    if len(shares) < MIN_SIGNERS:
      raise "invalid parameters"
    scalar_shares = [(Scalar(x), y) for x, y in shares]
    s = polynomial_interpolation(scalar_shares)
    return s
]]></artwork>
      </section>
      <section anchor="dep-vss">
        <name>Verifiable Secret Sharing</name>
        <t>Feldman's Verifiable Secret Sharing (VSS) builds upon Shamir secret sharing,
adding a verification step to demonstrate the consistency of a participant's
share with a public commitment to the polynomial <tt>f</tt> for which the secret <tt>s</tt>
is the constant term. This check ensure that all participants have a point
(their share) on the same polynomial, ensuring that they can later reconstruct
the correct secret.</t>
        <t>The procedure for committing to a polynomial <tt>f</tt> of degree <tt>MIN_SIGNERS-1</tt> is as follows.</t>
        <artwork><![CDATA[
  vss_commit(coeffs):

  Inputs:
  - coeffs, a vector of the MIN_SIGNERS coefficients which uniquely determine
  a polynomial f.

  Outputs: a commitment vss_commitment, which is a vector commitment to each of the
  coefficients in coeffs, where each element of the vector commitment is an `Element` in `G`.

  def vss_commit(coeffs):
    vss_commitment = []
    for coeff in coeffs:
      A_i = G.ScalarBaseMult(coeff)
      vss_commitment.append(A_i)
    return vss_commitment
]]></artwork>
        <t>The procedure for verification of a participant's share is as follows.
If <tt>vss_verify</tt> fails, the participant MUST abort the protocol, and failure should be investigated out of band.</t>
        <artwork><![CDATA[
  vss_verify(share_i, vss_commitment):

  Inputs:
  - share_i: A tuple of the form (i, sk_i), where i indicates the participant
    identifier, and sk_i the participant's secret key, a secret share of the
    constant term of f, where sk_i is a Scalar.
  - vss_commitment: A VSS commitment to a secret polynomial f, a vector commitment
    to each of the coefficients in coeffs, where each element of the vector commitment
    is an Element

  Outputs: 1 if sk_i is valid, and 0 otherwise

  vss_verify(share_i, commitment)
    (i, sk_i) = share_i
    S_i = ScalarBaseMult(sk_i)
    S_i' = G.Identity()
    for j in range(0, MIN_SIGNERS):
      S_i' += G.ScalarMult(vss_commitment[j], pow(i, j))
    if S_i == S_i':
      return 1
    return 0
]]></artwork>
        <t>We now define how the Coordinator and signer participants can derive group info,
which is an input into the FROST signing protocol.</t>
        <artwork><![CDATA[
    derive_group_info(MAX_SIGNERS, MIN_SIGNERS, vss_commitment):

    Inputs:
    - MAX_SIGNERS, the number of shares to generate, an integer
    - MIN_SIGNERS, the threshold of the secret sharing scheme, an integer
    - vss_commitment: A VSS commitment to a secret polynomial f, a vector commitment to each of the
    coefficients in coeffs, where each element of the vector commitment is an Element in G.

    Outputs:
    - PK, the public key representing the group, an Element.
    - signer_public_keys, a list of MAX_SIGNERS public keys PK_i for i=1,...,MAX_SIGNERS,
      where each PK_i is the public key, an Element, for participant i.

    derive_group_info(MAX_SIGNERS, MIN_SIGNERS, vss_commitment)
      PK = vss_commitment[0]
      signer_public_keys = []
      for i in range(1, MAX_SIGNERS+1):
        PK_i = G.Identity()
        for j in range(0, MIN_SIGNERS):
          PK_i += G.ScalarMult(vss_commitment[j], pow(i, j))
        signer_public_keys.append(PK_i)
      return PK, signer_public_keys
]]></artwork>
      </section>
    </section>
    <section anchor="random-scalar">
      <name>Random Scalar Generation</name>
      <t>Two popular algorithms for generating a random integer uniformly distributed in
the range [0, G.Order() -1] are as follows:</t>
      <section anchor="rejection-sampling">
        <name>Rejection Sampling</name>
        <t>Generate a random byte array with <tt>Ns</tt> bytes, and attempt to map to a Scalar
by calling <tt>DeserializeScalar</tt>. If it succeeds, return the result. If it fails,
try again with another random byte array, until the procedure succeeds.</t>
        <t>Note the that the Scalar size might be some bits smaller than the array size,
which can result in the loop iterating more times than required. In that case
it's acceptable to set the high-order bits to 0 before calling <tt>DeserializeScalar</tt>,
but care must be taken to not set to zero more bits than required. For example,
in the <tt>FROST(Ed25519, SHA-512)</tt> ciphersuite, the order has 253 bits while
the array has 256; thus the top 3 bits of the last byte can be set to zero.</t>
      </section>
      <section anchor="wide-reduction">
        <name>Wide Reduction</name>
        <t>Generate a random byte array with <tt>L = ceil(((3 * ceil(log2(G.Order()))) / 2) / 8)</tt>
bytes, and interpret it as an integer; reduce the integer modulo <tt>G.Order()</tt> and return the
result. See <xref section="5" sectionFormat="of" target="HASH-TO-CURVE"/> for the underlying derivation of <tt>L</tt>.</t>
      </section>
    </section>
    <section anchor="test-vectors">
      <name>Test Vectors</name>
      <t>This section contains test vectors for all ciphersuites listed in <xref target="ciphersuites"/>.
All <tt>Element</tt> and <tt>Scalar</tt> values are represented in serialized form and encoded in
hexadecimal strings. Signatures are represented as the concatenation of their
constituent parts. The input message to be signed is also encoded as a hexadecimal
string.</t>
      <t>Each test vector consists of the following information.</t>
      <ul spacing="normal">
        <li>Configuration: This lists the fixed parameters for the particular instantiation
of FROST, including MAX_SIGNERS, MIN_SIGNERS, and NUM_SIGNERS.</li>
        <li>Group input parameters: This lists the group secret key and shared public key,
generated by a trusted dealer as described in <xref target="dep-dealer"/>, as well as the
input message to be signed. All values are encoded as hexadecimal strings.</li>
        <li>Signer input parameters: This lists the signing key share for each of the
NUM_SIGNERS signers.</li>
        <li>Round one parameters and outputs: This lists the NUM_SIGNERS participants engaged
in the protocol, identified by their integer identifier, the hiding and binding commitment
values produced in <xref target="frost-round-one"/>, as well as the resulting group binding factor input,
computed in part from the group commitment list encoded as described in <xref target="dep-encoding"/>,
and group binding factor as computed in <xref target="frost-round-two"/>).</li>
        <li>Round two parameters and outputs: This lists the NUM_SIGNERS participants engaged
in the protocol, identified by their integer identifier, along with their corresponding
output signature share as produced in <xref target="frost-round-two"/>.</li>
        <li>Final output: This lists the aggregate signature as produced in <xref target="frost-aggregation"/>.</li>
      </ul>
      <section anchor="frosted25519-sha-512-1">
        <name>FROST(Ed25519, SHA-512)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
MIN_SIGNERS: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: 7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a7
90c6e13a98304
group_public_key: 15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040
d380fb9738673
message: 74657374

// Signer input parameters
S1 signer_share: 929dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033
f2ec83d93509
S2 signer_share: a91e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07ee
d76bf409e80d
S3 signer_share: d3cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8
bdea643a9a02

// Round one parameters
participants: 1,3

// Signer round one outputs
S1 hiding_nonce: 1c406170127e33142b8611bc02bf14d5909e49d5cb87150eff3e
c9804212920c
S1 binding_nonce: 5be4edde8b7acd79528721191626810c94fbc2bcc814b7a67d3
01fbd7fc16e07
S1 hiding_nonce_commitment: eab073cf90278e1796c2db197566c8d1f62f9992d
399a5329239481f9cbb5811
S1 binding_nonce_commitment: 13172c94dec7b22eb0a910e93fa1af8a79e27f61
b69981e1ebb227438ca3be84
S1 binding_factor_input: 25120720c3a416e292edfb0510780bc84eb734347a5f
d84dd46d0dcbf3a21d21a23a776628859678a968acc8c8564c4641a1fd4b29a12d536
7ca12ab10b6b497980a7514dabb157e25a78ab2f02572efad70a677a398de943abb9a
f16d2decc1197f36000ae9db37db3b39f3fbf9d854bbed9cb84d41973ac81af76ad63
7166a0001
S1 binding_factor: c538ab7707e484ba5d29bb80d9ac795e0542e8089debbaca4d
f090e92a6d5504
S3 hiding_nonce: 795f87122f05b7efc4b1a52f435c3d28597411b1a6fec198ce9c
818c5451c401
S3 binding_nonce: c9193aaef37bc074ea3286d0361c815f7201bf764cd9e7d8bb4
eb5ecca840a09
S3 hiding_nonce_commitment: 049e0a8d62db8fd2f8401fb027e0a51374f5c4c79
6a1765ecf14467df8c4829a
S3 binding_nonce_commitment: eeb691d3dc19e0dbc33471c7a7681a51801c481d
a34a8f55efe3070a75e9991d
S3 binding_factor_input: 25120720c3a416e292edfb0510780bc84eb734347a5f
d84dd46d0dcbf3a21d21a23a776628859678a968acc8c8564c4641a1fd4b29a12d536
7ca12ab10b6b497980a7514dabb157e25a78ab2f02572efad70a677a398de943abb9a
f16d2decc1197f36000ae9db37db3b39f3fbf9d854bbed9cb84d41973ac81af76ad63
7166a0003
S3 binding_factor: 9e4474b925576c54c8e50ec27e09a04537c837f38b0f71312a
58a8c12861b408

// Round two parameters
participants: 1,3

// Signer round two outputs
S1 sig_share: 1f16a3989b4aa2cc3782a503331b9a21d7ba56c9c5455d06981b542
5306c9d01
S3 sig_share: 4c8f33c301c05871b434a686847d5818417a01e50a59e9e7fddaefd
e7d244207

sig: 1aff2259ecb59cfcbb36ae77e02a9b134422abeae47cf7ff56c85fdf90932b18
6ba5d65b9d0afb3decb64b8ab798f239183558aed09e46ee95f64304ae90df08
]]></artwork>
      </section>
      <section anchor="frosted448-shake256-1">
        <name>FROST(Ed448, SHAKE256)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
MIN_SIGNERS: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: 6298e1eef3c379392caaed061ed8a31033c9e9e3420726f23b4
04158a401cd9df24632adfe6b418dc942d8a091817dd8bd70e1c72ba52f3c00
group_public_key: 1588564c56a8edb53b55399df5b65fd2abe777717baa2ef440b
13fe13b7ce077347f5e4346ab4475f9258fb947978b0123884832a46c6be800
message: 74657374

// Signer input parameters
S1 signer_share: 4a2b2f5858a932ad3d3b18bd16e76ced3070d72fd79ae4402df2
01f525e754716a1bc1b87a502297f2a99d89ea054e0018eb55d39562fd0100
S2 signer_share: 2503d56c4f516444a45b080182b8a2ebbe4d9b2ab509f25308c8
8c0ea7ccdc44e2ef4fc4f63403a11b116372438a1e287265cadeff1fcb0700
S3 signer_share: 00db7a8146f995db0a7cf844ed89d8e94c2b5f259378ff66e39d
172828b264185ac4decf7219e4aa4478285b9c0eef4fccdf3eea69dd980d00

// Round one parameters
participants: 1,3

// Signer round one outputs
S1 hiding_nonce: bc449f3c5a05ab89eca0578a83ec16541c53867e56ff6bed852d
fda64785047245a0aa539a0ca7f4ba04d788e20f81210c9ee4688d25a82800
S1 binding_nonce: 7b34c981d62440777a1481dc62ec3629742a72b59cb1987209a
2d9be358ed0980f5695666c1a43837f471e0f5c311a6a223502bbea3fe21900
S1 hiding_nonce_commitment: 6bc549d7741bc4816d2baa27b8092b4e3b723d185
8cb706f618ec5ba0d1e9f22a1737a9a0659478dcb1d55e5270e7b2d5af6a0ba8d9358
7f00
S1 binding_nonce_commitment: 5fba493104d0ce08fb78bf1cfa600f9858183aa0
b561744449e2f069a6711f9736c65bd07145a0b82d9afb58b117a6e61b0bb7c9bf508
66200
S1 binding_factor_input: 766a004ac6e87a2fa70f2095b19596ac33b94e2f6803
e1a5b8fa8ea5adaf3e7989b2c167a38a42a1693ad69cfd674e089a498672753563d53
54654ba106d5fdffb134a8917fae91d412164436f734b95572af6208605744400c6ff
9a60fa2ce8fb7f3213414c32e347ee2e29e3d17654ef02da59085fa87ee0f01ff5b94
2dd66846e07ff61868d5f8ab2e11e6e59682cb8d9fec6bb1d3559b84facb63cac87e0
d9ef46411497f1866830953485da9c5ed2492c0cd23d775bcb160bc43427cf1d2a2e6
fd32488f37fc41c27e0efdf4be9f7d843dbb6673faef7f981e5b40795608d80d74700
01
S1 binding_factor: c1b2ad1032bf0fec6504d2af7d09b1b39691f33b7f5a64f6da
61322f7a8d88d8af1f2c2a474909812a956fbfa26441e08f86eab74d1b342900
S3 hiding_nonce: a1546a8083c9ccc1c5553e4376a4be3f90f5ab6d44be636032b0
645afabedd70ba4d84c5845b3b7b7c07c2d027263c4ed40c501e19076c2900
S3 binding_nonce: b8ae00851628a94ee932227f8b7b61c1a7ff878d034bc682087
dd7460b49c26956c68a9ad6303a003ae11b87bb76dd6a4e4af8073e0daf2300
S3 hiding_nonce_commitment: b7fbafb73633ca009e40671a926996bda341ce50b
6473013e865a445c64b8097c314603f2996b94a564f71322e51f4c224710252bf708f
3800
S3 binding_nonce_commitment: a9e8016ebac078f133ed18ccbaff75cb8c213cbe
03809dd2e6480e8c0b9c743af242eec49a4e1d38808956c7d6f1fb96795ed949f02cd
e5880
S3 binding_factor_input: 766a004ac6e87a2fa70f2095b19596ac33b94e2f6803
e1a5b8fa8ea5adaf3e7989b2c167a38a42a1693ad69cfd674e089a498672753563d53
54654ba106d5fdffb134a8917fae91d412164436f734b95572af6208605744400c6ff
9a60fa2ce8fb7f3213414c32e347ee2e29e3d17654ef02da59085fa87ee0f01ff5b94
2dd66846e07ff61868d5f8ab2e11e6e59682cb8d9fec6bb1d3559b84facb63cac87e0
d9ef46411497f1866830953485da9c5ed2492c0cd23d775bcb160bc43427cf1d2a2e6
fd32488f37fc41c27e0efdf4be9f7d843dbb6673faef7f981e5b40795608d80d74700
03
S3 binding_factor: 470a1fbfd4ab8f72a976b3f3a583fb9f7b7b45691a519efec8
54fa47db6335e9ab41cc95d26066a6809722523b1583f02469950bca37680c00

// Round two parameters
participants: 1,3

// Signer round two outputs
S1 sig_share: 7aee2e4005d5ad2ea252cd954d42376a5f962973211dfca267eeea5
f8dadc2b729ea136817e8f7652ac7beb49983ffdcef1d75ffa69c821a00
S3 sig_share: dc8075aee647361bfa613637fcc5a276705b1e79acff7dadcfecd4f
f9f73b32b78cbed3c633ee22eae9d023f17488624088cfaf54599dd2d00

sig: e8832eb0488e7a2b4a063eff722da98549c2ca3ffc4dec1ae2e9e5704c0880f4
f7d545bb9f47d97c62d2eec9be19027879367f6b276046db80632a4c43595a6b26472
53e3fd7456dbf3fbb713d84412b8c4db7f5e22d2176e3a1b501a57a26da94d864c1f3
b0cb8501f8a96ff5ec35600800
]]></artwork>
      </section>
      <section anchor="frostristretto255-sha-512">
        <name>FROST(ristretto255, SHA-512)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
MIN_SIGNERS: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: 1b25a55e463cfd15cf14a5d3acc3d15053f08da49c8afcf3ab2
65f2ebc4f970b
group_public_key: e2a62f39eede11269e3bd5a7d97554f5ca384f9f6d3dd9c3c0d
05083c7254f57
message: 74657374

// Signer input parameters
S1 signer_share: 5c3430d391552f6e60ecdc093ff9f6f4488756aa6cebdbad75a7
68010b8f830e
S2 signer_share: b06fc5eac20b4f6e1b271d9df2343d843e1e1fb03c4cbb673f28
72d459ce6f01
S3 signer_share: f17e505f0e2581c6acfe54d3846a622834b5e7b50cad9a2109a9
7ba7a80d5c04

// Round one parameters
participants: 1,3

// Signer round one outputs
S1 hiding_nonce: 1eaee906e0554a5e533415e971eefa909f3c614c7c75e27f381b
0270a9afe308
S1 binding_nonce: 16175fc2e7545baf7180e8f5b6e1e73c4f2769323cc76754bdd
79fe93ab0bd0b
S1 hiding_nonce_commitment: 80d35700fda011d9e2b2fad4f237bf88f2978d954
382dfd36a517ab0497a474f
S1 binding_nonce_commitment: 40f0fecaf94e656b3f802ba9827fca9fa994c13c
98a5ff257973f8bdbc733324
S1 binding_factor_input: fe9082dcc1ae1ae11380ac4cf0b6e2770af565ff5af9
016254dc7c9d4869cbae0f6e4d94b23e5781b91bc74a25e0c773446b2640290d07c83
f0b067ff870a80179b2d1262816a7a4fad96b747bd6b35ccf4a912a793c5701d54852
db80904a767cbbd6e37377eec77f407b22890c01190995066cce59d88a14ac56ac40b
3bdc90001
S1 binding_factor: c0f5ee2613c448137bae256a4e95d56deb8c59f934332c0c00
41720b8819680f
S3 hiding_nonce: 48d78b8c2de1a515513f9d3fc464a19a72304fac522f17cc6477
06cb22c21403
S3 binding_nonce: 5c0f10966b3f1386660a87de0fafd69decbe9ffae1a152a88b7
d83bb4fb1c908
S3 hiding_nonce_commitment: 20dec6ad0795f82009a1a94b6ad79f01a1e95ae8e
308d8d8fae8285982308113
S3 binding_nonce_commitment: 98437dafb20fdb18255464072bee514889aeeec3
24f149d49747143c3613056d
S3 binding_factor_input: fe9082dcc1ae1ae11380ac4cf0b6e2770af565ff5af9
016254dc7c9d4869cbae0f6e4d94b23e5781b91bc74a25e0c773446b2640290d07c83
f0b067ff870a80179b2d1262816a7a4fad96b747bd6b35ccf4a912a793c5701d54852
db80904a767cbbd6e37377eec77f407b22890c01190995066cce59d88a14ac56ac40b
3bdc90003
S3 binding_factor: 8ea449e545706bb3b42c66423005451457e4bb4dea2c2d0b1d
157e6bb652ec09

// Round two parameters
participants: 1,3

// Signer round two outputs
S1 sig_share: 5ae13621ebeef844e39454eb3478a50c4531d25939e1065f44f5b04
a8535090e
S3 sig_share: aa432dcf274a9441c205e76fe43497be99efe374f9853477bd5add2
075f6970c

sig: 9c407badb8cacf10f306d94e31fb2a71d6a8398039802b4d80a1278472397206
17516e93f8d57a2ecffd43b83ab35db6de20b6ce32673bd601508e6bfa2ba10a
]]></artwork>
      </section>
      <section anchor="frostp-256-sha-256-1">
        <name>FROST(P-256, SHA-256)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
MIN_SIGNERS: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: 8ba9bba2e0fd8c4767154d35a0b7562244a4aaf6f36c8fb8735
fa48b301bd8de
group_public_key: 023a309ad94e9fe8a7ba45dfc58f38bf091959d3c99cfbd02b4
dc00585ec45ab70
message: 74657374

// Signer input parameters
S1 signer_share: 0c9c1a0fe806c184add50bbdcac913dda73e482daf95dcb9f35d
bb0d8a9f7731
S2 signer_share: 8d8e787bef0ff6c2f494ca45f4dad198c6bee01212d6c8406715
9c52e1863ad5
S3 signer_share: 0e80d6e8f6192c003b5488ce1eec8f5429587d48cf001541e713
b2d53c09d928

// Round one parameters
participants: 1,3

// Signer round one outputs
S1 hiding_nonce: e9165dad654fc20a9e31ca6f32ac032ec327b551a50e8ac5cf25
f5c4c9e20757
S1 binding_nonce: e9059a232598a0fba0e495a687580e624ab425337c3221246fb
2c716905bc9e7
S1 hiding_nonce_commitment: 0228df2e7f6c254b40a9f8853cf6c4f21eacbb6f0
663027384966816b57e513304
S1 binding_nonce_commitment: 02f5b7f48786f8b83ebefed6249825650c4fa657
da66ae0da1b2613dedbe122ec8
S1 binding_factor_input: 3617acb73b44df565fbcbbbd1824142c473ad1d6c800
7c4b72a298d1eaae5766b730d2e6594ea697a5971f15e989ac47ecc015692ad88b615
a41e652a306c7e50001
S1 binding_factor: 95f987c0ab590507a8c4deaf506ffc182d3626e30386306f7a
b3aaf0b0013cd3
S3 hiding_nonce: b9d136e29eb758bd77cb83c317ac4e336cf8cda830c089deddf6
d5ec81da9884
S3 binding_nonce: 5261e2d00ce227e67bb9b38990294e2c82970f335b2e6d9f1d0
7a72ba43d01f0
S3 hiding_nonce_commitment: 02f87bd95ab5e08ea292a96e21caf9bdc5002ebf6
e3ce14f922817d26a4d08144d
S3 binding_nonce_commitment: 0263cb513e347fcf8492c7f97843ed4c3797f2f3
fe925b1e68f65fb90826fe9597
S3 binding_factor_input: 3617acb73b44df565fbcbbbd1824142c473ad1d6c800
7c4b72a298d1eaae5766b730d2e6594ea697a5971f15e989ac47ecc015692ad88b615
a41e652a306c7e50003
S3 binding_factor: 2f21db4f811b13f938a13b8f2633467d250703fe5bd63cd24f
08bef6fd2f3c29

// Round two parameters
participants: 1,3

// Signer round two outputs
S1 sig_share: bdaa275f10ca57e3a3a9a7a0d95aeabb517897d8482873a8f9713d4
58f94756f
S3 sig_share: 0e8fd85386939e8974a8748e66641df0fe043323c52487a2b10b8a3
97897de21

sig: 03c41521412528dce484c35b6b9b7cc8150102ab3e4bdf858d702270c05098e6
c6cc39ffb2975df66d18521c2f3fbf08ac4f7ccafc0d4cfb4baa7cc77f082c5390
]]></artwork>
      </section>
      <section anchor="frostsecp256k1-sha-256-1">
        <name>FROST(secp256k1, SHA-256)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
MIN_SIGNERS: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: 0d004150d27c3bf2a42f312683d35fac7394b1e9e318249c1bf
e7f0795a83114
group_public_key: 02f37c34b66ced1fb51c34a90bdae006901f10625cc06c4f646
63b0eae87d87b4f
message: 74657374

// Signer input parameters
S1 signer_share: 08f89ffe80ac94dcb920c26f3f46140bfc7f95b493f8310f5fc1
ea2b01f4254c
S2 signer_share: 04f0feac2edcedc6ce1253b7fab8c86b856a797f44d83d82a385
554e6e401984
S3 signer_share: 00e95d59dd0d46b0e303e500b62b7ccb0e555d49f5b849f5e748
c071da8c0dbc

// Round one parameters
participants: 1,3

// Signer round one outputs
S1 hiding_nonce: 95f352cf568508bce96ef3cb816bf9229eb521ca9c2aff6a4fe8
b86bf49ae16f
S1 binding_nonce: c675aea50ff2510ae6b0fcb55432b97ad0b55a28b959bacb0e8
b466dbf43dd26
S1 hiding_nonce_commitment: 028acf8c9e345673e2544248006f4ba7ead5e94e1
70062b86eb532a74c26f79f98
S1 binding_nonce_commitment: 0314c33f75948224dd39cdffc68fa0faeeb42f7e
f94f1552c920196d53fbda04ce
S1 binding_factor_input: d759fa818c284537bbb2efa2d7247eac9232b7b992cd
49237106acab251dd9543f613ca4fea19d29cc54b4aa618e93289eff0da1a87fcebd1
d690283016126580001
S1 binding_factor: 6c7933abb7bc86bcc5c549ba984b9526dca099f9d9b787cedd
e20c70d36f5fc1
S3 hiding_nonce: b5089ebf363630d3477711005173c1419f4f40514f7287b4ca6f
f110967a2d70
S3 binding_nonce: 5e50ce9975cfc6164e85752f52094b11091fdbca846a9c245fd
bfa4bab1ae28c
S3 hiding_nonce_commitment: 039121f05be205b6a52ffdfdcd5f9cdc3b074a7f0
f031dac294e747b7ca83567d5
S3 binding_nonce_commitment: 0265c40f57bdcdcd0dfa43a8d353301e1474517b
70da29ddb1cb4461cd09eee1ce
S3 binding_factor_input: d759fa818c284537bbb2efa2d7247eac9232b7b992cd
49237106acab251dd9543f613ca4fea19d29cc54b4aa618e93289eff0da1a87fcebd1
d690283016126580003
S3 binding_factor: 1b18e710a470fe513e4387c613321aa41151990f65a8577343
b45d6883ab877d

// Round two parameters
participants: 1,3

// Signer round two outputs
S1 sig_share: 280c44c6c37cd64c7f5a552ae8416a57d21c115cab524dbff5fbceb
bf5c0019d
S3 sig_share: e372bca35133a80ca140dcac2125c966b763a934678f40e09fb8b0a
e9d4aee1b

sig: 0364b02292a4b0e61f849f4d6fac0e67c2f698a21e1cba9e4a5b8fa535f2f931
0d0b7f016a14b07e59209b31d7096733bfced0ddaa6398ee64d5e220ddc2d4ae77
]]></artwork>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+29+37cRpIm+j+eAmv/0aRNlnG/qFuzS0uypV/LlyPa3TvT
7VUlgARZdrGKUyhKot2eZ9lnOU92vojIBBKoKorypcczx+q2RFYBeY3LF5GR
Eaenp952sV3qB/57X71en75Y36wa/6vLje4u18vGP68vV+vNxj9fXKzU9gYf
+68X20v/kxdfnH/1nqeqaqNf4V3ze7OuV+oKjTUb1W5PF5tte1q3m4vTdrPu
tqdB4dVqqy/Wm9sH/mLVrj1vcb154G83N902CoIyiDy10eqB/6le6Y1aeq/X
m+8uNuub6wf+o09efOp9p2/xUfPAf7ba6s1Kb08fU0+e123VqnmplusVer/V
ndddqc325b/frLe6e+Cv1t714oH/t+26PvG79Wa70W2Hn26v6IdvPE/dbC/X
mweef+pjZHjj8cx/tF6t1svlrefjj8zrsV5smo0ef7XeXKjV4nu1XaxXD/x/
q1WHBaKF5E/4EX2lFkssy83m5qqm2d4sb67+1wV9OqvXV0O3j2b+n9dXy7XT
56NLvey0cj4fd/j1avFKb7rF9tZft/5fscCb5Xp9cudA6u+osf9189o8PavV
MIZnM/9TbH6lNxfOMJ6p1fjj+4zC7XOhVhcHesSsz2b+X9frZjTvzaLbrq8v
9Wb07bjfR8v1TdMuQTaj+anX/+tSq+vF6qJabLsZKMXzQMlXeOuVxjb7b8pZ
Fj3gdywDfHlTLRe1/2d96z/a3F5v1xcbdX1567frjb+91P4ni5Va1Qu19M/1
5tWiBjM8WzXYTCJneuDJcrm43qKJRzebV9p/vLhYbOlpyzz+2RK0D/658o+e
PHp8fnb8Hg8A+4P+z/X1iR+WZcGfdXqz0B0xiQzS9987+/z82XsP/P9NIz/t
H+wpl/+cmn95mR749Ao+OX/yKBzPdTJUd74n/jkxk9o0HU/9Sdsu6oVebcer
8imx5YmPTZ/5kcxjqzYXevvAv9xur7sHH33U6fpihnHQD+Hpq2h23bTOhInj
ZXCTjXihwRNXetXoZmdN19jglf+l2oBGQEndrzPaaN9ow8Cj/XCIiMVeFDzY
256+3ixW29lC1RtuNgqi4KMiHdq9U/DuF7h7NvyglBi+22FdO6MoOA2j0yii
XRBJH4X3nkz4URjn6WgmT9ev/e3a/3KzxlZZ3XHWdTdXYET7wV2zeLIEY1ca
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
UZLgf82MtzbmKgY0FJCVjRrntXdLF53I0ioS+FpSFZo5WIOmz0bVSFmaN5JR
Q5QXp/7pbWkn/8QP7+9Jc+9556S4lJupn8a/N08/V5+yifoH468lYKQ3lGbE
k/wNvG6fkDoTFc9E1iwugLKXdIqwYbeIGpcHwKpQtRS5/W0zOshoIJaXtgIY
j4ZL8EK3K1PMWSL3JI+U1bXuFDyXj4cIu1GJAaMmQDu32EoKhOOIQ6EHpzdI
qKFQVz/Bm85wF6TJ5XrZjO8qUNIcyo2Afx5SYGCSZED0A1D3nKepFeqNc4qw
k1RTGS4qSrx3Vya5SCUdrp0T50qWKdAQnIadCi39GdCQ9mQ8AEt4Jtew1Hnv
6zyPV3GccYRcS041Blu7xB95FT0ePBVF5hzNBHHNiROtKlusIlAdj58jV3jv
nTQ20tyIuqQk2QCIYcLWYDrJM4Km+4TCpnqI5UCb6djgYxEbnCa0lySA7EtT
HbmvXTHCk+RWleLTlC8RBu4z8pg+h+lQb27aLT44W4KhIWdoB8iRCZgFOI3l
+ngDo5u9WCtY3mv/0/XNK608Ki/Lca3U+llNFdUBbi9Yk5hD+d5F8ZqgyRXI
jFRfv7ayZSYnmgyO18LkVvi3mg5kPiG9LzupyUrUWvC8VlfiNzbOisEJPcpL
TCvyJfuc2YEuZ/HkVd7jiLb1sadJixSBj+3CZK0Z0srs+kkEtg41DGUjZ975
qFrOwvUmKzdr1gu27QAfTEIL57yY0u6sbL5QbydjUJ90jb95yd+8lKEeccJQ
dEKpOill1jgzm/12NVgg5MJwrkV4JrXaUN/MZPcy99P6JHQyicF34UnqXzf9
6cmkIFmfFy2kQ72hkXF20mDITGpzn90xT6rpZbKs8YQl2vDqivJxSQLE3eRd
cvby3eFH0JI0ZBMfvhTyfTg0/Y9/2BbovmEnp8bU3NPoaPKaSZW4Nx/j90MW
xhe7yRdP/HpUfsxNs/h+f/zwWI4c/gzCGVWncsrDex5VHLQ17w+Xml90YrBe
c8Hx1U7d+ZNeaxJhmrMOt7yfyW0rBwvzbr7Pc8K7zHE755fqaiFlRP7SH0t4
5/L2uRxL7LkFSRPr+NX+pKc/rmDbkqS2Pd6wRyBQcjQeY5kZq+QOo5PcekvW
gYwa6VdffHy2cJg3YLqp39cAbrNA4/OecCgV41+s143jBBMGiI5tMQCzjgZm
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
+FUWAwHpLGnoYA6f1BENJc8Zrfx/uhzE10tEAQA=

-->

</rfc>
