<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.30 (Ruby 3.4.8) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-privacypass-arc-crypto-01" category="info" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.31.0 -->
  <front>
    <title abbrev="ARC Cryptography">Anonymous Rate-Limited Credentials Cryptography</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-privacypass-arc-crypto-01"/>
    <author initials="C." surname="Yun" fullname="Cathie Yun">
      <organization>Apple, Inc.</organization>
      <address>
        <email>cathieyun@gmail.com</email>
      </address>
    </author>
    <author initials="C. A." surname="Wood" fullname="Christopher A. Wood">
      <organization>Apple, Inc.</organization>
      <address>
        <email>caw@heapingbits.net</email>
      </address>
    </author>
    <author initials="A." surname="Faz-Hernandez" fullname="Armando Faz-Hernandez">
      <organization>Cloudflare</organization>
      <address>
        <email>armfazh@cloudflare.com</email>
      </address>
    </author>
    <date year="2026" month="March" day="02"/>
    <abstract>
      <?line 60?>

<t>This document specifies the Anonymous Rate-Limited Credential (ARC) protocol,
a specialization of keyed-verification anonymous credentials with support for
rate limiting. ARC credentials can be presented from client to server up to
some fixed number of times, where each presentation is cryptographically bound
to client secrets and application-specific public information, such that each
presentation is unlinkable from the others as well as the original credential
creation. ARC is useful in applications where a server needs to throttle or
rate-limit access from anonymous clients.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://ietf-wg-privacypass.github.io/draft-arc/draft-ietf-privacypass-arc-crypto.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ietf-privacypass-arc-crypto/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        PRIVACYPASS Privacy Pass mailing list (<eref target="mailto:privacy-pass@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/privacy-pass"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/privacy-pass/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/ietf-wg-privacypass/draft-arc"/>.</t>
    </note>
  </front>
  <middle>
    <?line 71?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>This document specifies the Anonymous Rate-Limited Credential (ARC) protocol,
a specialization of keyed-verification anonymous credentials with support for
rate limiting.</t>
      <t>ARC is privately verifiable (keyed-verification), yet differs from similar token-based
protocols in that each credential can be presented multiple times without violating
unlinkability of different presentations. Servers issue credentials to clients that
are cryptographically bound to client secrets and some public information.
Afterwards, clients can present this credential to the server up to some fixed
number of times, where each presentation provides proof that it was derived
from a valid (previously issued) credential and bound to some public information.
Each presentation is pairwise unlinkable, meaning the server cannot link any two
presentations to the same client credential, nor can the server link a presentation
to the preceding credential issuance flow. Notably, the maximum number of
presentations from a credential is fixed by the application.</t>
      <t>ARC is useful in settings where applications require a fixed number of zero-knowledge
proofs about client secrets that can also be cryptographically bound to some public
information. This capability lets servers use credentials in applications that need
throttled or rate-limited access from anonymous clients.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <section anchor="notation-and-terminology">
        <name>Notation and Terminology</name>
        <t>The following functions and notation are used throughout the document.</t>
        <ul spacing="normal">
          <li>
            <t>concat(x0, ..., xN): Concatenation of byte strings. For example,
concat(0x01, 0x0203, 0x040506) = 0x010203040506.</t>
          </li>
          <li>
            <t>bytes_to_int and int_to_bytes: Convert a byte string to and from a non-negative integer.
bytes_to_int and int_to_bytes are implemented as OS2IP and I2OSP as described in
<xref target="RFC8017"/>, respectively. Note that these functions operate on byte strings
in big-endian byte order.</t>
          </li>
          <li>
            <t>random_integer_uniform(M, N): Generate a random, uniformly distributed integer R
between M inclusive and N exclusive, i.e., M &lt;= R &lt; N.</t>
          </li>
          <li>
            <t>random_integer_uniform_excluding_set(M, N, S): Generate a random, uniformly
distributed integer R between M inclusive and N exclusive, i.e., M &lt;= R &lt; N,
such that R does not exist in the set of integers S.</t>
          </li>
        </ul>
        <t>All algorithms and procedures described in this document are laid out
in a Python-like pseudocode. Each function takes a set of inputs and parameters
and produces a set of output values. Parameters become constant values once the
protocol variant and the ciphersuite are fixed.</t>
        <t>The notation <tt>T U[N]</tt> refers to an array called U containing N items of type
T. The type <tt>opaque</tt> means one single byte of uninterpreted data. Items of
the array are zero-indexed and referred as <tt>U[j]</tt> such that 0 &lt;= j &lt; N.
The notation <tt>{T}</tt> refers to a set consisting of elements of type <tt>T</tt>.
For any object <tt>x</tt>, we write <tt>len(x)</tt> to denote its length in bytes.</t>
        <t>String values such as "CredentialRequest", "CredentialResponse", "Presentation", and "Tag"
are ASCII string literals.</t>
        <t>The following terms are used throughout this document.</t>
        <ul spacing="normal">
          <li>
            <t>Client: Protocol initiator. Creates a credential request, and uses the
corresponding server response to make a credential. The client can
make multiple presentations of this credential.</t>
          </li>
          <li>
            <t>Server: Computes a response to a credential request, with its
server private keys. Later the server can verify the client's presentations
with its private keys. Learns nothing about the client's secret attributes,
and cannot link a client's request/response and presentation steps.</t>
          </li>
        </ul>
        <!-- TODO(caw): define these terms:
- tag
- attribute
- requestContext
- presentationContext
- presentationLimit
- presentation
-->

</section>
    </section>
    <section anchor="preliminaries">
      <name>Preliminaries</name>
      <t>The construction in this document has one primary dependency:</t>
      <ul spacing="normal">
        <li>
          <t><tt>Group</tt>: A prime-order group implementing the API described below in <xref target="pog"/>.
See <xref target="ciphersuites"/> for specific instances of groups.</t>
        </li>
      </ul>
      <section anchor="pog">
        <name>Prime-Order Group</name>
        <t>In this document, we assume the construction of an additive, prime-order
group <tt>Group</tt> for performing all mathematical operations. In prime-order groups,
any element (other than the identity) can generate the other elements of the
group. Usually, one element is fixed and defined as the group generator.
In the ARC setting, there are two fixed generator elements (generatorG, generatorH).
Such groups are uniquely determined by the choice of the prime <tt>p</tt> that defines the
order of the group. (There may, however, exist different representations
of the group for a single <tt>p</tt>. <xref target="ciphersuites"/> lists specific groups which
indicate both order and representation.)</t>
        <t>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>A + B = B + A</tt> is
also a member of the group. Also, for any <tt>A</tt> in the group, there exists an element
<tt>-A</tt> such that <tt>A + (-A) = (-A) + A = I</tt>. Scalar multiplication by <tt>r</tt> 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>. The case when the scalar multiplication is
performed on the group generator is denoted as <tt>ScalarMultGen(r)</tt>.
Given two elements A and B, the discrete logarithm problem is to find
an integer k such that B = k*A. Thus, k is the discrete logarithm of
B with respect to the base A.
The set of scalars corresponds to <tt>GF(p)</tt>, a prime field of order p, and are
represented as the set of integers defined by <tt>{0, 1, ..., p-1}</tt>.
This document uses types
<tt>Element</tt> and <tt>Scalar</tt> to denote elements of the group and its set of
scalars, respectively.</t>
        <t>We now detail a number of member functions that can be invoked on a
prime-order group.</t>
        <ul spacing="normal">
          <li>
            <t>Order(): Outputs the order of the group (i.e. <tt>p</tt>).</t>
          </li>
          <li>
            <t>Identity(): Outputs the identity element of the group (i.e. <tt>I</tt>).</t>
          </li>
          <li>
            <t>Generator(): Outputs the fixed generator of the group.</t>
          </li>
          <li>
            <t>HashToGroup(x, info): Deterministically maps
an array of bytes <tt>x</tt> with domain separation value <tt>info</tt> to an element of <tt>Group</tt>. The map must ensure that,
for any adversary receiving <tt>R = HashToGroup(x, info)</tt>, it is
computationally difficult to reverse the mapping.
Security properties of this function are described
in <xref target="I-D.irtf-cfrg-hash-to-curve"/>.</t>
          </li>
          <li>
            <t>HashToScalar(x, info): Deterministically maps
an array of bytes <tt>x</tt> with domain separation value <tt>info</tt> to an element in GF(p).
Security properties of this function are described in <xref section="10.5" sectionFormat="comma" target="I-D.irtf-cfrg-hash-to-curve"/>.</t>
          </li>
          <li>
            <t>RandomScalar(): Chooses at random a non-zero element in GF(p).</t>
          </li>
          <li>
            <t>ScalarInverse(s): Returns the inverse of input <tt>Scalar</tt> <tt>s</tt> on <tt>GF(p)</tt>.</t>
          </li>
          <li>
            <t>SerializeElement(A): Maps an <tt>Element</tt> <tt>A</tt>
to a canonical byte array <tt>buf</tt> of fixed length <tt>Ne</tt>.</t>
          </li>
          <li>
            <t>DeserializeElement(buf): Attempts to map a byte array <tt>buf</tt> to
an <tt>Element</tt> <tt>A</tt>, and fails if the input is not the valid canonical 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.</t>
          </li>
          <li>
            <t>SerializeScalar(s): Maps a <tt>Scalar</tt> <tt>s</tt> to a canonical
byte array <tt>buf</tt> of fixed length <tt>Ns</tt>.</t>
          </li>
          <li>
            <t>DeserializeScalar(buf): Attempts to map a byte array <tt>buf</tt> to a <tt>Scalar</tt> <tt>s</tt>.
This function can raise a DeserializeError if deserialization fails; see
<xref target="ciphersuites"/> for group-specific input validation steps.</t>
          </li>
        </ul>
        <t>For each group, there exists two distinct generators, generatorG and
generatorH, generatorG = G.Generator() and generatorH = G.HashToGroup(G.SerializeElement(generatorG), "generatorH").
The group member functions GeneratorG() and GeneratorH() are shorthand
for returning generatorG and generatorH, respectively.</t>
        <t><xref target="ciphersuites"/> contains details for the implementation of this interface
for different prime-order groups instantiated over elliptic curves.</t>
      </section>
    </section>
    <section anchor="arc-protocol">
      <name>ARC Protocol</name>
      <t>The ARC protocol is a two-party protocol run between client and server
consisting of three distinct phases:</t>
      <ol spacing="normal" type="1"><li>
          <t>Key generation. In this phase, the server generates its private and public
keys to be used for the remaining phases. This phase is described in <xref target="setup"/>.</t>
        </li>
        <li>
          <t>Credential issuance. In this phase, the client and server interact to issue
the client a credential that is cryptographically bound to client secrets.
This phase is described in <xref target="issuance"/>.</t>
        </li>
        <li>
          <t>Presentation. In this phase, the client uses the credential to create a "presentation"
to the server, where the server learns nothing more than whether or not the
presentation is valid and corresponds to some previously issued credential,
without learning which credential it corresponds to. This phase is described
in <xref target="presentation"/>.</t>
        </li>
      </ol>
      <t>This protocol bears resemblance to anonymous token protocols, such as those built on
Blind RSA <xref target="BLIND-RSA"/> and Oblivious Pseudorandom Functions <xref target="OPRFS"/>
with one critical distinction: unlike anonymous tokens, an anonymous credential can be
used multiple times to create unlinkable presentations (up to the fixed presentation
limit). This means that a single issuance invocation can drive multiple presentation
invocations, whereas with anonymous tokens, each presentation invocation requires
exactly one issuance invocation. As a result, credentials are generally longer lived
than tokens. Applications configure the credential presentation limit after the
credential is issued such that client and server agree on the limit during presentation.
Servers are responsible for ensuring this limit is not exceeded. Clients that exceed
the agreed-upon presentation limit break the unlinkability guarantees provided by
the protocol.</t>
      <t>The rest of this section describes the three phases of the ARC protocol.</t>
      <section anchor="setup">
        <name>Key Generation</name>
        <t>In the key generation phase, the server generates its private and public
keys, denoted ServerPrivateKey and ServerPublicKey, as follows.</t>
        <artwork><![CDATA[
Input: None
Output:
- ServerPrivateKey:
  - x0: Scalar
  - x1: Scalar
  - x2: Scalar
  - x0Blinding: Scalar
- ServerPublicKey:
  - X0: Element
  - X1: Element
  - X2: Element

Parameters
- Group G

def SetupServer():
  x0 = G.RandomScalar()
  x1 = G.RandomScalar()
  x2 = G.RandomScalar()
  x0Blinding = G.RandomScalar()
  X0 = x0 * G.GeneratorG() + x0Blinding * G.GeneratorH()
  X1 = x1 * G.GeneratorH()
  X2 = x2 * G.GeneratorH()
  return (ServerPrivateKey(x0, x1, x2, x0Blinding),
    ServerPublicKey(X0, X1, X2))
]]></artwork>
        <t>The server public key can be serialized as follows:</t>
        <artwork><![CDATA[
struct {
  uint8 X0[Ne]; // G.SerializeElement(X0)
  uint8 X1[Ne]; // G.SerializeElement(X1)
  uint8 X2[Ne]; // G.SerializeElement(X2)
} ServerPublicKey;
]]></artwork>
        <t>The length of this encoded response structure is <tt>NserverPublicKey = 3*Ne</tt>.</t>
      </section>
      <section anchor="issuance">
        <name>Issuance</name>
        <t>The purpose of the issuance phase is for the client and server to cooperatively compute a credential
that is cryptographically bound to the client's secrets. Clients do not choose these secrets;
they are computed by the protocol.</t>
        <t>The issuance phase of the protocol requires clients to know the server public key a priori, as well as
an arbitrary, application-specific request context. It requires no other input. It consists of three
distinct steps:</t>
        <ol spacing="normal" type="1"><li>
            <t>The client generates and sends a credential request to the server. This credential request contains a
proof that the request is valid with respect to the client's secrets and request context. See
<xref target="issuance-step1"/> for details about this step.</t>
          </li>
          <li>
            <t>The server validates the credential request. If valid, it computes a credential response with the server
private keys. The response includes a proof that the credential response is valid with respect to the
server keys. The server sends the response to the client. See <xref target="issuance-step2"/> for details about this
step.</t>
          </li>
          <li>
            <t>The client finalizes the credential by processing the server response. If valid, this step yields a
credential that can then be used in the presentation phase of the protocol. See <xref target="issuance-step3"/> for
details about this step.</t>
          </li>
        </ol>
        <t>Each of these steps is described in the following subsections.</t>
        <section anchor="issuance-step1">
          <name>Credential Request</name>
          <t>Given a request context, the process for creating a credential request is as follows:</t>
          <artwork><![CDATA[
(clientSecrets, request) = CreateCredentialRequest(requestContext, rng)

Inputs:
- requestContext: Data, context for the credential request
- rng: a cryptographically secure random number generator, as defined
  in the Sigma Protocols specification.

Outputs:
- request:
  - m1Enc: Element, first encrypted secret.
  - m2Enc: Element, second encrypted secret.
  - requestProof: String (ZKProof), a proof of correct generation of
    m1Enc and m2Enc.
- clientSecrets:
  - m1: Scalar, first secret.
  - m2: Scalar, second secret.
  - r1: Scalar, blinding factor for first secret.
  - r2: Scalar, blinding factor for second secret.

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

def CreateCredentialRequest(requestContext, rng):
  m1 = G.RandomScalar()
  m2 = G.HashToScalar(requestContext, "requestContext")
  r1 = G.RandomScalar()
  r2 = G.RandomScalar()
  m1Enc = m1 * generatorG + r1 * generatorH
  m2Enc = m2 * generatorG + r2 * generatorH
  requestProof = MakeCredentialRequestProof(m1, m2, r1, r2,
    m1Enc, m2Enc, rng)
  request = (m1Enc, m2Enc, requestProof)
  clientSecrets = (m1, m2, r1, r2)
  return (clientSecrets, request)
]]></artwork>
          <t>See <xref target="request-proof"/> for more details on the generation of the credential request proof.</t>
          <t>The resulting request can be serialized as follows.</t>
          <artwork><![CDATA[
struct {
  uint8 m1Enc[Ne];
  uint8 m2Enc[Ne];
  uint8 requestProof[5*Ns];
} CredentialRequest;
]]></artwork>
          <t>The length of this encoded request structure is <tt>Nrequest = 2*Ne + 5*Ns</tt>.</t>
        </section>
        <section anchor="issuance-step2">
          <name>Credential Response</name>
          <t>Given a credential request and server public and private keys, the process
for creating a credential response is as follows.</t>
          <sourcecode type="pseudocode"><![CDATA[
response = CreateCredentialResponse(serverPrivateKey,
  serverPublicKey, request, rng)

Inputs:
- serverPrivateKey:
  - x0: Scalar (private), server private key 0.
  - x1: Scalar (private), server private key 1.
  - x2: Scalar (private), server private key 2.
  - x0Blinding: Scalar (private), blinding value for x0.
- serverPublicKey:
  - X0: Element, server public key 0.
  - X1: Element, server public key 1.
  - X2: Element, server public key 2.
- request:
  - m1Enc: Element, first encrypted secret.
  - m2Enc: Element, second encrypted secret.
  - requestProof: String (ZKProof), a proof of correct generation
    of m1Enc and m2Enc.
- rng: a cryptographically secure random number generator, as defined
  in the Sigma Protocols specification.

Outputs:
- U: Element, a randomized generator for the response, `b*G`.
- encUPrime: Element, encrypted UPrime.
- X0Aux: Element, auxiliary point for X0.
- X1Aux: Element, auxiliary point for X1.
- X2Aux: Element, auxiliary point for X2.
- HAux: Element, auxiliary point for generatorH.
- responseProof: String (ZKProof), a proof of correct generation of
  U, encUPrime, server public keys, and auxiliary points.

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

Exceptions:
- VerifyError, raised when response verification fails

def CreateCredentialResponse(serverPrivateKey, serverPublicKey, request, rng):
  if VerifyCredentialRequestProof(request) == false:
    raise VerifyError

  b = G.RandomScalar()
  U = b * generatorG
  encUPrime = b * (serverPublicKey.X0 +
        serverPrivateKey.x1 * request.m1Enc +
        serverPrivateKey.x2 * request.m2Enc)
  X0Aux = b * serverPrivateKey.x0Blinding * generatorH
  X1Aux = b * serverPublicKey.X1
  X2Aux = b * serverPublicKey.X2
  HAux = b * generatorH

  responseProof = MakeCredentialResponseProof(serverPrivateKey,
    serverPublicKey, request, b, U, encUPrime,
    X0Aux, X1Aux, X2Aux, HAux, rng)
  return (U, encUPrime, X0Aux, X1Aux, X2Aux, HAux, responseProof)
]]></sourcecode>
          <t>The resulting response can be serialized as follows. See <xref target="response-proof"/> for more details on the generation of the credential response proof.</t>
          <artwork><![CDATA[
struct {
  uint8 U[Ne];
  uint8 encUPrime[Ne];
  uint8 X0Aux[Ne];
  uint8 X1Aux[Ne];
  uint8 X2Aux[Ne];
  uint8 HAux[Ne];
  uint8 responseProof[8*Ns];
} CredentialResponse
]]></artwork>
          <t>The length of this encoded response structure is <tt>Nresponse = 6*Ne + 8*Ns</tt>.</t>
        </section>
        <section anchor="issuance-step3">
          <name>Finalize Credential</name>
          <t>Given a credential request and response, server public keys, and the client
secrets produced when creating a credential request, the process for
finalizing the issuance flow and creating a credential is as follows.</t>
          <artwork><![CDATA[
credential = FinalizeCredential(clientSecrets,
  serverPublicKey, request, response)

Inputs:
- clientSecrets:
  - m1: Scalar, first secret.
  - m2: Scalar, second secret.
  - r1: Scalar, blinding factor for first secret.
  - r2: Scalar, blinding factor for second secret.
- serverPublicKey: ServerPublicKey, shared with the client out-of-band
- request:
  - m1Enc: Element, first encrypted secret.
  - m2Enc: Element, second encrypted secret.
  - requestProof: String (ZKProof), a proof of correct generation
    of m1Enc and m2Enc.
- response:
  - U: Element, a randomized generator for the response. `b*G`.
  - encUPrime: Element, encrypted UPrime.
  - X0Aux: Element, auxiliary point for X0.
  - X1Aux: Element, auxiliary point for X1.
  - X2Aux: Element, auxiliary point for X2.
  - HAux: Element, auxiliary point for generatorH.
  - responseProof: String (ZKProof), a proof of correct generation of
    U, encUPrime, server public keys, and auxiliary points.

Outputs:
- credential:
  - m1: Scalar, client's first secret.
  - U: Element, a randomized generator for the response. `b*G`.
  - UPrime: Element, the MAC over the server's private keys and the
    client's secrets.
  - X1: Element, server public key 1.

Exceptions:
- VerifyError, raised when response verification fails

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

def FinalizeCredential(clientSecrets, serverPublicKey, request,
  response):
  if VerifyCredentialResponseProof(serverPublicKey, response,
    request) == false:
    raise VerifyError
  UPrime = response.encUPrime - response.X0Aux
    - clientSecrets.r1 * response.X1Aux
    - clientSecrets.r2 * response.X2Aux
  return (clientSecrets.m1, response.U, UPrime, serverPublicKey.X1)
]]></artwork>
        </section>
      </section>
      <section anchor="presentation">
        <name>Presentation</name>
        <t>The purpose of the presentation phase is for the client to create a "presentation" to the server
which can be verified using the server private key. This phase is non-interactive, i.e., there is
no state stored between client and server in order to produce and then verify a presentation.
Client and server agree upon a fixed limit of presentations in order to create and verify
presentations; presentations will not verify correctly if the client and server use different
limits.</t>
        <t>This phase consists of three steps:</t>
        <ol spacing="normal" type="1"><li>
            <t>The client creates a presentation state for a given presentation context and presentation limit.
This state is used to produce a fixed amount of presentations.</t>
          </li>
          <li>
            <t>The client creates a presentation from the presentation state and sends it to the server.
The presentation is cryptographically bound to the state's presentation context, and
contains proof that the presentation is valid with respect to the presentation context.
Moreover, the presentation contains proof that the nonce (an integer) associated with this
presentation is within the presentation limit. The nonce value used in each presentation
is hidden in a Pedersen commitment, ensuring servers cannot link presentations using the nonce.</t>
          </li>
          <li>
            <t>The server verifies the presentation with respect to the presentation context and presentation
limit.</t>
          </li>
        </ol>
        <t>Details for each of these steps are in the following subsections.</t>
        <section anchor="presentation-state">
          <name>Presentation State</name>
          <t>Presentation state is used to track the number of presentations for a given credential.
This state is important for ARC's unlinkability goals: reuse of state can break
unlinkability properties of credential presentations. State is initialized
with a credential, presentation context, and presentation limit. It is then mutated
after each presentation construction (as described in <xref target="presentation-construction"/>).</t>
          <artwork><![CDATA[
state = MakePresentationState(credential, presentationContext,
  presentationLimit)

Inputs:
- credential:
  - m1: Scalar, client's first secret.
  - U: Element, a randomized generator for the response `b*G`.
  - UPrime: Element, the MAC over the server's private keys and the
    client's secrets.
  - X1: Element, server public key 1.
- presentationContext: Data (public), used for presentation tag
  computation.
- presentationLimit: Integer, the fixed presentation limit.

Outputs:
- credential
- presentationContext: Data (public), used for presentation tag
  computation.
- nextNonce: Integer, the next nonce that can be used. This
  increments by 1 for each use.
- presentationLimit: Integer, the fixed presentation limit.

def MakePresentationState(credential, presentationContext,
  presentationLimit):
  return PresentationState(credential, presentationContext, 0,
    presentationLimit)
]]></artwork>
        </section>
        <section anchor="presentation-construction">
          <name>Presentation Construction</name>
          <t>Creating a presentation requires a credential, presentation context, and presentation limit.
This process is necessarily stateful on the client since the number of times a credential
is used for a given presentation context cannot exceed the presentation limit; doing so
would break presentation unlinkability, as two presentations created with the same nonce
can be directly compared for equality (via the "tag"). As a result, the process for creating
a presentation accepts as input a presentation state and then outputs an updated presentation
state.</t>
          <artwork><![CDATA[
newState, nonce, presentation = Present(state, rng)

Inputs:
state: input PresentationState
  - credential
  - presentationContext: Data (public), used for presentation tag
    computation.
  - nextNonce: Integer, the next nonce that can be used. This
    increments by 1 for each use.
  - presentationLimit: Integer, the fixed presentation limit.
rng: a cryptographically secure random number generator, as defined
  in the Sigma Protocol spec {{SIGMA}}.

Outputs:
- newState: updated PresentationState
- nonce: Integer, the nonce associated with this presentation.
- presentation:
  - U: Element, re-randomized from the U in the response.
  - UPrimeCommit: Element, a public key to the issued UPrime.
  - m1Commit: Element, a public key to the client secret (m1).
  - tag: Element, the tag element used for enforcing the
    presentation limit.
  - nonceCommit: Element, a Pedersen commitment to the nonce.
  - presentationProof: ZKProof, a joint proof of correct generation
    of the presentation and that the committed nonce is in
    [0, presentationLimit).

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

Exceptions:
- LimitExceededError, raised when the presentation count meets or
  exceeds the presentation limit for the given presentation context

def Present(state, rng):
  if state.nextNonce >= state.presentationLimit:
    raise LimitExceededError

  nonce = state.nextNonce
  # This step mutates the state by incrementing nextNonce by 1.
  state.nextNonce += 1

  a = G.RandomScalar()
  r = G.RandomScalar()
  z = G.RandomScalar()

  U = a * state.credential.U
  UPrime = a * state.credential.UPrime
  UPrimeCommit = UPrime + r * generatorG
  m1Commit = state.credential.m1 * U + z * generatorH

  # Create Pedersen commitment to the nonce
  nonceBlinding = G.RandomScalar()
  nonceCommit = G.Scalar(nonce) * generatorG + nonceBlinding * generatorH

  generatorT = G.HashToGroup(state.presentationContext, "Tag")
  tag = (state.credential.m1 + nonce)^(-1) * generatorT
  V = z * state.credential.X1 - r * generatorG

  # Generate presentation proof with integrated range proof
  presentationProof = MakePresentationProof(U, UPrimeCommit,
    m1Commit, tag, generatorT, state.credential, V, r, z, nonce,
    nonceBlinding, nonceCommit, state.presentationLimit, rng)

  presentation = (U, UPrimeCommit, m1Commit, tag, nonceCommit,
    presentationProof)

  return state, nonce, presentation
]]></artwork>
          <t>OPEN ISSUE: should the tag also fold in the presentation limit?</t>
          <t>The resulting presentation can be serialized as follows. See <xref target="presentation-proof"/>
for more details on the generation of the presentation proof. The presentation proof
integrates the range proof as described in <xref target="range-proof"/>.</t>
          <artwork><![CDATA[
struct {
  uint8 U[Ne];
  uint8 UPrimeCommit[Ne];
  uint8 m1Commit[Ne];
  uint8 tag[Ne];
  uint8 nonceCommit[Ne];
  PresentationProof presentationProof;
} Presentation

struct {
  uint8 D[k][Ne]; // k = ceil(log2(presentationLimit))
  uint8 challenge[Ns];
  // Variable length based on presentation variables plus range proof variables
  uint8 responses[5 + 3 * k][Ns];
} PresentationProof
]]></artwork>
          <t>The length of the Presentation structure is <tt>Npresentation = 5*Ne + Npresentationproof</tt>.
<tt>Npresentationproof = k * Ne + (6 + 3 * k) * Ns</tt>, which includes the D commitments (k * Ne), the challenge (Ns), the response scalars for presentation variables (5 scalars: m1, z, -r, nonce, nonceBlinding), and range proof variables (3 * k scalars: <tt>b[i]</tt>, <tt>s[i]</tt>, <tt>s2[i]</tt> for each bit).
<tt>k</tt> is the number of bits it takes to represent the presentationLimit, i.e., <tt>k = ceil(log2(presentationLimit))</tt></t>
        </section>
        <section anchor="presentation-verification">
          <name>Presentation Verification</name>
          <t>The server processes the presentation by verifying the integrated presentation proof, which includes
verification of the range proof, against server-computed values. Note that the server does not receive
the raw nonce value, only the Pedersen commitment to it.</t>
          <artwork><![CDATA[
validity, tag = VerifyPresentation(serverPrivateKey,
  serverPublicKey, requestContext, presentationContext,
  presentation, presentationLimit)

Inputs:
- serverPrivateKey:
  - x0: Scalar (private), server private key 0.
  - x1: Scalar (private), server private key 1.
  - x2: Scalar (private), server private key 2.
  - x0Blinding: Scalar (private), blinding value for x0.
- serverPublicKey:
  - X0: Element, server public key 0.
  - X1: Element, server public key 1.
  - X2: Element, server public key 2.
- requestContext: Data, context for the credential request.
- presentationContext: Data (public), used for presentation tag
  computation.
- presentation:
  - U: Element, re-randomized from the U in the response.
  - UPrimeCommit: Element, a public key to the issued UPrime.
  - m1Commit: Element, a public key to the client secret (m1).
  - tag: Element, the tag element used for enforcing the
    presentation limit.
  - nonceCommit: Element, a Pedersen commitment to the nonce.
  - presentationProof: ZKProof, a joint proof of correct generation
    of the presentation and that the committed nonce is in
    [0, presentationLimit).
- presentationLimit: Integer, the fixed presentation limit.

Outputs:
- validity: Boolean, True if the presentation is valid,
  False otherwise.
- tag: Bytes, the value of the presentation tag used for rate
  limiting.

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

def VerifyPresentation(serverPrivateKey, serverPublicKey,
  requestContext, presentationContext, presentation,
  presentationLimit):

  # The presentation proof verifies the relationship between the tag,
  # m1, and the committed nonce using zero-knowledge techniques,
  # without learning the value of the nonce. It also includes
  # verification that the committed nonce is in
  # [0, presentationLimit).

  validity = VerifyPresentationProof(serverPrivateKey,
    serverPublicKey, requestContext, presentationContext,
    presentation, presentationLimit)

  return validity, presentation.tag
]]></artwork>
          <t>Implementation-specific steps: the server must perform a check that the tag (presentation.tag) has
not previously been seen, to prevent double spending. It then stores the tag for use in future double
spending checks. To reduce the overhead of performing double spend checks, the server can store and
look up the tags corresponding to the associated requestContext and presentationContext values.</t>
        </section>
      </section>
    </section>
    <section anchor="zero-knowledge-proofs">
      <name>Zero-Knowledge Proofs</name>
      <t>This section uses the Interactive Sigma Protocol <xref target="SIGMA"/> to create zero-knowledge proofs of knowledge for various ARC operations, and the Fiat-Shamir Transform <xref target="FIAT-SHAMIR"/> to make those proofs non-interactive.</t>
      <section anchor="request-proof">
        <name>CredentialRequest Proof</name>
        <t>The request proof is a proof of knowledge of (m1, m2, r1, r2) used to generate the encrypted request. Statements to prove:</t>
        <artwork><![CDATA[
1. m1Enc = m1 * generatorG + r1 * generatorH
2. m2Enc = m2 * generatorG + r2 * generatorH
]]></artwork>
        <section anchor="credentialrequest-proof-creation">
          <name>CredentialRequest Proof Creation</name>
          <artwork><![CDATA[
requestProof = MakeCredentialRequestProof(m1, m2, r1, r2, m1Enc,
  m2Enc, rng)

Inputs:
- m1: Scalar, first secret.
- m2: Scalar, second secret.
- r1: Scalar, blinding factor for first secret.
- r2: Scalar, blinding factor for second secret.
- m1Enc: Element, first encrypted secret.
- m2Enc: Element, second encrypted secret.
- rng: a cryptographically secure random number generator, as defined
  in the Sigma Protocols specification.

Outputs:
- proof: String (ZKProof)

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()
- contextString: public input

def MakeCredentialRequestProof(m1, m2, r1, r2, m1Enc, m2Enc, rng):
  statement = LinearRelation(G)
  [m1Var, m2Var, r1Var, r2Var] = statement.allocate_scalars(4)
  witness = [m1, m2, r1, r2]

  [genGVar, genHVar, m1EncVar, m2EncVar]
    = statement.allocate_elements(4)
  statement.set_elements([(genGVar, generatorG),
    (genHVar, generatorH), (m1EncVar, m1Enc), (m2EncVar, m2Enc)])

  # 1. m1Enc = m1 * generatorG + r1 * generatorH
  statement.append_equation(m1EncVar,
    [(m1Var, genGVar), (r1Var, genHVar)])

  # 2. m2Enc = m2 * generatorG + r2 * generatorH
  statement.append_equation(m2EncVar,
    [(m2Var, genGVar), (r2Var, genHVar)])

  session_id = contextString + "CredentialRequest"
  prover = NISchnorrProofShake128P256(session_id, statement)
  return prover.prove(witness, rng)
]]></artwork>
          <t>Where the request proof returned is a serialization of the following:
~~~
- challenge: Scalar, the challenge used in the proof of valid
  encryption.
- response0: Scalar, the response corresponding to m1.
- response1: Scalar, the response corresponding to m2.
- response2: Scalar, the response corresponding to r1.
- response3: Scalar, the response corresponding to r2.
~~~</t>
        </section>
        <section anchor="credentialrequest-proof-verification">
          <name>CredentialRequest Proof Verification</name>
          <artwork><![CDATA[
validity = VerifyCredentialRequestProof(request)

Inputs:
- request:
  - m1Enc: Element, first encrypted secret.
  - m2Enc: Element, second encrypted secret.
  - requestProof: String (ZKProof), a proof of correct generation
    of m1Enc and m2Enc.

Outputs:
- validity: Boolean, True if the proof verifies correctly, False otherwise.

Parameters:
- G: group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()
- contextString: public input

def VerifyCredentialRequestProof(request):
  statement = LinearRelation(G)
  [m1Var, m2Var, r1Var, r2Var] = statement.allocate_scalars(4)

  [genGVar, genHVar, m1EncVar, m2EncVar]
    = statement.allocate_elements(4)
  statement.set_elements([(genGVar, generatorG),
    (genHVar, generatorH), (m1EncVar, m1Enc), (m2EncVar, m2Enc)])

  # 1. m1Enc = m1 * generatorG + r1 * generatorH
  statement.append_equation(m1EncVar,
    [(m1Var, genGVar), (r1Var, genHVar)])

  # 2. m2Enc = m2 * generatorG + r2 * generatorH
  statement.append_equation(m2EncVar,
    [(m2Var, genGVar), (r2Var, genHVar)])

  session_id = contextString + "CredentialRequest"
  verifier = NISchnorrProofShake128P256(session_id, statement)
  return verifier.verify(request.requestProof)
]]></artwork>
        </section>
      </section>
      <section anchor="response-proof">
        <name>CredentialResponse Proof</name>
        <t>The response proof is a proof of knowledge of (x0, x1, x2, x0Blinding, b) used in the server's CredentialResponse for the client's CredentialRequest. Statements to prove:</t>
        <artwork><![CDATA[
1. X0 = x0 * generatorG + x0Blinding * generatorH
2. X1 = x1 * generatorH
3. X2 = x2 * generatorH
4. X0Aux = b * x0Blinding * generatorH
  4a. HAux = b * generatorH
  4b: X0Aux = x0Blinding * HAux (= b * x0Blinding * generatorH)
5. X1Aux = b * x1 * generatorH
  5a. X1Aux = t1 * generatorH (t1 = b * x1)
  5b. X1Aux = b * X1 (X1 = x1 * generatorH)
6. X2Aux = b * x2 * generatorH
  6a. X2Aux = b * X2 (X2 = x2 * generatorH)
  6b. X2Aux = t2 * generatorH (t2 = b * x2)
7. U = b * generatorG
8. encUPrime = b * (X0 + x1 * Enc(m1) + x2 * Enc(m2))
]]></artwork>
        <section anchor="credentialresponse-proof-creation">
          <name>CredentialResponse Proof Creation</name>
          <artwork><![CDATA[
responseProof = MakeCredentialResponseProof(serverPrivateKey,
  serverPublicKey, request, b, U, encUPrime,
  X0Aux, X1Aux, X2Aux, HAux, rng)

Inputs:
- serverPrivateKey:
  - x0: Scalar (private), server private key 0.
  - x1: Scalar (private), server private key 1.
  - x2: Scalar (private), server private key 2.
  - x0Blinding: Scalar (private), blinding value for x0.
- serverPublicKey:
  - X0: Element, server public key 0.
  - X1: Element, server public key 1.
  - X2: Element, server public key 2.
- request:
  - m1Enc: Element, first encrypted secret.
  - m2Enc: Element, second encrypted secret.
  - requestProof: String (ZKProof), a proof of correct generation
    of m1Enc and m2Enc.
- encUPrime: Element, encrypted UPrime.
- X0Aux: Element, auxiliary point for X0.
- X1Aux: Element, auxiliary point for X1.
- X2Aux: Element, auxiliary point for X2.
- HAux: Element, auxiliary point for generatorH.
- rng: a cryptographically secure random number generator, as defined
  in the Sigma Protocols specification.

Outputs:
- proof: String (ZKProof)

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()
- contextString: public input

def MakeCredentialResponseProof(serverPrivateKey, serverPublicKey,
  request, b, U, encUPrime, X0Aux, X1Aux, X2Aux, HAux, rng):
  statement = LinearRelation(G)
  [x0Var, x1Var, x2Var, x0BlindingVar, bVar, t1Var, t2Var]
    = statement.allocate_scalars(7)
  witness = [serverPrivateKey.x0, serverPrivateKey.x1,
    serverPrivateKey.x2, serverPrivateKey.x0Blinding, b,
    b*serverPrivateKey.x1, b*serverPrivateKey.x2]

  [genGVar, genHVar, m1EncVar, m2EncVar, UVar, encUPrimeVar, X0Var,
    X1Var, X2Var, X0AuxVar, X1AuxVar, X2AuxVar, HAuxVar]
    = statement.allocate_elements(13)
  statement.set_elements([(genGVar, generatorG),
    (genHVar, generatorH), (m1EncVar, request.m1Enc),
    (m2EncVar, request.m2Enc), (UVar, U), (encUPrimeVar, encUPrime),
    (X0Var, serverPublicKey.X0), (X1Var, serverPublicKey.X1),
    (X2Var, serverPublicKey.X2), (X0AuxVar, X0Aux),
    (X1AuxVar, X1Aux), (X2AuxVar, X2Aux), (HAuxVar, HAux)])

  # 1. X0 = x0 * generatorG + x0Blinding * generatorH
  statement.append_equation(X0Var, [(x0Var, genGVar),
    (x0BlindingVar, genHVar)])
  # 2. X1 = x1 * generatorH
  statement.append_equation(X1Var, [(x1Var, genHVar)])
  # 3. X2 = x2 * generatorH
  statement.append_equation(X2Var, [(x2Var, genHVar)])

  # 4. X0Aux = b * x0Blinding * generatorH
  # 4a. HAux = b * generatorH
  statement.append_equation(HAuxVar, [(bVar, genHVar)])
  # 4b: X0Aux = x0Blinding * HAux (= b * x0Blinding * generatorH)
  statement.append_equation(X0AuxVar, [(x0BlindingVar, HAuxVar)])

  # 5. X1Aux = b * x1 * generatorH
  # 5a. X1Aux = t1 * generatorH (t1 = b * x1)
  statement.append_equation(X1AuxVar, [(t1Var, genHVar)])
  # 5b. X1Aux = b * X1 (X1 = x1 * generatorH)
  statement.append_equation(X1AuxVar, [(bVar, X1Var)])

  # 6. X2Aux = b * x2 * generatorH
  # 6a. X2Aux = b * X2 (X2 = x2 * generatorH)
  pstatement.append_equation(X2AuxVar, [(bVar, X2Var)])
  # 6b. X2Aux = t2 * H (t2 = b * x2)
  statement.append_equation(X2AuxVar, [(t2Var, genHVar)])

  # 7. U = b * generatorG
  statement.append_equation(UVar, [(bVar, genGVar)])
  # 8. encUPrime = b * (X0 + x1 * Enc(m1) + x2 * Enc(m2))
  # simplified: encUPrime = b * X0 + t1 * m1Enc + t2 * m2Enc,
  # since t1 = b * x1 and t2 = b * x2
  statement.append_equation(encUPrimeVar, [(bVar, X0Var),
    (t1Var, m1EncVar), (t2Var, m2EncVar)])

  session_id = contextString + "CredentialResponse"
  prover = NISchnorrProofShake128P256(session_id, statement)
  return prover.prove(witness, rng)
]]></artwork>
          <t>Where the response proof returned is a serialization of the following:
~~~
- challenge: Scalar, the challenge used in the proof of valid
  response.
- response0: Scalar, the response corresponding to x0.
- response1: Scalar, the response corresponding to x1.
- response2: Scalar, the response corresponding to x2.
- response3: Scalar, the response corresponding to x0Blinding.
- response4: Scalar, the response corresponding to b.
- response5: Scalar, the response corresponding to t1.
- response6: Scalar, the response corresponding to t2.
~~~</t>
        </section>
        <section anchor="credentialresponse-proof-verification">
          <name>CredentialResponse Proof Verification</name>
          <artwork><![CDATA[
validity = VerifyCredentialResponseProof(serverPublicKey, response,
  request)

Inputs:
- serverPublicKey:
  - X0: Element, server public key 0.
  - X1: Element, server public key 1.
  - X2: Element, server public key 2.
- response:
  - U: Element, a randomized generator for the response. `b*G`.
  - encUPrime: Element, encrypted UPrime.
  - X0Aux: Element, auxiliary point for X0.
  - X1Aux: Element, auxiliary point for X1.
  - X2Aux: Element, auxiliary point for X2.
  - HAux: Element, auxiliary point for generatorH.
  - responseProof: String (ZKProof), a proof of correct generation of
    U, encUPrime, server public keys, and auxiliary points.
- request:
  - m1Enc: Element, first encrypted secret.
  - m2Enc: Element, second encrypted secret.
  - requestProof: String (ZKProof), a proof of correct generation of
    m1Enc and m2Enc.

Outputs:
- validity: Boolean, True if the proof verifies correctly,
  False otherwise.

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

def VerifyCredentialResponseProof(serverPublicKey, response, request):
  statement = LinearRelation(G)
  [x0Var, x1Var, x2Var, x0BlindingVar, bVar, t1Var, t2Var]
    = statement.allocate_scalars(7)

  [genGVar, genHVar, m1EncVar, m2EncVar, UVar, encUPrimeVar, X0Var,
    X1Var, X2Var, X0AuxVar, X1AuxVar, X2AuxVar, HAuxVar]
    = statement.allocate_elements(13)
  statement.set_elements([(genGVar, generatorG),
    (genHVar, generatorH), (m1EncVar, request.m1Enc),
    (m2EncVar, request.m2Enc), (UVar, response.U),
    (encUPrimeVar, response.encUPrime), (X0Var, serverPublicKey.X0),
    (X1Var, serverPublicKey.X1), (X2Var, serverPublicKey.X2),
    (X0AuxVar, response.X0Aux), (X1AuxVar, response.X1Aux),
    (X2AuxVar, response.X2Aux), (HAuxVar, response.HAux)])

  # 1. X0 = x0 * generatorG + x0Blinding * generatorH
  statement.append_equation(X0Var, [(x0Var, genGVar),
    (x0BlindingVar, genHVar)])
  # 2. X1 = x1 * generatorH
  statement.append_equation(X1Var, [(x1Var, genHVar)])
  # 3. X2 = x2 * generatorH
  statement.append_equation(X2Var, [(x2Var, genHVar)])

  # 4. X0Aux = b * x0Blinding * generatorH
  # 4a. HAux = b * generatorH
  statement.append_equation(HAuxVar, [(bVar, genHVar)])
  # 4b: X0Aux = x0Blinding * HAux (= b * x0Blinding * generatorH)
  statement.append_equation(X0AuxVar, [(x0BlindingVar, HAuxVar)])

  # 5. X1Aux = b * x1 * generatorH
  # 5a. X1Aux = t1 * generatorH (t1 = b * x1)
  statement.append_equation(X1AuxVar, [(t1Var, genHVar)])
  # 5b. X1Aux = b * X1 (X1 = x1 * generatorH)
  statement.append_equation(X1AuxVar, [(bVar, X1Var)])

  # 6. X2Aux = b * x2 * generatorH
  # 6a. X2Aux = b * X2 (X2 = x2 * generatorH)
  pstatement.append_equation(X2AuxVar, [(bVar, X2Var)])
  # 6b. X2Aux = t2 * H (t2 = b * x2)
  statement.append_equation(X2AuxVar, [(t2Var, genHVar)])

  # 7. U = b * generatorG
  statement.append_equation(UVar, [(bVar, genGVar)])
  # 8. encUPrime = b * (X0 + x1 * Enc(m1) + x2 * Enc(m2))
  # simplified: encUPrime = b * X0 + t1 * m1Enc + t2 * m2Enc,
  # since t1 = b * x1 and t2 = b * x2
  statement.append_equation(encUPrimeVar, [(bVar, X0Var),
    (t1Var, m1EncVar), (t2Var, m2EncVar)])

  session_id = contextString + "CredentialResponse"
  verifier = NISchnorrProofShake128P256(session_id, statement)
  return verifier.verify(response.responseProof)
]]></artwork>
        </section>
      </section>
      <section anchor="presentation-proof">
        <name>Presentation Proof</name>
        <t>The presentation proof is a proof of knowledge of (m1, r, z, nonce, nonceBlinding) used in the presentation, as well as a proof that nonce is in the range [0, presentationLimit).</t>
        <t>Statements to prove:</t>
        <artwork><![CDATA[
# The m1 commitment was correctly formed
1. m1Commit = m1 * U + z * generatorH
# Other presentation elements are consistent with the credential
2. V = z * X1 - r * generatorG
# The nonceCommit is a Pedersen commitment to nonce with blinding factor nonceBlinding
3. nonceCommit = nonce * generatorG + nonceBlinding * generatorH
# The tag was correctly computed using m1 and the nonce
4. T = m1 * tag + nonce * tag, where T = G.HashToGroup(presentationContext, "Tag")
# The nonce is in the range [0, presentationLimit)
5. constraints added by the range proof. See {#range-proof}.
]]></artwork>
        <section anchor="presentation-proof-creation">
          <name>Presentation Proof Creation</name>
          <artwork><![CDATA[
presentationProof = MakePresentationProof(U, UPrimeCommit,
  m1Commit, tag, generatorT, credential, V, r, z, nonce,
  nonceBlinding, nonceCommit, presentationLimit, rng)

Inputs:
- U: Element, re-randomized from the U in the response.
- UPrimeCommit: Element, a public key to the MACGGM output UPrime.
- m1Commit: Element, a public key to the client secret (m1).
- tag: Element, the tag element used for enforcing the presentation
  limit.
- generatorT: Element, used for presentation tag computation.
- credential:
  - m1: Scalar, client's first secret.
  - U: Element, a randomized generator for the response. `b*G`.
  - UPrime: Element, the MAC over the server's private keys and the
    client's secrets.
  - X1: Element, server public key 1.
- V: Element, a proof helper element.
- r: Scalar (private), a randomly generated element used in
  presentation.
- z: Scalar (private), a randomly generated element used in
  presentation.
- nonce: Int, the nonce associated with the presentation.
- nonceBlinding: Scalar (private), the blinding factor for the nonce commitment.
- nonceCommit: Element, the Pedersen commitment to the nonce.
- presentationLimit: Integer, the fixed presentation limit.
- rng: a cryptographically secure random number generator, as defined
  in the Sigma Protocols specification.

Outputs:
- presentationProof: ZKProof, a joint proof covering both
  presentation and range proof
  - D: [Element], array of commitments to the bit decomposition of
    the nonce
  - challenge: Scalar, the challenge used in the proof of valid
    presentation.
  - response: [Scalar], an array of scalars for all variables
    (presentation + range proof)

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()
- contextString: public input

def MakePresentationProof(U, UPrimeCommit, m1Commit, tag, generatorT,
  credential, V, r, z, nonce, nonceBlinding, nonceCommit,
  presentationLimit, rng):
  statement = LinearRelation(G)
  [m1Var, zVar, rNegVar, nonceVar, nonceBlindingVar] = statement.allocate_scalars(5)

  [genGVar, genHVar, UVar, UPrimeCommitVar, m1CommitVar, VVar, X1Var,
    tagVar, genTVar, nonceCommitVar] = statement.allocate_elements(10)
  statement.set_elements([(genGVar, generatorG),
    (genHVar, generatorH), (UVar, U),
    (UPrimeCommitVar, UPrimeCommit), (m1CommitVar, m1Commit),
    (VVar, V), (X1Var, credential.X1), (tagVar, tag),
    (genTVar, generatorT), (nonceCommitVar, nonceCommit)])

  # 1. m1Commit = m1 * U + z * generatorH
  statement.append_equation(m1CommitVar,
    [(m1Var, UVar),(zVar, genHVar)])
  # 2. V = z * X1 - r * generatorG
  statement.append_equation(VVar, [(zVar, X1Var), (rNegVar, genGVar)])
  # 3. nonceCommit = nonce * generatorG + nonceBlinding * generatorH
  statement.append_equation(nonceCommitVar,
    [(nonceVar, genGVar), (nonceBlindingVar, genHVar)])
  # 4. T = m1 * tag + nonce * tag, where
  #    T = G.HashToGroup(presentationContext, "Tag")
  statement.append_equation(genTVar,
    [(m1Var, tagVar), (nonceVar, tagVar)])
  # 5. Add range proof constraints
  (statement, D, rangeWitness) = MakeRangeProofHelper(statement, nonce,
    nonceBlinding, presentationLimit, genGVar, genHVar, rng)

  # Build witness vector matching the scalar allocations
  witness = [credential.m1, z, -r, nonce, nonceBlinding]
  witness.extend(rangeWitness)

  session_id = contextString + "CredentialPresentation"
  prover = NISchnorrProofShake128P256(session_id, statement)
  return (prover.prove(witness, rng), D)
]]></artwork>
          <t>Where the presentation proof returned is a serialization of the following:
~~~
- challenge: Scalar, the challenge used in the proof of valid
  presentation.
- response0: Scalar, the response corresponding to m1.
- response1: Scalar, the response corresponding to z.
- response2: Scalar, the response corresponding to -r.
- response3: Scalar, the response corresponding to nonce.
~~~</t>
        </section>
        <section anchor="presentation-proof-verification">
          <name>Presentation Proof Verification</name>
          <artwork><![CDATA[
validity = VerifyPresentationProof(serverPrivateKey,
  serverPublicKey, requestContext, presentationContext,
  presentation, presentationLimit)

Inputs:
- serverPrivateKey:
  - x0: Scalar (private), server private key 0.
  - x1: Scalar (private), server private key 1.
  - x2: Scalar (private), server private key 2.
  - x0Blinding: Scalar (private), blinding value for x0.
- serverPublicKey:
  - X0: Element, server public key 0.
  - X1: Element, server public key 1.
  - X2: Element, server public key 2.
- requestContext: Data, context for the credential request.
- presentationContext: Data (public), used for presentation tag
  computation.
- presentation:
  - U: Element, re-randomized from the U in the response.
  - UPrimeCommit: Element, a public key to the issued UPrime.
  - m1Commit: Element, a public key to the client secret (m1).
  - tag: Element, the tag element used for enforcing the
    presentation limit.
  - nonceCommit: Element, a Pedersen commitment to the nonce.
  - D: [Element], array of commitments to the bit decomposition of
    nonceCommit
  - presentationProof: ZKProof, a joint proof covering both
    presentation and range proof
    - challenge: Scalar, the challenge used in the proof of valid
      presentation.
    - response: [Scalar], an array of scalars for all variables
      (presentation + range proof)
- presentationLimit: Integer, the fixed presentation limit.

Outputs:
- validity: Boolean, True if the proof verifies correctly,
  False otherwise.

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()
- contextString: public input

def VerifyPresentationProof(serverPrivateKey, serverPublicKey,
  requestContext, presentationContext, presentation,
  presentationLimit):

  m2 = G.HashToScalar(requestContext, "requestContext")
  V = serverPrivateKey.x0 * presentation.U + serverPrivateKey.x1 *
    presentation.m1Commit + serverPrivateKey.x2 * m2 *
    presentation.U - presentation.UPrimeCommit
  generatorT = G.HashToGroup(presentationContext, "Tag")

  statement = LinearRelation(G)
  [m1Var, zVar, rNegVar, nonceVar, nonceBlindingVar] =
    statement.allocate_scalars(5)

  [genGVar, genHVar, UVar, UPrimeCommitVar, m1CommitVar, VVar, X1Var,
    tagVar, genTVar, nonceCommitVar] = statement.allocate_elements(10)
  statement.set_elements([(genGVar, generatorG),
    (genHVar, generatorH), (UVar, presentation.U),
    (UPrimeCommitVar, presentation.UPrimeCommit),
    (m1CommitVar, presentation.m1Commit), (VVar, V),
    (X1Var, serverPublicKey.X1), (tagVar, presentation.tag),
    (genTVar, generatorT), (nonceCommitVar, presentation.nonceCommit)])

  # 1. m1Commit = m1 * U + z * generatorH
  statement.append_equation(m1CommitVar,
    [(m1Var, UVar),(zVar, genHVar)])
  # 2. V = z * X1 - r * generatorG
  statement.append_equation(VVar,
    [(zVar, X1Var), (rNegVar, genGVar)])
  # 3. nonceCommit = nonce * generatorG + nonceBlinding * generatorH
  statement.append_equation(nonceCommitVar,
    [(nonceVar, genGVar), (nonceBlindingVar, genHVar)])
  # 4. G.HashToGroup(presentationContext, "Tag")
  #    = m1 * tag + nonce * tag
  statement.append_equation(genTVar,
    [(m1Var, tagVar), (nonceVar, tagVar)])
  # 5. Add range proof constraints and verify the sum of the
  #    nonceCommit bit commitments
  (statement, sumValid) = VerifyRangeProofHelper(statement,
    presentation.proof.D, presentation.nonceCommit,
    presentationLimit, genGVar, genHVar)

  # Verify the joint proof
  session_id = contextString + "CredentialPresentation"
  verifier = NISchnorrProofShake128P256(session_id, statement)
  proofValid = sumValid and verifier.verify(
    presentation.presentationProof)
  return proofValid
]]></artwork>
        </section>
      </section>
      <section anchor="range-proof">
        <name>Range Proof for Arbitrary Values</name>
        <t>This section specifies a range proof to prove a secret value <tt>nonce</tt> lies
in an arbitrary interval <tt>[0, presentationLimit)</tt>. Before specifying the proof system, we first
give a brief overview of how it works. For simplicity, assume that <tt>presentationLimit</tt> is a
power of two, that is, <tt>presentationLimit = 2^k</tt> for some integer <tt>k &gt; 0</tt>.</t>
        <t>To prove a value lies in <tt>[0,(2^k)-1)</tt>, we prove it has a valid <tt>k</tt>-bit representation.
This is proven by committing to the full value <tt>nonce</tt>, then all bits of the bit decomposition
<tt>b</tt> of the value <tt>nonce</tt>, and then proving each coefficient of the bit decomposition is
actually <tt>0</tt> or <tt>1</tt> and that the sum of the bits multiplied by their associated bases equals
the full value <tt>nonce</tt>.
This involves the following steps:</t>
        <ol spacing="normal" type="1"><li>
            <t>Commit to the bits of <tt>nonce</tt>. That is, for each bit <tt>b[i]</tt> of the k-bit decomposition of <tt>nonce</tt>,
let <tt>D[i] = b[i] * generatorG + s[i] * generatorH</tt>, where <tt>s[i]</tt> is a blinding scalar.</t>
          </li>
          <li>
            <t>Prove that <tt>b[i]</tt> is in <tt>{0,1}</tt> by proving the algebraic relation <tt>b[i] *
(b[i]-1) == 0</tt> holds. This quadratic relation can be linearized by
adding an auxilary witness <tt>s2[i]</tt> and adding the linear relation
<tt>D[i] = b[i] * D[i] + s2[i] * generatorH</tt> to the equation system.
A valid witness <tt>s2[i]</tt> can only be computed by the prover if <tt>b[i]</tt> is in <tt>{0,1}</tt>,
and is computed as <tt>s2[i] = (1 - b[i]) * s[i]</tt>. Successfully computing a witness for
any other value, while satisfying the linear relation constraints, requires the prover
to break the discrete logarithm problem.</t>
          </li>
          <li>
            <t>In addition to verifying the proof of the above relation, the verifier checks that the sum of the bit
commitments is equal to the sum of the commitment to <tt>nonce</tt>:</t>
          </li>
        </ol>
        <artwork><![CDATA[
nonceCommit = D[0] * 2^0 + D[1] * 2^1 + D[2] * 2^2 + ... + D[k-1] * 2^{k-1}
]]></artwork>
        <t>The third step is verified outside of the proof by adding the commitments
homomorphically.</t>
        <t>To support the general case, where <tt>presentationLimit</tt> is not necessarily a power of two,
we extend the range proof for arbitrary ranges by decomposing the range
up to the second highest power of two and adding an additional, non-binary range that
covers the remaining range. This is detailed in <tt>ComputeBases</tt> below.</t>
        <artwork><![CDATA[
bases = ComputeBases(presentationLimit)

Inputs:
- presentationLimit: Integer, the maximum value of the range (exclusive).

Outputs:
- bases: an array of Scalar bases to represent elements, sorted in descending order. A base is
  either a power of two or a unique remainder that can be used to represent any integer
  in [0, presentationLimit).

def ComputeBases(presentationLimit):
  # compute bases to express the commitment as a linear combination of the bit decomposition
  remainder = presentationLimit
  bases = []
  k = ceil(log2(presentationLimit))
  # Generate all but the last power-of-two base.
  for i in range(k - 1):
      base = 2 ** i
      remainder -= base
      bases.append(base)
  bases.append(remainder - 1) # add non-binary base to close the gap

  # call sorted on array to ensure the additional base is in correct order
  return sorted(bases, reverse=True)
]]></artwork>
        <t>Note that by extending the range proof for arbitrary ranges, we are changing the bases used for decomposition and therefore introducing the potential for multiple valid decompositions of a value (the nonce). Implementations compliant with this specification MUST follow the canonical decomposition defined in <xref target="range-proof-creation"/>.</t>
        <section anchor="range-proof-creation">
          <name>Range Proof Creation</name>
          <t>Using the bases from <tt>ComputeBases</tt>, the function <tt>MakeRangeProofHelper</tt>
represents the secret <tt>nonce</tt> as a linear combination of the bases, using the resulting
bit representation to generate the cryptographic commitments and witness values for the
range proof. This helper function is called from within <tt>MakePresentationProof</tt> to add
range proof constraints to the presentation proof statement.</t>
          <artwork><![CDATA[
(prover, D, rangeWitness) = MakeRangeProofHelper(prover, nonce, nonceBlinding,
                                                  presentationLimit, genGVar, genHVar, rng)

Inputs:
- prover: Prover statement to which constraints will be added
- nonce: Integer, the nonce value to prove is in range
- nonceBlinding: Scalar, the blinding factor for the nonce commitment
- presentationLimit: Integer, the maximum value of the range (exclusive).
- genGVar: Integer, variable index for generator G
- genHVar: Integer, variable index for generator H
- rng: a cryptographically secure random number generator, as defined
  in the Sigma Protocols specification.

Outputs:
- prover: Modified prover statement with range proof constraints added
- D: [Element], array of commitments to the bit decomposition of nonceCommit
- rangeWitness: [Scalar], witness values for the range proof scalars, in the
  order they were allocated: b[0], ..., b[n-1], s[0], ..., s[n-1],
  s2[0], ..., s2[n-1]

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

def MakeRangeProofHelper(statement, nonce, nonceBlinding, presentationLimit,
                         genGVar, genHVar):

  # Compute bit decomposition and commitments
  bases = ComputeBases(presentationLimit)

  # Compute bit decomposition of nonce
  b = []
  remainder = nonce
  # must run in constant-time (branching depends on secret value)
  for base in bases:
    bitValue = 1 if (remainder >= base) else 0
    remainder -= bitValue * base
    b.append(G.Scalar(bitValue))

  # Compute commitments to bits
  D = []
  s = []
  s2 = []
  partial_sum = G.Scalar(0)
  for i in range(len(bases) - 1):
    s.append(G.RandomScalar())
    partial_sum += bases[i] * s[i]
    s2.append((G.Scalar(1) - b[i]) * s[i])
    D.append(b[i] * generatorG + s[i] * generatorH)
  # Blinding value for the last bit commitment is chosen strategically
  # so that all the bit commitments will sum up to nonceCommit.
  idx = len(bases) - 1
  s.append(G.ScalarInverse(bases[idx]) * (nonceBlinding - partial_sum))
  s2.append((G.Scalar(1) - b[idx]) * s[idx])
  D.append(b[idx] * generatorG + s[idx] * generatorH)

  # Allocate scalar variables (b, s, s2 for each bit)
  num_bits = len(b)
  vars_b = statement.allocate_scalars(num_bits)
  vars_s = statement.allocate_scalars(num_bits)
  vars_s2 = statement.allocate_scalars(num_bits)

  # Allocate and set element variables for bit commitments D
  vars_D = statement.allocate_elements(num_bits)
  statement.set_elements([(vars_D[i], D[i]) for i in range(num_bits)])

  # Add constraints proving each b[i] is in {0,1}
  for i in range(len(b)):
    # D[i] = b[i] * generatorG + s[i] * generatorH
    statement.append_equation(vars_D[i], [(vars_b[i], genGVar), (vars_s[i], genHVar)])
    # D[i] = b[i] * D[i] + s2[i] * generatorH (proves b[i] is in {0,1})
    statement.append_equation(vars_D[i], [(vars_b[i], vars_D[i]), (vars_s2[i], genHVar)])

  # Build witness array: all b values, then all s values, then all s2 values
  rangeWitness = []
  rangeWitness.extend(b)
  rangeWitness.extend(s)
  rangeWitness.extend(s2)

  return (statement, D, rangeWitness)
]]></artwork>
        </section>
        <section anchor="range-proof-verification">
          <name>Range Proof Verification</name>
          <artwork><![CDATA[
(verifier, sumValid) = VerifyRangeProofHelper(verifier, D, nonceCommit, presentationLimit,
                                              genGVar, genHVar)

Inputs:
- verifier: Verifier statement to which constraints will be added
- D: [Element], array of commitments to the bit decomposition of nonceCommit
- nonceCommit: Element, the Pedersen commitment to the nonce
- presentationLimit: Integer, the maximum value of the range (exclusive).
- genGVar: Integer, variable index for generator G
- genHVar: Integer, variable index for generator H

Outputs:
- verifier: Modified verifier statement with range proof constraints added
- validity: Boolean, True if sum(bases[i] * D[i]) == nonceCommit, False otherwise

Parameters:
- G: Group
- generatorG: Element, equivalent to G.GeneratorG()
- generatorH: Element, equivalent to G.GeneratorH()

def VerifyRangeProofHelper(statement, D, nonceCommit, presentationLimit,
                           genGVar, genHVar):

  bases = ComputeBases(presentationLimit)
  num_bits = len(bases)

  # Allocate scalar variables (b, s, s2 for each bit)
  vars_b = statement.allocate_scalars(num_bits)
  vars_s = statement.allocate_scalars(num_bits)
  vars_s2 = statement.allocate_scalars(num_bits)

  # Allocate and set element variables for bit commitments D
  vars_D = statement.allocate_elements(num_bits)
  statement.set_elements([(vars_D[i], D[i]) for i in range(num_bits)])

  # Add constraints proving each b[i] is in {0,1}
  for i in range(num_bits):
    # D[i] = b[i] * generatorG + s[i] * generatorH
    statement.append_equation(vars_D[i], [(vars_b[i], genGVar), (vars_s[i], genHVar)])
    # D[i] = b[i] * D[i] + s2[i] * generatorH
    statement.append_equation(vars_D[i], [(vars_b[i], vars_D[i]), (vars_s2[i], genHVar)])

  # Verify the sum check: nonceCommit == sum(bases[i] * D[i])
  # This is done explicitly by computing the sum homomorphically
  sum_D = G.Identity()
  for i in range(len(bases)):
    sum_D = sum_D + bases[i] * D[i]

  sumValid = (sum_D == nonceCommit)
  return (statement, sumValid)
]]></artwork>
        </section>
      </section>
    </section>
    <section anchor="ciphersuites">
      <name>Ciphersuites</name>
      <t>A ciphersuite (also referred to as 'suite' in this document) for the protocol
wraps the functionality required for the protocol to take place. The
ciphersuite should be available to both the client and server, and agreement
on the specific instantiation is assumed throughout.</t>
      <t>A ciphersuite contains an instantiation of the following functionality:</t>
      <ul spacing="normal">
        <li>
          <t><tt>Group</tt>: A prime-order Group exposing the API detailed in <xref target="pog"/>, with the
generator element defined in the corresponding reference for each group. Each
group also specifies HashToGroup, HashToScalar, and serialization functionalities.
For HashToGroup, the domain separation tag (DST) is constructed in accordance
with the recommendations in <xref section="3.1" sectionFormat="comma" target="I-D.irtf-cfrg-hash-to-curve"/>.
For HashToScalar, each group specifies an integer order that is used in
reducing integer values to a member of the corresponding scalar field.</t>
        </li>
      </ul>
      <t>This section includes an initial set of ciphersuites with supported groups.
It also includes implementation details for each ciphersuite, focusing on input validation.</t>
      <section anchor="arcp-256">
        <name>ARC(P-256)</name>
        <t>This ciphersuite uses P-256 <xref target="NISTCurves"/> for the Group.
The value of the ciphersuite identifier is "P256". The value of
contextString is "ARCV1-P256".</t>
        <ul spacing="normal">
          <li>
            <t>Group: P-256 (secp256r1) <xref target="NISTCurves"/>
            </t>
            <ul spacing="normal">
              <li>
                <t>Order(): Return 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551.</t>
              </li>
              <li>
                <t>Identity(): As defined in <xref target="NISTCurves"/>.</t>
              </li>
              <li>
                <t>Generator(): As defined in <xref target="NISTCurves"/>.</t>
              </li>
              <li>
                <t>RandomScalar(): Implemented by returning a uniformly random Scalar in the range
[1, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for implementation guidance.</t>
              </li>
              <li>
                <t>HashToGroup(x, info): Use hash_to_curve with suite P256_XMD:SHA-256_SSWU_RO_
<xref target="I-D.irtf-cfrg-hash-to-curve"/>, input <tt>x</tt>, and DST =
"HashToGroup-" || contextString || info.</t>
              </li>
              <li>
                <t>HashToScalar(x, info): Use hash_to_field from <xref target="I-D.irtf-cfrg-hash-to-curve"/>
using L = 48, <tt>expand_message_xmd</tt> with SHA-256, input <tt>x</tt> and
DST = "HashToScalar-" || contextString || info, and
prime modulus equal to <tt>Group.Order()</tt>.</t>
              </li>
              <li>
                <t>ScalarInverse(s): Returns the multiplicative inverse of input Scalar <tt>s</tt> mod <tt>Group.Order()</tt>.</t>
              </li>
              <li>
                <t>SerializeElement(A): Implemented using the compressed Elliptic-Curve-Point-to-Octet-String
method according to <xref target="SEC1"/>; Ne = 33.</t>
              </li>
              <li>
                <t>DeserializeElement(buf): Implemented by attempting to deserialize a 33-byte array to
a public key using the compressed Octet-String-to-Elliptic-Curve-Point method according to <xref target="SEC1"/>,
and then performs partial public-key validation as defined in section 5.6.2.3.4 of
<xref target="KEYAGREEMENT"/>. This includes checking that the
coordinates of the resulting point are in the correct range, that the point is on
the curve, and that the point is not the point at infinity. Additionally, this function
validates that the resulting element is not the group identity element.
If these checks fail, deserialization returns an InputValidationError error.</t>
              </li>
              <li>
                <t>SerializeScalar(s): Implemented using the Field-Element-to-Octet-String conversion
according to <xref target="SEC1"/>; Ns = 32.</t>
              </li>
              <li>
                <t>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar from a 32-byte
string using Octet-String-to-Field-Element from <xref target="SEC1"/>. This function can fail if the
input does not represent a Scalar in the range [1, <tt>G.Order()</tt> - 1].</t>
              </li>
            </ul>
          </li>
        </ul>
      </section>
      <section anchor="random-scalar">
        <name>Random Scalar Generation</name>
        <t>Two popular algorithms for generating a random integer uniformly distributed in
the range [1, G.Order() -1] are as follows:</t>
        <section anchor="rejection-sampling">
          <name>Rejection Sampling</name>
          <t>Generate a random byte array with <tt>Ns</tt> bytes, and attempt to map to a Scalar
by calling <tt>DeserializeScalar</tt> in constant time. If it succeeds and is non-zero,
return the result. Otherwise, try again with another random byte array, until the
procedure succeeds. Failure to implement <tt>DeserializeScalar</tt> in constant time
can leak information about the underlying corresponding Scalar.</t>
          <t>As an optimization, if the group order is very close to a power of
2, it is acceptable to omit the rejection test completely.  In
particular, if the group order is p, and there is an integer b
such that |p - 2<sup>b</sup>| is less than 2<sup>(b/2)</sup>, then
<tt>RandomScalar</tt> can simply return a uniformly random integer of at
most b bits.</t>
        </section>
        <section anchor="random-number-generation-using-extra-random-bits">
          <name>Random Number Generation Using Extra Random Bits</name>
          <t>Generate a random byte array with <tt>L = ceil(((3 * ceil(log2(G.Order()))) / 2) / 8)</tt>
bytes, and interpret it as an integer; reduce the integer modulo <tt>G.Order()</tt> and return the
result. See <xref section="5" sectionFormat="comma" target="I-D.irtf-cfrg-hash-to-curve"/> for the underlying derivation of <tt>L</tt>.</t>
        </section>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>For arguments about correctness, unforgeability, anonymity, and blind issuance of the ARC protocol, see the
"Formal Security Definitions for Keyed-Verification Anonymous Credentials" in <xref target="KVAC"/>.</t>
      <t>This section elaborates on unlinkability properties for ARC and other implementation details
necessary for these properties to hold.</t>
      <section anchor="credential-request-unlinkability">
        <name>Credential Request Unlinkability</name>
        <t>Client credential requests are constructed such that the server cannot distinguish between any two credential requests from the same client and two requests from different clients. We refer to this property as issuance unlinkability. This property is achieved by the way the credential requests are constructed. In particular, each credential request consists of two Pedersen commitments with fresh blinding factors, which are used to commit to a freshly generated client secret and request context. The resulting request is therefore statistically hiding, and independent from other requests from the same client. More details about this unlinkability property can be found in <xref target="KVAC"/> and <xref target="REVISITING_KVAC"/>.</t>
      </section>
      <section anchor="credential-issuance-unlinkability">
        <name>Credential Issuance Unlinkability</name>
        <t>The server commitment to <tt>x0</tt> is defined as <tt>X0 = x0 * G.generatorG() + x0Blinding * G.GeneratorH()</tt>, following the definitions in <xref target="KVAC"/>. This is computationally binding to the secret key <tt>x0</tt>. This means that unless the discrete log is broken, the credentials issued under one server commitment <tt>X0, X1, ...</tt> will all be issued under the same private keys <tt>x0, x1, ...</tt></t>
        <t>However, an adversary breaking the discrete log (e.g., a quantum adversary) can find pairs <tt>(x0, x0Blinding)</tt> and <tt>(x0', x0Blinding')</tt> both committing to <tt>X0</tt> and use them to issue different credentials. This capability would let the adversary partitioning the client anonymity set by linking clients to the underlying secret used for credential issuance, i.e., <tt>x0</tt> or <tt>x0'</tt>. This requires an active attack and therefore is not an immediate concern.</t>
        <t>Statistical anonymity is possible by committing to <tt>x0</tt> and <tt>x0Blinding</tt> separately, as in <xref target="REVISITING_KVAC"/>. However, the security of this construction requires additional analysis.</t>
      </section>
      <section anchor="pres-unlinkability">
        <name>Presentation Unlinkability</name>
        <t>Client credential presentations are constructed so that all presentations are indistinguishable, even if coming from the same user. We refer to this property as presentation unlinkability. This property is achieved by the way the credential presentations are constructed. The presentation elements <tt>[U, UPrimeCommit, m1Commit]</tt> are indistinguishable from all other presentations made from credentials issued with the same server keys, as detailed in <xref target="KVAC"/>.</t>
        <t>The indistinguishability set for these presentation elements is <tt>sum_{i=0}^c(p_i)</tt>, where <tt>c</tt> is the number of credentials issued with the same server keys, and <tt>p_i</tt> is the number of presentations made for each of those credentials.</t>
        <t>The presentation elements <tt>[tag, nonceCommit, presentationContext, presentationProof, rangeProof]</tt> are indistinguishable from all presentations made from credentials issued with the same server keys for that presentationContext. The nonce is never revealed to the server since it is hidden within a Pedersen commitment. The range proof ensures the committed nonce is within the valid range [0, presentationLimit) without revealing its value. This provides strong unlinkability properties: the server cannot link presentations based on nonce values, as the nonce commitment uses a fresh random blinding factor for each presentation.</t>
        <t>The indistinguishability set for these presentation elements is <tt>sum_{i=0}^c(p_i[presentationContext])</tt>, where <tt>c</tt> is the number of credentials issued with the same server keys and <tt>p_i[presentationContext]</tt> is the number of presentations made for each of those credentials with the same presentationContext. Unlike protocols where nonces are revealed, presentations can not be linked by comparing nonce values, resulting in maximum unlinkability within the presentation context.</t>
      </section>
      <section anchor="timing-leaks">
        <name>Timing Leaks</name>
        <t>To ensure no information is leaked during protocol execution, all operations that use secret data MUST run in constant time. This includes all prime-order group operations and proof-specific operations that operate on secret data, including proof generation and verification.</t>
      </section>
    </section>
    <section anchor="alternatives-considered">
      <name>Alternatives considered</name>
      <t>ARC uses the MACGGM algebraic MAC as its underlying primitive, as detailed in <xref target="KVAC"/> and <xref target="REVISITING_KVAC"/>. This offers the benefit of having a lower credential size than MACDDH, which is an alternative algebraic MAC detailed in <xref target="KVAC"/>.</t>
      <t>The BBS anonymous credential scheme, as detailed in <xref target="BBS"/> and its variants, is efficient and publicly verifiable, but requires pairings for verification. This is problematic for adoption because pairings are not supported as widely in software and hardware as non-pairing elliptic curves.</t>
      <t>It is possible to construct a keyed-verification variant of BBS which doesn't use pairings, as discussed in <xref target="BBDT17"/> and <xref target="REVISITING_KVAC"/>. However these keyed-verification BBS variants require more analysis, proofs of security properties, and review to be considered mature enough for safe deployment.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
    <section anchor="test-vectors">
      <name>Test Vectors</name>
      <section anchor="seeded-prng">
        <name>Seeded PRNG</name>
        <t>For interoperability, the random number generator used for test vectors is implemented using the SeededPRNG defined in Section A.1 of <xref target="SIGMA"/>.</t>
        <t>The following sections contain test vectors for the ARC ciphersuites specified in this document.</t>
      </section>
      <section anchor="arcv1-p256">
        <name>ARCV1-P256</name>
        <artwork><![CDATA[
// ServerKey
x0 = 1008f2c706ae2157c75e41b2d75695c7bf480d0632a1ef447036cafe4cabb02
1
x1 = 526e009578f6f25fdec992343f09f5e6c58489c31fcf8a934bbaf85797121bd
d
x2 = 549075ccd3d1c36b3546725c43e71943414409a23b980b2c47a3fc2b9c37679
b
xb = 7276533ce3c89f04a007c2e8aa7d2e3b36829d0eaab5631347d8336c2da09a8
e
X0 = 03bad54cc48293ef3472ac1ada55c9c9fdb3eb99ee47369bbe1d3ce46b300cd
7b3
X1 = 02a0323862a05707d76862bfa8477eed468441ceae14c8fb1659e0b3020b8a2
4e1
X2 = 031d16ef08ede5a347e94a8eca071bec7bedb9d8ba943d24bde912a4e1578e5
29b

// CredentialRequest
request_context = 74657374207265717565737420636f6e74657874
m1 = 141c4ca5e614af8e5e323eb47a7e7673ebb67caf49dfa8e109f45f231227f7a
0
m2 = 911fb315257d9ae29d47ecb48c6fa27074dee6860a0489f8db6ac9a486be6a3
e
r1 = 5c183d2dea942eb2780afb90cfd94983ae6575d60e350021c8c93008ac50397
3
r2 = 044d4a5b5daf00dd1fb4444ca2f8c3facc95d537d5ad0e0a2815c912e98a431
d
m1_enc = 033fe5d950712f711e5d292d68f804fad4c35fb7f3f1866516448647d4a
ab12590
m2_enc = 026502a833ed1d972ee27175e750b1719adee12726c653125887c0d32b1
f3747ab
proof = 2a088673e302502a3dc80d6100a1bb709083ac7b31da34f9a7c52e7cfeaa
2ea30b7341133086e64b79dfc6cdac9f348ddbed0b087746f0167ea238d3ddf17e61
3880b73e85f499c7eddc6555355ea71487b49862400091b5b32cb219d7104f571306
bc6f2487bab299bb2e9a1078dee94d83b6536ed570f8114ee9c97b8b602bfacbeb37
64f6a22915a19c24895a6bf7048c663337f7690f0182a1f866586d9e

// CredentialResponse
b = 9ac9d836ef405f4c6c1de4de18d210c929a8dc786c95e3eac3a828cc19e1636e
U = 021cf52318c97c33472cc8fb42a5b5a774f83c3b36e6c782209d53e5945d99a4
93
enc_U_prime = 02ae23020d5427c7f785a72d77c24997f955e66ab7c378c334b7c2
59dabdf572d7
X0_aux = 031523abe64e436e65e592abdae322dc556fcbea707757e18d4160ba57d
574cd87
X1_aux = 023cc3b53807f6e0082b675794ae9f6b370483ca5a3e6d688c3b81f2fdb
6d4ec00
X2_aux = 0329dc7c93f8a231a1f16ec69f0fba446e022ce69945b20f37386a7fda3
e573b79
H_aux = 0389746891b6dbf062511619eae7d72ae87630bea1e277a925708fdfef83
63a1d4
proof = ec342aee0d481435379ea6bbe919edd5d2eb9c12198a083e0e899da1f14d
bc46a8048f5a12c5cae21e5f5949fe08d1c15c266c63544615400def4ce9a6cf8aee
32052ced26e7a9d854f2c45ea23ffea0f6bf977f6155d412991abc0e2d1ad8350412
9c1ac8319b2a45940c52c4b41bde80969313641b9cb727445e20b44d0ea884e9b180
cd152442883038b97d72772201f281d76a18d22e374bd989accd7654806739916242
8c4d25daf1b7f68f3580a38cc4564a88f28494649064500f06c5b946dde032a389f8
fe337605627ce91a92c20db911100a2c7c42ae15fde5a5cbd9d078b819a804235931
92c40d70ce77f1a6d377770fe5c05781782bd1eaa43f

// Credential
m1 = 141c4ca5e614af8e5e323eb47a7e7673ebb67caf49dfa8e109f45f231227f7a
0
U = 021cf52318c97c33472cc8fb42a5b5a774f83c3b36e6c782209d53e5945d99a4
93
U_prime = 02646199272c28911165b4d1c5f4ffbd8a83f686948fd4c7250e28c81d
bfecd354
X1 = 02a0323862a05707d76862bfa8477eed468441ceae14c8fb1659e0b3020b8a2
4e1

// Presentation1
presentation_context = 746573742070726573656e746174696f6e20636f6e746
57874
a = a3c469d2d55062b463b17f45acd2fb17c038b18df4c8d6c9c745866ba961de9a
r = 54925f70e9ec2128114c6ae8bfc6e1a2914a8fdd383e5ff03d8c2992edd081a9
z = 9ed3c3ddb1b5ff64e55b1d0a4f58eee67351fea7de16baf644e80f4d0949cf5f
U = 0216af8901c1ad38a703bf9003fabea440b411b4f072fd23b5254cb17d1b5bf3
3d
U_prime_commit = 03140f8e6f6c5eab3d03a7fba5d542362a9bc00a89d80caa505
1b4e4446b0b01f3
m1_commit = 0214d0297c21120d621cc6fed75852569de3cbf0bd9f5a8a812cf6b0
24bf51e627
nonce = 0x0
nonce_blinding = ed8b643e3c8ba74cc417b5bbfc4f42bee6dcd2d6c5ea48fb227
3afec7b6505a4
nonce_commit = 032326abcd4eb2fd1a47053ec9ce1aab3ee91e98373d610e9752a
7d16a5c1e38d8
tag = 0281428e61688f4e7989dbe8dab170705c81b294c4a73b785a0754712fc968
eb40
D_0 = 032326abcd4eb2fd1a47053ec9ce1aab3ee91e98373d610e9752a7d16a5c1e
38d8
proof = 032326abcd4eb2fd1a47053ec9ce1aab3ee91e98373d610e9752a7d16a5c
1e38d8946f5f0b44e34f826b41ec59a4e2dcfaa826b8a39cc278e10b1b02b5dbaafd
b6e789639885a8d2d69269a9fea55830f1d7e1fd0a771183b7b4eebe5e03e0c0255d
1ba614de7e31d4f46eb93a24e0ffe9864b002527109a516a10dc1ad718b8d984efd1
6ab245d7a5dfabe2d0027e23796981422b19c2821a831cb46a8e9b8b566bbdb55b64
9021bf2f777b9130c2e375f560eee4691d04bd38e9571d9451257858d9128002a2f8
908d7e4521510a2185244fa533e2502b61e502fd157d974f91acc4f2ba0d724f2bfd
182d5df4d038e74b5c35cc7c4aa7622c2682e040877eebcc18fe822cc6abab5d3adc
9db836991d3d1ecf699658245b8b0756946ba0d7756b433aae3b476ccbc2186b2fe2
ecc2fe0da30df264802829254df8196a8307f0

// Presentation2
presentation_context = 746573742070726573656e746174696f6e20636f6e746
57874
a = ae14ddaf96907f2fee72069664e1883fee4582cefcfbb2f3fae380c317018ab2
r = f994bf66d0c7943ce97331da186e231281b691eb271c7c524ff9f8bc7804b41d
z = fa27efc5066bca91121642d629477eb1c7812fa9c473b30dea3eaba8a1731568
U = 0357e53851143e7cc34311bdba0d44d4d3c9192180434ce247b8766232b5de1e
08
U_prime_commit = 02bad8dc9b0179dff7a1d63d03d92810520085cbc41b65b667d
3cbe2203eb7c544
m1_commit = 02455589d2b92a24e49ff8c2e8287f6eeb05cbfddc16aba66dfe9ab9
7702bc3c35
nonce = 0x1
nonce_blinding = 90b8387fe4145c2d47a0f042c26119939bcbcc8c2c32f81d103
4db3958b9af39
nonce_commit = 0363d6bd2969b64a42354ba896be33a4abce479261d7dec0001fa
1af7fbdeecb41
tag = 02ad6c293325d0c2c388c8b2240b6d8ab9e52395297ef5921fb78ace6a1274
b03b
D_0 = 0363d6bd2969b64a42354ba896be33a4abce479261d7dec0001fa1af7fbdee
cb41
proof = 0363d6bd2969b64a42354ba896be33a4abce479261d7dec0001fa1af7fbd
eecb417c59300e0aafb0d58e3f85423030401dabe5dd39566924f07e99cae5b3be62
f45e736890857cfe0950c22c93c52d56e6ade5f5a1c1d486e9261e7788b745438701
15370c46e62e376b17844a287bbb6722dc5e5848fdbd8d19d259ec1cec83851a1ef4
a21dadefeef3f5222eb19361facbb2ec3ba640aef22cd5700a17ea17fc3ece772f5b
5cca1e119bf32cfa7f3459c2184d6d8c777d281c91b416187ee949c9557fece8afb0
ac785c7b8c4854e622f8b005daf5c0682cfdc2d900150087bae0090d44b7bac130c7
f4067bb8b3374b159106d0c03e30f9577063de0b52d15d1f5f41328b335ee23d10ca
7dc4e0717bd9e919e3f6f580e594b3c48b358baa7a320ec9e1019260efe2cbf6e9cb
a6871ffee3b5566d5e865c729c5e1d48529559

]]></artwork>
      </section>
    </section>
    <section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors would like to acknowledge helpful conversations with Tommy Pauly about rate limiting and Privacy Pass integration, as well as Lena Heimberger for specifying the range proof.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC8017">
          <front>
            <title>PKCS #1: RSA Cryptography Specifications Version 2.2</title>
            <author fullname="K. Moriarty" initials="K." role="editor" surname="Moriarty"/>
            <author fullname="B. Kaliski" initials="B." surname="Kaliski"/>
            <author fullname="J. Jonsson" initials="J." surname="Jonsson"/>
            <author fullname="A. Rusch" initials="A." surname="Rusch"/>
            <date month="November" year="2016"/>
            <abstract>
              <t>This document provides recommendations for the implementation of public-key cryptography based on the RSA algorithm, covering cryptographic primitives, encryption schemes, signature schemes with appendix, and ASN.1 syntax for representing keys and for identifying the schemes.</t>
              <t>This document represents a republication of PKCS #1 v2.2 from RSA Laboratories' Public-Key Cryptography Standards (PKCS) series. By publishing this RFC, change control is transferred to the IETF.</t>
              <t>This document also obsoletes RFC 3447.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8017"/>
          <seriesInfo name="DOI" value="10.17487/RFC8017"/>
        </reference>
        <reference anchor="I-D.irtf-cfrg-hash-to-curve">
          <front>
            <title>Hashing to Elliptic Curves</title>
            <author fullname="Armando Faz-Hernandez" initials="A. F." surname="Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Sam Scott" initials="S." surname="Scott">
              <organization>Cornell Tech</organization>
            </author>
            <author fullname="Nick Sullivan" initials="N." surname="Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Riad S. Wahby" initials="R. S." surname="Wahby">
              <organization>Stanford University</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="15" month="June" year="2022"/>
            <abstract>
              <t>This document specifies a number of algorithms for encoding or hashing an arbitrary string to a point on an elliptic curve.  This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.
              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-hash-to-curve-16"/>
        </reference>
        <reference anchor="SIGMA">
          <front>
            <title>Interactive Sigma Proofs</title>
            <author fullname="Michele Orrù" initials="M." surname="Orrù">
              <organization>CNRS</organization>
            </author>
            <author fullname="Cathie Yun" initials="C." surname="Yun">
              <organization>Apple, Inc.</organization>
            </author>
            <date day="20" month="October" year="2025"/>
            <abstract>
              <t>   A Sigma Protocol is an interactive zero-knowledge proof of knowledge
   that allows a prover to convince a verifier of the validity of a
   statement.  It satisfies the properties of completeness, soundness,
   and zero-knowledge, as described in Section 3.

   This document describes Sigma Protocols for proving knowledge of pre-
   images of linear maps in prime-order elliptic curve groups.  Examples
   include zero-knowledge proofs for discrete logarithm relations,
   ElGamal encryptions, Pedersen commitments, and range proofs.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-sigma-protocols-01"/>
        </reference>
        <reference anchor="FIAT-SHAMIR">
          <front>
            <title>Fiat-Shamir Transformation</title>
            <author fullname="Michele Orrù" initials="M." surname="Orrù">
              <organization>CNRS</organization>
            </author>
            <date day="20" month="October" year="2025"/>
            <abstract>
              <t>   This document describes how to construct a non-interactive proof via
   the Fiat–Shamir transformation, using a generic procedure that
   compiles an interactive proof into a non-interactive one by relying
   on a stateful hash object that provides a duplex sponge interface.

   The duplex sponge interface requires two methods: absorb and squeeze,
   which respectively read and write elements of a specified base type.
   The absorb operation incrementally updates the sponge's internal hash
   state, while the squeeze operation produces variable-length,
   unpredictable outputs.  This interface can be instantiated with
   various hash functions based on permutation or compression functions.

   This specification also defines codecs to securely map elements from
   the prover into the duplex sponge domain, and from the duplex sponge
   domain into verifier messages.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-fiat-shamir-01"/>
        </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="DOI" value="10.6028/nist.sp.800-56ar3"/>
          <refcontent>National Institute of Standards and Technology</refcontent>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="KVAC" target="https://eprint.iacr.org/2013/516">
          <front>
            <title>Keyed-Verification Anonymous Credentials from Algebraic MACs</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="REVISITING_KVAC" target="https://eprint.iacr.org/2024/1552">
          <front>
            <title>Revisiting Keyed-Verification Anonymous Credentials</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="BBS" target="https://eprint.iacr.org/2004/174">
          <front>
            <title>Short Group Signatures</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="BBDT17" target="https://link.springer.com/chapter/10.1007/978-3-319-69453-5_20">
          <front>
            <title>Improved Algebraic MACs and Practical Keyed-Verification Anonymous Credentials</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="NISTCurves">
          <front>
            <title>Digital Signature Standard (DSS)</title>
            <author>
              <organization/>
            </author>
            <date month="February" year="2023"/>
          </front>
          <seriesInfo name="DOI" value="10.6028/nist.fips.186-5"/>
          <refcontent>National Institute of Standards and Technology (U.S.)</refcontent>
        </reference>
        <reference anchor="SEC1" target="https://www.secg.org/sec1-v2.pdf">
          <front>
            <title>SEC 1: Elliptic Curve Cryptography</title>
            <author initials="" surname="Standards for Efficient Cryptography Group (SECG)">
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="BLIND-RSA">
          <front>
            <title>RSA Blind Signatures</title>
            <author fullname="F. Denis" initials="F." surname="Denis"/>
            <author fullname="F. Jacobs" initials="F." surname="Jacobs"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="October" year="2023"/>
            <abstract>
              <t>This document specifies an RSA-based blind signature protocol. RSA blind signatures were first introduced by Chaum for untraceable payments. A signature that is output from this protocol can be verified as an RSA-PSS signature.</t>
              <t>This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9474"/>
          <seriesInfo name="DOI" value="10.17487/RFC9474"/>
        </reference>
        <reference anchor="OPRFS">
          <front>
            <title>Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order Groups</title>
            <author fullname="A. Davidson" initials="A." surname="Davidson"/>
            <author fullname="A. Faz-Hernandez" initials="A." surname="Faz-Hernandez"/>
            <author fullname="N. Sullivan" initials="N." surname="Sullivan"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="December" year="2023"/>
            <abstract>
              <t>An Oblivious Pseudorandom Function (OPRF) is a two-party protocol between a client and a server for computing the output of a Pseudorandom Function (PRF). The server provides the PRF private key, and the client provides the PRF input. At the end of the protocol, the client learns the PRF output without learning anything about the PRF private key, and the server learns neither the PRF input nor output. An OPRF can also satisfy a notion of 'verifiability', called a VOPRF. A VOPRF ensures clients can verify that the server used a specific private key during the execution of the protocol. A VOPRF can also be partially oblivious, called a POPRF. A POPRF allows clients and servers to provide public input to the PRF computation. This document specifies an OPRF, VOPRF, and POPRF instantiated within standard prime-order groups, including elliptic curves. This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9497"/>
          <seriesInfo name="DOI" value="10.17487/RFC9497"/>
        </reference>
      </references>
    </references>
    <?line 1801?>



  </back>
  <!-- ##markdown-source:
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
IELCagtEffdEB9EBT7eSJSfFooQbsfsio/I9d8E1GiqEyHD0ucS0SKVDwCbp
+U4zmrUUFUB12VKiI+9OtTpB80sZJ2jKMHFOkltHNVRv8Y5TJJUQmGOKa2gu
OoSecu0W2QnkjqnAMQZVnaQm8RhJQBT3dbJEL616rNJYBEDc262zVdvUQizc
OwauWgh0voNDA/mrKmCoFIYiCI6KQiq207kd9LktlGuuHRDD8EoQKvWlNIcx
fG0dqaLWpMmeFprM/XBfaRHHBGHfVTTdpyg40m7dIpCkUP5CNaPBqaV+yO3x
rEtCRWWvSNn/7//+L6CBSXfsPgedOsrJPy7yPWVnVGvZc6+8Y+1Aqa9+9WtQ
/eqxuMJCF497dXhUtz96VDCqgov83a99D8rvTpm/pRAFG25PHSeWCfoGftUA
cA3x5pXHxmHVZ6Tn/p7nwZ7nxUzaf/+RxsFgX9mGKtmMX9uvVn59pl4kQABN
208ECwBq+UmZmW6nvkZcfXLl439B1xr4iLVeHfOdH9H4RzT+MTg6YkLQkTyV
qVPVXESiOlJVOBOxRULHioRUisX9gHF2MHKmQMib5/KnP7gPHrgt1viP3lHZ
0j/Y0rdaBgdbBkfOx/oc/1DOS7thhq/liooM4jKHqaZA4hO/wlmrdoSlGHzF
Hjkx9qmR5h/uFyaVGmW926yzvMhvFGK/MByM/dkUrKQWMx3bJtdAR5mqiVzn
FlZhS84zL8VpnLGcjThsonOUutEfSBqqCgE9dpG2qYnI2ryKbI7xBLQKLIso
M5cq0mzZZhEYR4WzTdq1CnkdjlGF6XYjNiS02oqIdf6UHSZ5taVyh3LoVaZT
aeyx8m/aBckLB8QpHBD2YpX/YWXKS/mr1olswbZEd9XeNSVxzWaFZyeUVVsU
YiqPRDUq7Nu2mHt9XXX2qYaHM3bnLYO/R/PztUdv3EqTIScth5/7ZvJ6gbSP
3zT99XBAaaIadZW9XNQFVNpq9uLJlDhS87fT91rzqtZcwhRzZzUstfV9CGM0
kJ5QOY5+oBZ0aw9cQXNfp6wrWAz2YpGHshGpqSihWnRIqgYiw2tVM5XntcpX
A46N4mKd3GtKnmgaqvuLutx1Vfi7OqFXLQVuY9rWyQ7UZGmkvVSjinxVbyxH
5Tpv+J7bSs1Mvgu1XaXy+/dtn1oX7ViyVVOvo1Niok7wXTMRVSdKVb9c7U+J
+zY2TPOmBuuoxTpTbNU1bSmlqSpzGlVFnWr5Bl6BpnWUNcUFH9Xfj93HYiu6
BuZSETTgo1fJZBItQj6nKLs0kW6dYyqCS11Vc8npMZU9oBHO0vOlKAI6ZWrb
1B3rxI4FsjLKlv6TVVTYXV3Q8YZTKQwVeQmMq75qG1Tb4jd4znsa61FeEGfT
bh12BTr/8Wd+cNQtmB7/z154GTNUYS+2Zhg6Fn88NoVWK0to5mBMTwN/Fery
Vw1xBU7r5dAYcQmcOiwdLV+zw01w+I3aIJYpS9h/eqzMWXwsw4cWUqvJ8qql
ab/z7DbvkCXJRvNdyJuQutxjOy8DKxCrn9f7uFd9cI+N2T39bfbY4mrhHxIc
X9lh1q+pJ+vJM4ZJtw0abYN6W5sq8cp34l0TKfxjZwmjeQkLe4O/m6BbkmNX
DahFQdEllUXUfre6o4YVylXN7SFsm3+PnFKGrhLh+lmPuUirKw6xGRluahJs
ptojjBQrlp4xxU5A04UEPuAb9Pf4BowKNuXLR0HjkY2iN6Ovnuf47aPbWJHb
WPgK1JqBX65NAMMeFEFjzNvUkTYNavoosPRRC9osw15buqp8sDR5KlrLOaS1
SjOnjlyrXtop2rVpLPVTJ685jFz/XQ8QFNWbdYVWf7seEqA9Q/zbUbeYezlh
1+vXYgY3tPf7taDCDe2D/p6og/1eIZVVWpvQfuX1y8ntjUt0WxwXPSMrWtHW
Ss/DimG0tQr6vw79q/abJ23695eyWl5bEzdbJlgWlQUqZdpHcULXnYdfPeWE
LHD0mutLba1Z4E39RO1+9E52V/ZIu6t0kVLxyDqjLTI0xI9MSj/6t2jpc8vg
Fi2ZMp7d3LDUZoqU1Ew/x8p63S2x00KzuS7bqsKS/xPYNU+uIrlm/4LG593z
15wD76rseKxK+AqRWdkiyznxfbbRPkF6gxgljk4TDckes6J0OR6qne5qe7tK
51tzcKjcoN02eo3HYcXUwcNiCfWPnRqo/R899+tiB319Zn2OThqfX3H9odaB
3Zokg4qPgnz18M1X7AhpxSRjRqq+VgLtc4z0QAM6zeFZ+bvVM5tTFnu0mHvW
r61a85DeDLtVzuHmjIKumlJXAd5l8CxrUVl4Va479J4NpRXCtc00TeAH7TTX
mI2q8efajXpIYzi22oCvq8ZeMd/qY5577ZHffBQ0Hj1rPKng6s20zZ5UDT45
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
glYViTTm314jIquObq08pMZhI1UiUnnMsM37zrz5lI5rA0z8TmdsICR59zyn
s3M5n1PsmiJYHluyP3c76u0jfa6DwanbeZ7rZ0W4yZzh1nBbSnx2RqbVsUvZ
Lwii3qbg74ogOlIeeCvy3Q7PouxrHr5Jf6IT93LzN6APpScTsgE3f1ccCVQ6
4nSZEicQ+JxoPodLQ9/gUS37VMZqfiMpzluiGPaFPNV9s8oHbotph/rWjOui
mKZUJU1RUV9Up5JJ1gRnoRV4PqfEwlZD0iu2cJpzrysnrBt4ixO/1Qlo0lHd
XtopAzpudKH2ge4xLDgsRUzByRKOQiiVrdK3NuruVINeWAK3CGa1Gfu/Va//
AtXrd97w9neOLf/m0v/Lu/RfKplgxNex+02WLaSAUHm1AaOlLSCb1DDJoW+p
bEXtN6ebbfqOXrhv6HBFBYDi2La504IWC7lR0Ubr6qVfOlpBoYHbiPGGEHfc
W4nxqhDfk6HQ4YFWt6ySRd7IhYp4X6TrouhEs02XeyGDpaiUrVGayldXb9Bx
tzK64AOtc9VB4/ioxvIqhqGEJ7svhQqntytq/EaSv78/iuUW1NqqZz+ldP0m
dXsbhVs4faUpUIm3krhm8/m0cppdeaqDqn6xbRQ+wlWfqExB6AvJ2XWNOmKf
Tn2IIzrc3iG7Zl2eBhYSLeT4p6sKXCRdGgQLaEeuRE5n3/OVeqdblXvgyqW8
GIO4c8dnE7jJju169aZj3lSA0REDZHxy8Qy9S6nZCyn4uGPrSHl7WP1m5ewf
8lsZAq5XWWTZO778SwFjn7Csb/ShX6xod3VFG1kw81zbhnTq338Q1f+5oHqm
n1xXKplTkIqT4E7L0q96OP/Dh99xKP8hHeyq73UtjnfNqW2vOOes59GhFGUh
Vo3z9N1VdJNd8YyWgTwIOo+LjlwqT+Iv2fpb4KB3diGW6QbyW6xyphwA9u3p
yave2bOT705ftoKX0Is5v1iAxldlqGPYNDy12jd1JkxjU4/CoPvhfnU7rglW
WLtr1YmKhdos54ov9Z3ARY1J5dKAssC5OJyDcyPK+VPVXHzTK3Ge37/DHuqg
f4dN1EXGdx8yHulbGBUgn7zjWu+2dtzKfmvL1t9f93+w6v+uNf+fUPF/2+r8
O9Tm/3IbL9ftJei/uM3SM06Hguy4vJsQkJf1E3ciNpvUjk22ga3kh+5fgEGx
ealNj85Til69Wfo/EFUsA/6zUd829O0nE9bni4GwUHQioHyrwyCdIb0OI2NF
ufSH1JENz0+kYt8AJ0+5Q3x4psYhKPWI6tNPrLFbhzIn3auxyga53Ja/venY
oxTH53KvnWJc6yKQrj7moISHHwUVwI5+OlLW3J3EkA2kWJPOfEuFCYzuYkzl
InQ04jXwBMLGt3FVQHAn2XYQgqAGQdCAIGiBIJd8EfzbNKYQlE2xGL/lGiu2
jbnS6yHd0AyrFEYA0yx03TvpB9MXwWjcKbvtljBbGwxVH33+09F0pkUoC/C/
Fqe1VrWUep2C0+puNfscaW34FmWUx9xVr4w0lmKyGoCsHlKkNSCbjo5rZJ32
6Y1X7lX7KgKXDZNo6duv+bd+LbBfC2772qYy2uDWr2E0RvtBxVmNN9qRtsL4
v2FXccvJRL/K/WJ3ctcr7mFRrd9t+utNjXX+z6axbrXKf3fN9Jvy+b+rfDQn
fab6Mb30VTLEkG6/eiaS2SjV3FNm+VWV/epFFtjafn7Qs2o/LBV2/FFFKxUV
1S2gVPdf1drcxhErD46trP++IxFANOWJsdbzQd86LtZ6PuxXjl7Yf9LCUPT3
nJWA38LjopdKD/xC52DXR86oXznGoQ65645E2WJb/dXtbP3iPSKhUVjtDcjo
tCHkyBn3K4dD1BHjumNRbQH8ddpwSMOOw7LtNqiDGBRjHDmTftsZHNN+8xAO
OnRDgQ32pXg/fQ3M1+JI3rpRUOGBujv9eUda3OlAi5uOs/gt8fbbsVG33P//
r3oA029Bmc8NyhyUWAfyTU2JdZO8upXdfOWxHXWlDLorZVWVcoO/hvzvVjXZ
BoctYWNXT2oRn5YjkroNMdqH7WJnc+wzmNpa2xaOejH8qq3P1sd3CDsB8/xv
gXz+9qNXmKg/KuT8GOgfsAjqk198CsynZ+rDbbwJf/B3cycqp1+Zt8r5Vo+7
wpsKAa/pYxULxTfTiUJL86gAj97ViGo5R8C8HbQ3CPjtErH0qXjHr+CbWwYV
xNOjZ/YC2F7THQ3WQ46LnvubjuarwmNRgNYYy/JetPvUagkfHNA3AzZcMupy
nxF9sMvAdNnmY913b22A3z9ogu8HoFioN52wbVKfZ7wfXr5y6NpaaaAKLNzo
A9y/kxdwaIVLmLati3x7D+K244SamewJ3+h93L+T/7E+RIANSAJrug3Ppe6w
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
6Oid4/x/7QzfGasrAQA=

-->

</rfc>
