<?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-01" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.31.0 -->
  <front>
    <title>Interactive Sigma Proofs</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-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="October" day="20"/>
    <area>IRTF</area>
    <workgroup>Crypto Forum</workgroup>
    <keyword>zero-knowledge</keyword>
    <keyword>sigma protocols</keyword>
    <keyword>cryptography</keyword>
    <keyword>proofs of knowledge</keyword>
    <abstract>
      <?line 89?>

<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 <xref target="security"/>.</t>
      <t>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>
    <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 95?>

<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 a <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 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 return value response is a public value and is transmitted to the verifier.</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.</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>The simulated transcript <tt>(commitment, challenge, response)</tt> must be indistinguishable from the one generated using the prover algorithms.</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 <xref target="CS97"/> 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 needs 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>: returns the order of the group <tt>p</tt>.</t>
            </li>
            <li>
              <t><tt>random()</tt>: returns an element sampled uniformly at random from 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>, fails if the input is not the valid canonical byte representation of an array of elements 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>: returns an element sampled uniformly at random from the scalar field.</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 array of elements of the scalar field. 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="witness">
          <name>Witness representation</name>
          <t>A witness is an array of scalar elements. The length of the array is denoted <tt>num_scalars</tt>.</t>
          <artwork><![CDATA[
Witness = [Scalar; num_scalars]
]]></artwork>
        </section>
        <section anchor="linear-map">
          <name>Linear map</name>
          <t>A <em>linear map</em> takes a <tt>Witness</tt> (an array of <tt>num_scalars</tt> in the scalar field) and maps it to an array of group elements. The length of the image is denoted <tt>num_elements</tt>.</t>
          <t>Linear maps can be represented as matrix-vector multiplications, where the multiplication is the elliptic curve scalar multiplication defined in <xref target="group-abstraction"/>.</t>
          <t>Since the matrix is oftentimes sparse, it is stored 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; num_scalars]) -> list[Group; num_elements]
]]></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 vector of group elements via:</t>
            <artwork><![CDATA[
map(self, scalars: [Scalar; num_scalars]) -> list[Group; num_elements]

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>A <tt>LinearRelation</tt> encodes a proof statement of the form <tt>linear_map(witness) = image</tt>, and is used to prove knowledge of a witness that produces <tt>image</tt> under linear map.
It internally stores <tt>linear_map</tt> (cf. <xref target="linear-map"/>) and an <tt>image</tt> (an array of <tt>num_elements</tt> Group elements).</t>
          <artwork><![CDATA[
class LinearRelation:
    Domain = group.ScalarField
    Image = group.Group

    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="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="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>
        <t>We consider ciphersuites of prime-order elliptic curve groups.</t>
        <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">
      <name>Security Considerations</name>
      <t>Sigma Protocols 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>Sigma Protocols 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>
        <reference anchor="CS97" target="https://crypto.ethz.ch/publications/files/CamSta97b.pdf">
          <front>
            <title>Proof Systems for General Statements about Discrete Logarithms</title>
            <author fullname="Jan Camenisch">
              <organization/>
            </author>
            <author fullname="Markus Stadler">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
      </references>
    </references>
    <?line 517?>

<section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors thank Jan Bobolz, Vishruti Ganesh, 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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

-->

</rfc>
