<?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.29 (Ruby 2.6.10) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-orru-zkproof-sigma-protocols-01" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.29.0 -->
  <front>
    <title>Interactive Sigma Proofs</title>
    <seriesInfo name="Internet-Draft" value="draft-orru-zkproof-sigma-protocols-01"/>
    <author fullname="Michele Orrù">
      <organization>CNRS</organization>
      <address>
        <email>m@orru.net</email>
      </address>
    </author>
    <author fullname="Cathie Yun">
      <organization>Apple, Inc.</organization>
      <address>
        <email>cathieyun@gmail.com</email>
      </address>
    </author>
    <date year="2025" month="July" day="07"/>
    <keyword>zero-knowledge</keyword>
    <abstract>
      <?line 86?>

<t>This document describes interactive sigma protocols, a class of secure, general-purpose zero-knowledge proofs of knowledge consisting of three moves: commitment, challenge, and response. Concretely, the protocol allows one to prove knowledge of a secret witness without revealing any information about it.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://mmaker.github.io/draft-zkproof-sigma-protocols/draft-orru-zkproof-sigma-protocols.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-orru-zkproof-sigma-protocols/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/mmaker/draft-zkproof-sigma-protocols"/>.</t>
    </note>
  </front>
  <middle>
    <?line 90?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Any sigma protocol must define three objects: a <em>commitment</em> (computed by the prover), a <em>challenge</em> (computed by the verifier), and a <em>response</em> (computed by the prover).</t>
      <section anchor="core-interface">
        <name>Core interface</name>
        <t>The public functions are obtained relying on an internal structure containing the definition of a sigma protocol.</t>
        <artwork><![CDATA[
class SigmaProtocol:
   def new(instance) -> SigmaProtocol
   def prover_commit(self, witness, rng) -> (commitment, prover_state)
   def prover_response(self, prover_state, challenge) -> response
   def verifier(self, commitment, challenge, response) -> bool
   def serialize_commitment(self, commitment) -> bytes
   def serialize_response(self, response) -> bytes
   def deserialize_commitment(self, data: bytes) -> commitment
   def deserialize_response(self, data: bytes) -> response
   # optional
   def simulate_response(self, rng) -> response
   # optional
   def simulate_commitment(self, response, challenge) -> commitment
]]></artwork>
        <t>Where:</t>
        <ul spacing="normal">
          <li>
            <t><tt>new(instance) -&gt; SigmaProtocol</tt>, denoting the initialization function. This function takes as input an instance generated via the <tt>LinearRelation</tt>, the public information shared between prover and verifier.</t>
          </li>
          <li>
            <t><tt>prover_commit(self, witness: Witness, rng) -&gt; (commitment, prover_state)</tt>, denoting the <strong>commitment phase</strong>, that is, the computation of the first message sent by the prover in a Sigma protocol. This method outputs a new commitment together with its associated prover state, depending on the witness known to the prover, the statement to be proven, and a random number generator <tt>rng</tt>. This step generally requires access to a high-quality entropy source to perform the commitment. Leakage of even just of a few bits of the commitment could allow for the complete recovery of the witness. The commitment is meant to be shared, while <tt>prover_state</tt> must be kept secret.</t>
          </li>
          <li>
            <t><tt>prover_response(self, prover_state, challenge) -&gt; response</tt>, denoting the <strong>response phase</strong>, that is, the computation of the second message sent by the prover, depending on the witness, the statement, the challenge received from the verifier, and the internal state <tt>prover_state</tt>. The returned value <tt>response</tt> is meant to be shared.</t>
          </li>
          <li>
            <t><tt>verifier(self, commitment, challenge, response) -&gt; bool</tt>, denoting the <strong>verifier algorithm</strong>. This method checks that the protocol transcript is valid for the given statement. The verifier algorithm outputs true if verification succeeds, or false if verification fails.</t>
          </li>
          <li>
            <t><tt>serialize_commitment(self, commitment) -&gt; bytes</tt>, serializes the commitment into a canonical byte representation.</t>
          </li>
          <li>
            <t><tt>serialize_response(self, response) -&gt; bytes</tt>, serializes the response into a canonical byte representation.</t>
          </li>
          <li>
            <t><tt>deserialize_commitment(self, data: bytes) -&gt; commitment</tt>, deserializes a byte array into a commitment. This function can raise a <tt>DeserializeError</tt> if deserialization fails.</t>
          </li>
          <li>
            <t><tt>deserialize_response(self, data: bytes) -&gt; response</tt>, deserializes a byte array into a response. This function can raise a <tt>DeserializeError</tt> if deserialization fails.</t>
          </li>
        </ul>
        <t>The final two algorithms describe the <strong>zero-knowledge simulator</strong>. In particular, they may be used for proof composition (e.g. OR-composition). The function <tt>simulate_commitment</tt> is also used when verifying short proofs. We have:</t>
        <ul spacing="normal">
          <li>
            <t><tt>simulate_response(self, rng) -&gt; response</tt>, denoting the first stage of the simulator. It is an algorithm drawing a random response given a specified cryptographically secure RNG that follows the same output distribution of the algorithm <tt>prover_response</tt>.</t>
          </li>
          <li>
            <t><tt>simulate_commitment(self, response, challenge) -&gt; commitment</tt>, returning a simulated commitment -- the second phase of the zero-knowledge simulator.</t>
          </li>
        </ul>
        <t>Together, these zero-knowledge simulators provide a transcript that should be computationally indistinguishable from the transcript generated by running the original sigma protocol.</t>
        <t>The abstraction <tt>SigmaProtocol</tt> allows implementing different types of statements and combiners of those, such as OR statements, validity of t-out-of-n statements, and more.</t>
      </section>
    </section>
    <section anchor="sigma-protocol-group">
      <name>Sigma protocols over prime-order groups</name>
      <t>The following sub-section presents concrete instantiations of sigma protocols over prime-order elliptic curve groups.
It relies on a prime-order elliptic-curve group as described in <xref target="group-abstraction"/>.</t>
      <t>Valid choices of elliptic curves can be found in <xref target="ciphersuites"/>.</t>
      <t>Traditionally, sigma protocols are defined in Camenisch-Stadler notation as (for example):</t>
      <artwork><![CDATA[
1. DLEQ(G, H, X, Y) = PoK{
2.   (x):        // Secret variables
3.   X = x * G, Y = x * H        // Predicates to satisfy
4. }
]]></artwork>
      <t>In the above, line 1 declares that the proof name is "DLEQ", the public information (the <strong>instance</strong>) consists of the group elements <tt>(G, X, H, Y)</tt> denoted in upper-case.
Line 2 states that the private information (the <strong>witness</strong>) consists of the scalar <tt>x</tt>.
Finally, line 3 states that the linear relation that need to be proven is
<tt>x * G  = X</tt> and <tt>x * H = Y</tt>.</t>
      <section anchor="group-abstraction">
        <name>Group abstraction</name>
        <t>Because of their dominance, the presentation in the following focuses on proof goals over elliptic curves, therefore leveraging additive notation. For prime-order subgroups of residue classes, all notation needs to be changed to multiplicative, and references to elliptic curves (e.g., curve) need to be replaced by their respective counterparts over residue classes.</t>
        <t>We detail the functions that can be invoked on these objects. Example choices can be found in <xref target="ciphersuites"/>.</t>
        <section anchor="group">
          <name>Group</name>
          <ul spacing="normal">
            <li>
              <t><tt>identity()</tt>, returns the neutral element in the group.</t>
            </li>
            <li>
              <t><tt>generator()</tt>, returns the generator of the prime-order elliptic-curve subgroup used for cryptographic operations.</t>
            </li>
            <li>
              <t><tt>order()</tt>: Outputs the order of the group <tt>p</tt>.</t>
            </li>
            <li>
              <t><tt>random()</tt>: outputs a random element in the group.</t>
            </li>
            <li>
              <t><tt>serialize(elements: [Group; N])</tt>, serializes a list of group elements and returns a canonical byte array <tt>buf</tt> of fixed length <tt>Ne * N</tt>.</t>
            </li>
            <li>
              <t><tt>deserialize(buffer)</tt>, attempts to map a byte array <tt>buffer</tt> of size <tt>Ne * N</tt> into <tt>[Group; N]</tt>, and fails if the input is not the valid canonical byte representation of an element of the group. This function can raise a <tt>DeserializeError</tt> if deserialization fails.</t>
            </li>
            <li>
              <t><tt>add(element: Group)</tt>, implements elliptic curve addition for the two group elements.</t>
            </li>
            <li>
              <t><tt>equal(element: Group)</tt>, returns <tt>true</tt> if the two elements are the same and false` otherwise.</t>
            </li>
            <li>
              <t><tt>scalar_mul(scalar: Scalar)</tt>, implements scalar multiplication for a group element by an element in its respective scalar field.</t>
            </li>
          </ul>
          <t>In this spec, instead of <tt>add</tt> we will use <tt>+</tt> with infix notation; instead of <tt>equal</tt> we will use <tt>==</tt>, and instead of <tt>scalar_mul</tt> we will use <tt>*</tt>. A similar behavior can be achieved using operator overloading.</t>
        </section>
        <section anchor="scalar">
          <name>Scalar</name>
          <ul spacing="normal">
            <li>
              <t><tt>identity()</tt>: outputs the (additive) identity element in the scalar field.</t>
            </li>
            <li>
              <t><tt>add(scalar: Scalar)</tt>: implements field addition for the elements in the field.</t>
            </li>
            <li>
              <t><tt>mul(scalar: Scalar)</tt>, implements field multiplication.</t>
            </li>
            <li>
              <t><tt>random()</tt>: outputs a random scalar field element.</t>
            </li>
            <li>
              <t><tt>serialize(scalars: list[Scalar; N])</tt>: serializes a list of scalars and returns their canonical representation of fixed length <tt>Ns * N</tt>.</t>
            </li>
            <li>
              <t><tt>deserialize(buffer)</tt>, attempts to map a byte array <tt>buffer</tt> of size <tt>Ns * N</tt> into <tt>[Scalar; N]</tt>, and fails if the input is not the valid canonical byte representation of an element of the group. This function can raise a <tt>DeserializeError</tt> if deserialization fails.</t>
            </li>
          </ul>
          <t>In this spec, instead of <tt>add</tt> we will use <tt>+</tt> with infix notation; instead of <tt>equal</tt> we will use <tt>==</tt>, and instead of <tt>mul</tt> we will use <tt>*</tt>. A similar behavior can be achieved using operator overloading.</t>
        </section>
      </section>
      <section anchor="proofs-of-preimage-of-a-linear-map">
        <name>Proofs of preimage of a linear map</name>
        <section anchor="core-protocol">
          <name>Core protocol</name>
          <t>This defines the object <tt>SchnorrProof</tt>. The initialization function takes as input the statement, and pre-processes it.</t>
        </section>
        <section anchor="prover-procedures">
          <name>Prover procedures</name>
          <t>The prover of a sigma protocol is stateful and will send two messages, a "commitment" and a "response" message, described below.</t>
          <section anchor="prover-commitment">
            <name>Prover commitment</name>
            <artwork><![CDATA[
prover_commit(self, witness, rng)

Inputs:

- witness, an array of scalars
- rng, a random number generator

Outputs:

- A (private) prover state, holding the information of the interactive prover necessary for producing the protocol response
- A (public) commitment message, an element of the linear map image, that is, a vector of group elements.

Procedure:

1. nonces = [self.instance.Domain.random(rng) for _ in range(self.instance.linear_map.num_scalars)]
2. prover_state = self.ProverState(witness, nonces)
3. commitment = self.instance.linear_map(nonces)
4. return (prover_state, commitment)
]]></artwork>
          </section>
          <section anchor="prover-response">
            <name>Prover response</name>
            <artwork><![CDATA[
prover_response(self, prover_state, challenge)

Inputs:

    - prover_state, the current state of the prover
    - challenge, the verifier challenge scalar

Outputs:

    - An array of scalar elements composing the response

Procedure:

1. witness, nonces = prover_state
2. return [nonces[i] + witness[i] * challenge for i in range(self.instance.linear_map.num_scalars)]
]]></artwork>
          </section>
        </section>
        <section anchor="verifier">
          <name>Verifier</name>
          <artwork><![CDATA[
verify(self, commitment, challenge, response)

Inputs:

- self, the current state of the SigmaProtocol
- commitment, the commitment generated by the prover
- challenge, the challenge generated by the verifier
- response, the response generated by the prover

Outputs:

- A boolean indicating whether the verification succeeded

Procedure:

1. assert len(commitment) == self.instance.linear_map.num_constraints and len(response) == self.instance.linear_map.num_scalars
2. expected = self.instance.linear_map(response)
3. got = [commitment[i] + self.instance.image[i] * challenge for i in range(self.instance.linear_map.num_constraints)]
4. return got == expected
]]></artwork>
        </section>
        <section anchor="witness">
          <name>Witness representation</name>
          <t>A witness is simply a list of <tt>num_scalars</tt> elements.</t>
          <artwork><![CDATA[
Witness = [Scalar; num_scalars]
]]></artwork>
        </section>
        <section anchor="linear-map">
          <name>Linear map</name>
          <t>A <tt>LinearMap</tt> represents a function (a <em>linear map</em> from the scalar field to the elliptic curve group) that, given as input an array of <tt>Scalar</tt> elements, outputs an array of <tt>Group</tt> elements. This can be represented as matrix-vector (scalar) product using group multi-scalar multiplication. However, since the matrix is oftentimes sparse, it is often more convenient to store the matrix in Yale sparse matrix format.</t>
          <t>Here is an example:</t>
          <artwork><![CDATA[
class LinearCombination:
    scalar_indices: list[int]
    element_indices: list[int]
]]></artwork>
          <t>The linear map can then be presented as:</t>
          <artwork><![CDATA[
class LinearMap:
    Group: groups.Group
    linear_combinations: list[LinearCombination]
    group_elements: list[Group]
    num_scalars: int
    num_elements: int

    def map(self, scalars: list[Group.ScalarField]) -> Group
]]></artwork>
          <section anchor="initialization">
            <name>Initialization</name>
            <t>The linear map <tt>LinearMap</tt> is initialized with</t>
            <artwork><![CDATA[
linear_combinations = []
group_elements = []
num_scalars = 0
num_elements = 0
]]></artwork>
          </section>
          <section anchor="linear-map-evaluation">
            <name>Linear map evaluation</name>
            <t>A witness can be mapped to a group element via:</t>
            <artwork><![CDATA[
map(self, scalars: [Scalar; num_scalars])

Inputs:

- self, the current state of the constraint system
- witness,

1. image = []
2. for linear_combination in self.linear_combinations:
3.     coefficients = [scalars[i] for i in linear_combination.scalar_indices]
4.     elements = [self.group_elements[i] for i in linear_combination.element_indices]
5.     image.append(self.Group.msm(coefficients, elements))
6. return image
]]></artwork>
          </section>
        </section>
        <section anchor="statements-for-linear-relations">
          <name>Statements for linear relations</name>
          <t>The object <tt>LinearRelation</tt> has two attributes: a linear map <tt>linear_map</tt>, which will be defined in <xref target="linear-map"/>, and <tt>image</tt>, the linear map image of which the prover wants to show the pre-image of.</t>
          <t>class LinearRelation:
        Domain = group.ScalarField
        Image = group.Group</t>
          <artwork><![CDATA[
    linear_map = LinearMap
    image = list[group.Group]

def allocate_scalars(self, n: int) -> list[int]
def allocate_elements(self, n: int) -> list[int]
def append_equation(self, lhs: int, rhs: list[(int, int)]) -> None
def set_elements(self, elements: list[(int, Group)]) -> None
]]></artwork>
          <section anchor="element-and-scalar-variables-allocation">
            <name>Element and scalar variables allocation</name>
            <t>Two functions allow to allocate the new scalars (the witness) and group elements (the instance).</t>
            <artwork><![CDATA[
allocate_scalars(self, n)

Inputs:
    - self, the current state of the LinearRelation
    - n, the number of scalars to allocate
Outputs:
    - indices, a list of integers each pointing to the new allocated scalars

Procedure:

1. indices = range(self.num_scalars, self.num_scalars + n)
2. self.num_scalars += n
3. return indices
]]></artwork>
            <t>and below the allocation of group elements</t>
            <artwork><![CDATA[
allocate_elements(self, n)

1. linear_combination = LinearMap.LinearCombination(scalar_indices=[x[0] for x in rhs], element_indices=[x[1] for x in rhs])
2. self.linear_map.append(linear_combination)
3. self._image.append(lhs)
]]></artwork>
            <t>Group elements, being part of the instance, can later be set using the function <tt>set_elements</tt></t>
            <artwork><![CDATA[
set_elements(self, elements)

Inputs:
    - self, the current state of the LinearRelation
    - elements, a list of pairs of indices and group elements to be set

Procedure:

1. for index, element in elements:
2.   self.linear_map.group_elements[index] = element
]]></artwork>
          </section>
          <section anchor="constraint-enforcing">
            <name>Constraint enforcing</name>
            <artwork><![CDATA[
append_equation(self, lhs, rhs)

Inputs:

- self, the current state of the constraint system
- lhs, the left-hand side of the equation
- rhs, the right-hand side of the equation (a list of (ScalarIndex, GroupEltIndex) pairs)

Outputs:

- An Equation instance that enforces the desired relation

Procedure:

1. linear_combination = LinearMap.LinearCombination(scalar_indices=[x[0] for x in rhs], element_indices=[x[1] for x in rhs])
2. self.linear_map.append(linear_combination)
3. self._image.append(lhs)
]]></artwork>
          </section>
        </section>
        <section anchor="example-schnorr-proofs">
          <name>Example: Schnorr proofs</name>
          <t>The statement represented in <xref target="sigma-protocol-group"/> can be written as:</t>
          <artwork><![CDATA[
statement = LinearRelation(group)
[var_x] = statement.allocate_scalars(1)
[var_G, var_X] = statement.allocate_elements(2)
statement.append_equation(var_X, [(var_x, var_G)])
]]></artwork>
          <t>At which point it is possible to set <tt>var_G</tt> and <tt>var_X</tt> whenever the group elements are at disposal.</t>
          <artwork><![CDATA[
G = group.generator()
statement.set_elements([(var_G, G), (var_X, X)])
]]></artwork>
          <t>It is worth noting that in the above example, <tt>[X] == statement.linear_map.map([x])</tt>.</t>
        </section>
        <section anchor="example-dleq-proofs">
          <name>Example: DLEQ proofs</name>
          <t>A DLEQ proof proves a statement:</t>
          <artwork><![CDATA[
    DLEQ(G, H, X, Y) = PoK{(x): X = x * G, Y = x * H}
]]></artwork>
          <t>Given group elements <tt>G</tt>, <tt>H</tt> and <tt>X</tt>, <tt>Y</tt> such that <tt>x * G = X</tt> and <tt>x * H = Y</tt>, then the statement is generated as:</t>
          <artwork><![CDATA[
1. statement = LinearRelation()
2. [var_x] = statement.allocate_scalars(1)
3. statement.append_equation(X, [(var_x, G)])
4. statement.append_equation(Y, [(var_x, H)])
]]></artwork>
        </section>
        <section anchor="example-pedersen-commitments">
          <name>Example: Pedersen commitments</name>
          <t>A representation proof proves a statement</t>
          <artwork><![CDATA[
    REPR(G, H, C) = PoK{(x, r): C = x * G + r * H}
]]></artwork>
          <t>Given group elements <tt>G</tt>, <tt>H</tt> such that <tt>C = x * G + r * H</tt>, then the statement is generated as:</t>
          <artwork><![CDATA[
statement = LinearRelation()
var_x, var_r = statement.allocate_scalars(2)
statement.append_equation(C, [(var_x, G), (var_r, H)])
]]></artwork>
        </section>
      </section>
      <section anchor="ciphersuites">
        <name>Ciphersuites</name>
        <section anchor="p-256-secp256r1">
          <name>P-256 (secp256r1)</name>
          <t>This ciphersuite uses P-256 <xref target="SP800"/> for the Group.</t>
          <section anchor="elliptic-curve-group-of-p-256-secp256r1-sp800">
            <name>Elliptic curve group of P-256 (secp256r1) <xref target="SP800"/></name>
            <ul spacing="normal">
              <li>
                <t><tt>order()</tt>: Return the integer <tt>115792089210356248762697446949407573529996955224135760342422259061068512044369</tt>.</t>
              </li>
              <li>
                <t><tt>serialize([A])</tt>: Implemented using the compressed Elliptic-Curve-Point-to-Octet-String method according to <xref target="SEC1"/>; <tt>Ne = 33</tt>.</t>
              </li>
              <li>
                <t><tt>deserialize(buf)</tt>: Implemented by attempting to read <tt>buf</tt> into chunks of 33-byte arrays and convert them 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.</t>
              </li>
            </ul>
          </section>
          <section anchor="scalar-field-of-p-256">
            <name>Scalar Field of P-256</name>
            <ul spacing="normal">
              <li>
                <t><tt>serialize(s)</tt>: Relies on the Field-Element-to-Octet-String conversion according to <xref target="SEC1"/>; <tt>Ns = 32</tt>.</t>
              </li>
              <li>
                <t><tt>deserialize(buf)</tt>: Reads the byte array <tt>buf</tt> in chunks of 32 bytes 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 <tt>[0, G.Order() - 1]</tt>.</t>
              </li>
            </ul>
          </section>
        </section>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>Interactive sigma proofs are special sound and honest-verifier zero-knowledge. These proofs are deniable (without transferable message authenticity).</t>
      <t>We focus on the security guarantees of the non-interactive Fiat-Shamir transformation, where they provide the following guarantees (in the random oracle model):</t>
      <ul spacing="normal">
        <li>
          <t><strong>Knowledge soundness</strong>: If the proof is valid, the prover must have knowledge of a secret witness satisfying the proof statement. This property ensures that valid proofs cannot be generated without possession of the corresponding witness.</t>
        </li>
        <li>
          <t><strong>Zero-knowledge</strong>: The proof string produced by the <tt>prove</tt> function does not reveal any information beyond what can be directly inferred from the statement itself. This ensures that verifiers gain no knowledge about the witness.</t>
        </li>
      </ul>
      <t>While theoretical analysis demonstrates that both soundness and zero-knowledge properties are statistical in nature, practical security depends on the cryptographic strength of the underlying hash function, which is defined by the Fiat-Shamir transformation. It's important to note that the soundness of a zero-knowledge proof provides no guarantees regarding the computational hardness of the relation being proven. An assessment of the specific hardness properties for relations proven using these protocols falls outside the scope of this document.</t>
      <section anchor="privacy-considerations">
        <name>Privacy Considerations</name>
        <t>Interactive sigma proofs are insecure against malicious verifiers and should not be used.
The non-interactive Fiat-Shamir transformation leads to publicly verifiable (transferable) proofs that are statistically zero-knowledge.</t>
      </section>
    </section>
    <section anchor="post-quantum-security-considerations">
      <name>Post-Quantum Security Considerations</name>
      <t>The zero-knowledge proofs described in this document provide statistical zero-knowledge and statistical soundness properties when modeled in the random oracle model.</t>
      <section anchor="privacy-considerations-1">
        <name>Privacy Considerations</name>
        <t>These proofs offer zero-knowledge guarantees, meaning they do not leak any information about the prover's witness beyond what can be inferred from the proven statement itself. This property holds even against quantum adversaries with unbounded computational power.</t>
        <t>Specifically, these proofs can be used to protect privacy against post-quantum adversaries, in applications demanding:</t>
        <ul spacing="normal">
          <li>
            <t>Post-quantum anonymity</t>
          </li>
          <li>
            <t>Post-quantum unlinkability</t>
          </li>
          <li>
            <t>Post-quantum blindness</t>
          </li>
          <li>
            <t>Protection against "harvest now, decrypt later" attacks.</t>
          </li>
        </ul>
      </section>
      <section anchor="soundness-considerations">
        <name>Soundness Considerations</name>
        <t>While the proofs themselves offer privacy protections against quantum adversaries, the hardness of the relation being proven depends (at best) on the hardness of the discrete logarithm problem over the elliptic curves specified in <xref target="ciphersuites"/>.
Since this problem is known to be efficiently solvable by quantum computers using Shor's algorithm, these proofs MUST NOT be relied upon for post-quantum soundness guarantees.</t>
        <t>Implementations requiring post-quantum soundness SHOULD transition to alternative proof systems such as:</t>
        <ul spacing="normal">
          <li>
            <t>MPC-in-the-Head approaches as described in <xref target="GiacomelliMO16"/></t>
          </li>
          <li>
            <t>Lattice-based approaches as described in <xref target="AttemaCK21"/></t>
          </li>
          <li>
            <t>Code-based approaches as described in <xref target="Stern93"/></t>
          </li>
        </ul>
        <t>Implementations should consider the timeline for quantum computing advances when planning migration to post-quantum sound alternatives.
Implementers MAY adopt a hybrid approach during migration to post-quantum security by using AND composition of proofs. This approach enables gradual migration while maintaining security against classical adversaries.
This composition retains soundness if <strong>both</strong> problems remain hard. AND composition of proofs is NOT described in this specification, but examples may be found in the proof-of-concept implementation and in <xref target="BonehS23"/>.</t>
      </section>
    </section>
    <section anchor="protocol-id-generation">
      <name>Generation of the protocol identifier</name>
      <t>As of now, it is responsibility of the user to pick a unique protocol identifier that identifies the proof system. This will be expanded in future versions of this specification.</t>
    </section>
    <section anchor="instance-id-generation">
      <name>Generation of the instance identifier</name>
      <t>As of now, it is responsibility of the user to pick a unique instance identifier that identifies the statement being proven.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <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="fiat-shamir" target="https://mmaker.github.io/spfs/draft-orru-zkproof-fiat-shamir.html">
          <front>
            <title>draft-orru-zkproofs-fiat-shamir</title>
            <author>
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="SP800" target="https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-186.pdf">
          <front>
            <title>Recommendations for Discrete Logarithm-based Cryptography</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </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="GiacomelliMO16" target="https://eprint.iacr.org/2016/163.pdf">
          <front>
            <title>ZKBoo: Faster Zero-Knowledge for Boolean Circuits</title>
            <author fullname="Irene Giacomelli">
              <organization/>
            </author>
            <author fullname="Jesper Madsen">
              <organization/>
            </author>
            <author fullname="Claudio Orlandi">
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="AttemaCK21" target="https://dl.acm.org/doi/10.1007/978-3-030-84245-1_19">
          <front>
            <title>A Compressed Sigma-Protocol Theory for Lattices</title>
            <author fullname="Thomas Attema">
              <organization/>
            </author>
            <author fullname="Ronald Cramer">
              <organization/>
            </author>
            <author fullname="Lisa Kohl">
              <organization/>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="BonehS23" target="https://toc.cryptobook.us/">
          <front>
            <title>A Graduate Course in Applied Cryptography</title>
            <author fullname="Dan Boneh">
              <organization/>
            </author>
            <author fullname="Victor Schoup">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="Stern93" target="https://link.springer.com/chapter/10.1007/3-540-48329-2_2">
          <front>
            <title>A New Identification Scheme Based on Syndrome Decoding</title>
            <author fullname="Jacques Stern">
              <organization/>
            </author>
            <date year="1993"/>
          </front>
        </reference>
      </references>
    </references>
    <?line 505?>

<section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors thank Jan Bobolz, Stephan Krenn, Mary Maller, Ivan Visconti, Yuwen Zhang for reviewing a previous edition of this specification.</t>
    </section>
    <section numbered="false" anchor="test-vectors">
      <name>Test Vectors</name>
      <t>Test vectors will be made available in future versions of this specification.
They are currently developed in the <eref target="https://github.com/mmaker/draft-zkproof-sigma-protocols/tree/main/poc/vectors">proof-of-concept implementation</eref>.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAINbbGgAA91cW3PbOJZ+16/AOg8jeUT67sSeytZ4HLfj6Vw8caa706mU
BZGQhDFFsnmxo3blh+3z/rE9FwAEKcl29/bW1m5XzcSScD2X71xwgCAIepWu
EnUsNi7SShUyqvStEld6OpfissiySbnRi2SlplmxOBY6nWS9XpxFqZxDn7iQ
kyrIiqIOfr3JsXVQYs8A/q6yKEvKYHunV9bjuS5LnaXVIlc4SKxyBf+XVr20
no9VcdyLYYrj3u2x2Os9E7JQ8licfDg7gQ93WXEzLbI6PxY/nosf4ZNOp+Ic
v+ndqAX8HB/3RCB+VUUW3KTZXaLiqerdqrSGEZ8J4TrjB15BexT4ei51gk3+
qr7KeZ6oKJvj17KIZsdiVlV5eby11fy2BYPBwLqa1WOg3Hwub1SxxdRYQ4gN
6JDAJssKOtgRuWPIA4U6e3iIrcfJHc6qebLR68m6mmUF0gWmFWJSJwlzbOOt
jmYqUeJ9Ufznf2zQr1kxlan+VVbAoWNx+u7DFX2tmCgb87/ijGGqqo0V453K
aqaV+FSnqwY7yYFgQ3GRRqE/ZkSdFnX61yl+ESK5e2lWzCVK33Gvh3LmPsF8
WlZBOZNzjXuC/6zMLlOkDLzGvCSSLTGRSam4syymqmr4usSFMp+sJLY3MhEa
Rru6fLG93V7TB5SQOcg30aAUsBPxSpdRoSol3mRTWcBE82AsSxWL02KRV9m0
kPlssbFydeltktfjMkx1WYXT7HYL/8Bvtq5yFWmZXNbjREc82da7i6uP4dVl
CKsKdl4chnk8wVWene60FwnfiJ1jcZYkOq90JE7rAtT+8dXc3d2FpYqmIfB5
C/7YCW53zSTLhHZSSP8F5l8BAFAei6tKAomKmAl0NpnoSAMitNbACir6sNrz
AXQ/1xJoq2DRb9/vHLZ39PP3f8uyY/GdLAHGxM+IBt9bNKAp4OdEyVSc6iKq
dVWu3qDKC51WIUxU0B53t3cOt3YO9560SbtFTz8uCpUqb+Eb6xr+XZU5LPyt
jEuVrm11msg61hmobwLko9FOqgrU6vT73Q6LT8RpNs8LVaKcEaAHlwYnxMeZ
AjwnsryRFQiAWkOOOAllNCdKxJne2tkOd7a3n28dPX8R7AXbe9vBi/3d/YNg
53rn6HdQ5+Msm8vS7GBNmw9ZKhNUFPhUrGnzRpdSfJ/NUCP/lqVqdrW7Z8Wu
Icd5IeMa1gd0qYtSgRgSPumVarhMCqBcGFG7cZbdhHW5ZRquE/Nmfa9A7Ghd
D7T5QUcVsOMqmqFNAp0FMU6P9ro8fafuxAWaTj0xSo9d1FyJvxGg4OdFGhcg
beIVIFEMdm41axOd3oQlivsU0A+tWjSTOczquLwXHOxvB/sv9naPgt3rXY/B
O0dHe6tUvCXQMvqlViVvBGxSEARCjssKfYxe7+NMlwIciXqOSh8rwEc9htba
80LIuAln3IZCiiiRZSmyiQDsqQswLVNQr0ImQV4XeQZMbbsBgm0Cdmi+iwAo
AUPRAYDvq1mhlJhntwpACZFbV7ikoQBqJIkC4sC8aSxAkXLoqEIQn5TAPFkM
obdyCxTQPruDyUDhqwy/hj0008JcEpcNXcWdrlJQTPwX2F3B4LdKJrgimS6E
s37ATDnG33UVMgHnOo4T1QPnBNy1IovrCFv1eifQrU0uMa9LJOxE43Jok9n4
XyqqYJtSbDY73RR9+JDXFUjPeGF3dKuKwZAaWjKsaAeNQAy5JZAIWlsqrR8U
NvLsGdCwUMzriYwUigM0IEMGIpRGbDnBD4Q1VxJ2gPRPFsQyoEnKXQEYBMgT
0ABEAdmKTbENTkc710RDpnyLOrAKFFgWJwJHi41WlnEAkaq7PlgrMFWRGojg
39tN/Za8u2sma79UyWRouTwURTql3n1fvkwPGLxSgxVDWVKawfzmnnDSuLap
P4rljem+RrJtTxoGcK21pxKGAKn8VV03vZeG454L8GxXd+1soz1htxvgwPo5
AXogLKA+1LtpsG6IztzdAbpkeyayHAVGtqmg5zV67ks7MUz9jaMsbcv27zLV
217vx5kq0C8OxOhhkRzBLlWaVVYLSAWQGIwmVrdCQfhrP4JtuAHslQi/oLOs
YDyFAVjU41staczRG1BIWXxQCQ06MijI2utjF7jKBeq/qu6USo0EE1JY4Qxp
Sw/oDgRlT1ei7uY3PZQT+Qzs4+YmLlYCoJa8agYpaWECv5roAoBzDnNKQO0S
+7YQDP0GaSJkBydMz7kCOAcbXIODXgE9ET88PoJVAAsMrCTcB1BHkpcZOPFI
XjO6UXAOkQ3g4eTWZKBBSdG+NCvirVBHMw3QnH9LLTIX8E82FxxvW6aCvzEC
so7M8sFzzq1BTRYgmL/UukC5iCKcGYaVYqans+CXGkSqWgiFNigHywMOVcRG
DwAd+G9pazYeijdK3kg2gmDqUvEvNE6EyxMg0RhJYcjvkSvKavD8yKqSq2oZ
lmAkVYBzA3tf2H6GPriV1iDEFumowjIJ8jXTEAWPfPkZscmERjcqr4ypbkno
74DkZZm0vzxdImElGTBxvUiuF5eOaJgp7EqRiAo8rVhMwGFsmXSWG4YQZ2rR
eW6TjMkNdKoLNNK3Mqmhidv8auozTX+ngVomqB0IJGWaUXC9udlWSHCQo5uS
6dzy2MAZTdHzzElOYPU6dpI21SiojnS80+W5nLaDIwLEsobX+OZlDbqjYuAD
jEph0VKTidRJyST5jQYXSOF6lF3lAbahvkYyzVKYKqEuQE6MCOF3mrs766O2
enlGJ81Pn+93GnlivDe75BlkUciFm92DnLaFg3UBBmpYqBSjV804Z0WRFSNk
SjP4El9+h0/xlNU2IcUftdaPZL9QWau7rJHR0gVYRmU6UZJxTrICFecCLLUs
Kh3BV2xaFmIOi4bONUaYqB8UVhFUZSX72H0VTkPx/kPgfTlgnXH7Gq1wgggi
QC8yHvxuBjpH6kHOfgnBZWWCuFD8qMRM3ho/6KluWRcv2LyDWrM1Ini024fN
ExAA/Rv9jgt5R5GZtaFO5BkhILTARNwE8whRk0dAHQAjynGq+PDunOFnknGQ
SPNCoGzgQ8QQkQKDah/3mzV0DdAobNPgdziVo6GBbd6bHSr2MQQCTs/+kL2y
a1snQSiExssh2VkOyV3TkqyXjlHMPSAmMgHj0faPW/aQCKrTmIP3WoM1GYMR
d7bLG6TxWsFQFnXqwkIg6JQUZCkeRFG1+QmS1rZjbaN7jf4HUgdHjPVkAp45
2rdFrjgxYQ1GSRYUlj8Gd7kw/k2GLAGjMENn+/0Hr/WQzQ+6VdgyALkIskmQ
tprgiHMInTGI7rigMAG6j3mh5yrIihi9PMyeluL+WfuUIKDvvxm0IHkkXavH
AXCa9m5Au8SgmhPXHA9ALMGhOW70semVTS5HlFzm1YS9C0x3JBqphcqzqkfg
9UBCWfSK0fe+v6fvA49X374BQX4g6x3NMsxmkqPZmr8kWB3jjuvUDBTpHOS0
rDWgN43xsZCxtqI2XNoiJiQ4o0IDnIL+prqMZsFVJeMENgA4Y9I2pegjUJoz
o8Ex5xt2QvHqzdk/+udD8XoofhqKTwPxUlxm39/Tz7sh/F//6+DYpge3tsQV
Z4xuJeA9SDuHy3vY8Cfo+lVsChjsk/nztdfxEjwt9DEUee4lrKucLKj3fiiA
+xfsKMoxMG4oEkwT7cDuIkB91faVgJaY00Nk3MDlb6yN+PpsXmzwuLk5sNk2
598zU1VidGSEtPiJyPFpMGKoZurWOQQTQQSYE/Yw4hS7rAqttelbScK5tATj
/65aQQnILCHy+Qoo+p02rKb97y3NkFCoiwLLo9MPKXh0rSALKNMbESsEMOKn
EenpiBnyUnwacc6LDzN8iLl/tizKvd7fVCRrh7S6EGB0YJlAT5tvbDwqJFTV
UuNJFkFnUi5m3TSTVjs7GkHDFWqCubgEwrJCTskYxKgDoH9WmkPxXdZWbcAK
Ay4wASxHx+D7UjINRwWKNpqAxCoNtcAWgSEi2oENqHTOB1e3LsVKYBqxxHbV
lzyMIX8a+DwAHzORkUs06oKsn+IcMsSQGL+gR2OI0Fku8OZH1OoKXCgmpcs/
ErMNauj0Nrvh/DpbNZNMDcUZq7hDnifAzDMnDUYCvpE515TXrxb9gTPO7Cik
qgb5SKzWWKZT1xB7unh+qWsT6RvpfwBvLVcbP6/lz4gsx6GQNDQpjQETHov3
NgQiA4sjt5R9lI+oA/tP1KNJkRinau3WnPfbt5hxLD4T8f4i3n0ZtCMSCQrL
iYUOzLB4MVmWghR2ykfjejLCrhP9FbaPPlM1E6N3gCbiHW/A8+j70BqkFeeX
eHyVVyS0c5m3Xf0RtxuxxfxVuQE5CBg1WxmxEpArjz4+x97oGwLugjpxeM5G
7qEgi9IqqSOoz4k/LNAAWgBKWI4cszAjLZx3VHbNP6MKDmHia4xQ2lyicRUm
l1aMbLk3wjh7ZAmEgzRMLlTjVzMtE0xCZAhzdxoNCQoUwf81AFCf/zwWV/Rv
Z/3GTPhAZVYv2+tG3PEIDhKM6SwPg8xIECEkmPsgw4vpNvh9SI6VkjHyCWk6
EneYvAEERRMw+vPI5ApTkEoHqn9p9SKKdfq9fGnEyW/Y7LzTenMUihN0zDWu
c6wgytKo/YxkMppphUmiuqQEU24BBdA0ySRmnQymMR27WNZoOzKnb83LQNg2
XeVv08vIWpdXxz6vqOmyiDnJsFbSjfgo93nENvMfBTF/4XbyDohxE8AwBKrP
PDUD2fFqIDMdWgjGVq5BgWUA6GBY+UdjWNnCsGYb/5dA7H9PEf+nNNBU7OEc
QEw9l/bY2bixwFlWVDp+tXGNPYynwMYYcXJuIASOZmlWFDSsyfWuOVHqHiF1
0s5IAVgSxqB4loAH/ZUBjcvCRI7wS1yDDJjTYP56xdmtoKMKGHpSJzQwkRFE
JyZzYNLkVC6w0SQzNsxByIZNjWzYlkMvvhwrcKN5YW5l/kEchk+PHvVyswuk
Q2kCv6BpgcklUqtGuU0T6Dtcf1TDAxlXyw17IvomChp0TpBmWRI3x4BNgJRZ
rWwKLUzHVCFvpCkMyqm8wI7giN867uT5KQ4c+IkjR9llHW5EUZCAescfUtyq
yLiqXc+Apru0MtKE04Ah6HS/FJ+REaGNPMNX2VzqNDRoTUlB3NQ1moICo5B+
uz0v6xqWFQLhrw1jBl9sXO6fesBs1Jnl4wq/6jv28oIGNkz3iGJ6rZiy73eC
6JxxHjnbOmBqjgDaAupY4ovnE8+qVsgqM7bdgQ4X6oJSXUwDF05gM6+fd3bj
nyd5h06l8RKWxdmI1JKCNIbcZJeNULY3vkI6OlwBFvjbsrw15P7MjT7rL+LP
tid+2PTWjjKkf7MMEc79YCjBi+Mc9xPPvlYCCnddy5jlSpWgNU/nuKiVMO0w
dompDT2Wull+W0hzeejWYdG62dZA3NiUbmLuF10xYP/djE/SmznbJ24qXisU
GPYXFTpHff9U7eV6/SR2YhoJonBtw0ns35yQPdbbR3oQOfUVgwPY/wOg0LDf
YMk0QxD53CyaRbU9AIHqf0dsvX0a+GsQiVbw0q2eBdtUaHQ9uPtnRoe+9Xon
rnwBbTe62QvPxR15BBp1Md+ODhu3bqbX3OjWm8ao3D/j/QTwgWY25SpvZT5q
logetnNd+lJcN2bpujlQaPnzpuRiVVZ7QDZsaA+EvDIaB2QjXnyzvWETPvjN
KN71iMDOrvED3fJBcGAWMOiF/hoYo2lCi4Ex3JVxFtmQUiATrAxpQ/E6u1NU
RQAdIg6heWjkVjapMEoDiw5+MlAcVFlX7gc6jcAMK2xcm9qTssqK9iip+CQT
Zfrbb9kjAS6/VoUyp24mXX7sV+cx+07pHIWvFThbYQJaggVlYyoQ3C+uhaHj
qibkZXreCNK4wuPHsUuxEplXLAZkqVnEOd8vMccbfKXE/mZUK2oWb5ewtKtm
zTTSdZPtovY0btPGUwG8UFO1fmi6auuz4n9Yhoa4woajHYjS8CHL6Hco7l/o
uJB3w87GRcvxXyKfr2a6bMIEPNSFwImXsYIeqNi8r/a+m++9vcKX273uNulL
XqOHAwprUcxSG/gxigQNcs4fd3M5t1oahq8g1UoE+l3WuQFZUS4gMJx3ogRn
rDiIc7QA04FYvkxHVDKC9VUi15wZgRxnyt61YLeZt4EWw1mJ5THCtqo5u+Dp
WOOEtxn52MgdFeWhD3ho2n2IzEpjtlosqPNy3vc3MnSLGLC1PHQmi4Yw6anm
aLYhojvbMXGnDX07RY5iBoBLRRUVn9MrqqP2FaCxoyOqL4tmHJmOW4eG9/ee
ffrGkfGIFmkKKbsBEooMj+bVIN7JlJM15Sy7s6dCgW0PoOrDld1Eg1kcHQHD
pl29d00ujOBxCwMEHVzDNb5sMLG54GP6ErR4A3zhERCI8DQdDyetGhlVSwmz
CHvaYN7qY5n9pE4kPNeYm0EamC7JjNERnOyZxcA+fcaRGPzeZalyw5Sq6k7b
QWjuzvlqbwAGpjMDL8htY4Xdia7dF6MqiJhXAU+1jwhTZuvmOOjOpQX7XrHf
gIbvnHz0Odg3BcPGqVpH/Q6WWX4+CmdtOfP6pdzJ5DK8dKa3p7bT3/Q1gDD0
PEVMWkyxmEJJ0Ic801yGYVwzpIsdNHa5lXVhgBkexNRzij1gH4ruN+BrpwML
w8s/vhSpBVqLPTxFr4d8odSSqeux/F7OdHT405X0gVv+ChPgqWK45F/02wj+
8vPXz9sMzOSggRp8GXbdJWy002nUJoAXOxiUXl6Xi1+ox3UL00EPYUvnLRIM
gVTIVTyzbbJVLMBDsuBYqFRQPamybq5/cov59kZbR0yyBxT4D5f6ZieN6OZS
cxGQlbsVumqKZFW1VmjJkKax+jr0D00cEjVVJF3udG0yjvEFJMZ8Y2DqtHFL
FKYMMf1nJHIdjBKC/qE+EA1KllBNqmBGkIlVYqabXYLNMNjWhZ7OHmiOUZ7l
RZ8N3gUTkqTvLKno44AZNViTikjFmR3P3ZCg/CWTy6TPY1Xqgu8sGVhfw87/
T0pMZs7Eb8IcHJjSTfasmgsKfhxLLtHKArVv1lu/K3RVUWBtKNeM9LKjhH2O
x6nVZ7Cw1yTkTRH3kuHb8dqeYw1ecf3Tmi4OPXYH7VWEXeWgUYbiM/3xlUc9
H2CkcFIZX45sl4mk86wsNVYyoj8HiDai9qaKiMYaUWEsBumraqjw3FtSCSmM
JO3dtnPnvHnVIZ2Ft0CRlwtEOB8Mhd3DT7RsLou9y4pqJlwtrXQHtlRDZoP3
oRh9RhL6NPQkDMOqz1+/DEZhR2SwsszJy4n3kX1ezNi4Ab188Zp6OqqiW1Uh
9w3MDaVpuoVo5+B/j14bqv+EHz6NuFSTtmrqu1aVdw05b9A68kJ6NVlOJ7mg
8w8Ir1PL3yK6e+EDkuhLIUkg9th/qMcnr8drYn6LS5cqBv8LdttkIYldneTf
OsY1fPtwdvnB8O20YRpYE+DbqeUbeFzFk5jm8Wmp82/hz6PM8TS6eJg9j6LE
aYs3RuWKhuri1KsbE/fPWmVk5uw02D04FGCMoxz+KEAi+CzXayqoGpAb3t/T
exWArLZCgsNpF6QspzbRXC7N0gzUaxeCfWC/154vgqsuRjs7B8+PdrdfHO3u
bO8dHO7uv3h+uHt49Hx///Bo/2h/+/nB872D3aOjo8Ojg4Pd3f2dvYPnh9t7
+7v7u7u7B0fbhzvbhy8Odna39/f3Do9GnXqKzydUOnFhKzfcIbk537APINi9
BfTSRXCJ8BtUWfA+qlQVXFV4Dd5eF5JRBFsygQVs9ex059u3v1Dl1kuxt7ey
jqK7CKwJ4poKM06Bh/9cY0ZVE9GsTm/IIdzbC5piC1s1nt7iGQVsYr56P/66
cR+r9vfgftwFr9Re2iv53odMTGVvcKMWXKvhapq9PIYtFT8ID8PdcC/cx63c
3//b92efTs4/nJ29PXv38eWr9xfhznZ4uL37ovU0ycHhSbH37ZvJbus0SuoY
SyfxnpYzLrxjWjkV5RqHDgiA+WsMEGiTkm6Sm9bgZkYVB3RDr06YjW1pL8eR
fFsCdNvYKhUzekUlH6muFlZN2HkUlC5x6tHrlPmwNtgydxyP2gcmEbAkeszx
kui8TvwwVt3bXSt+H0DC2P9cqmoE+njytsv3lYxgdSWptU4+C7GLWFV6g8U0
7UqfOFNMRWcT8L4sE80wihgEfsI2IF/4nuED3OudLyO+2YCXZrAwDOMR8OUL
m6C7WPU6BFa8oBCU/B4O3kbFSg/43yxLVVkF7gy6fROF6llK5Q8Rq5RyMqJv
X2agOyUTmBS/tTcw8dULPBSJYI0DLiCmsmvL6tKuf1pL6F+pRnrTLA380ovv
8E2hK3pTyMxlCzUwh6j4IGXhbsq0a7294fsNZbF4JIPxccFZrJIBXZja3Gye
wyEKcXk8oJY7yMfg1NyCdC9boMtJ12Lx5tUjr1mYOwZeyYh/H8YID3wLeEOX
h8va3TTgkjDDCRArFJ+xf05s+YG+sqLHxJowsuCTUlIZew2Yt/xzi+G424/e
wkjx+LSsOYnmq1ajRsg9ccZHOpZe6BirBd6OuvOKxWONMESXlUB0Cv9+reeA
VBRKMVXaxDDyCh4KZmnTzKM7vwfiJf1Q/Oguc4Vv+qiKKupkKpNFSUVdc46y
3a2GcQY+vBMAUpPlN1OQQwhdpFbo0pU8Lq5GVvTwSk4SjF86aedLyA3KtorH
YRFcjWjYBgtQBT/pMZPlzNHbps51Y20MZ9arCt7b+xNdzYIIxdw2xnskDbo3
GybBXfVKjNUxZLavWYWayiL2TbC7jgYrL9yobJsSKxRGtsBpDamihcTWL4Qy
twajZhCP8OifuYMJe8vEOQJlU49VYpEz3u+oq9ICRBnBODyN98iOrRDUtzL6
jciqU3ONUaJA4usIoK6RzgDxGlmlxAtf2zPai9cIQgr9n456ImErlhknBJSI
p2BY9uF4YJdIXO6IKvTroD0alssMzME/auBsPV9vZXDFq98Ral1Ea1HXIbSv
Lp1BiELez41QepynG7CE23aWlaD+MDdbhi3D4t3uWhoBH9INfSNZoMSkOsiG
mzWPETWW4U+lw/4VKLgMfkaO12CgswxYuVjyOxFW4H4xPJMxekmyIEphPW6d
jpGKfG/V08w8u6PnRa6MlvEtr8qni1kmXXbh95oqdB5zQ1M7dY4ys2L+IT0E
krs6CgJbSVaIDO5lqx9owALi5UX3hzrFd7jkWCcrfgQFYAHBH3h5xAazsg1A
DoivK2DYHRaxEuBycnwDow8Z3ZQsJ1dO0rqS4mxHo0xqDky5VVZwLD1yt4Dy
Ibaw5/AkYHQGo492CTYysKaj2z227ycm9v1EHAIwYM53upYLc0rvVvbKS1hX
ptaFBY+G0t7rKiAY7ngZr3FnyS0hENgiu2nzwFVhHemrWYYa4W5td8Tt7T+v
Pop37z9yIQ89O1fn5rJCS8YaWGiUFKvVbXRppI2fZ+E4aGXvq9fv//nmFeMr
34ugQzd6zcOW/aIfRLn30t5KJtl9e3kKeB3A+oPXGLeCmBeZhPCsXHEdt/0q
47dv0N88KmgeuXywd/N8IfU8BXB7SjfzPB5mILqEMUYoMpJOwoEFTHTFE6nd
ZiBfebyVVCBK6Jsnki+Mz/W0kJZyy1T2iYkXm134DyLx9uQTjJrlGPvMFuNC
N/sRcV08Mrq1TCBtLFsn7161nltgd4VeRSDsdGOrlM+Up/TYYeJNwi/e4Lm/
fSbNTWPVmYoG2IFsFDo0KSVv9gJvSyKlnaxBALi5ia7l5qZVJ5RQqjJAZQ7X
7wDVDtVi2bZaD8mEQ2OwPSbHXNoXKdwtS4dgeGkeb63jEz66JRnmGgYIj30j
ki9jinOOMryYorlqYJ5aBDG6f+bOJ3QcTF0fLDIkoCIU5oy+Kd3UDOvO5S1R
GoHXOgLbCtCvf6lXz8XJdfu59MMp0lbDdVteor7mkmygxgsZ9BqeSSaUzg1s
EXPNtt2RVmvb9ts/dtur5lq17cZZaPnU/BziGEwcbuUksp4NJ6Tvj7niAAts
N+gW4IZ574AfrCSfMb0Rf6eHOcdZ8usQ36nM4UvxPcQpIG1v8R7EWyygLYbi
AuBB/ABGKIOlDcWn+g5g4me8zWw89VutzCMhOX5Az1jFuqHtSgZ8RNv9A1Vv
+kv2V4wtuL6z4fZc4pMZt1InZJGezvOP6N+hn2yOYxMM2W5VkuWNq/n5ESX6
0rfvh5r3kvHh0Kc8gL0F8Z/aQkDYyrNoy2xqEPb+C5vwaSmEXAAA

-->

</rfc>
