<?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 3.4.4) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-sigma-protocols-00" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.30.0 -->
  <front>
    <title>Interactive Sigma Proofs</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-sigma-protocols-00"/>
    <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="August" day="09"/>
    <area>IRTF</area>
    <workgroup>Crypto Forum</workgroup>
    <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-irtf-cfrg-sigma-protocols/draft-irtf-cfrg-sigma-protocols.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-irtf-cfrg-sigma-protocols/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Crypto Forum Research Group mailing list (<eref target="mailto:cfrg@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/cfrg"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/cfrg/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/mmaker/draft-irtf-cfrg-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 <tt>false</tt> 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-irtf-cfrg-fiat-shamir.html">
          <front>
            <title>draft-irtf-cfrg-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:
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
NQh7/wV+x5TUn1wAAA==

-->

</rfc>
