<?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-rfc2629 version 1.6.5 (Ruby 3.0.3) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-frost-04" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.12.3 -->
  <front>
    <title abbrev="FROST">Two-Round Threshold Schnorr Signatures with FROST</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-frost-04"/>
    <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="March" day="29"/>
    <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, and implements
signing efficiency improvements described by <xref target="Schnorr21"/>. 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>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-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 notation and terminology are used throughout this document.</t>
      <ul spacing="normal">
        <li>A participant is an entity that is trusted to hold a secret share.</li>
        <li>
          <tt>NUM_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>THRESHOLD_LIMIT</tt> denotes the threshold number of participants required to issue a signature. More specifically,
at least THRESHOLD_LIMIT shares must be combined to issue a valid signature.</li>
        <li>
          <tt>len(x)</tt> is the length of integer input <tt>x</tt> as an 8-byte, big-endian integer.</li>
        <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>|| denotes concatenation, i.e., x || y = xy.</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 <tt>G</tt> of prime order <tt>p</tt>. The fundamental group operation
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>GG</tt>, there exists an element
<tt>-A</tt> such that <tt>A + (-A) = (-A) + A = I</tt>. Scalar multiplication is equivalent to the repeated
application of the group operation on an element A with itself <tt>r-1</tt> times, this is denoted
as <tt>r*A = A + ... + A</tt>. For any element <tt>A</tt>, <tt>p * A = I</tt>. We denote <tt>B</tt> as the 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 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 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 a prime-order group <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 element of the group (i.e. <tt>I</tt>).</li>
          <li>RandomScalar(): A member function of <tt>G</tt> that chooses at random a
Scalar element in GF(p).</li>
          <li>RandomNonzeroScalar(): A member function of <tt>G</tt> that chooses at random a
non-zero Scalar element in GF(p).</li>
          <li>SerializeElement(A): A member function of <tt>G</tt> that maps an Element <tt>A</tt>
to a unique byte array <tt>buf</tt> of fixed length <tt>Ne</tt>.</li>
          <li>DeserializeElement(buf): A member function of <tt>G</tt> that attempts to map a
byte array <tt>buf</tt> to an Element <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): A member function of <tt>G</tt> that maps a Scalar <tt>s</tt>
to a unique byte array <tt>buf</tt> of fixed length <tt>Ns</tt>.</li>
          <li>DeserializeScalar(buf): A member function of <tt>G</tt> that attempts to map a
byte array <tt>buf</tt> to a Scalar <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 three separate domain-separated hashes,
H1, H2, and H3, where H1 and H2 map arbitrary inputs to non-zero Scalar elements of
the prime-order group scalar field, and H3 is an alias for H with domain separation
applied. The details of H1, H2, and H3 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>Schnorr signatures, <xref target="dep-schnorr"/>;</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>This sections describes these operations in more detail.</t>
      <section anchor="dep-schnorr">
        <name>Schnorr Signature Operations</name>
        <t>In the single-party setting, a Schnorr signature is generated with the
following operation.</t>
        <artwork><![CDATA[
  schnorr_signature_generate(msg, SK):

  Inputs:
  - msg, message to be signed, an octet string
  - SK, private key, a scalar

  Outputs: signature (R, z), a pair of scalar values

  def schnorr_signature_generate(msg, SK):
    PK = G.ScalarBaseMult(SK)
    k = G.RandomScalar()
    R = G.ScalarBaseMult(k)

    comm_enc = G.SerializeElement(R)
    pk_enc = G.SerializeElement(PK)
    challenge_input = comm_enc || pk_enc || msg
    c = H2(challenge_input)

    z = k + (c * SK)
    return (R, z)
]]></artwork>
        <t>The corresponding verification operation is as follows.  Here, <tt>h</tt> is
the cofactor for the group being operated over, e.g. <tt>h=8</tt> for the
case of Curve25519, <tt>h=4</tt> for Ed448, and <tt>h=1</tt> for groups such as
ristretto255 and secp256k1, etc.  This final scalar multiplication
MUST be performed when <tt>h&gt;1</tt>.</t>
        <artwork><![CDATA[
  schnorr_signature_verify(msg, sig, PK):

  Inputs:
  - msg, signed message, an octet string
  - sig, a tuple (R, z) output from schnorr_signature_generate or FROST
  - PK, public key, a group element

  Outputs: 1 if signature is valid, and 0 otherwise

  def schnorr_signature_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 + (c * PK)
    check = (l - r) * h
    return check == G.Identity()
]]></artwork>
      </section>
      <section anchor="dep-polynomial">
        <name>Polynomial Operations</name>
        <t>This section describes operations on and associated with polynomials
that are used in the main signing protocol. A polynomial of degree t
is represented as a sorted list of t coefficients. A point on the
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 (counter, coeff) in coeffs.reverse():
      if counter == coeffs.len() - 1:
        value += coeff // add the constant term
      else:
        value += coeff
        value *= x

    return value
]]></artwork>
        </section>
        <section anchor="lagrange-coefficients">
          <name>Lagrange coefficients</name>
          <t>Lagrange coefficients are used in FROST to evaluate a polynomial
<tt>f</tt> at <tt>f(0)</tt>, given a set of <tt>t</tt> other points, where <tt>f</tt> is
represented as a set of coefficients.</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 coordinate is less than or equal to 0

  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"

    numerator = 1
    denominator = 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</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 = F(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>Commitment List Encoding</name>
        <t>This section describes the subroutine used for encoding a list of signer
commitments into a bytestring that is used 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 index 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 index.

  Outputs: A byte string containing the serialized representation of commitment_list.

  def encode_group_commitment_list(commitment_list):
    encoded_group_commitment = nil
    for (index, hiding_nonce_commitment, binding_nonce_commitment) in commitment_list:
      encoded_commitment = encode_uint16(index) ||
                           G.SerializeElement(hiding_nonce_commitment) ||
                           G.SerializeElement(binding_nonce_commitment)
      encoded_group_commitment = encoded_group_commitment || encoded_commitment
    return encoded_group_commitment
]]></artwork>
      </section>
      <section anchor="dep-binding-factor">
        <name>Binding Factor Computation</name>
        <t>This section describes the subroutine for computing the binding factor based
on the signer commitment list and message to be signed.</t>
        <artwork><![CDATA[
  Inputs:
  - encoded_commitment_list, an encoded commitment list (as computed
    by encode_group_commitment_list)
  - msg, the message to be signed (sent by the Coordinator).

  Outputs: binding_factor, a Scalar representing the binding factor

  def compute_binding_factor(encoded_commitment_list, msg):
    msg_hash = H3(msg)
    rho_input = encoded_commitment_list || msg_hash
    binding_factor = H1(rho_input)
    return binding_factor
]]></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 index 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 index.
  - binding_factor, a Scalar

  Outputs: An Element representing the group commitment

  def compute_group_commitment(commitment_list, binding_factor):
    group_commitment = G.Identity()
    for (_, hiding_nonce_commitment, binding_nonce_commitment) in commitment_list:
      group_commitment = group_commitment + (hiding_nonce_commitment + (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 representing the group commitment
  - group_public_key, public key corresponding to the signer secret key share.
  - msg, the message to be signed (sent by the Coordinator).

  Outputs: a challenge Scalar value

  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. Signing participants are
entities with signing key shares that participate in the threshold signing
protocol. The coordinator is a distinguished signer with the following responsibilities:</t>
      <ol spacing="normal" type="1"><li>Determining which signers will participate (at least THRESHOLD_LIMIT 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 the dealer, signer, and
Coordinator 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 signing participant <tt>P_i</tt> knows the following
group info:</t>
      <ul spacing="normal">
        <li>Group public key, denoted <tt>PK = G.ScalarMultBase(s)</tt>, corresponding to the group secret key <tt>s</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 = G.ScalarMultBase(sk_i)</tt>, which are similarly
outputs from the group's key generation protocol.</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>.</li>
      </ul>
      <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                     |
            |<-----------------------------------------+

      == 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"/>. The final Aggregation step is described in
<xref target="frost-aggregation"/>.</t>
      <t>FROST assumes reliable message delivery between Coordinator and signing participants in
order for the protocol to complete. Messages exchanged during signing operations are all within
the public domain. An attacker masquerading as another participant will result only in an invalid
signature; see <xref target="sec-considerations"/>.</t>
      <section anchor="frost-round-one">
        <name>Round One - Commitment</name>
        <!-- Should we only require that the set of participants be selected and used in round 2? -->

<t>Round one involves each signer generating a pair of 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: None

  Outputs: (nonce, comm), a tuple of nonce and nonce commitment pairs.

  def commit():
    hiding_nonce = G.RandomNonzeroScalar()
    binding_nonce = G.RandomNonzeroScalar()
    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; see <xref target="encode-commitment"/>
for encoding recommendations.</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 THRESHOLD_LIMIT). 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 other 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. 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:
  - index, Index `i` of the signer. Note index will never equal `0`.
  - sk_i, Signer secret key share.
  - group_public_key, public key corresponding to the signer secret key share.
  - 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, where each element in the list indicates the signer index j and their
    two commitment Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
    This list MUST be sorted in ascending order by signer index.
  - participant_list, a set containing identifiers for each signer, similarly of length
    NUM_SIGNERS (sent by the Coordinator).

  Outputs: a Scalar value representing the signature share

  def sign(index, sk_i, group_public_key, nonce_i, msg, commitment_list, participant_list):
    # Encode the commitment list
    encoded_commitments = encode_group_commitment_list(commitment_list)

    # Compute the binding factor
    binding_factor = compute_binding_factor(encoded_commitments, msg)

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

    # Compute Lagrange coefficient
    lambda_i = derive_lagrange_coefficient(index, 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 collector; see <xref target="encode-sig-share"/> for encoding
recommendations. Each signer MUST delete the nonce and corresponding commitment
after this round completes.</t>
        <t>Upon receipt from each Signer, the Coordinator MUST validate the input
signature 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:
  - index, Index `i` of the signer. Note index will never equal `0`.
  - PK_i, the public key for the ith signer, where `PK_i = G.ScalarBaseMult(sk_i)`
  - comm_i, pair of Element values (hiding_nonce_commitment, binding_nonce_commitment) generated
    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 index 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 index.
  - participant_list, a set containing identifiers for each signer, similarly of length
    NUM_SIGNERS (sent by the Coordinator).
  - group_public_key, the public key for the group
  - msg, the message to be signed

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

  def verify_signature_share(index, PK_i, comm_i, sig_share_i, commitment_list,
                             participant_list, group_public_key, msg):
    # Encode the commitment list
    encoded_commitments = encode_group_commitment_list(commitment_list)

    # Compute the binding factor
    binding_factor = compute_binding_factor(encoded_commitments, msg)

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

    # Compute the commitment share
    (hiding_nonce_commitment, binding_nonce_commitment) = comm_i
    comm_share = hiding_nonce_commitment + (binding_nonce_commitment * binding_factor)

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

    # Compute Lagrange coefficient
    lambda_i = derive_lagrange_coefficient(index, participant_list)

    # Compute relation values
    l = G.ScalarBaseMult(sig_share_i)
    r = comm_share + (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. Otherwise, if all signer shares
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
  - sig_shares, a set of signature shares z_i for each signer, of length NUM_SIGNERS,
  where THRESHOLD_LIMIT <= NUM_SIGNERS <= MAX_SIGNERS.

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

  def frost_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:</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>
      <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 empty.</t>
        <ul spacing="normal">
          <li>
            <t>Group: edwards25519 <xref target="RFC8032"/>
            </t>
            <ul spacing="normal">
              <li>Cofactor (<tt>h</tt>): 8</li>
              <li>SerializeElement: Implemented as specified in <xref section="5.1.2" sectionFormat="comma" target="RFC8032"/>.</li>
              <li>DeserializeElement: 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.</li>
              <li>SerializeScalar: Implemented by outputting the little-endian 32-byte encoding of
the Scalar value.</li>
              <li>DeserializeScalar: Implemented by attempting to deserialize a Scalar from a 32-byte
string. This function can fail if the input does not represent a Scalar between
the value 0 and <tt>G.Order() - 1</tt>.</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("rho" || m), interpreting the lower
32 bytes 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 lower 32 bytes
as a little-endian integer, and reducing the resulting integer modulo
L = 2^252+27742317777372353535851937790883648493.</li>
              <li>H3(m): Implemented as an alias for H, i.e., H(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>
      </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".</t>
        <ul spacing="normal">
          <li>
            <t>Group: ristretto255 <xref target="RISTRETTO"/>
            </t>
            <ul spacing="normal">
              <li>Cofactor (<tt>h</tt>): 1</li>
              <li>SerializeElement: Implemented using the 'Encode' function from <xref target="RISTRETTO"/>.</li>
              <li>DeserializeElement: Implemented using the 'Decode' function from <xref target="RISTRETTO"/>.</li>
              <li>SerializeScalar: Implemented by outputting the little-endian 32-byte encoding of
the Scalar value.</li>
              <li>DeserializeScalar: Implemented by attempting to deserialize a Scalar from a 32-byte
string. This function can fail if the input does not represent a Scalar between
the value 0 and <tt>G.Order() - 1</tt>.</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 || "digest" || m).</li>
            </ul>
          </li>
        </ul>
      </section>
      <section anchor="frosted448-shake256">
        <name>FROST(Ed448, SHAKE256)</name>
        <t>This ciphersuite uses edwards448 for the Group and SHA256 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 empty.</t>
        <ul spacing="normal">
          <li>
            <t>Group: edwards448 <xref target="RFC8032"/>
            </t>
            <ul spacing="normal">
              <li>Cofactor (<tt>h</tt>): 4</li>
              <li>SerializeElement: Implemented as specified in <xref section="5.2.2" sectionFormat="comma" target="RFC8032"/>.</li>
              <li>DeserializeElement: 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: Implemented by outputting the little-endian 48-byte encoding of
the Scalar value.</li>
              <li>DeserializeScalar: Implemented by attempting to deserialize a Scalar from a 48-byte
string. This function can fail if the input does not represent a Scalar between
the value 0 and <tt>G.Order() - 1</tt>.</li>
            </ul>
          </li>
          <li>
            <t>Hash (<tt>H</tt>): SHAKE256, and Nh = 117.
            </t>
            <ul spacing="normal">
              <li>H1(m): Implemented by computing H("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 as an alias for H, i.e., H(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>
      </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".</t>
        <ul spacing="normal">
          <li>
            <t>Group: P-256 (secp256r1) <xref target="x9.62"/>
            </t>
            <ul spacing="normal">
              <li>Cofactor (<tt>h</tt>): 1</li>
              <li>SerializeElement: Implemented using the compressed Elliptic-Curve-Point-to-Octet-String
method according to <xref target="SECG"/>.</li>
              <li>DeserializeElement: Implemented by attempting to deserialize a public key using
the compressed Octet-String-to-Elliptic-Curve-Point method according to <xref target="SECG"/>,
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: Implemented using the Field-Element-to-Octet-String conversion
according to <xref target="SECG"/>.</li>
              <li>DeserializeScalar: Implemented by attempting to deserialize a Scalar from a 32-byte
string using Octet-String-to-Field-Element from <xref target="SECG"/>. This function can fail if the
input does not represent a Scalar between the value 0 and <tt>G.Order() - 1</tt>.</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 by computing H(contextString || "digest" || m).</li>
            </ul>
          </li>
        </ul>
      </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 less than <tt>(t-1)</tt> corrupted signers. So long as an adverary
corrupts fewer than <tt>(t-1)</tt> participants, the scheme remains secure against EUF-CMA attacks.</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 signing 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. The sender and receiver 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>Nonces generated by each participant in the first round of signing must be sampled
uniformly at random and cannot be derived from some deterministic function. This
is to avoid replay attacks initiated by other signers, which allows for a complete
key-recovery attack. Coordinates 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>frost_commit()</tt> as is done in the setting
where a coordinator is used. However, instead of sending the commitment
<tt>SigningCommitment</tt> to the coordinator, every participant instead will publish
this commitment to every other participant. Then, in the second round, instead of
receiving a <tt>SigningPackage</tt> from the coordinator, signers will already have
sufficient information to perform signing. They will directly perform <tt>frost_sign</tt>.
All participants will then publish a <tt>SignatureShare</tt> to one another. After having
received all signature shares from all other signers, each signer will then perform
<tt>frost_verify</tt> and then <tt>frost_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>T. Wilson-Brown</li>
        <li>Alden Torres</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="SECG" 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="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="18" month="February" 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-14"/>
        </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="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="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>The Zcash Foundation engineering team designed a serialization format for FROST messages which
we employ a slightly adapted version here.</t>
    </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 Sections <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>
      <artwork><![CDATA[
  Inputs:
  - s, a group secret that MUST be derived from at least `Ns` bytes of entropy
  - n, the number of shares to generate, an integer
  - t, the threshold of the secret sharing scheme, an integer

  Outputs:
  - signer_private_keys, `n` shares of the secret key `s`, each a Scalar value.
  - vss_commitment, a vector commitment to each of the coefficients in the polynomial defined by secret_key_shares and whose constant term is s.

  def trusted_dealer_keygen(s, n, t):
    signer_private_keys, coefficients = secret_share_shard(secret_key, n, t)
    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>C</tt>.
After receiving their secret key share and <tt>C</tt> each participant MUST perform <tt>vss_verify(secret_key_share_i, C)</tt>.
It is assumed that all participant have the same view of <tt>C</tt>.
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>s</tt> to <tt>n</tt> participants
in such a way that any cooperating subset of <tt>t</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, n, t):

  Inputs:
  - s, secret to be shared, an element of F
  - n, the number of shares to generate, an integer
  - t, the threshold of the secret sharing scheme, an integer

  Outputs:
  - secret_key_shares, A list of n secret shares, which is a tuple
  consisting of the participant identifier and the key share, each of
  which is an element of F
  - coefficients, a vector of the t coefficients which uniquely determine
  a polynomial f.

  Errors:
  - "invalid parameters", if t > n or if t is less than 2

  def secret_share_shard(s, n, t):
    if t > n:
      raise "invalid parameters"
    if t < 2:
      raise "invalid parameters"

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

    # Evaluate the polynomial for each point x=1,...,n
    secret_key_shares = []
    for x_i in range(1, n + 1):
      y_i = polynomial_evaluate(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>t</tt> to recover the
secret <tt>s</tt> is as follows.</t>
        <artwork><![CDATA[
  secret_share_combine(shares):

  Inputs:
  - shares, a list of t secret shares, each a tuple (i, f(i))

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

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

  def secret_share_combine(shares):
    if len(shares) < t:
      raise "invalid parameters"
    s = polynomial_interpolation(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>t-1</tt> is as follows.</t>
        <artwork><![CDATA[
    vss_commit(coeffs):

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

    Outputs: a commitment vss_commitment, which is a vector commitment to each of the
    coefficients in coeffs.

    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, where sk_i is a secret share of
    the constant term of f.
    - vss_commitment: A VSS commitment to a secret polynomial f.

    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, THRESHOLD_LIMIT-1):
        S_i' += vss_commitment_j * i^j
      if S_i == S_i':
        return 1
      return 0
]]></artwork>
        <t>We now define how the coordinator and signing participants can derive group info, which is an input into the FROST signing protocol.</t>
        <artwork><![CDATA[
    derive_group_info(MAX_SIGNERS, THRESHOLD_LIMIT, vss_commitment):

    Inputs:
    - MAX_SIGNERS, the number of shares to generate, an integer
    - THRESHOLD_LIMIT, the threshold of the secret sharing scheme, an integer
    - vss_commitment: A VSS commitment to a secret polynomial f.

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

    derive_group_info(MAX_SIGNERS, THRESHOLD_LIMIT, vss_commitment)
      PK = vss_commitment[0]
      signer_public_keys = []
      for i in range(1, MAX_SIGNERS):
        PK_i = G.Identity()
        for j in range(0, THRESHOLD_LIMIT-1):
          PK_i += vss_commitment_j * i^j
        signer_public_keys.append(PK_i)
      return PK, signer_public_keys
]]></artwork>
      </section>
    </section>
    <section anchor="wire-format">
      <name>Wire Format</name>
      <t>Applications are responsible for encoding protocol messages between peers. This section
contains RECOMMENDED encodings for different protocol messages as described in <xref target="frost-spec"/>.</t>
      <section anchor="encode-commitment">
        <name>Signing Commitment</name>
        <t>A commitment from a signer is a pair of Element values. It can be encoded in the following manner.</t>
        <artwork><![CDATA[
  SignerID uint64;

  struct {
    SignerID id;
    opaque D[Ne];
    opaque E[Ne];
  } SigningCommitment;
]]></artwork>
        <dl>
          <dt>id</dt>
          <dd>
            <t>The SignerID.</t>
          </dd>
          <dt>D</dt>
          <dd>
            <t>The commitment hiding factor encoded as a serialized group element.</t>
          </dd>
          <dt>E</dt>
          <dd>
            <t>The commitment binding factor encoded as a serialized group element.</t>
          </dd>
        </dl>
      </section>
      <section anchor="encode-package">
        <name>Signing Packages</name>
        <t>The Coordinator sends "signing packages" to each Signer in Round two. Each package
contains the list of signing commitments generated during round one along with the
message to sign. This package can be encoded in the following manner.</t>
        <artwork><![CDATA[
struct {
  SigningCommitment signing_commitments<1..2^16-1>;
  opaque msg<0..2^16-1>;
} SigningPackage;
]]></artwork>
        <dl>
          <dt>signing_commitments</dt>
          <dd>
            <t>An list of SIGNING_COUNT SigningCommitment values, where THRESHOLD_LIMIT &lt;= SIGNING_COUNT &lt;= NUM_SIGNERS,
ordered in ascending order by SigningCommitment.id. This list MUST NOT contain more than one
SigningCommitment value corresponding to each signer. Signers MUST ignore SigningPackage values with
duplicate SignerIDs. <!-- this requirement should move to the main body of the spec -->
            </t>
          </dd>
          <dt>msg</dt>
          <dd>
            <t>The message to be signed.</t>
          </dd>
        </dl>
      </section>
      <section anchor="encode-sig-share">
        <name>Signature Share</name>
        <t>The output of each signer is a signature share which is sent to the Coordinator. This
can be constructed as follows.</t>
        <artwork><![CDATA[
  struct {
    SignerID id;
    opaque signature_share[Ns];
  } SignatureShare;
]]></artwork>
        <dl>
          <dt>id</dt>
          <dd>
            <t>The SignerID.</t>
          </dd>
          <dt>signature_share</dt>
          <dd>
            <t>The signature share from this signer encoded as a serialized scalar.</t>
          </dd>
        </dl>
      </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 Element and Scalar 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, THRESHOLD_LIMIT, 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 index, 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 index, 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
THRESHOLD_LIMIT: 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,2
group_binding_factor_input: 000178e175d15cb5cec1257e0d84d797ba8c3dd9b
4c7bc50f3fa527c200bcc6c4a954cdad16ae67ac5919159d655b681bd038574383bab
423614f8967396ee12ca62000288a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea98
981bfb25375996c5767c932bbf10c41feb17d41cc6433e69f16cceccc42a00aedf72f
eb5f44929fdf2e2fee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a
5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f500
28a8ff
group_binding_factor: c4d7668d793ff4c6ec424fb493cdab3ef5b625eefffe775
71ff28a345e5f700a

// Signer round one outputs
S1 hiding_nonce: 570f27bfd808ade115a701eeee997a488662bca8c2a073143e66
2318f1ed8308
S1 binding_nonce: 6720f0436bd135fe8dddc3fadd6e0d13dbd58a1981e587d377d
48e0b8f1c3c01
S1 hiding_nonce_commitment: 78e175d15cb5cec1257e0d84d797ba8c3dd9b4c7b
c50f3fa527c200bcc6c4a95
S1 binding_nonce_commitment: 4cdad16ae67ac5919159d655b681bd038574383b
ab423614f8967396ee12ca62
S2 hiding_nonce: 2a67c5e85884d0275a7a740ba8f53617527148418797345071dd
cf1a1bd37206
S2 binding_nonce: a0609158eeb448abe5b0df27f5ece96196df5722c01a999e8a4
5d2d5dfc5620c
S2 hiding_nonce_commitment: 88a4e6c3d8353dc3f4aca2e10d10a75fb98d9fbea
98981bfb25375996c5767c9
S2 binding_nonce_commitment: 32bbf10c41feb17d41cc6433e69f16cceccc42a0
0aedf72feb5f44929fdf2e2f

// Round two parameters
participants: 1,2

// Signer round two outputs
S1 sig_share: b7e8f03a1a1149adacb96f952dbc39b6034facceafe4a70d6963592
fce75570c
S2 sig_share: cd388f9aff4376397c5ad231713fe6b167bed9cc88a1cc97b0b6bbe
0316a7909

sig: ebe7efbb42c4b1c55106b5536fb5e9ac7a6d0803ea4ae9c8c629ca51e05c230e
974d8a78fff1ac8e52774a24c00141536b0d869b388674a5191a151000e0d005
]]></artwork>
      </section>
      <section anchor="frosted448-shake256-1">
        <name>FROST(Ed448, SHAKE256)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
THRESHOLD_LIMIT: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: cdf4a803a21d82fa90692e86541e08d878c9f688e5d71a2bd35
4a9a3af62b8c7c89753055949cab8fd044c17c94211f167672b053659420b00
group_public_key: 800e9b495543b04aaebdba2813de65d1aefe78e8b219d38966b
c0afa1d5d9d685c740c8ab720bff3c84cd9f4a701c1588e40d981f4abb19600
message: 74657374

// Signer input parameters
S1 signer_share: d208a2f1d9ead0cc4b4b9b2e84a22f8e2aa2ab4ee715febe7a08
175d4298dd6bbe2e1c0b29aaa972c78555ea3b3d7308b248994780219e0800
S2 signer_share: d71c9bdf11b81f9f062d08d7b3265744dc7a6014e953e15222bc
8416d5cd0210b4c5e410f90a892c91065fbdae37d51ffc29078acae9f90500
S3 signer_share: dc3094cd49856e71c10e757fe3aa7efa8d5315daea91c4e6c96f
f2cf670328b4a95cad16c96b68e65a87689021323737460b75cc14b2550300

// Round one parameters
participants: 1,2
group_binding_factor_input: 00016d8ef55145bab18c129311f1d07bef2110d0b
6841aae919eb6abf5e523d26f819d3695d78f8aa246c6b6d6fd6c2b8a63dd1cf8e8c8
9a870400a0c29f750605b10c52e347fc538af0d4ebddd23a1e0300482a7d98a39d408
356b9041d5fbaa274c2dc3f248601f21cee912e2f5700c1753a80000242c2fdc11e5f
726d4c897ed118f668a27bfb0d5946b5f513e975638b7c4b0a46cf5184d4a9c1f6310
fd3c10f84d9de704a33aab2af976d60804fa4ecba88458bcf7677a3952f540e20556d
5e90d5aa7e8f226d303ef7b88fb33a63f6cac6a9d638089b1739a5d2564d15fb3e43e
1b0b28a80b54ff7255705a71ee2925e4a3e30e41aed489a579d5595e0df13e32e1e4d
d202a7c7f68b31d6418d9845eb4d757adda6ab189e1bb340db818e5b3bc725d992faf
63e9b0500db10517fe09d3f566fba3a80e46a403e0c7d41548fbf75cf2662b00225b5
02961f98d8c9ff937de0b24c231845
group_binding_factor: 2716e157c3da80b65149b1c2cb546723516272ccf75e111
334533e2840a9bf85f3c71478ade11be26d26d8e4b9a1667af88f7df61670f60a00

// Signer round one outputs
S1 hiding_nonce: 04eccfe12348a5a2e4b30e95efcf4e494ce64b89f6504de46b3d
67a5341baaa931e455c57c6c5c81f4895e333da9d71f7d119fcfbd0d7d2000
S1 binding_nonce: 80bcd1b09e82d7d2ff6dd433b0f81e012cadd4661011c44d929
1269cf24820f5c5086d4363dc67450f24ebe560eb4c2059883545d54aa43a00
S1 hiding_nonce_commitment: 6d8ef55145bab18c129311f1d07bef2110d0b6841
aae919eb6abf5e523d26f819d3695d78f8aa246c6b6d6fd6c2b8a63dd1cf8e8c89a87
0400
S1 binding_nonce_commitment: a0c29f750605b10c52e347fc538af0d4ebddd23a
1e0300482a7d98a39d408356b9041d5fbaa274c2dc3f248601f21cee912e2f5700c17
53a80
S2 hiding_nonce: 3b3bbe82babf2a67ded81b308ba45f73b88f6cf3f6aaa4442256
b7a0354d1567478cfde0a2bba98ba4c3e65645e1b77386eb4063f925e00700
S2 binding_nonce: bcbd112a88bebf463e3509076c5ef280304cb4f1b3a7499cca1
d5e282cc2010a92ff56a3bdcf5ba352e0f4241ba2e54c1431a895c19fff0600
S2 hiding_nonce_commitment: 42c2fdc11e5f726d4c897ed118f668a27bfb0d594
6b5f513e975638b7c4b0a46cf5184d4a9c1f6310fd3c10f84d9de704a33aab2af976d
6080
S2 binding_nonce_commitment: 4fa4ecba88458bcf7677a3952f540e20556d5e90
d5aa7e8f226d303ef7b88fb33a63f6cac6a9d638089b1739a5d2564d15fb3e43e1b0b
28a80

// Round two parameters
participants: 1,2

// Signer round two outputs
S1 sig_share: c5ab0a80c561d1a616ac70f4f13d993156f65f2b44a4a90f37f0640
7a1b62e3940bf14199301d128358b812bef32cb4bffaf03030238772000
S2 sig_share: 15211cb96d6aa73de803d46caf2043859fd796a6282f9adb00033f1
4f4827f23f8cc792c2e322a1f30631ec7690ac587e5eb9c2afd323e3300

sig: 4d9883057726b029d042418600abe88ad3fec06d6a48dca289482e9d51c10353
37e4d1aae5fd1c73a55701133238602f423886fc134a3c6580e787ce8da00900c1a92
07fd32e9c6f956597202323f8f4264ecfd99e9539ae5c388c8e45c133fb4765ee9ff2
583d90d3e49ba02dff6ab51300
]]></artwork>
      </section>
      <section anchor="frostristretto255-sha-512">
        <name>FROST(ristretto255, SHA-512)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
THRESHOLD_LIMIT: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: b020be204b5e758960458ca9c4675b56b12a8faff2be9c94891
d5e1cd75c880e
group_public_key: e22ac4850672021eac8e0a36dfc4811466fb01108c3427d2347
827467ba02a34
message: 74657374

// Signer input parameters
S1 signer_share: 92ae65bb90030a89507fa00fff08dfed841cf996de5a0c574f1f
4693ddcb6705
S2 signer_share: 611003b3f00bb1e01656ac1818a4419a580e637ecaf67b191521
2e0ae43a470c
S3 signer_share: 439eaa4d36b145e00690c07e5245c5312c00cd65b692ebdbda22
1681eaa92603

// Round one parameters
participants: 1,2
group_binding_factor_input: 0001824e9eddddf02b2a9caf5859825e999d791ca
094f65b814a8bca6013d9cc312774c7e1271d2939a84a9a867e3a06579b4d25659b42
7439ccf0d745b43f75b76600028013834ff4d48e7d6b76c2e732bc611f54720ef8933
c4ca4de7eaaa77ff5cd125e056ecc4f7c4657d3a742354430d768f945db229c335d25
8e9622ad99f3e7582d07b35bd9849ce4af6ad403090d69a7d0eb88bba669a9f985175
d70cd15ad5f1ef5b734c98a32b4aab7b43a57e93fc09281f2e7a207076b31e416ba63
f53d9d
group_binding_factor: f00ae6007f2d74a1507c962cf30006be77596106db28f2d
5443fd66d755e780c

// Signer round one outputs
S1 hiding_nonce: 349b3bb8464a1d87f7d6b56f4559a3f9a6335261a3266089a9b1
2d9d6f6ce209
S1 binding_nonce: ce7406016a854be4291f03e7d24fe30e77994c3465de031515a
4c116f22ca901
S1 hiding_nonce_commitment: 824e9eddddf02b2a9caf5859825e999d791ca094f
65b814a8bca6013d9cc3127
S1 binding_nonce_commitment: 74c7e1271d2939a84a9a867e3a06579b4d25659b
427439ccf0d745b43f75b766
S2 hiding_nonce: 4d66d319f20a728ec3d491cbf260cc6be687bd87cc2b5fdb4d5f
528f65fd650d
S2 binding_nonce: 278b9b1e04632e6af3f1a3c144d07922ffcf5efd3a341b47abc
19c43f48ce306
S2 hiding_nonce_commitment: 8013834ff4d48e7d6b76c2e732bc611f54720ef89
33c4ca4de7eaaa77ff5cd12
S2 binding_nonce_commitment: 5e056ecc4f7c4657d3a742354430d768f945db22
9c335d258e9622ad99f3e758

// Round two parameters
participants: 1,2

// Signer round two outputs
S1 sig_share: 6a539c3a4ee281879a6fb350d20d53e17473f28cd3409ffc238dafe
8d9330605
S2 sig_share: 1d4e59636ee089bfaf548834b07658216649a37f87f0818d5190aa9
b90957505

sig: 7e92309bf40993141acd5f2c7680a302cc5aa5dd291a833906da8e35bc39b03e
87a1f59dbcc20b474ac43b858284ab02dbbc950c5b31218a751d5a846ac97b0a
]]></artwork>
      </section>
      <section anchor="frostp-256-sha-256-1">
        <name>FROST(P-256, SHA-256)</name>
        <artwork><![CDATA[
// Configuration information
MAX_SIGNERS: 3
THRESHOLD_LIMIT: 2
NUM_SIGNERS: 2

// Group input parameters
group_secret_key: 6f090d1393ff53bbcbba036c00b8830ab4546c251dece199eb0
3a6a51a5a5928
group_public_key: 033a2a83f9c9fdfdab7d620f48238a5e6157a8eb1d6c382c7b0
ba95b7c9f69679c
message: 74657374

// Signer input parameters
S1 signer_share: 738552e18ea4f2090597aca6c23c1666845c21c676813f9e2678
6f1e410dcecd
S2 signer_share: 780198af894a90563f7555e183bfa9c25463d767cf159da261ed
379767c14472
S3 signer_share: 7c7dde7d83f02ea37952ff1c45433d1e246b8d0927a9fba69d62
00108e74ba17

// Round one parameters
participants: 1,2
group_binding_factor_input: 000102f34caab210d59324e12ba41f0802d9545f7
f702906930766b86c462bb8ff7f3402b724640ea9e262469f401c9006991ba3247c2c
91b97cdb1f0eeab1a777e24e1e0002037f8a998dfc2e60a7ad63bc987cb27b8abf78a
68bd924ec6adb9f251850cbe711024a4e90422a19dd8463214e997042206c39d3df56
168b458592462090c89dbcf84efca0c54f70a585d6aae28679482b4aed03ae5d38297
b9092ab3376d46fdf55
group_binding_factor: 9df349a9f34bf01627f6b4f8b376e8c8261d55508d1cac2
919cdaf7f9cb20e70

// Signer round one outputs
S1 hiding_nonce: 3da92a503cf7e3f72f62dabedbb3ffcc9f555f1c1e78527940fe
3fed6d45e56f
S1 binding_nonce: ec97c41fc77ae7e795067976b2edd8b679f792abb062e4d0c33
f0f37d2e363eb
S1 hiding_nonce_commitment: 02f34caab210d59324e12ba41f0802d9545f7f702
906930766b86c462bb8ff7f34
S1 binding_nonce_commitment: 02b724640ea9e262469f401c9006991ba3247c2c
91b97cdb1f0eeab1a777e24e1e
S2 hiding_nonce: 06cb4425031e695d1f8ac61320717d63918d3edc7a02fcd3f23a
de47532b1fd9
S2 binding_nonce: 2d965a4ea73115b8065c98c1d95c7085db247168012a834d828
5a7c02f11e3e0
S2 hiding_nonce_commitment: 037f8a998dfc2e60a7ad63bc987cb27b8abf78a68
bd924ec6adb9f251850cbe711
S2 binding_nonce_commitment: 024a4e90422a19dd8463214e997042206c39d3df
56168b458592462090c89dbcf8

// Round two parameters
participants: 1,2

// Signer round two outputs
S1 sig_share: 0a658fe198caddf5ddc407ad58c4615458f02a58d0c1f7a38e25692
98dc41df0
S2 sig_share: e84d948cfec74b5e7540ad09fd69dcd1570f708f2d8573dbbf08cb0
2bc872c75

sig: 035cfbd148da711bbc823455b682ed01a1be3c5415cf692f4a91b7fe22d1dec3
45f2b3246e979229545304b4b7562e3e25afff9ae7fe476b7f4d2e342c4a4b4a65
]]></artwork>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAHA8Q2IAA+196XbcRrLmfzwFRvph0maVsS90q++lJWo51jai7J47PX1Z
WBIk7GIVb6FKEq32fZZ5lnmy+SIyE0gsRdG2PN1zzlW3JbIKyCUyli8iIyNn
s5m1rbdLcWzfe/t+PXuz3q1K++3lRjSX62VpnxWXq/VmY5/VF6tsu8PH9vt6
e2k/fvPq7O09K8vzjXiHd9Xv5bpYZVdorNxk1XZWb7bVrKg2F7Nqs262Myew
imwrLtabm2O7XlVry6qvN8f2drNrtp7jpI5nZRuRHdtPxEpssqX1fr356WKz
3l0f2w8fv3li/SRu8FF5bD9bbcVmJbazR9STZTXbbFWeZ8v1Cr3fiMZqrrLN
9vw/duutaI7t1dq6ro/tv27XxZHdrDfbjaga/HRzRT/8zbKy3fZyvTm27JmN
keGNR3P74Xq1Wi+XN5aNP3Jej0S9KTei/9V6c5Gt6p+zbb1eHdv/s8gaEIgI
yZ/wI+Iqq5cgy26zuypotrvl7upfL+jTebG+6rp9OLe/W18t10afDy/FshGZ
8Xm/w+9X9Tuxaertjb2u7L+AwJvlen1060CKn6ixf929V0/Pi6wbw7O5/QSL
n4vNhTGMZ9mq//FdRmH2WWeriz09YtYnc/sv63XZm/embrbr60ux6X3b7/fh
cr0rqyXYpje/7P2/Xorsul5d5PW2mYNTLAucfIW33gkss/0hnUfeMb+jBeD1
Ll/Whf2duLEfbm6ut+uLTXZ9eWNX6429vRT243qVrYo6W9pnYvOuLiAMz1Yl
FpPYmR44XS7r6y2aeLjbvBP2o/qi3tLTWnjskyV4H/JzZR+cPnx0dnJ4jweA
9UH/Z+L6yHbTNOHPGrGpRUNCIgdp2/dOXp49u3ds/w8a+ax9sOVc/jNT/zKZ
jm16BZ+cnT580p/rYKjmfI/sMxKmbFM2PPXTqqqLWqy2fao8IbE8srHoc9uT
89hmmwuxPbYvt9vr5vjrrxtRXMwxDvrBnb3z5tdlZUyYJN6iGRrLworEc44n
2xPXm3q1nddZseFmPcdzvk7Crt1bVdm0Cpsg4V65674bCYOekefMXG/meUR0
qTs9986Tcb92/TjszeTp+r29XduvN2usktbGJ02zuwJr6w9um8XpEqKSC0z4
ITgPivHuk3yRbW7w13IpNv05ujMX03Qtazab2VkOAcgKyNezFaSgbqTyP7Lf
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
dS9I/aGJqHJfxJ4982y8DsTBCnuD55h5++vZDg6D+c///E+yJbKN87aNc93A
wVWDXs6+O8Sa2/YzFjbKA5rZ/MUVbYtc6LCbDFEQMe11sRVbFXjgx8++OzK3
3GnkUvyoXQXjjo1JHLw5sn8+pMeus3rTgVwFTumtUlR3GzllGL3+Dh7Lk/kA
7+Nr/vYn/rKPCvmLN1Nv/XRo8ZfEPudgTPnMEAS9kS1c/7T/kdeq+5azzqXR
edA1/fe/6xbwE6Ykn8cTT72DwWtqVD/jy5/I9Szgp+kJQuPvNitFVV51jlH2
A979vZXWqSKN2KgYQTO3oYFox3txSTDHkqpGBbt1OqMUulx03Ebaj3dFxfwC
MPzyQbLQT1tFJi0i5wt6YUjbSngikE+clkGQSAHFh+6ig0eN3r+1KJsTM9yu
8bbcTRHFtRdGP0EVi20xV5HJirIdNB/1XU+L45XgYYyWIlAkOZQztLj8s7u4
RU7kBqvkNXx6BD7bIyoqfqckZlpIuIXM3u6ul1oCaL+ZWIL3q/Zzu623qrmd
1yRs7QYiNSlXREcqTJFzCSz1lAdDHklxpwvj7Ze4AQ0o3KGE97WWvn9OSVlO
CffPSmDw3RstRV3vtBOO+S1B5M0hvrk0pUt9TY12TqoUNgqmdZZwpO0NQ9g3
LYZlMWyK2kqA174u6k7Nd600lk7la0EbyaWEMComqZHAnDYYDCtN0PmCoNqW
4nCtByUDJhmnuJMnAJFjZ6a3by/bqsnPkSjCaJgT5RRrfziybw41tFtQ6Lii
wLdEqHq7JFtaBW9KUQKNYDTZRlpoNh9gvwHnINTkO4AeN+YHBLEtOZZrjnVc
zz+oSMv1/GYxjJVghe7bp2RcOlfRIMveVclUuoXc31Pvc7zamPoCDg0thyV3
MnbLzNgk0HH0jgy2DHk/XW8g3F80qodWC3UNn6sOBRGU16EZa58PR6ovjEAi
esqoVC9KTNg2aJhlelU2eTR4qLfi9IbmBRWG6qkXBcZBbAiX9n6NtvRAShqe
HOcHrWo+NVESPbnb9MB2+DdahINivaP9P/XgITG/fGW+ocycRhwc6lRmqD71
NImteor2dw4xe1c/pXv5Sj1if/0150ZI27eiAyJb3tdTz1Pe8753Bx9/+UBO
t9Uh/LHWGfft5xn8QwlJO5pb1uTHPXGXjqe50j12Vhy5qA4cimNe1JQbm+l4
4mK7kIpfCnPTSmrFNn+sE+RrPU2guVXmGZ0v1YjPjYcOPpzXR/bzCZalz2Eg
exJOmShtxuvzAac+V8luciDmexg8p9xM4s3n1BFHambQn1NUpcc5pqCGdq9e
yfgS+YFXlDvR3DsiPqI4uTFaKAveBuPET1INFIGl9XA0d9+JMIpJ8TvxuGYq
GfmYGkorBR/Of2Q6GZxOHxmN3NqMPCwDx1Buoj2wXZmnL4h/Vr3PbuvtAY38
mJeuXu2E+rZrl9j//Ef1sdm4/EKyghzMcyZB9+rX5vOmBOHBTn4e6QzDkayO
NfxZt2VOb7RBm3u8yU1a/V67sa5jLyMLaWXjbpr1lRiag87MQtjm9huZzahG
ag2aKIrdptH5goaMSulU5sKYisx/WC/VPq3O7jVQvJZOU+q0rE91IWP43RSq
VqqkRSfF/l6e8uj5aR119CJ8kKbakJW+wXg7tVCVNpKkrybMQ2/CB3LMSnqe
067231pOlYiAglj8kGbY53PK7ViV8t35B4UQq3OOKD2wH1O/n2ijFMtthmdl
EzdAh7eJuOqIxFy933amfvhKttgzD/KrFlM+7OIaz8kItwEUCSvboMle+MJK
c5fDO9hSuhBbD0YyuiHDunNmvWUm0XG6ZcbBW+nFtAkpJurUidYKbk6xXtfo
OXeHJTuABrysaQznnFR2bjxTH+m4z8R3wJXz+fxvJjDpjVme2MlvJAPLWR0x
jaWR44+NbRbO8aCGqEdKf2javGrO9SjFB7vW2TK1VEWUt2HEnPQGhpKJg982
LxUD57Fod1WhccpIagoh3XgOcfIw8pveMOc9QTsxk0O0ddVS2sbTy4k9lMFq
zbVAqowS9jXPBw8dDH5X0ilfKUfvkKqvlx2m4/HvZYj9ZFPor9e1llfdd6/X
flYMd3sIh7K1mRN/JtzVPeP8DS3tndhgEhME3PsV/OPx3E0ts+/NVu98q6Ku
j2Xc56EZL70/EYi9q/7ROfO71lzo+K6KMHEg3VqvTBE0ZsayQaI4FZic1Dxj
QjCPHMkkO/5u1MFB1uhTIKWWs9t4/7CLArEXPjE2+4BPM/LBDDoDrmzjenPY
F1rNDpIcR90e2cjO9gmnRVQN+7zfzsFeKmDQSlLx0znvDz2wn/oU7FFxkst1
G4rZ04qKx/Dbkly9zqlB96Btpxev7D/Zsp/MRTKM35gBewH+X8V+G5G1RBzu
HlgchsuGHPEPsGltWO12u/ZPb9O46V9h18Y2jWi9Tyz6Bq/LJBhJy2ihB/Iy
lOuhOTsaDEEJzYRW7sUGW/t2/plt20THo4++2rto9NW+XgFrB1PtSexek9Ht
dT1s99nGYtvfZ/vNcnstNjOtZtvmJqV0ON4jM+Hk02zSNSHj7eccbzcO7wyO
FKxNOevOaOs87c9mJzJjN/PMcMiGfN0+dTAmxHhenTXont4fsx+2eGi82bX6
qfe7J/ftAAzGAmsz2Ye5K9DSZnp3wODn9jvFyHZXAEL6NWcqnP5ab6x/vC9L
0lB0+Zc2eW66XoFxprfzlKaOsk4fqJ/YhJ9bz7acebd8p872i8G5Pd456Nzv
9WbezqH/3EZYQtcu4NiD3jloGbbRh77VaxT3Wg3S+NVLVrfdID38tnu5MUBl
DvDYrm4u1SFNjFtvXhsJylKYGnnUBiM7tix3bj/Sh5joqCwHZvQ58Pf1ctkb
4MHe4wAYusxsPPzG8uadcHG38qzRwUYUQgaUOA9tvXmfbViyVR6KPJpu0vHw
Gy7W4M/tk4uLDZ+PpDzr4bE1tc2nzbfRgtyJY2ZuLrUikvH0XktznW0kk+yV
kuRjwXpDwyQFh3q6Q01bTmKhw1JHLXagcRsqhuPLfPDlct1QPYUPVChJRjXN
1JK5/XK9VUn+db8Ow3ZtQcsv1zf9XBRaZ0pyGbKB0bnO3FqtZwbvqNwtTrBo
y71wYsO3osgo02pw2k2lCbYnbLnqRsssPEGmnjxKk72TGyQHUpUc6ryhbabn
Z+5JwSu41535vGflAjx71KGogS0YS9Ockz26PaIjRb52SNTjdiA91HyL+AZC
bC9en9cL+6cVnaHuyZHVDZSzeSSiNveMdZb0opc5QVuktFV60NC2waRxUzTq
bBul71loZqFyq8wd7fYFdQzWWCrNHd0x7YU65nQuGZU0O55f8NnwR989oYzE
1+0MZPZWDwsbU+Jg8nhSPwGStmndfDClvqrxxPLGWqtU47sOG4t5slJrNhRp
80ADuHBjL7BK3UmU5c3UkskjIebi1otmzEUgN2axMALU7f6GeSaM47u0MJwH
Ij4Ayg1nciWoikjdXO0/9t4etGKpA7DSRTJGh91ZybcCz1TRFD1wD3WFjlIn
bBkICvy3fg/oY2ndeNapJ/vAO2Qf5l1d0v6KVqZVC7M0bbgJu9/E3DIGzP5N
q6j2kULqCP3YEVeS4cno3QJLVzc5GpxB7Q7UyZ01fXRAbTKovBMZcm1r/mDW
+9iLjl5c1heXS/x3y9JhxsMSA9aoqoA86MKKjLbadRWSfdWUulFrxUlFOeQE
mIy6UIi0msc2FlgPTllOw5wZTuyRRd9hSQfm0Zxa+7ZmureDQ9yN2AD6WK30
m3JnnOwzPBoOYrOf01aC6U6OS4s/PD1OOsc0HPLksaUOgBhJPqXssDFPKapJ
DYs2ydxs+aociGl8FX2bvgFQlp0mqo7ZwOZJsgNwSGsh6CRrNToTfzR0Iej3
VdcPZcFqxLJeWZT9LA/FGmcuVEZVd/yS+aat08HbMlmhFYA8I8vcV9WqlhCX
tJBumfxz0FmmQzM2anx+NPqgF1T9+yCqOlKRh5Mf3trGLd/0I7rv9r44+uZd
+6K5CP0/UlHNXPxIx7LaD2TJxdnv+EMNKGazzM//3KeD+u3BA1lpyHbtg4dG
BOLBgzHZxmHZKXr2yfb3P+0Z5leferH7URJo/5+JF6eG+skX9w11YvDWkHye
fdAFQs5YDTxpdduYnBNTbYNfhKFGNJh88at94/vzXWg00lt36PEftJxTxPnU
i3uJM0GuuxHnUz3enX/AQFPNgJtOOs08xTTdqP5u/anXHqnaj8f2/VYBy3qQ
D+4NKhxyuu67Wry/Z/9iWY/UWQSGCczIBHxGZ4mh1zn0wY/M8IhOrS9H71O2
wCfexyN0muRta2fMSbM5qpve+5Z+37BbbF/6fvGGjigTyNMBthIfcPnAHLhF
wAY+HPhXE64VbX5bMiKts547dLtuTeDcfiE7aagQgiqBJMumTRVL0x42QQO0
z61KJCzPn8wpiC0LXqHjq6z5jx3elRv1ZLFV0lbP0+BKfzL7jspZ1HxIWOX8
dEXhtH8NhDDTZZ3koHTRKanAXmHdZ+bWiw53dWtuWX/6b7MZtBuXHnwvZL+6
kF/rxKokkx5Ncx2xoGwVWbaHGUPyjPcvNgmh9ablwDbQZfh5PajZnh5QFcb2
OeOSymZyA6Wyymo20nVR7ZjBVFUko4clew/390hAxlNjmO20aCI6j7vRSNRe
yH8e9IP0g92Aw4WqW9MGpBf08/Ctu20nLIYBcvslhtYLKx+oQdBbh0dm9o8c
bVcCyCAJUaOZG5FnfKFTMM1RGmcwBkdne7uGd3l2377GRL63+ehER594u78a
MmvuLuvWbt/9tqUyI9S9NemOdujDNiraItlpIcMXr0chIkLn0HaU2L1Wlfew
lD+J661uiB0qiqipCK/pSijcL2feVn7JKTamJZhDdDIZUsmtOnhhlG/iQ+3t
FmB3hkltuqpiqBSFkOck5elGqq0nrYRSlXLGUhJunbDoigxMRBrlbvaso7o6
nNemRg0OUM6V3hs6blxehoKOF4KS5VcVk0Se6pNBANOzLChXkMfci2MfwQCQ
Kl0JGZpsshtJUtnOJVfKU+UNQGClKFut/RZOuXlqbog8B1qcLC/HIltbPXYW
OfNRxeKXQlXzW7Wx5H0nw0qmIZ91v0uwnjSLrDawL2x/OFc+UWP1Imja3mh+
vhQwRliq7Jt+eSBlDoyzadpIWMpmTEU5601f6fPeu6nRVWDNpFguLuoVl1XQ
hDKt1t4dP7p54KI7x6dLPijwMIxKSASgCapk1QQEnK9gG4ZIHn1S55xFd6Se
rHG1lntPVP5Qr6wxpS8aXUSYY39G5Jqhi1wXu9/+aOO8O6jdkkR69qe9fAWL
8wNkquu45IAUGaM6Dga05wy4ZOUzY+6Qoc12sIVx0hUbafqxOolgNIVJsBWB
ulPJlnRArjT0k7CuWfeKV/EHOmoGTCre0fIYRU5my+xGOzOWcQ5dlnbUakp1
MuseUCUEzEPEVJYJDCyDWdeq4uCuoFFXu+XoqPuRGSWVYaHNbjXcQuBpl7uN
ruDLp7ypKglFeQZ+0eTeu0rqe8bpJhQCN+K2VPuft5FkMgprhhUd31CZ9Atn
IbfLKdp9pIc6vaP+mTfopTVGp5OY8Ha7b1i1vrb4XTv/+9KNftyfbvTjLWk5
P3bpRgw0bkmjxSR0XOjzZR79+Hkyj26f4mfKPDJUq04cZM/GyKft9nkm9qTa
DSYisCyvwQMzyvXdPefDZMRx8spAJNsDnfhY59dKYRrLS8vyzKIjFT4kggL3
92U+ulAh617KXC/712SsB78ujdhSPT1UVbknUh9NTN+mHN45EbKRaS9T/Uxk
A01mXv3mJLJhp5MHlFhCs6u8zHhT87YzB2qVR8s1NbnJFKpR9sxvzyOa6nPI
ofTE7er0gWZNSwXjzmUY7kHfsxzms42T2OiRlopfsiDgn3Zah71TGG0/nbul
3Cy2YHVjd7axntj66eEvaV8JEvJp+qZNCcn5Kou1kp7lkivRDrwTypfjx5XR
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
5e44+9lW79e1FedWg9TvKwp0b1rlJcuvP3tk7yDwUfANsXmvhl77QF32Suc9
GhXTO9Wf/KIn2s1TFdOrS0v6dLpVjOOR+siYsaxXqsq9mtX+uu1n/C61d3sY
zzodN9QvHHvnloylUjltTbdQ1/KTX8Z3N8kNpHud1ZGv3mtB7Fl7qd8bXZpa
FdtTz3ZMaAYepq5x2lPgnJPX+ndBGfkp1JDietXhr2MXgzFGK6xHaVba/ZM7
n3v/7kYz98/EF4pPrpqLPznGFy27KForXploDwt8smrJQkrv2csn5w9fff/y
7cSA9PWLe8tw9hvo1+U8kvd27q1pPepuXusb7rrC2HTBnVrR/t121p7Rjsv9
GZlH7R1msnH8vFaVKTva6Sw2Wn2r3ElN2YkbVARfPyevaOgyCDXYv1q/E9rZ
5nTBfF3etFgBmkxeGYcVVLI2lXk7faFBKz/dbRTDSzHMLKupGzE6jLbnVj51
BEDxdOt19yqFzicrhe7TcoPauhNlQnl2t6i3QQvqgVGRX5kxWzd6/vtUVdMW
QrTf0tGPH9hjbro9r36ZzS09I73q7kL6XqlG4lZtsXoVR3+RObT7yspq26tQ
mz553g5Unkqj/MJWtViX4kNWiqK+ovRtPoXZzDtKjlvM2jgOcXF3kz3HZCxe
33q7Y3sMrKYueJzKylPZS8RUVNGhR1xjUJYqWKLuYDWIp+NXTeegag1pZCxz
gYSHtHN8sZPx2eNOJajzmvUHYQb+uk2S7ohOVyNUHuru0v3lcQnq9XbYyWea
O2U213UbFHG67kfj6yXxtHv8vJNo4GOqUtA7BTRMq5qAQ0byFl34DB0llku1
xJZ9y7LNbeJDg+mM5ZviKGvWGdpPzFZb1i4To930aQNOZrKHPjSKLrr7hY3F
JGKtu9h1r699SSOUbYcpl0yDQTzGSNWVFxnUm7aCiqprTi8ovES9a8TTK2+t
aGfejTF9C3dvUYzAu+SKAZpi6h7xbiwX1uZ2aWZd/v+oHjfbRmP9JnhEQ25Z
C4PmNNl71vT6nbgV/LBbJspL+McuUx+UDa+WtuxxNezJK02mLj/HLB/z1eey
idGM2jMERuN7mh3eiX5btV2yeF9/3Vd3pjK0DBV1bPvWQEkd255l0Jp+peam
1ZQlHe5un/LYjnO38P3Sr0IvdcskLEUUBYnv5yJ3szKI0iqu8sjxwswRRZzk
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

-->

</rfc>
