<?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.39 (Ruby 3.4.9) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-fiat-shamir-03" category="info" consensus="true" submissionType="IRTF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.0 -->
  <front>
    <title>Fiat-Shamir Transformation</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-fiat-shamir-03"/>
    <author fullname="Michele Orrù">
      <organization>CNRS</organization>
      <address>
        <email>m@orru.net</email>
      </address>
    </author>
    <date year="2026" month="August" day="17"/>
    <area>IRTF</area>
    <workgroup>Crypto Forum</workgroup>
    <keyword>zero knowledge</keyword>
    <keyword>hash</keyword>
    <abstract>
      <?line 147?>

<t>This document describes the Fiat-Shamir transformation, which allows making a public-coin protocol non-interactive by means of a cryptographic hash function.</t>
      <t>It specifies how the hash function is employed, how prover messages are encoded as hash-function input, and how verifier messages are decoded from the hash function's output, as well as the serialization and deserialization of the non-interactive argument string.</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-fiat-shamir.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-irtf-cfrg-fiat-shamir/"/>.
      </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 153?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The Fiat-Shamir transformation removes interaction from a <em>public-coin</em> interactive argument by relying on a cryptographic hash function. The non-interactive prover derives each verifier message on its own via a hash function, and serializes the protocol transcript into a <em>non-interactive argument</em> (NARG) string. The verifier recomputes the same verifier messages from the NARG string and checks the interactive verifier's decision. The resulting argument is secure in the random oracle model, where the hash function is treated as an ideal random function (see <xref target="sec-transformation"/>).</t>
      <t>Many non-interactive arguments apply the Fiat-Shamir transformation to a public-coin interactive proof, yet each protocol re-specifies it from scratch, duplicating the security analysis and reopening the same bugs. It is notoriously easy to get the Fiat-Shamir transformation wrong, introducing critical security bugs <xref target="BPW16"/>, <xref target="DMWG23"/>, <xref target="FROZENHEART"/>, <xref target="SOLANA-ZK"/>.</t>
      <t>This document specifies the duplex sponge Fiat-Shamir transformation, and in particular:</t>
      <ul spacing="normal">
        <li>
          <t>a non-interactive argument prover (NARG prover), and</t>
        </li>
        <li>
          <t>a non-interactive argument verifier (NARG verifier)</t>
        </li>
      </ul>
      <t>The prover is a randomized procedure and generally relies on a cryptographically-secure entropy source; the verifier <strong>SHOULD</strong> be deterministic.</t>
      <t>Both the non-interactive prover and verifier rely on:</t>
      <ul spacing="normal">
        <li>
          <t>a duplex sponge, prescribing how to interact with the cryptographic hash function (<xref target="hash-instantiations"/>);</t>
        </li>
        <li>
          <t>a set of codecs, describing how each prover and verifier message talk to the duplex sponge (<xref target="codecs"/>);</t>
        </li>
        <li>
          <t>a serialization and deserialization procedure for the NARG string produced by the prover (<xref target="narg-string"/>).</t>
        </li>
      </ul>
      <t>This transformation is also well-suited for recursive proving, since the in-circuit cost of recomputing the Fiat-Shamir challenges is low. It is compatible with arithmetization-friendly hash functions (e.g. Poseidon2 <xref target="POSEIDON2"/>) that operate natively on field elements. See <xref target="CO25"/> for the general construction.</t>
      <t>Other types of non-interactive transformations (with and without random oracles) are possible, but outside the scope of this specification.</t>
      <figure anchor="fig-fiat-shamir-prover">
        <name>Non-interactive prover for the Fiat-Shamir transformation</name>
        <artset>
          <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="848" width="568" viewBox="0 0 568 848" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
              <path d="M 8,32 L 8,832" fill="none" stroke="black"/>
              <path d="M 24,192 L 24,784" fill="none" stroke="black"/>
              <path d="M 184,192 L 184,784" fill="none" stroke="black"/>
              <path d="M 328,160 L 328,192" fill="none" stroke="black"/>
              <path d="M 328,256 L 328,288" fill="none" stroke="black"/>
              <path d="M 328,336 L 328,368" fill="none" stroke="black"/>
              <path d="M 328,416 L 328,448" fill="none" stroke="black"/>
              <path d="M 328,496 L 328,528" fill="none" stroke="black"/>
              <path d="M 328,624 L 328,656" fill="none" stroke="black"/>
              <path d="M 328,704 L 328,736" fill="none" stroke="black"/>
              <path d="M 432,160 L 432,192" fill="none" stroke="black"/>
              <path d="M 432,256 L 432,288" fill="none" stroke="black"/>
              <path d="M 432,336 L 432,368" fill="none" stroke="black"/>
              <path d="M 432,416 L 432,448" fill="none" stroke="black"/>
              <path d="M 432,496 L 432,528" fill="none" stroke="black"/>
              <path d="M 432,624 L 432,656" fill="none" stroke="black"/>
              <path d="M 432,704 L 432,736" fill="none" stroke="black"/>
              <path d="M 464,80 L 464,112" fill="none" stroke="black"/>
              <path d="M 464,160 L 464,192" fill="none" stroke="black"/>
              <path d="M 464,256 L 464,288" fill="none" stroke="black"/>
              <path d="M 464,336 L 464,368" fill="none" stroke="black"/>
              <path d="M 464,416 L 464,448" fill="none" stroke="black"/>
              <path d="M 464,496 L 464,528" fill="none" stroke="black"/>
              <path d="M 464,624 L 464,656" fill="none" stroke="black"/>
              <path d="M 464,704 L 464,736" fill="none" stroke="black"/>
              <path d="M 496,120 L 496,152" fill="none" stroke="black"/>
              <path d="M 496,200 L 496,248" fill="none" stroke="black"/>
              <path d="M 496,296 L 496,328" fill="none" stroke="black"/>
              <path d="M 496,376 L 496,408" fill="none" stroke="black"/>
              <path d="M 496,456 L 496,488" fill="none" stroke="black"/>
              <path d="M 496,576 L 496,616" fill="none" stroke="black"/>
              <path d="M 496,664 L 496,696" fill="none" stroke="black"/>
              <path d="M 520,80 L 520,112" fill="none" stroke="black"/>
              <path d="M 536,160 L 536,192" fill="none" stroke="black"/>
              <path d="M 536,256 L 536,288" fill="none" stroke="black"/>
              <path d="M 536,416 L 536,448" fill="none" stroke="black"/>
              <path d="M 536,624 L 536,656" fill="none" stroke="black"/>
              <path d="M 544,336 L 544,368" fill="none" stroke="black"/>
              <path d="M 544,496 L 544,528" fill="none" stroke="black"/>
              <path d="M 544,704 L 544,736" fill="none" stroke="black"/>
              <path d="M 560,32 L 560,832" fill="none" stroke="black"/>
              <path d="M 8,32 L 560,32" fill="none" stroke="black"/>
              <path d="M 464,80 L 520,80" fill="none" stroke="black"/>
              <path d="M 112,96 L 456,96" fill="none" stroke="black"/>
              <path d="M 464,112 L 520,112" fill="none" stroke="black"/>
              <path d="M 328,160 L 432,160" fill="none" stroke="black"/>
              <path d="M 464,160 L 536,160" fill="none" stroke="black"/>
              <path d="M 96,176 L 320,176" fill="none" stroke="black"/>
              <path d="M 440,176 L 456,176" fill="none" stroke="black"/>
              <path d="M 24,192 L 184,192" fill="none" stroke="black"/>
              <path d="M 328,192 L 432,192" fill="none" stroke="black"/>
              <path d="M 464,192 L 536,192" fill="none" stroke="black"/>
              <path d="M 328,256 L 432,256" fill="none" stroke="black"/>
              <path d="M 464,256 L 536,256" fill="none" stroke="black"/>
              <path d="M 184,272 L 320,272" fill="none" stroke="black"/>
              <path d="M 440,272 L 456,272" fill="none" stroke="black"/>
              <path d="M 328,288 L 432,288" fill="none" stroke="black"/>
              <path d="M 464,288 L 536,288" fill="none" stroke="black"/>
              <path d="M 328,336 L 432,336" fill="none" stroke="black"/>
              <path d="M 464,336 L 544,336" fill="none" stroke="black"/>
              <path d="M 192,352 L 320,352" fill="none" stroke="black"/>
              <path d="M 440,352 L 456,352" fill="none" stroke="black"/>
              <path d="M 328,368 L 432,368" fill="none" stroke="black"/>
              <path d="M 464,368 L 544,368" fill="none" stroke="black"/>
              <path d="M 328,416 L 432,416" fill="none" stroke="black"/>
              <path d="M 464,416 L 536,416" fill="none" stroke="black"/>
              <path d="M 184,432 L 320,432" fill="none" stroke="black"/>
              <path d="M 440,432 L 456,432" fill="none" stroke="black"/>
              <path d="M 328,448 L 432,448" fill="none" stroke="black"/>
              <path d="M 464,448 L 536,448" fill="none" stroke="black"/>
              <path d="M 328,496 L 432,496" fill="none" stroke="black"/>
              <path d="M 464,496 L 544,496" fill="none" stroke="black"/>
              <path d="M 192,512 L 320,512" fill="none" stroke="black"/>
              <path d="M 440,512 L 456,512" fill="none" stroke="black"/>
              <path d="M 328,528 L 432,528" fill="none" stroke="black"/>
              <path d="M 464,528 L 544,528" fill="none" stroke="black"/>
              <path d="M 328,624 L 432,624" fill="none" stroke="black"/>
              <path d="M 464,624 L 536,624" fill="none" stroke="black"/>
              <path d="M 184,640 L 320,640" fill="none" stroke="black"/>
              <path d="M 440,640 L 456,640" fill="none" stroke="black"/>
              <path d="M 328,656 L 432,656" fill="none" stroke="black"/>
              <path d="M 464,656 L 536,656" fill="none" stroke="black"/>
              <path d="M 328,704 L 432,704" fill="none" stroke="black"/>
              <path d="M 464,704 L 544,704" fill="none" stroke="black"/>
              <path d="M 192,720 L 320,720" fill="none" stroke="black"/>
              <path d="M 440,720 L 456,720" fill="none" stroke="black"/>
              <path d="M 328,736 L 432,736" fill="none" stroke="black"/>
              <path d="M 464,736 L 544,736" fill="none" stroke="black"/>
              <path d="M 184,768 L 320,768" fill="none" stroke="black"/>
              <path d="M 24,784 L 184,784" fill="none" stroke="black"/>
              <path d="M 8,832 L 560,832" fill="none" stroke="black"/>
              <polygon class="arrowhead" points="504,696 492,690.4 492,701.6" fill="black" transform="rotate(90,496,696)"/>
              <polygon class="arrowhead" points="504,616 492,610.4 492,621.6" fill="black" transform="rotate(90,496,616)"/>
              <polygon class="arrowhead" points="504,488 492,482.4 492,493.6" fill="black" transform="rotate(90,496,488)"/>
              <polygon class="arrowhead" points="504,408 492,402.4 492,413.6" fill="black" transform="rotate(90,496,408)"/>
              <polygon class="arrowhead" points="504,328 492,322.4 492,333.6" fill="black" transform="rotate(90,496,328)"/>
              <polygon class="arrowhead" points="504,248 492,242.4 492,253.6" fill="black" transform="rotate(90,496,248)"/>
              <polygon class="arrowhead" points="504,152 492,146.4 492,157.6" fill="black" transform="rotate(90,496,152)"/>
              <polygon class="arrowhead" points="464,640 452,634.4 452,645.6" fill="black" transform="rotate(0,456,640)"/>
              <polygon class="arrowhead" points="464,432 452,426.4 452,437.6" fill="black" transform="rotate(0,456,432)"/>
              <polygon class="arrowhead" points="464,272 452,266.4 452,277.6" fill="black" transform="rotate(0,456,272)"/>
              <polygon class="arrowhead" points="464,176 452,170.4 452,181.6" fill="black" transform="rotate(0,456,176)"/>
              <polygon class="arrowhead" points="464,96 452,90.4 452,101.6" fill="black" transform="rotate(0,456,96)"/>
              <polygon class="arrowhead" points="448,720 436,714.4 436,725.6" fill="black" transform="rotate(180,440,720)"/>
              <polygon class="arrowhead" points="448,512 436,506.4 436,517.6" fill="black" transform="rotate(180,440,512)"/>
              <polygon class="arrowhead" points="448,352 436,346.4 436,357.6" fill="black" transform="rotate(180,440,352)"/>
              <polygon class="arrowhead" points="328,768 316,762.4 316,773.6" fill="black" transform="rotate(0,320,768)"/>
              <polygon class="arrowhead" points="328,640 316,634.4 316,645.6" fill="black" transform="rotate(0,320,640)"/>
              <polygon class="arrowhead" points="328,432 316,426.4 316,437.6" fill="black" transform="rotate(0,320,432)"/>
              <polygon class="arrowhead" points="328,272 316,266.4 316,277.6" fill="black" transform="rotate(0,320,272)"/>
              <polygon class="arrowhead" points="328,176 316,170.4 316,181.6" fill="black" transform="rotate(0,320,176)"/>
              <polygon class="arrowhead" points="200,720 188,714.4 188,725.6" fill="black" transform="rotate(180,192,720)"/>
              <polygon class="arrowhead" points="200,512 188,506.4 188,517.6" fill="black" transform="rotate(180,192,512)"/>
              <polygon class="arrowhead" points="200,352 188,346.4 188,357.6" fill="black" transform="rotate(180,192,352)"/>
              <g class="text">
                <text x="36" y="52">NARG</text>
                <text x="84" y="52">Prover</text>
                <text x="164" y="52">(session_id,</text>
                <text x="256" y="52">instance,</text>
                <text x="332" y="52">witness)</text>
                <text x="60" y="100">session_id</text>
                <text x="492" y="100">Init</text>
                <text x="52" y="180">instance</text>
                <text x="376" y="180">encode[0]</text>
                <text x="500" y="180">Absorb</text>
                <text x="80" y="212">Interactive</text>
                <text x="156" y="212">Prover</text>
                <text x="68" y="228">(instance,</text>
                <text x="148" y="228">witness)</text>
                <text x="248" y="244">prover_msg[1]</text>
                <text x="376" y="276">encode[1]</text>
                <text x="500" y="276">Absorb</text>
                <text x="256" y="324">verifier_msg[1]</text>
                <text x="376" y="356">decode[1]</text>
                <text x="504" y="356">Squeeze</text>
                <text x="248" y="404">prover_msg[2]</text>
                <text x="376" y="436">encode[2]</text>
                <text x="500" y="436">Absorb</text>
                <text x="256" y="484">verifier_msg[2]</text>
                <text x="376" y="516">decode[2]</text>
                <text x="504" y="516">Squeeze</text>
                <text x="256" y="548">.</text>
                <text x="496" y="548">.</text>
                <text x="256" y="564">.</text>
                <text x="496" y="564">.</text>
                <text x="256" y="580">.</text>
                <text x="256" y="612">prover_msg[k-1]</text>
                <text x="384" y="644">encode[k-1]</text>
                <text x="500" y="644">Absorb</text>
                <text x="264" y="692">verifier_msg[k-1]</text>
                <text x="384" y="724">decode[k-1]</text>
                <text x="504" y="724">Squeeze</text>
                <text x="248" y="756">prover_msg[k]</text>
                <text x="88" y="820">narg_string</text>
                <text x="148" y="820">:=</text>
                <text x="264" y="820">serialize(prover_msg[..])</text>
              </g>
            </svg>
          </artwork>
          <artwork type="ascii-art"><![CDATA[
+--------------------------------------------------------------------+
| NARG Prover (session_id, instance, witness)                        |
|                                                                    |
|                                                        +------+    |
| session_id ------------------------------------------->| Init |    |
|                                                        +------+    |
|                                                            |       |
|                                                            v       |
|                                       +------------+   +--------+  |
| instance ---------------------------->| encode[0]  |-->| Absorb |  |
| +-------------------+                 +------------+   +--------+  |
| | Interactive Prover|                                      |       |
| |(instance, witness)|                                      |       |
| |                   | prover_msg[1]                        v       |
| |                   |                 +------------+   +--------+  |
| |                   +---------------->| encode[1]  |-->| Absorb |  |
| |                   |                 +------------+   +--------+  |
| |                   |                                      |       |
| |                   | verifier_msg[1]                      v       |
| |                   |                 +------------+   +---------+ |
| |                   |<----------------| decode[1]  |<--| Squeeze | |
| |                   |                 +------------+   +---------+ |
| |                   |                                      |       |
| |                   | prover_msg[2]                        v       |
| |                   |                 +------------+   +--------+  |
| |                   +---------------->| encode[2]  |-->| Absorb |  |
| |                   |                 +------------+   +--------+  |
| |                   |                                      |       |
| |                   | verifier_msg[2]                      v       |
| |                   |                 +------------+   +---------+ |
| |                   |<----------------| decode[2]  |<--| Squeeze | |
| |                   |                 +------------+   +---------+ |
| |                   |        .                             .       |
| |                   |        .                             .       |
| |                   |        .                             .       |
| |                   |                                      |       |
| |                   | prover_msg[k-1]                      v       |
| |                   |                 +------------+   +--------+  |
| |                   +---------------->| encode[k-1]|-->| Absorb |  |
| |                   |                 +------------+   +--------+  |
| |                   |                                      |       |
| |                   | verifier_msg[k-1]                    v       |
| |                   |                 +------------+   +---------+ |
| |                   |<----------------| decode[k-1]|<--| Squeeze | |
| |                   |                 +------------+   +---------+ |
| |                   | prover_msg[k]                                |
| |                   +---------------->                             |
| +-------------------+                                              |
|                                                                    |
|    narg_string := serialize(prover_msg[..])                        |
+--------------------------------------------------------------------+
]]></artwork>
        </artset>
      </figure>
      <figure anchor="fig-fiat-shamir-verifier">
        <name>Non-interactive verifier for the Fiat-Shamir transformation</name>
        <artset>
          <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="896" width="560" viewBox="0 0 560 896" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
              <path d="M 8,32 L 8,880" fill="none" stroke="black"/>
              <path d="M 24,800 L 24,864" fill="none" stroke="black"/>
              <path d="M 128,208 L 128,240" fill="none" stroke="black"/>
              <path d="M 128,288 L 128,320" fill="none" stroke="black"/>
              <path d="M 128,448 L 128,480" fill="none" stroke="black"/>
              <path d="M 136,624 L 136,656" fill="none" stroke="black"/>
              <path d="M 152,368 L 152,400" fill="none" stroke="black"/>
              <path d="M 152,528 L 152,560" fill="none" stroke="black"/>
              <path d="M 168,704 L 168,736" fill="none" stroke="black"/>
              <path d="M 224,208 L 224,240" fill="none" stroke="black"/>
              <path d="M 224,288 L 224,320" fill="none" stroke="black"/>
              <path d="M 224,448 L 224,480" fill="none" stroke="black"/>
              <path d="M 232,624 L 232,656" fill="none" stroke="black"/>
              <path d="M 248,368 L 248,400" fill="none" stroke="black"/>
              <path d="M 248,528 L 248,560" fill="none" stroke="black"/>
              <path d="M 264,704 L 264,736" fill="none" stroke="black"/>
              <path d="M 296,624 L 296,656" fill="none" stroke="black"/>
              <path d="M 296,704 L 296,736" fill="none" stroke="black"/>
              <path d="M 312,128 L 312,160" fill="none" stroke="black"/>
              <path d="M 312,208 L 312,240" fill="none" stroke="black"/>
              <path d="M 312,288 L 312,320" fill="none" stroke="black"/>
              <path d="M 312,368 L 312,400" fill="none" stroke="black"/>
              <path d="M 312,448 L 312,480" fill="none" stroke="black"/>
              <path d="M 312,528 L 312,560" fill="none" stroke="black"/>
              <path d="M 336,800 L 336,864" fill="none" stroke="black"/>
              <path d="M 344,168 L 344,200" fill="none" stroke="black"/>
              <path d="M 344,248 L 344,280" fill="none" stroke="black"/>
              <path d="M 344,328 L 344,360" fill="none" stroke="black"/>
              <path d="M 344,408 L 344,440" fill="none" stroke="black"/>
              <path d="M 344,488 L 344,520" fill="none" stroke="black"/>
              <path d="M 344,664 L 344,696" fill="none" stroke="black"/>
              <path d="M 368,128 L 368,160" fill="none" stroke="black"/>
              <path d="M 368,624 L 368,656" fill="none" stroke="black"/>
              <path d="M 376,704 L 376,736" fill="none" stroke="black"/>
              <path d="M 384,208 L 384,240" fill="none" stroke="black"/>
              <path d="M 384,288 L 384,320" fill="none" stroke="black"/>
              <path d="M 384,448 L 384,480" fill="none" stroke="black"/>
              <path d="M 392,368 L 392,400" fill="none" stroke="black"/>
              <path d="M 392,528 L 392,560" fill="none" stroke="black"/>
              <path d="M 552,32 L 552,880" fill="none" stroke="black"/>
              <path d="M 8,32 L 552,32" fill="none" stroke="black"/>
              <path d="M 312,128 L 368,128" fill="none" stroke="black"/>
              <path d="M 112,144 L 304,144" fill="none" stroke="black"/>
              <path d="M 312,160 L 368,160" fill="none" stroke="black"/>
              <path d="M 128,208 L 224,208" fill="none" stroke="black"/>
              <path d="M 312,208 L 384,208" fill="none" stroke="black"/>
              <path d="M 96,224 L 120,224" fill="none" stroke="black"/>
              <path d="M 232,224 L 304,224" fill="none" stroke="black"/>
              <path d="M 128,240 L 224,240" fill="none" stroke="black"/>
              <path d="M 312,240 L 384,240" fill="none" stroke="black"/>
              <path d="M 128,288 L 224,288" fill="none" stroke="black"/>
              <path d="M 312,288 L 384,288" fill="none" stroke="black"/>
              <path d="M 16,304 L 120,304" fill="none" stroke="black"/>
              <path d="M 232,304 L 304,304" fill="none" stroke="black"/>
              <path d="M 128,320 L 224,320" fill="none" stroke="black"/>
              <path d="M 312,320 L 384,320" fill="none" stroke="black"/>
              <path d="M 152,368 L 248,368" fill="none" stroke="black"/>
              <path d="M 312,368 L 392,368" fill="none" stroke="black"/>
              <path d="M 24,384 L 144,384" fill="none" stroke="black"/>
              <path d="M 256,384 L 304,384" fill="none" stroke="black"/>
              <path d="M 152,400 L 248,400" fill="none" stroke="black"/>
              <path d="M 312,400 L 392,400" fill="none" stroke="black"/>
              <path d="M 128,448 L 224,448" fill="none" stroke="black"/>
              <path d="M 312,448 L 384,448" fill="none" stroke="black"/>
              <path d="M 16,464 L 120,464" fill="none" stroke="black"/>
              <path d="M 232,464 L 304,464" fill="none" stroke="black"/>
              <path d="M 128,480 L 224,480" fill="none" stroke="black"/>
              <path d="M 312,480 L 384,480" fill="none" stroke="black"/>
              <path d="M 152,528 L 248,528" fill="none" stroke="black"/>
              <path d="M 312,528 L 392,528" fill="none" stroke="black"/>
              <path d="M 24,544 L 144,544" fill="none" stroke="black"/>
              <path d="M 256,544 L 304,544" fill="none" stroke="black"/>
              <path d="M 152,560 L 248,560" fill="none" stroke="black"/>
              <path d="M 312,560 L 392,560" fill="none" stroke="black"/>
              <path d="M 136,624 L 232,624" fill="none" stroke="black"/>
              <path d="M 296,624 L 368,624" fill="none" stroke="black"/>
              <path d="M 16,640 L 128,640" fill="none" stroke="black"/>
              <path d="M 240,640 L 288,640" fill="none" stroke="black"/>
              <path d="M 136,656 L 232,656" fill="none" stroke="black"/>
              <path d="M 296,656 L 368,656" fill="none" stroke="black"/>
              <path d="M 168,704 L 264,704" fill="none" stroke="black"/>
              <path d="M 296,704 L 376,704" fill="none" stroke="black"/>
              <path d="M 24,720 L 160,720" fill="none" stroke="black"/>
              <path d="M 272,720 L 288,720" fill="none" stroke="black"/>
              <path d="M 168,736 L 264,736" fill="none" stroke="black"/>
              <path d="M 296,736 L 376,736" fill="none" stroke="black"/>
              <path d="M 24,800 L 336,800" fill="none" stroke="black"/>
              <path d="M 24,864 L 336,864" fill="none" stroke="black"/>
              <path d="M 8,880 L 552,880" fill="none" stroke="black"/>
              <polygon class="arrowhead" points="352,696 340,690.4 340,701.6" fill="black" transform="rotate(90,344,696)"/>
              <polygon class="arrowhead" points="352,520 340,514.4 340,525.6" fill="black" transform="rotate(90,344,520)"/>
              <polygon class="arrowhead" points="352,440 340,434.4 340,445.6" fill="black" transform="rotate(90,344,440)"/>
              <polygon class="arrowhead" points="352,360 340,354.4 340,365.6" fill="black" transform="rotate(90,344,360)"/>
              <polygon class="arrowhead" points="352,280 340,274.4 340,285.6" fill="black" transform="rotate(90,344,280)"/>
              <polygon class="arrowhead" points="352,200 340,194.4 340,205.6" fill="black" transform="rotate(90,344,200)"/>
              <polygon class="arrowhead" points="312,464 300,458.4 300,469.6" fill="black" transform="rotate(0,304,464)"/>
              <polygon class="arrowhead" points="312,304 300,298.4 300,309.6" fill="black" transform="rotate(0,304,304)"/>
              <polygon class="arrowhead" points="312,224 300,218.4 300,229.6" fill="black" transform="rotate(0,304,224)"/>
              <polygon class="arrowhead" points="312,144 300,138.4 300,149.6" fill="black" transform="rotate(0,304,144)"/>
              <polygon class="arrowhead" points="296,640 284,634.4 284,645.6" fill="black" transform="rotate(0,288,640)"/>
              <polygon class="arrowhead" points="280,720 268,714.4 268,725.6" fill="black" transform="rotate(180,272,720)"/>
              <polygon class="arrowhead" points="264,544 252,538.4 252,549.6" fill="black" transform="rotate(180,256,544)"/>
              <polygon class="arrowhead" points="264,384 252,378.4 252,389.6" fill="black" transform="rotate(180,256,384)"/>
              <polygon class="arrowhead" points="136,640 124,634.4 124,645.6" fill="black" transform="rotate(0,128,640)"/>
              <polygon class="arrowhead" points="128,464 116,458.4 116,469.6" fill="black" transform="rotate(0,120,464)"/>
              <polygon class="arrowhead" points="128,304 116,298.4 116,309.6" fill="black" transform="rotate(0,120,304)"/>
              <polygon class="arrowhead" points="128,224 116,218.4 116,229.6" fill="black" transform="rotate(0,120,224)"/>
              <polygon class="arrowhead" points="32,720 20,714.4 20,725.6" fill="black" transform="rotate(180,24,720)"/>
              <polygon class="arrowhead" points="32,544 20,538.4 20,549.6" fill="black" transform="rotate(180,24,544)"/>
              <polygon class="arrowhead" points="32,384 20,378.4 20,389.6" fill="black" transform="rotate(180,24,384)"/>
              <g class="text">
                <text x="36" y="52">NARG</text>
                <text x="92" y="52">Verifier</text>
                <text x="184" y="52">V(session_id,</text>
                <text x="280" y="52">instance,</text>
                <text x="372" y="52">narg_string)</text>
                <text x="28" y="84">1.</text>
                <text x="100" y="84">prover_msg[..]</text>
                <text x="172" y="84">:=</text>
                <text x="284" y="84">deserialize(narg_string)</text>
                <text x="28" y="100">2.</text>
                <text x="68" y="100">derive</text>
                <text x="132" y="100">verifier</text>
                <text x="208" y="100">messages:</text>
                <text x="60" y="148">session_id</text>
                <text x="340" y="148">Init</text>
                <text x="52" y="228">instance</text>
                <text x="176" y="228">encode[0]</text>
                <text x="348" y="228">Absorb</text>
                <text x="64" y="292">prover_msg[1]</text>
                <text x="176" y="308">encode[1]</text>
                <text x="348" y="308">Absorb</text>
                <text x="80" y="372">verifier_msg[1]</text>
                <text x="200" y="388">decode[1]</text>
                <text x="352" y="388">Squeeze</text>
                <text x="64" y="452">prover_msg[2]</text>
                <text x="176" y="468">encode[2]</text>
                <text x="348" y="468">Absorb</text>
                <text x="80" y="532">verifier_msg[2]</text>
                <text x="200" y="548">decode[2]</text>
                <text x="352" y="548">Squeeze</text>
                <text x="72" y="580">.</text>
                <text x="344" y="580">.</text>
                <text x="72" y="596">.</text>
                <text x="344" y="596">.</text>
                <text x="72" y="612">.</text>
                <text x="344" y="612">.</text>
                <text x="64" y="628">prover_msg[k]</text>
                <text x="184" y="644">encode[k]</text>
                <text x="332" y="644">Absorb</text>
                <text x="80" y="708">verifier_msg[k]</text>
                <text x="216" y="724">decode[k]</text>
                <text x="336" y="724">Squeeze</text>
                <text x="28" y="772">3.</text>
                <text x="56" y="772">Run</text>
                <text x="88" y="772">the</text>
                <text x="152" y="772">interactive</text>
                <text x="236" y="772">verifier</text>
                <text x="80" y="820">Interactive</text>
                <text x="164" y="820">Verifier</text>
                <text x="84" y="836">(instance,</text>
                <text x="192" y="836">prover_msg[..],</text>
                <text x="120" y="852">verifier_msg[..])</text>
              </g>
            </svg>
          </artwork>
          <artwork type="ascii-art"><![CDATA[
+-------------------------------------------------------------------+
| NARG Verifier V(session_id, instance, narg_string)                |
|                                                                   |
| 1. prover_msg[..] := deserialize(narg_string)                     |
| 2. derive verifier messages:                                      |
|                                                                   |
|                                     +------+                      |
| session_id ------------------------>| Init |                      |
|                                     +------+                      |
|                                         |                         |
|                                         v                         |
|              +-----------+          +--------+                    |
| instance --->| encode[0] |--------->| Absorb |                    |
|              +-----------+          +--------+                    |
|                                         |                         |
|                                         v                         |
|prover_msg[1] +-----------+          +--------+                    |
|------------->| encode[1] |--------->| Absorb |                    |
|              +-----------+          +--------+                    |
|                                         |                         |
|                                         v                         |
| verifier_msg[1] +-----------+       +---------+                   |
| <---------------| decode[1] |<------| Squeeze |                   |
|                 +-----------+       +---------+                   |
|                                         |                         |
|                                         v                         |
|prover_msg[2] +-----------+          +--------+                    |
|------------->| encode[2] |--------->| Absorb |                    |
|              +-----------+          +--------+                    |
|                                         |                         |
|                                         v                         |
| verifier_msg[2] +-----------+       +---------+                   |
| <---------------| decode[2] |<------| Squeeze |                   |
|                 +-----------+       +---------+                   |
|       .                                 .                         |
|       .                                 .                         |
|       .                                 .                         |
|prover_msg[k]  +-----------+       +--------+                      |
|-------------->| encode[k] |------>| Absorb |                      |
|               +-----------+       +--------+                      |
|                                         |                         |
|                                         v                         |
| verifier_msg[k]   +-----------+   +---------+                     |
| <-----------------| decode[k] |<--| Squeeze |                     |
|                   +-----------+   +---------+                     |
|                                                                   |
| 3. Run the interactive verifier                                   |
|                                                                   |
| +--------------------------------------+                          |
| | Interactive Verifier                 |                          |
| |  (instance, prover_msg[..],          |                          |
| |   verifier_msg[..])                  |                          |
| +--------------------------------------+                          |
+-------------------------------------------------------------------+
]]></artwork>
        </artset>
      </figure>
      <t>Note that the prover does not need to compute the last verifier message <tt>verifier_msg[k]</tt>. The security guarantees provided by this transformation are described in <xref target="security-considerations"/>.</t>
    </section>
    <section anchor="terminology-and-conventions-in-this-document">
      <name>Terminology and conventions in this document</name>
      <t>The key words "<strong>MUST</strong>", "<strong>MUST NOT</strong>", "<strong>REQUIRED</strong>", "<strong>SHALL</strong>", "<strong>SHALL NOT</strong>", "<strong>SHOULD</strong>", "<strong>SHOULD NOT</strong>", "<strong>RECOMMENDED</strong>", "<strong>NOT RECOMMENDED</strong>", "<strong>MAY</strong>", and "<strong>OPTIONAL</strong>" in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t>
      <t>The algorithms and procedures in this document are specified using Python-like pseudocode. Each function accepts defined inputs and parameters and returns one or more output values. Once a protocol variant and ciphersuite are selected, all associated parameters are treated as constants.</t>
      <t>The following notation is used throughout this document.</t>
      <section anchor="bytes-and-integers">
        <name>Bytes and integers</name>
        <t>A byte is an 8-bit unsigned integer (an octet), and a <strong>byte string</strong> is a finite sequence of bytes. An <tt>N</tt>-byte string is a byte string of length <tt>N</tt>. The empty byte string is written <tt>""</tt>; <tt>x || y</tt> is the concatenation of the byte strings <tt>x</tt> and <tt>y</tt>. <tt>len(x)</tt> denotes the length in bytes of the byte string <tt>x</tt>. <tt>zeros(N)</tt> denotes the <tt>N</tt>-byte string of zero bytes.</t>
        <t>Byte strings are indexed from zero. For integers <tt>0 &lt;= i &lt;= j &lt;= len(x)</tt>, <tt>x[i : j]</tt> denotes the <tt>(j - i)</tt>-byte substring of <tt>x</tt> consisting of the bytes at positions <tt>i, i+1, ..., j-1</tt>. In particular, <tt>x[0 : N]</tt> is the first <tt>N</tt> bytes of <tt>x</tt>, <tt>x[i : i]</tt> is the empty byte string <tt>""</tt>, and <tt>x[0 : len(x)]</tt> is <tt>x</tt> itself.</t>
        <t>A byte string <tt>x</tt> is a <strong>prefix</strong> of a byte string <tt>y</tt> if <tt>y == x || z</tt> for some byte string <tt>z</tt> (even empty). An encoding is <strong>prefix-free</strong> if, for any two distinct values, the encoding of one is never a prefix of the encoding of the other. A simple prefix-free encoding of a byte string <tt>b</tt> is <tt>LE(len(b), 4) || b</tt> as described in <xref target="serialize-byte-strings"/>.</t>
        <t><tt>LE(n, w)</tt> and <tt>LE2IP(x)</tt> are the integer/byte-string conversion primitives used throughout this document, in little-endian byte order. <tt>LE(n, w)</tt> converts a non-negative integer <tt>n</tt> less than <tt>256^w</tt> into a <tt>w</tt>-byte, little-endian byte string, and fails if <tt>n &gt;= 256^w</tt>. <tt>LE2IP(x)</tt> converts a byte string <tt>x</tt> into a non-negative integer using the little-endian byte order.</t>
        <artwork><![CDATA[
LE(n, w)

Inputs:

- n, a non-negative integer with 0 <= n < 256^w
- w, the output length in bytes

Output: out, a w-byte string

1. fail if n < 0 or n >= 256^w
2. out = zeros(w)
3. for i in 0, ..., w-1:
4.    out[i] := n mod 256
5.    n := floor(n / 256)
6. return out
]]></artwork>
        <artwork><![CDATA[
LE2IP(x)

Input: x, a byte string of length w

Output: n, a non-negative integer with 0 <= n < 256^w

1. n = 0
2. for i in 0, ..., len(x)-1:
3.    n = n + x[i] * 256^i
4. return n
]]></artwork>
        <t>The set of integers between <tt>0</tt> and <tt>N-1</tt> is denoted <tt>[0, N)</tt>.</t>
      </section>
      <section anchor="duplex-sponge-interface">
        <name>Duplex sponge interface</name>
        <t>The Fiat-Shamir transformation relies on a cryptographic hash function, modeled as a random oracle. This is implemented as a stateful interface called a <strong>duplex sponge</strong> (defined in <xref target="hash-instantiations"/>), which <tt>Absorb</tt>s prover messages into an evolving internal state and <tt>Squeeze</tt>s from that state the bytes from which verifier messages are derived.</t>
        <t>The interface generalizes the <strong>sponge</strong> <xref target="SPONGE"/>, which maps a variable-length input to a variable-length output by absorbing all of its input and then squeezing all of its output, to the <strong>duplex</strong> setting <xref target="DUPLEX"/>, in which absorbing and squeezing may be arbitrarily interleaved while retaining the same state. The state is split into a <strong>rate</strong>, the portion through which bytes are absorbed and squeezed, and a <strong>capacity</strong>, which is never read or written directly. Security relies on the size of the capacity. The properties a concrete instantiation must satisfy for this to hold, and the resulting security loss, are given in <xref target="security-considerations"/> and analyzed in <xref target="CO25"/>.</t>
      </section>
      <section anchor="proof-systems-terminology">
        <name>Proof systems terminology</name>
        <t>The <strong>session identifier</strong> is a 32-byte string that identifies the application context and the specific non-interactive argument in use; it is held by both the prover and the verifier (see <xref target="session-id"/>).</t>
        <t>A <strong>prover message</strong> is a message sent by the interactive prover, and a <strong>verifier message</strong> is a message sent by the interactive verifier (a uniformly random value, sometimes called <em>challenge</em>). A message can be a value of any type for which a codec (<xref target="codecs"/>) is defined, such as a byte string, an unsigned integer, or a group element. The <strong>transcript</strong> is the ordered sequence of prover and verifier messages. In particular, the transcript does <em>not</em> include the instance and session identifier.</t>
        <t>The <strong>instance</strong> specifies the statement being proven and is held by both the prover and the verifier. The (encoded) instance <strong>MUST</strong> be non-empty.</t>
        <t>The <strong>witness</strong> is the prover's private input. It is known only to the prover and is never revealed. It appears neither in the transcript nor in the NARG string.</t>
        <t>For an NP language, the instance is a word, the witness is a proof of its membership in the language, and the resulting non-interactive argument proves that the instance is indeed in the language. This claim is also referred to as the <strong>statement</strong>. Proof systems might support different statements or express the same language in different ways.</t>
        <t>The <strong>NARG string</strong> (non-interactive argument string) is the serialized output of the non-interactive prover.</t>
        <t>The notation in this document is for an interactive argument with <tt>k</tt> rounds in which the prover moves first (that is, sends the first message) and the verifier moves last. Other types of interactions can be expressed in the same notation by setting the unused messages to the empty string: a protocol whose verifier moves first (such as a batch argument) sets its first prover message to <tt>""</tt>, and one whose prover moves last (such as a sigma protocol) sets its final verifier message to <tt>""</tt>. Prover and verifier round messages <tt>2</tt>, ..., <tt>k-1</tt> <strong>MUST</strong> be non-empty.</t>
      </section>
      <section anchor="codec-and-serialization">
        <name>Codec and serialization</name>
        <t>A prover message is processed in two independent ways: it is absorbed into the hash function to derive the verifier messages, and it is written into the NARG string sent to the verifier. This document keeps the two separate.</t>
        <t>A <strong>codec</strong> (<xref target="codecs"/>) is the pair of maps between messages and the hash function's alphabet (bytes, in this document):</t>
        <ul spacing="normal">
          <li>
            <t><strong>Encoding</strong> converts the instance and each prover message into the bytes absorbed by the duplex sponge (<xref target="encoding-bytes"/>).</t>
          </li>
          <li>
            <t><strong>Decoding</strong> converts the bytes squeezed from the duplex sponge into a uniformly-distributed verifier message (<xref target="decoding"/>).</t>
          </li>
        </ul>
        <t><strong>Serialization</strong> (<xref target="narg-string"/>) is concerned with mapping prover messages to and from the NARG string:</t>
        <ul spacing="normal">
          <li>
            <t><strong>Serialization</strong> writes the prover messages into the NARG string produced by the non-interactive prover.</t>
          </li>
          <li>
            <t><strong>Deserialization</strong> reads the prover messages back from the NARG string, and returns an error if the message is invalid.</t>
          </li>
        </ul>
        <t>For a prover message, the encoded bytes coincide with the serialized bytes: the encoding maps are the serialization functions of <xref target="serialization"/>. However, codecs and serialization serve different purposes. Codecs must maintain the soundness of the transformation, whereas deserialization keeps the NARG string unambiguous and rejects malformed proofs (see <xref target="decoding"/> and <xref target="deserialization"/>).</t>
      </section>
    </section>
    <section anchor="hash-instantiations">
      <name>Duplex sponge</name>
      <t>This section defines the duplex sponge instantiations used in this document.</t>
      <section anchor="interface">
        <name>Interface</name>
        <t>Prover and verifier messages are handled via three operations:</t>
        <ul spacing="normal">
          <li>
            <t><tt>Init(session_id) -&gt; state</tt>: create a new duplex sponge state, seeded by the 32-byte string <tt>session_id</tt>.</t>
          </li>
          <li>
            <t><tt>state.Absorb(x)</tt>: absorb <tt>x</tt> into the state.</t>
          </li>
          <li>
            <t><tt>state.Squeeze(n) -&gt; buf</tt>: produce <tt>n</tt> elements from the state.</t>
          </li>
        </ul>
        <t>In the duplex sponge interface, messages can be absorbed incrementally, and insert no separators: <tt>state.Absorb(x)</tt> followed by <tt>state.Absorb(y)</tt> (with no <tt>state.Squeeze</tt> in between) is equivalent to <tt>state.Absorb(x || y)</tt>.</t>
        <t>Each <tt>state.Squeeze(n)</tt> is uniformly distributed, and consecutive <tt>state.Squeeze</tt> calls continue one output stream.</t>
        <t>Guidance on how to produce a 32-byte <tt>session_id</tt>, and its security requirements, is given in <xref target="session-id"/>; its role in composability and reuse is discussed in <xref target="sec-session-identifiers"/>.</t>
      </section>
      <section anchor="xof-duplex-sponge">
        <name>XOF duplex sponge</name>
        <t>This section implements the duplex sponge interface using an eXtendable-Output Function (XOF). An XOF is a hash function mapping a byte string to an output string of any desired length. It has the following operations:</t>
        <ul spacing="normal">
          <li>
            <t><tt>XOF.New() -&gt; xof_state</tt>, a fresh XOF state;</t>
          </li>
          <li>
            <t><tt>xof_state.Update(x)</tt>, absorbing the byte string <tt>x</tt> into the state;</t>
          </li>
          <li>
            <t><tt>xof_state.Copy() -&gt; xof_state</tt>, a copy of the XOF state;</t>
          </li>
          <li>
            <t><tt>xof_state.Finalize() -&gt; reader</tt>, finalizing the XOF state and returning a reader over the output stream;</t>
          </li>
          <li>
            <t><tt>reader.Read(n) -&gt; buf</tt>, the next <tt>n</tt> bytes of the output stream.</t>
          </li>
        </ul>
        <t><tt>R</tt> (the rate) is the block size at which the XOF processes absorbed input. It <strong>MUST</strong> be <tt>R &gt;= 32</tt>. <tt>XOF(M, len)</tt> denotes the XOF evaluation of the byte string <tt>M</tt>, producing <tt>len</tt> bytes of output. The concrete XOF is fixed by the suite (<xref target="suites"/>). Consecutive <tt>Read</tt> calls continue the output stream.</t>
        <t>Every verifier message is the XOF evaluation over the session identifier, the encoded instance, and the encoded prover messages up to and including the current round. That is, the <tt>i</tt>-th verifier message (for <tt>1 &lt;= i &lt;= k</tt>) of byte length <tt>len_i</tt> is computed as:</t>
        <artwork><![CDATA[
verifier_msg[i] := decode[i](XOF(
                       session_id || zeros(R - 32)
                       || encode[0](instance)
                       || encode[1](prover_msg[1])
                       || ...
                       || encode[i](prover_msg[i]),
                   len_i))
]]></artwork>
        <t>The session identifier is padded with <tt>R - 32</tt> zero bytes so that the instance and prover messages begin on a fresh rate-block boundary (see <xref target="xof-init"/>), for efficiency (<xref target="efficiency"/>).</t>
        <t>The security properties required of the XOF, and the security level attained, are fixed by the suite (<xref target="suites"/>); the corresponding requirements on the construction are discussed in <xref target="sec-transformation"/>.</t>
        <section anchor="xof-init">
          <name>Init</name>
          <t>Seed the state by absorbing the session identifier, padded with zeros to fill the rate (the remaining <tt>R - 32</tt> bytes).</t>
          <artwork><![CDATA[
Init(session_id)

Input: session_id, a byte array

Output: a duplex sponge state

1. assert len(session_id) == 32
2. ctx = XOF.New()
3. ctx.Update(session_id || zeros(R - 32))
4. return state := (ctx, reader = None)
]]></artwork>
        </section>
        <section anchor="xof-absorb">
          <name>Absorb</name>
          <t>Feed a byte string <tt>x</tt> into the state. Absorbing the empty string leaves the state unchanged.</t>
          <artwork><![CDATA[
state.Absorb(x)

Input: x, a byte string

1. state.ctx.Update(x)
2. if len(x) != 0:
3.    state.reader = None
]]></artwork>
        </section>
        <section anchor="xof-squeeze">
          <name>Squeeze</name>
          <t>Returns the next <tt>n</tt> bytes of the XOF output stream computed over the absorbed input. If the duplex sponge is in the absorbing phase, it finalizes a copy of the absorbing context as an XOF reader. Consecutive <tt>Squeeze</tt> calls <strong>continue</strong> the same output stream.</t>
          <artwork><![CDATA[
state.Squeeze(n)

Input: n, the number of bytes to be squeezed

Output: a uniformly-distributed random n-byte string

1. if state.reader == None:
2.    state.reader = state.ctx.Copy().Finalize()
3. return state.reader.Read(n)
]]></artwork>
        </section>
      </section>
    </section>
    <section anchor="codecs">
      <name>Codecs</name>
      <t>A codec is a set of functions that map prover messages to, and verifier messages from, the hash function's alphabet.</t>
      <ul spacing="normal">
        <li>
          <t>Encoding maps convert the instance and the prover messages into the bytes absorbed by the duplex sponge. The only security requirement on encoding functions is that they be prefix-free.</t>
        </li>
        <li>
          <t>Decoding maps turn squeezed elements into verifier messages. Decoding <strong>MUST</strong> preserve the uniform distribution in the verifier message space (up to a small codec error). Decoding is infallible.</t>
        </li>
      </ul>
      <section anchor="encoding-bytes">
        <name>Encoding into byte strings</name>
        <t>The encoding of the instance and of each prover message is its serialization, as described in <xref target="serialization"/>.</t>
      </section>
      <section anchor="decoding">
        <name>Decoding from byte strings</name>
        <t>Decoding converts a uniformly-distributed <tt>Squeeze</tt> output into a verifier message. Each verifier message type fixes the number of bytes to squeeze.</t>
        <t>Decoding is not deserialization, and need not invert encoding nor even be injective; its only requirement is to be <em>distribution-preserving</em>: if its input is a uniformly random byte string, then its output is (statistically close to) uniformly distributed over the verifier message type.</t>
        <section anchor="byte-arrays">
          <name>Byte arrays</name>
          <t>The decoding function for fixed-length byte arrays is the identity.</t>
          <artwork><![CDATA[
DecodeBytes(buf, N)

Inputs:

- buf, a byte string
- N, the expected byte length

Output: out, a byte string of length N

1. assert len(buf) == N
2. return buf
]]></artwork>
        </section>
        <section anchor="decoding-uint">
          <name>Unsigned integers</name>
          <t>To sample a uniformly random element modulo <tt>M</tt>, let <tt>Ns</tt> be the smallest integer with <tt>256^Ns &gt;= M</tt>: squeeze <tt>Ns + 16</tt> bytes, interpret them as a little-endian non-negative integer via <tt>LE2IP</tt>, and reduce modulo <tt>M</tt>.</t>
          <artwork><![CDATA[
DecodeUint(buf, M)

Inputs:

- buf, a byte string of length Ns + 16
- M, the modulus

Output: out, an integer in the range [0, M)

1. assert len(buf) == Ns + 16
2. return LE2IP(buf) mod M
]]></artwork>
          <t>Decoding always interprets bytes in little-endian order via <tt>LE2IP</tt>.</t>
          <t>The 16 extra bytes bound the statistical distance between the reduced value and the uniform distribution over <tt>[0, M)</tt> to <tt>2^-128</tt>. More generally, sampling <tt>n</tt> extra bytes bounds the bias to <tt>2^-8n</tt>. An instantiation targeting a security level of <tt>lambda</tt> bits <strong>SHOULD</strong> squeeze <tt>lambda/8</tt> extra bytes.</t>
          <t>In three cases this approach is inefficient:</t>
          <ul spacing="normal">
            <li>
              <t>if <tt>M</tt> is a power of two, since the decoding bias is always 0;</t>
            </li>
            <li>
              <t>if <tt>M</tt> is only slightly below a power of <tt>256</tt> (for example, the secp256k1 scalar field order) where squeezing just <tt>Ns</tt> bytes and reducing with a single conditional subtraction already has bias of approximately <tt>2^-128</tt>;</t>
            </li>
            <li>
              <t>if the soundness error of the interactive argument is much smaller than the bias introduced, for example a protocol with 30-bit challenges does not require such a big modular reduction.</t>
            </li>
          </ul>
          <t>In such cases, applications <strong>MAY</strong> use an alternative decoding function, provided it meets the following security requirements:</t>
          <ul spacing="normal">
            <li>
              <t>The function <strong>MUST</strong> have bias at most the soundness error of the interactive argument. The bias adds to the soundness error of the resulting non-interactive argument, and this requirement asks that the resulting non-interactive soundness error stays within a small multiple of the interactive soundness error.</t>
            </li>
            <li>
              <t>The function <strong>SHOULD</strong> be amenable to straight-line implementations. In particular, rejection sampling <strong>SHOULD NOT</strong> be used (see <xref target="constant-time"/>).</t>
            </li>
          </ul>
          <t>A similar observation in the context of hashing to the elliptic curve field is available in <xref section="5" sectionFormat="of" target="RFC9380"/>.</t>
        </section>
        <section anchor="decoding-field">
          <name>Field elements</name>
          <t>A field element of a field of order <tt>p^m</tt> is decoded coordinate by coordinate, via <tt>DecodeUint</tt> (<xref target="decoding-uint"/>), starting from the least-significant. With <tt>Ns</tt> as in <xref target="serialize-field"/>, this consumes <tt>m * (Ns + 16)</tt> bytes. A prime field is the case <tt>m = 1</tt>.</t>
          <artwork><![CDATA[
DecodeField(buf, p, m)

Inputs:

- buf, a byte string of length m * (Ns + 16)
- p, the prime characteristic of the field
- m, the extension degree

Output: out, an element of the field of order p^m, given by its
        coordinates (a[0], ..., a[m-1]) over the prime field

1. assert len(buf) == m * (Ns + 16)
2. for i in 0, ..., m-1:
3.    chunk = buf[i * (Ns + 16) : (i + 1) * (Ns + 16)]
4.    a[i] = DecodeUint(chunk, p)
5. return (a[0], ..., a[m-1])
]]></artwork>
          <t>For <tt>m = 1</tt>, <tt>DecodeField</tt> is <tt>DecodeUint</tt>, and the same efficiency remarks apply. Applications <strong>MAY</strong> substitute a more efficient alternative, subject to the same security requirements described in <xref target="decoding-uint"/>.</t>
          <t>For <tt>m &gt; 1</tt>, decoding relies on <tt>16 * m</tt> additional randomness bytes. Applications with big-integer arithmetic available <strong>MAY</strong> use a more randomness-efficient decoding algorithm, by instead sampling <tt>Nm + 16</tt> bytes, where <tt>Nm</tt> is the smallest integer with <tt>256^Nm &gt;= p^m</tt>, interpreting them as an integer via <tt>LE2IP</tt>, reducing modulo <tt>p^m</tt>, and recovering the coordinates <tt>(a[0], ..., a[m-1])</tt> as the base-<tt>p</tt> digits of the result (least-significant digit first). This consumes <tt>Nm + 16</tt> bytes, with the same <tt>2^-128</tt> bias bound.</t>
        </section>
      </section>
    </section>
    <section anchor="initialization">
      <name>Initialization</name>
      <t>Before any prover message is processed, both parties start the duplex sponge with the session identifier (<xref target="session-id"/>), and then the instance (<xref target="instance"/>).</t>
      <t>Neither the session identifier nor the instance is part of the NARG string: the verifier holds both as its own inputs.</t>
      <section anchor="session-id">
        <name>Session identifiers</name>
        <t>The session identifier is a 32-byte string that identifies the context in which the non-interactive argument is used. The procedure <tt>DeriveSessionID</tt> below is the <strong>RECOMMENDED</strong> way to obtain a session identifier from a human-meaningful variable-length <tt>tag</tt>. An application <strong>MAY</strong> use any 32-byte string it derives by its own means.</t>
        <t>For a duplex sponge operating over bytes, the session identifier is derived from a <tt>tag</tt> via the procedure <tt>DeriveSessionID</tt>. The <tt>tag</tt> is a byte string whose encoding as a sequence of bytes <strong>MUST</strong> be specified unambiguously, so that every implementation reproduces identical bytes. It is <strong>RECOMMENDED</strong> the <tt>tag</tt> be a US-ASCII string, without byte-order mark at the beginning, nor <tt>0x00</tt> byte termination.</t>
        <t>When the <tt>tag</tt> is composed of several fields, those fields <strong>MUST</strong> be combined unambiguously, so that no two distinct tuples of field values yield the same byte string. For example, concatenating <tt>("SV1", "22")</tt> and <tt>("SV12", "2")</tt> both yield <tt>SV122</tt> and so would share the same session identifier. Using fixed-width fields or an unambiguous delimiter is sufficient.</t>
        <t>The tag has the following security requirements:</t>
        <ol spacing="normal" type="1"><li>
            <t>the tag <strong>MUST</strong> uniquely identify the <strong>non-interactive argument</strong> used, including the interactive argument system, the types of prover and verifier messages, the hash suite, and the language associated with the interactive argument.</t>
          </li>
          <li>
            <t>the tag <strong>MUST</strong> uniquely identify the <strong>codecs</strong> used: the order and types of encodings and decodings at each round. For example, implementations that sample verifier messages differently must have different session identifiers.</t>
          </li>
          <li>
            <t>the tag <strong>MUST</strong> identify the application context in which the non-interactive argument is used, so that a NARG string produced for one application cannot be accepted in another. A namespace string under the application's control is sufficient, such as the URL <tt>https://example.com/login/v2</tt>. Freshness information, such as an epoch number or timestamp, <strong>MAY</strong> additionally be included when the application requires proofs not to be replayed within its own context (see <xref target="sec-session-identifiers"/>).</t>
          </li>
          <li>
            <t>the tag <strong>SHOULD</strong> begin with a fixed identification string that is unique to the application.</t>
          </li>
          <li>
            <t>the tag <strong>SHOULD</strong> include a version number.</t>
          </li>
        </ol>
        <t>An application that bypasses <tt>DeriveSessionID</tt>, and sets the 32-byte <tt>session_id</tt> directly <strong>MUST</strong> ensure it satisfies the same requirements.</t>
        <artwork><![CDATA[
DeriveSessionID(tag)

Input: tag, an application-chosen byte string (see above)

Output: session_id, a 32-byte string

1. duplex_sponge := DS.Init("irtf-cfrg-fiat-shamir/session-id")
2. duplex_sponge.Absorb(tag)
3. return duplex_sponge.Squeeze(32)
]]></artwork>
        <t>Above, <tt>DS</tt> denotes the duplex sponge in use (<xref target="hash-instantiations"/>), instantiated with one of the suites of <xref target="suites"/>. The 32-byte string <tt>"irtf-cfrg-fiat-shamir/session-id"</tt> is a domain separator for this derivation.</t>
        <t>As an example, consider a fictional application named Foo that implements sigma protocols over elliptic curves for encrypted messages shared during a time epoch <tt>tttt</tt>. A reasonable choice of tag is:</t>
        <artwork><![CDATA[
FOO-SV{xx}-{tttt}-DSFS-{hashID}-SIGMA-PROOFS-{yy}
]]></artwork>
        <t>where <tt>xx</tt> is the two-digit number indicating the version, <tt>yy</tt> is the two-digit number indicating the elliptic-curve ciphersuite, <tt>hashID</tt> is the hash identifier, and <tt>tttt</tt> is the epoch number written in decimal US-ASCII digits.</t>
        <t>As another example, consider a fictional application named Bar that implements an ad-hoc zero-knowledge virtual machine for correct execution of circuits. A reasonable choice of tag is</t>
        <artwork><![CDATA[
BAR-COM{cc}
]]></artwork>
        <t>where <tt>{cc}</tt> is the commit hash of the associated version of the cryptographic specification of the protocol.</t>
        <t>Yet another reasonable choice for the session identifier is to append a description of the interactive argument system together with the length of each prover and verifier message, after the version string. For instance:</t>
        <artwork><![CDATA[
BAZ-SV{xx}-DSFS-{hashID}-sumcheck-{ff}-A2round-messageS1challenge
]]></artwork>
        <t>where <tt>xx</tt> is the two-digit version number, <tt>hashID</tt> is the hash identifier, and <tt>ff</tt> is the two-digit identifier of the finite field over which the proof is computed. The suffix <tt>A2round-messageS1challenge</tt> describes one sumcheck round where the prover absorbs (<tt>A</tt>) two field elements <tt>round-message</tt>, and the verifier squeezes (<tt>S</tt>) one field element <tt>challenge</tt>. This is similar to the SAFE API <xref target="SAFE"/> <em>IO pattern</em>.</t>
      </section>
      <section anchor="instance">
        <name>Instance</name>
        <t>The instance is input to the non-interactive prover and the non-interactive verifier; it fixes the specific statement being proven.</t>
        <t>The instance is the first value absorbed after <tt>Init(session_id)</tt> and before any prover message. The prover and verifier <strong>MUST</strong> absorb <tt>encode[0](instance)</tt>, where <tt>encode[0]</tt> is the first encoding map.
The encoded instance <strong>MUST</strong> be non-empty. While the session identifier of the previous section <xref target="session-id"/> fixes the language, the instance selects one of its members.</t>
        <t>As for every encoding map, <tt>encode[0]</tt> <strong>MUST</strong> be prefix-free, else a malicious prover may be able to satisfy the verification equations on a statement it cannot prove (see <xref target="instance-encoding"/>). The encoding map <tt>encode[0]</tt> <strong>SHOULD</strong> reuse the serialization functions of <xref target="serialization"/>.</t>
        <t>As an example, consider the sumcheck relation for multilinear polynomials in <tt>N</tt> variables over the field of size <tt>p^m</tt>. For a polynomial committed using the polynomial commitment scheme <tt>COM</tt>, the relation consists of:</t>
        <ul spacing="normal">
          <li>
            <t>instance <tt>(S, C)</tt>: <tt>C</tt> the commitment, and <tt>S</tt> the target sum;</t>
          </li>
          <li>
            <t>witness <tt>(F, r)</tt>: <tt>F</tt> is the multilinear polynomial in <tt>N</tt> variables, and <tt>r</tt> is the commitment opening information.</t>
          </li>
        </ul>
        <t>such that:</t>
        <artwork><![CDATA[
COM.Open(C, F, r)  = 1,
sum(F(b1, ..., bN) for (b1, ..., bN) in {0, 1}^N) = S
]]></artwork>
        <t>A valid instance encoding function is:</t>
        <artwork><![CDATA[
SerializeField(S, p, m) || SerializeUint(N, 2^32) || COM.Serialize(C)
]]></artwork>
        <t>where <tt>COM.Serialize</tt> is the commitment-serialization function of the scheme <tt>COM</tt> (the opening check <tt>COM.Open</tt> is used above).</t>
        <t>As another example, consider, in the discrete logarithm setting, the Chaum-Pedersen relation over an additive elliptic curve group with generators <tt>G</tt>, <tt>H</tt> (for which the relative discrete logarithm is not known). The relation consists of:</t>
        <ul spacing="normal">
          <li>
            <t>the instance <tt>(C, D)</tt>, a pair of Pedersen commitments;</t>
          </li>
          <li>
            <t>the witness <tt>(x, r, s)</tt>, scalar field elements with <tt>x</tt> the commitment message and <tt>r</tt>, <tt>s</tt> independent random commitment openings</t>
          </li>
        </ul>
        <t>such that</t>
        <artwork><![CDATA[
C = xG + rH, D = xG + sH.
]]></artwork>
        <t>A valid instance encoding function is:</t>
        <artwork><![CDATA[
enc(G) || enc(H) || enc(C) || enc(D)
]]></artwork>
        <t>where <tt>enc</tt> is the group element-serialization function described in <xref target="serialize-ec-point"/>.</t>
        <t>Omitting public statement data from the transformation, such as <tt>N</tt> in the first example or the group generators <tt>G</tt>, <tt>H</tt> in the second, can compromise soundness of the proof system. See <xref target="instance-encoding"/>.</t>
      </section>
    </section>
    <section anchor="narg-string">
      <name>Non-interactive argument string</name>
      <section anchor="serialization">
        <name>Serialization</name>
        <t>The NARG string is the concatenation of the serialization of each prover message, as defined below. The same bytes are absorbed into the duplex sponge to derive the verifier messages (<xref target="encoding-bytes"/>).</t>
        <section anchor="serialize-byte-strings">
          <name>Byte strings</name>
          <t>Serialization of an <tt>N</tt>-byte string is the identity function.</t>
          <artwork><![CDATA[
SerializeBytes(s)

Input: s, an N-byte string

Output: out, an N-byte string

1. return s
]]></artwork>
          <t><tt>SerializeBytes</tt> carries no length information of its own: it is the identity. It can therefore be used only when <tt>N</tt> is fixed and known by the message's type and the instance, that is: prover and verifier both agree on <tt>N</tt> before the NARG string is parsed (see <xref target="deserialize-byte-strings"/>). On such a fixed-length domain the identity is prefix-free, as required of encodings by <xref target="encoding-bytes"/>.</t>
          <t>When the length is not fixed in advance, <tt>SerializeBytes</tt> <strong>MUST NOT</strong> be used. Instead, when the length is below 2^32 bytes, a prefix-free serialization is given by</t>
          <artwork><![CDATA[
SerializeVarLenString(s)

Input: s, an N-byte string

Output: out, an (N+4)-byte string

1. return LE(len(s), 4) || s
]]></artwork>
        </section>
        <section anchor="sequences-and-tuples">
          <name>Sequences and tuples</name>
          <t>A fixed-length array or a tuple is serialized as the concatenation of the serializations of its elements, with no separators.</t>
        </section>
        <section anchor="serialize-uint">
          <name>Unsigned integers</name>
          <t>An integer modulo <tt>M</tt> is represented by its unique integer representative in the range <tt>[0, M)</tt> and serialized via <tt>LE</tt>.</t>
          <artwork><![CDATA[
SerializeUint(x, M)

Inputs:

- x, an integer modulo M
- M, the order of the integer ring

Output: out, an Ns-byte string

1. assert 0 <= x < M
2. return LE(x, Ns)
]]></artwork>
          <t>where <tt>Ns</tt> is the smallest integer with <tt>256^Ns &gt;= M</tt>.</t>
        </section>
        <section anchor="serialize-field">
          <name>Field elements</name>
          <t>This section specifies the <em>default</em> serialization of a finite field of order <tt>q = p^m</tt>, where <tt>p</tt> is the prime characteristic and <tt>m &gt;= 1</tt> is the extension degree.</t>
          <t>The choice of field serialization <strong>MUST</strong> be reflected in the session tag (see <xref target="session-id"/>). The field serialization function <strong>MUST</strong> be prefix-free, and the matching deserialization <strong>MUST</strong> reject invalid encodings (for instance, reject elements larger than or equal to <tt>p</tt>). The default is the serialization specified below, which encodes each prime-field coordinate as a fixed-width little-endian integer via <tt>SerializeUint</tt> (<xref target="serialize-uint"/>); if the standard the application builds on already fixes a canonical serialization for the field, that serialization <strong>SHOULD</strong> be pinned in place of the default.</t>
          <t>For example, Curve25519 <xref target="RFC7748"/>, Ed25519 <xref target="RFC8032"/>, ristretto255 <xref section="4.4" sectionFormat="of" target="RFC9496"/> serialize field elements as a fixed-width little-endian integer, matching the default. Similarly, in Section 7.1 of <xref target="FIPS204"/>, the integer coordinates of lattice vectors are serialized least-significant-byte first. Other standards instead fix a big-endian serialization, such as P-256 <xref target="SEC1"/> and BLS12-381 <xref target="I-D.irtf-cfrg-pairing-friendly-curves"/> via <tt>I2OSP</tt>.</t>
          <t>With respect to a fixed basis, a field element is represented by its <tt>m</tt> coordinates in the prime field, each an integer in <tt>[0, p)</tt>. It is serialized as the concatenation of the per-coordinate serializations produced by <tt>SerializeUint</tt> (<xref target="serialize-uint"/>) with modulus <tt>p</tt>. Let <tt>Ns</tt> be the smallest integer with <tt>256^Ns &gt;= p</tt>; a field element serializes to <tt>m * Ns</tt> bytes.</t>
          <artwork><![CDATA[
SerializeField(a, p, m)

Inputs:

- a, an element of the field of order p^m, given by its
     coordinates (a[0], ..., a[m-1]) over the prime field
- p, the prime characteristic of the field
- m, the extension degree

Output: out, an (m * Ns)-byte string

1. out := ""
2. for i in 0, ..., m-1:
3.    out := out || SerializeUint(a[i], p)
4. return out
]]></artwork>
          <t>Note that a prime field is the case <tt>m = 1</tt>, in which case <tt>SerializeField</tt> is equivalent to <tt>SerializeUint</tt>.</t>
        </section>
        <section anchor="serialize-ec-point">
          <name>Elliptic curve group elements</name>
          <t>A group element is serialized using the group's element-serialization function.</t>
          <t>For many prime-order elliptic-curve groups, this is the compressed Elliptic-Curve-Point-to-Octet-String conversion of <xref target="SEC1"/>. All non-trivial group elements have exactly one <tt>Ne</tt>-byte representation. The value of <tt>Ne</tt> and the concrete conversion are fixed by the ciphersuite.</t>
          <t>The <xref target="SEC1"/> serialization of the identity element (the single byte <tt>0x00</tt>) <strong>SHOULD</strong> be rejected to facilitate deserialization (<xref target="deserialization"/>).
The ristretto255 and decaf448 <xref target="RFC9496"/> identity encodings have a distinct, fixed-length <tt>Ne</tt>-byte encoding.</t>
        </section>
      </section>
      <section anchor="deserialization">
        <name>Deserialization</name>
        <t>Deserialization of the NARG string consists of reading the prover messages: each message is read by consuming, from the front of the input, a byte string whose length is determined by its type and the instance. Each deserialization function below returns the decoded value together with the unread remainder of its input; the remainder is the input to the next read.</t>
        <t>Verification <strong>MUST</strong> fail if any of the prover messages cannot be deserialized successfully. After the last expected prover message has been read, the verifier <strong>MUST</strong> verify that no bytes remain. Bytes that are never read will cause the proof to be malleable: an adversary will be able to maul a valid proof to obtain a second, distinct accepting proof for the same statement.</t>
        <section anchor="deserialize-byte-strings">
          <name>Byte strings</name>
          <t>For an <tt>N</tt>-byte string whose length is known from the message's type and the instance, deserialization reads <tt>N</tt> bytes.</t>
          <artwork><![CDATA[
DeserializeBytes(input, N)

Inputs:

- input, the unread remainder of the NARG string
- N, the expected byte length

Output: an N-byte string, and the unread remainder of input

1. fail if len(input) < N
2. return (input[0 : N], input[N : len(input)])
]]></artwork>
          <t><tt>DeserializeBytes</tt> is the inverse of <tt>SerializeBytes</tt> (<xref target="serialize-byte-strings"/>), and consumes <tt>N</tt> bytes of the NARG string, and fails if fewer bytes remain.</t>
          <t>A byte string whose length is not known in advance is deserialized by reading a 4-byte length <tt>N</tt> via <tt>LE2IP</tt>, then reading the next <tt>N</tt> bytes; this is the inverse of <tt>SerializeVarLenString</tt> (<xref target="serialize-byte-strings"/>).</t>
          <artwork><![CDATA[
DeserializeVarLenString(input)

Input: input, the unread remainder of the NARG string

Output: an N-byte string, and the unread remainder of input

1. fail if len(input) < 4
2. N := LE2IP(input[0 : 4])
3. fail if len(input) - 4 < N
4. return (input[4 : 4 + N], input[4 + N : len(input)])
]]></artwork>
          <t>This consumes <tt>4 + N</tt> bytes of the NARG string, and fails if fewer bytes remain. The value decoded is the resulting byte string.</t>
        </section>
        <section anchor="sequences-and-tuples-1">
          <name>Sequences and tuples</name>
          <t>Deserialize each element in order. Fail if any element fails to deserialize. The number and types of the elements are fixed by the protocol.</t>
        </section>
        <section anchor="unsigned-integers">
          <name>Unsigned integers</name>
          <t>Read the next <tt>Ns</tt> bytes, with <tt>Ns</tt> as in <xref target="serialize-uint"/>, and interpret them as a little-endian integer <tt>x = LE2IP(.)</tt>. If <tt>x &gt;= M</tt>, fail: non-canonical integer encodings <strong>MUST</strong> be rejected. The value returned is <tt>x</tt>. This is the inverse of <tt>SerializeUint</tt> (<xref target="serialize-uint"/>).</t>
          <artwork><![CDATA[
DeserializeUint(input, M)

Inputs:

- input, the unread remainder of the NARG string
- M, the modulus

Output: x, an integer in the range [0, M), and the unread
        remainder of input

1. fail if len(input) < Ns
2. x := LE2IP(input[0 : Ns])
3. fail if x >= M
4. return (x, input[Ns : len(input)])
]]></artwork>
          <t>This consumes <tt>Ns</tt> bytes of the NARG string. It fails if fewer bytes remain, or if the integer read is not in the range <tt>[0, M)</tt>.</t>
        </section>
        <section anchor="field-elements">
          <name>Field elements</name>
          <t>A field element of a field of order <tt>p^m</tt> is deserialized coordinate by coordinate: read <tt>m * Ns</tt> bytes, with <tt>Ns</tt> as in <xref target="serialize-field"/>, and deserialize each <tt>Ns</tt>-byte coordinate as an integer modulo <tt>p</tt> using the unsigned-integer deserialization above. A prime field is the case <tt>m = 1</tt>. This is the inverse of <tt>SerializeField</tt> (<xref target="serialize-field"/>).</t>
          <artwork><![CDATA[
DeserializeField(input, p, m)

Inputs:

- input, the unread remainder of the NARG string
- p, the prime characteristic of the field
- m, the extension degree

Output: a, an element of the field of order p^m, given by its
        coordinates (a[0], ..., a[m-1]) over the prime field, and
        the unread remainder of input

1. for i in 0, ..., m-1:
2.    (a[i], input) := DeserializeUint(input, p)
3. return ((a[0], ..., a[m-1]), input)
]]></artwork>
          <t>This consumes <tt>m * Ns</tt> bytes of the NARG string, and fails if fewer bytes remain or if any coordinate is non-canonical.</t>
          <t>The deserialization <strong>MUST</strong> match the pinned serialization (<xref target="serialize-field"/>): where the profile pins a standard's own serialization, that standard's deserialization governs.</t>
        </section>
        <section anchor="elliptic-curve-group-elements">
          <name>Elliptic-curve group elements</name>
          <t>Read the next <tt>Ne</tt> bytes and convert them to a group element using the group's element-deserialization function. Deserialization <strong>MUST</strong> perform the ciphersuite's input-validation steps, <strong>SHOULD</strong> reject the identity element (<xref target="serialize-ec-point"/>), and fail unless the input is the canonical encoding of a valid group element.</t>
          <t>Note that for elliptic curves defined in <xref target="SEC1"/>, decoding is the Octet-String-to-Elliptic-Curve-Point conversion, which checks that the encoding is well-formed and that the point lies on the curve, and returns "invalid" otherwise. The single-byte <tt>0x00</tt> encoding of the identity is not a valid <tt>Ne</tt>-byte input and <strong>SHOULD</strong> be rejected.</t>
        </section>
      </section>
    </section>
    <section anchor="efficiency">
      <name>Efficiency considerations</name>
      <t>For both codecs and serialization, batch algorithms should be preferred when available, because they amortize per-element cost over a whole sequence. For example, the dominant cost in point compression is a modular inversion, and serializing a batch of compressed elliptic-curve points requires only one modular inversion for the entire batch (via Montgomery's trick) rather than one per point. (Note that deserialization does not batch in the same way, since point decompression requires a per-element square root.)</t>
      <t><tt>Init(session_id)</tt> (see <xref target="session-id"/>) can be precomputed. Implementations can therefore start each prover and verifier execution from a copy of the duplex sponge state, instead of initializing it every time. In the XOF duplex sponge (<xref target="xof-duplex-sponge"/>), the padded session identifier fills exactly one rate block (<xref target="xof-init"/>), saving one invocation of the permutation function per execution. Similarly, <tt>DeriveSessionID</tt> can be precomputed when the session identifier is derived from a tag. The same observation extends to longer shared prefixes: proofs for the same instance can additionally start from a stored copy of the state obtained after absorbing <tt>encode[0](instance)</tt>.</t>
      <t>XOF evaluations (<xref target="xof-duplex-sponge"/>) without copying the XOF state (see the notation <tt>ctx.Copy()</tt> in the pseudocode) will yield identical bytes, but incur a cost quadratic in the number of rounds. Implementations <strong>SHOULD</strong> instead maintain the incremental duplex sponge state of <xref target="interface"/>.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security considerations</name>
      <t>This section contains additional security considerations about the Fiat-Shamir transformation.</t>
      <section anchor="codecs-1">
        <name>Codecs</name>
        <t>Encoding maps are inverted only in the security analysis (by the knowledge extractor), never by the prover or verifier. The proof relies on a left inverse existing and being efficiently computable, which the knowledge-soundness extractor uses to recover prover messages from the absorbed bytes <xref target="CO25"/>.</t>
        <t>Decoding preserves the uniform distribution only when its input is uniform. Verifier messages <strong>SHOULD</strong> therefore be derived from <tt>Squeeze</tt> output and never from prover-controlled, or non-uniform bytes: decoding a non-uniform input yields a verifier message that is distinguishable from uniform, which would break the public-coin property the transformation depends on.</t>
      </section>
      <section anchor="constant-time">
        <name>Constant-time requirements</name>
        <t>While the protocol operates on "public coins", the instance can contain private information, such as verification keys not meant to be shared, or messages meant to be private between prover and verifier. Therefore, constant-time implementation of all the functions in this document is <strong>RECOMMENDED</strong>, to avoid leaking information via side channels.</t>
        <t>For example, in the case of keyed-verification anonymous credentials, the non-interactive argument verifier will compute an instance that depends on the issuer's secret key and therefore the instance is not meant to be public.</t>
      </section>
      <section anchor="sec-session-identifiers">
        <name>Session identifiers</name>
        <t>The purpose of session identifiers is to ensure composability and mitigate protocol confusion.</t>
        <t>A session identifier uniquely identifies one session of a protocol, so that messages and state belonging to concurrent applications or proof systems are not confused. It <strong>MAY</strong> be reused, and reuse is expected whenever several proofs share the same application context: the identifier names that context, and identical contexts are meant to share one. Applications requiring proofs to be unique, non-replayable, or fresh can achieve this by adding, for example, a counter or timestamp to the session identifier.</t>
      </section>
      <section anchor="sec-transformation">
        <name>Security of the transformation</name>
        <t>The Fiat-Shamir transformation carries over the soundness and zero-knowledge properties of the interactive proof. The random oracle instantiation <strong>MUST</strong> be extraction-friendly and simulation-friendly indifferentiable to preserve soundness and zero-knowledge of the transformation. Both properties are stronger than indifferentiability alone <xref target="CO25"/>.</t>
        <t>Completeness of the non-interactive argument is preserved: if the statement being proven is true, then the resulting non-interactive argument string is valid.</t>
        <section anchor="knowledge-soundness">
          <name>Knowledge soundness</name>
          <t>If the interactive proof is state-restoration knowledge sound, then so is the non-interactive proof. In particular, valid proofs cannot be generated without the corresponding statement being true (in the random oracle model).</t>
          <t>Knowledge soundness carries over to the non-interactive argument, with a loss error quadratic in the number of queries the adversary makes to the random oracle <xref target="CO25"/>.</t>
        </section>
        <section anchor="zero-knowledge">
          <name>Zero-Knowledge</name>
          <t>If the interactive proof is honest-verifier zero-knowledge, then so is the non-interactive proof. In particular, the resulting argument string does not reveal any information beyond what can be directly inferred from the statement being valid.</t>
          <t>The additive zero-knowledge loss introduced by the transformation is linear in the number of queries the adversary makes to the random oracle <xref target="CO25"/>.</t>
          <t>Zero-knowledge holds only when the prover's random number generator is indistinguishable from fresh uniform randomness to any party that does not know the witness, as noted in <xref target="introduction"/>. Reusing the same randomness (or correlated randomness) across two distinct proofs will compromise zero-knowledge: for example, two Schnorr proofs sharing the same commitment nonce reveal the witness. This can be obtained by relying on a cryptographically secure random number generator meeting the requirements of <xref target="RFC4086"/> (for example, the operating system's <tt>getrandom(2)</tt> interface), or by deriving them with a pseudorandom function.</t>
        </section>
        <section anchor="quantum-adversaries">
          <name>Quantum adversaries</name>
          <t>If the interactive proof is state-restoration sound against quantum adversaries, then the non-interactive proof after the Fiat-Shamir transformation in the random oracle model is also secure against quantum adversaries.</t>
          <t>The loss introduced by a quantum adversary is polynomial (larger than quadratic) in the number of quantum random-oracle queries.</t>
        </section>
      </section>
      <section anchor="instance-encoding">
        <name>Instance encoding</name>
        <t>Incorrect encoding of the instance has historically led to a number of critical security vulnerabilities, often grouped under the term <em>weak Fiat-Shamir transformation</em>. In each of them, the cryptographic hash function was not provided the full statement being proven. A malicious prover can then compute the verifier message first, and choose the omitted part of the instance afterwards so that the verification equation is satisfied on a statement whose witness it does not hold.</t>
        <t>As an example <xref target="BPW16"/>, Chaum-Pedersen proof of equality for an instance <tt>(G, H, X, Y)</tt> proves knowledge of a witness <tt>x</tt> such that <tt>X = x * G</tt> and <tt>Y = x * H</tt>. The prover sends commitments <tt>(A, B)</tt>, obtains a challenge <tt>c</tt>, and replies with a scalar <tt>f</tt>. The verifier accepts if the verification equations hold: <tt>f * G == A + c * X</tt> and <tt>f * H == B + c * Y</tt>. Suppose the challenge <tt>c</tt> is derived only by absorbing <tt>(A, B)</tt> and omitting the instance <tt>(G, H, X, Y)</tt>. A malicious prover can pick <tt>A</tt>, <tt>B</tt>, <tt>H</tt>, and <tt>f</tt> at random, derive <tt>c</tt>, and then set <tt>X</tt> and <tt>Y</tt> to satisfy the verification equations. Verification passes, yet no single <tt>x</tt> satisfies both <tt>X = x * G</tt> and <tt>Y = x * H</tt>. A false statement has been proven. Other examples are available in <xref target="DMWG23"/> <xref target="CVE-2022-29566"/>.</t>
        <t>The transformation does not itself validate the instance. The verifier <strong>MUST</strong> therefore validate the syntax of the instance before use, exactly as it validates prover messages during deserialization (<xref target="deserialization"/>): for example, checking that each claimed group element lies in the prime-order group, and that integers are in canonical range.</t>
        <t>Completeness and zero-knowledge are guaranteed only for valid instances: if the prover is invoked on an instance-witness pair outside the relation, no guarantee is provided on its output.</t>
      </section>
      <section anchor="implementation-guidance">
        <name>Implementation guidance</name>
        <t>The Fiat-Shamir transformation has historically led to a number of critical security vulnerabilities.</t>
        <t>Some incorrect implementations involve out-of-order (or missing) prover messages <xref target="CVE-2024-45039"/> <xref target="CVE-2026-46654"/>. Absorbing a prover message and serializing it to (or reading it from) the NARG string should be performed within the same function call, to ensure that prover messages are both hashed and serialized, and to prevent them from being skipped or reordered. A byte-level interface, as described in this document, is advisable in place of proof data structures whose fields are randomly addressable. A sequential interface, by contrast, enforces in-order processing. An end-of-input check is necessary to prevent malleability.</t>
        <t>Test vectors can help confirm that honestly-generated proofs verify, but such tests exercise only completeness. Negative testing will help exercise the rejection paths too. Some such examples are: tampering with a valid NARG string to cause verification to fail, by flipping, appending, or prepending bytes, and by replacing each prover message in turn with a different value.</t>
        <t>The NARG string must be treated as untrusted input. Therefore, non-interactive verifiers <strong>MUST</strong> check that length indicators are correct, that integers fall within their expected range, and that the proof length is correct. For example, in <xref target="deserialize-byte-strings"/> the 4-byte length prefix read by <tt>LE2IP</tt> in <tt>DeserializeVarLenString</tt> is attacker-controlled, and can be as large as <tt>2^32 - 1</tt>, so computing <tt>4 + N</tt> can overflow 32-bit integers. As another example, a crafted length indicator can make verification checks trivial, or exhaust memory on deserialization before any cryptographic check runs <xref target="GNARK-OOM"/>.</t>
      </section>
    </section>
    <section anchor="suites">
      <name>Suites</name>
      <t>The suites defined by this document, and the identifiers used by the test vectors, are:</t>
      <table anchor="tab-suites">
        <name>Duplex sponge suites</name>
        <thead>
          <tr>
            <th align="left">Identifier</th>
            <th align="left">Primitive</th>
            <th align="left">Alphabet</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">
              <tt>SHAKE128</tt></td>
            <td align="left">SHAKE128 <xref target="SHA3"/></td>
            <td align="left">bytes</td>
          </tr>
          <tr>
            <td align="left">
              <tt>TurboSHAKE128</tt></td>
            <td align="left">TurboSHAKE128 <xref target="RFC9861"/></td>
            <td align="left">bytes</td>
          </tr>
        </tbody>
      </table>
      <t>The suite identifier is a natural component of the <tt>tag</tt> (<xref target="session-id"/>), since it fixes the hash instantiation.</t>
      <section anchor="suite-shake128">
        <name>SHAKE128</name>
        <t>In the SHA-3 family, two extendable-output functions (SHAKEs) are defined over the Keccak-f permutation: SHAKE128 and SHAKE256. A SHAKE is an eXtendable-Output Function (XOF) defined as SHAKE(M, n) where the output is an n-bit string. The corresponding collision and second-preimage-resistance for SHAKE128 are min(n/2,128) and min(n,128) bits, respectively (see Appendix A.1 of <xref target="SHA3"/>). This instantiation targets 128-bit security. The SHAKE128 state is a 200-byte (1600-bit) string, split into a rate of R = 168 bytes and a capacity of 32 bytes (256 bits).</t>
      </section>
      <section anchor="suite-turboshake128">
        <name>TurboSHAKE128</name>
        <t>TurboSHAKE128 <xref target="RFC9861"/> is an eXtendable-Output Function (XOF) built on Keccak-p[1600, 12], the Keccak-f[1600] permutation reduced to its last 12 rounds. Its state is a 200-byte (1600-bit) string, split into a rate of R = 168 bytes and a capacity of 32 bytes (256 bits). The corresponding collision and second-preimage-resistance are min(n/2,128) and min(n,128) bits for an n-bit output string, respectively. This instantiation targets 128-bit security.</t>
        <t>In this instantiation, every verifier message is the TurboSHAKE128 XOF evaluation TurboSHAKE128(M, D, L), where M is the concatenation of the session identifier, the encoded instance, and the encoded prover messages up to and including the current round, D (the domain-separation byte in the range 0x01 to 0x7F) is fixed to D = 0x1F, the default value, and L is the desired output length in bytes <xref target="RFC9861"/>.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors thank Thomas Pornin, Vishruti Ganesh, Brent Zundel, Hart Montgomery, Opal Wright, Giap Vu, David Wong, Théophile Wallez, and Thomas Coratger for their reviews and contributions to this specification.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="SHA3" target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf">
          <front>
            <title>SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions</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="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC9861">
          <front>
            <title>KangarooTwelve and TurboSHAKE</title>
            <author fullname="B. Viguier" initials="B." surname="Viguier"/>
            <author fullname="D. Wong" initials="D." role="editor" surname="Wong"/>
            <author fullname="G. Van Assche" initials="G." role="editor" surname="Van Assche"/>
            <author fullname="Q. Dang" initials="Q." role="editor" surname="Dang"/>
            <author fullname="J. Daemen" initials="J." role="editor" surname="Daemen"/>
            <date month="October" year="2025"/>
            <abstract>
              <t>This document defines four eXtendable-Output Functions (XOFs), hash functions with output of arbitrary length, named TurboSHAKE128, TurboSHAKE256, KT128, and KT256.</t>
              <t>All four functions provide efficient and secure hashing primitives, and the last two are able to exploit the parallelism of the implementation in a scalable way.</t>
              <t>This document is a product of the Crypto Forum Research Group. It builds up on the definitions of the permutations and of the sponge construction in NIST FIPS 202 and is meant to serve as a stable reference and an implementation guide.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9861"/>
          <seriesInfo name="DOI" value="10.17487/RFC9861"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="FIPS204" target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf">
          <front>
            <title>Module-Lattice-Based Digital Signature Standard</title>
            <author>
              <organization>National Institute of Standards and Technology (NIST)</organization>
            </author>
            <date year="2024"/>
          </front>
          <seriesInfo name="FIPS" value="204"/>
        </reference>
        <reference anchor="CO25" target="https://eprint.iacr.org/2025/536.pdf">
          <front>
            <title>A Fiat-Shamir Transformation From Duplex Sponges</title>
            <author fullname="Alessandro Chiesa">
              <organization/>
            </author>
            <author fullname="Michele Orrù">
              <organization/>
            </author>
            <date year="2025"/>
          </front>
        </reference>
        <reference anchor="SPONGE" target="https://keccak.team/files/CSF-0.1.pdf">
          <front>
            <title>Cryptographic Sponge Functions</title>
            <author fullname="Guido Bertoni">
              <organization/>
            </author>
            <author fullname="Joan Daemen">
              <organization/>
            </author>
            <author fullname="Michaël Peeters">
              <organization/>
            </author>
            <author fullname="Gilles Van Assche">
              <organization/>
            </author>
            <date year="2011"/>
          </front>
        </reference>
        <reference anchor="DUPLEX" target="https://keccak.team/files/SpongeDuplex.pdf">
          <front>
            <title>Duplexing the Sponge: Single-Pass Authenticated Encryption and Other Applications</title>
            <author fullname="Guido Bertoni">
              <organization/>
            </author>
            <author fullname="Joan Daemen">
              <organization/>
            </author>
            <author fullname="Michaël Peeters">
              <organization/>
            </author>
            <author fullname="Gilles Van Assche">
              <organization/>
            </author>
            <date year="2011"/>
          </front>
        </reference>
        <reference anchor="BPW16" target="https://eprint.iacr.org/2016/771">
          <front>
            <title>How not to Prove Yourself: Pitfalls of the Fiat-Shamir Heuristic and Applications to Helios</title>
            <author fullname="David Bernhard">
              <organization/>
            </author>
            <author fullname="Olivier Pereira">
              <organization/>
            </author>
            <author fullname="Bogdan Warinschi">
              <organization/>
            </author>
            <date year="2012"/>
          </front>
        </reference>
        <reference anchor="DMWG23" target="https://eprint.iacr.org/2023/691">
          <front>
            <title>Weak Fiat-Shamir Attacks on Modern Proof Systems</title>
            <author fullname="Quang Dao">
              <organization/>
            </author>
            <author fullname="Jim Miller">
              <organization/>
            </author>
            <author fullname="Opal Wright">
              <organization/>
            </author>
            <author fullname="Paul Grubbs">
              <organization/>
            </author>
            <date year="2023"/>
          </front>
        </reference>
        <reference anchor="FROZENHEART" target="https://blog.trailofbits.com/2022/04/18/the-frozen-heart-vulnerability-in-plonk/">
          <front>
            <title>The Frozen Heart vulnerability in PlonK</title>
            <author>
              <organization>Trail of Bits</organization>
            </author>
            <date year="2022"/>
          </front>
        </reference>
        <reference anchor="SOLANA-ZK" target="https://solana.com/news/post-mortem-may-2-2025">
          <front>
            <title>Post Mortem: ZK ElGamal Proof Program Bug</title>
            <author>
              <organization>Solana Foundation</organization>
            </author>
            <date year="2025"/>
          </front>
        </reference>
        <reference anchor="POSEIDON2" target="https://eprint.iacr.org/2023/323">
          <front>
            <title>Poseidon2: A Faster Version of the Poseidon Hash Function</title>
            <author fullname="Lorenzo Grassi">
              <organization/>
            </author>
            <author fullname="Dmitry Khovratovich">
              <organization/>
            </author>
            <author fullname="Markus Schofnegger">
              <organization/>
            </author>
            <date year="2023"/>
          </front>
        </reference>
        <reference anchor="SAFE" target="https://eprint.iacr.org/2023/522">
          <front>
            <title>SAFE: Sponge API for Field Elements</title>
            <author fullname="JP Aumasson">
              <organization/>
            </author>
            <author fullname="Dmitry Khovratovich">
              <organization/>
            </author>
            <author fullname="Bart Mennink">
              <organization/>
            </author>
            <author fullname="Porçu Quine">
              <organization/>
            </author>
            <date year="2023"/>
          </front>
        </reference>
        <reference anchor="GNARK-OOM" target="https://github.com/Consensys/gnark/security/advisories/GHSA-cph5-3pgr-c82g">
          <front>
            <title>Out-of-memory during deserialization with crafted inputs</title>
            <author>
              <organization>Consensys</organization>
            </author>
            <date year="2024"/>
          </front>
        </reference>
        <reference anchor="CVE-2022-29566" target="https://nvd.nist.gov/vuln/detail/CVE-2022-29566">
          <front>
            <title>CVE-2022-29566: Fiat-Shamir hashing omits public values from the statement and the proof in Bulletproofs (Frozen Heart)</title>
            <author>
              <organization/>
            </author>
            <date year="2022"/>
          </front>
        </reference>
        <reference anchor="CVE-2024-45039" target="https://nvd.nist.gov/vuln/detail/CVE-2024-45039">
          <front>
            <title>CVE-2024-45039: gnark Groth16 commitment extension unsound for more than one commitment</title>
            <author>
              <organization/>
            </author>
            <date year="2024"/>
          </front>
        </reference>
        <reference anchor="CVE-2026-46654" target="https://nvd.nist.gov/vuln/detail/CVE-2026-46654">
          <front>
            <title>CVE-2026-46654: Plonky3 Fiat-Shamir challenge collision from a non-binding transcript</title>
            <author>
              <organization/>
            </author>
            <date year="2026"/>
          </front>
        </reference>
        <reference anchor="RFC9380">
          <front>
            <title>Hashing to Elliptic Curves</title>
            <author fullname="A. Faz-Hernandez" initials="A." surname="Faz-Hernandez"/>
            <author fullname="S. Scott" initials="S." surname="Scott"/>
            <author fullname="N. Sullivan" initials="N." surname="Sullivan"/>
            <author fullname="R. S. Wahby" initials="R. S." surname="Wahby"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="August" year="2023"/>
            <abstract>
              <t>This document specifies a number of algorithms for encoding or hashing an arbitrary string to a point on an elliptic curve. This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9380"/>
          <seriesInfo name="DOI" value="10.17487/RFC9380"/>
        </reference>
        <reference anchor="RFC7748">
          <front>
            <title>Elliptic Curves for Security</title>
            <author fullname="A. Langley" initials="A." surname="Langley"/>
            <author fullname="M. Hamburg" initials="M." surname="Hamburg"/>
            <author fullname="S. Turner" initials="S." surname="Turner"/>
            <date month="January" year="2016"/>
            <abstract>
              <t>This memo specifies two elliptic curves over prime fields that offer a high level of practical security in cryptographic applications, including Transport Layer Security (TLS). These curves are intended to operate at the ~128-bit and ~224-bit security level, respectively, and are generated deterministically based on a list of required properties.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7748"/>
          <seriesInfo name="DOI" value="10.17487/RFC7748"/>
        </reference>
        <reference anchor="RFC8032">
          <front>
            <title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
            <author fullname="I. Liusvaara" initials="I." surname="Liusvaara"/>
            <date month="January" year="2017"/>
            <abstract>
              <t>This document describes elliptic curve signature scheme Edwards-curve Digital Signature Algorithm (EdDSA). The algorithm is instantiated with recommended parameters for the edwards25519 and edwards448 curves. An example implementation and test vectors are provided.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8032"/>
          <seriesInfo name="DOI" value="10.17487/RFC8032"/>
        </reference>
        <reference anchor="RFC9496">
          <front>
            <title>The ristretto255 and decaf448 Groups</title>
            <author fullname="H. de Valence" initials="H." surname="de Valence"/>
            <author fullname="J. Grigg" initials="J." surname="Grigg"/>
            <author fullname="M. Hamburg" initials="M." surname="Hamburg"/>
            <author fullname="I. Lovecruft" initials="I." surname="Lovecruft"/>
            <author fullname="G. Tankersley" initials="G." surname="Tankersley"/>
            <author fullname="F. Valsorda" initials="F." surname="Valsorda"/>
            <date month="December" year="2023"/>
            <abstract>
              <t>This memo specifies two prime-order groups, ristretto255 and decaf448, suitable for safely implementing higher-level and complex cryptographic protocols. The ristretto255 group can be implemented using Curve25519, allowing existing Curve25519 implementations to be reused and extended to provide a prime-order group. Likewise, the decaf448 group can be implemented using edwards448.</t>
              <t>This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9496"/>
          <seriesInfo name="DOI" value="10.17487/RFC9496"/>
        </reference>
        <reference anchor="I-D.irtf-cfrg-pairing-friendly-curves">
          <front>
            <title>Pairing-Friendly Curves</title>
            <author fullname="Yumi Sakemi" initials="Y." surname="Sakemi">
              <organization>GMO CONNECT Inc.</organization>
            </author>
            <author fullname="Satoru Kanno" initials="S." surname="Kanno">
              <organization>GMO CONNECT Inc.</organization>
            </author>
            <author fullname="Riad S. Wahby" initials="R. S." surname="Wahby">
              <organization>Stanford University</organization>
            </author>
            <date day="6" month="July" year="2026"/>
            <abstract>
              <t>   Pairing-based cryptography, a subfield of elliptic curve
   cryptography, has received attention due to its flexible and
   practical functionality.  Pairings are special maps defined using
   elliptic curves and it can be applied to construct several
   cryptographic protocols such as identity-based encryption, attribute-
   based encryption, and so on.  At CRYPTO 2016, Kim and Barbulescu
   proposed an efficient number field sieve algorithm named exTNFS for
   the discrete logarithm problem in a finite field.  Several types of
   pairing-friendly curves such as Barreto-Naehrig curves are affected
   by the attack.  In particular, a Barreto-Naehrig curve with a 254-bit
   characteristic was adopted by a lot of cryptographic libraries as a
   parameter of 128-bit security, however, it ensures no more than the
   100-bit security level due to the effect of the attack.  In this
   memo, we list the security levels of certain pairing-friendly curves,
   and motivate our choices of curves.  First, we summarize the adoption
   status of pairing-friendly curves in standards, libraries and
   applications, and classify them in the 128-bit, 192-bit, and 256-bit
   security levels.  Then, from the viewpoints of "security" and "widely
   used", we select the recommended pairing-friendly curves considering
   exTNFS.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-pairing-friendly-curves-13"/>
        </reference>
        <reference anchor="RFC4086">
          <front>
            <title>Randomness Requirements for Security</title>
            <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd"/>
            <author fullname="J. Schiller" initials="J." surname="Schiller"/>
            <author fullname="S. Crocker" initials="S." surname="Crocker"/>
            <date month="June" year="2005"/>
            <abstract>
              <t>Security systems are built on strong cryptographic algorithms that foil pattern analysis attempts. However, the security of these systems is dependent on generating secret quantities for passwords, cryptographic keys, and similar quantities. The use of pseudo-random processes to generate secret quantities can result in pseudo-security. A sophisticated attacker may find it easier to reproduce the environment that produced the secret quantities and to search the resulting small set of possibilities than to locate the quantities in the whole of the potential number space.</t>
              <t>Choosing random quantities to foil a resourceful and motivated adversary is surprisingly difficult. This document points out many pitfalls in using poor entropy sources or traditional pseudo-random number generation techniques for generating such quantities. It recommends the use of truly random hardware techniques and shows that the existing hardware on many systems can be used for this purpose. It provides suggestions to ameliorate the problem when a hardware solution is not available, and it gives examples of how large such quantities need to be for some applications. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="106"/>
          <seriesInfo name="RFC" value="4086"/>
          <seriesInfo name="DOI" value="10.17487/RFC4086"/>
        </reference>
      </references>
    </references>
    <?line 991?>

<section anchor="example-sumcheck">
      <name>Example protocol: sumcheck</name>
      <t>This appendix describes the Fiat-Shamir transformation for the sumcheck protocol. This protocol is not meant for standalone use; it is a toy example where the verifier's final check would still require the evaluation <tt>y = f(r[1], ..., r[v])</tt>, which is normally obtained via a polynomial commitment scheme opening.</t>
      <t>The protocol is parameterized by a prime <tt>p</tt> and a number of variables <tt>v</tt>. The witness is the table <tt>w</tt> of the <tt>2^v</tt> evaluations of a multilinear polynomial <tt>f</tt> on the hypercube: entry <tt>w[j]</tt> is <tt>f(j_0, ..., j_{v-1})</tt>, where <tt>j_0</tt> is the least-significant bit of <tt>j</tt>. The instance is <tt>(v, S)</tt>: the number of variables and the claimed sum <tt>S</tt> of all table entries. The application context is bound through the session identifier (<xref target="session-id"/>). All field arithmetic below is modulo <tt>p</tt>.</t>
      <t>In each round the prover message is the coefficient pair <tt>(a0, a1)</tt> of the round polynomial <tt>g(X) = a0 + a1 * X</tt> of the lowest unbound variable: <tt>g(0)</tt> and <tt>g(1)</tt> are the even- and odd-indexed half-sums of the table. Each verifier message is one field element, decoded from <tt>Ns</tt> squeezed bytes as <tt>LE2IP(Squeeze(Ns)) mod p</tt>. (For the Mersenne31 instantiation below, the bias of the reduction is approximately <tt>2^-31</tt>, less than the soundness error of the interactive argument.)</t>
      <artwork><![CDATA[
SumcheckProve(session_id, v, w)

Inputs:

- session_id, a 32-byte string
- v, the number of variables
- w, a table of 2^v field elements

Outputs: narg_string; y, the final folded evaluation
f(r[1], ..., r[v])

 1. S := w[0] + w[1] + ... + w[2^v - 1]
 2. state := Init(session_id)
 3. state.Absorb(SerializeUint(v, 2^32) || SerializeField(S, p, 1))
 4. narg_string := ""
 5. for i in 1, ..., v:
 6.    a0 := w[0] + w[2] + ... + w[len(w) - 2]
 7.    a1 := (w[1] + w[3] + ... + w[len(w) - 1]) - a0
 8.    msg := SerializeField((a0, a1), p, 2)
 9.    state.Absorb(msg)
10.    narg_string := narg_string || msg
11.    r := LE2IP(state.Squeeze(Ns)) mod p
12.    w := (w[0] + r * (w[1] - w[0]), w[2] + r * (w[3] - w[2]), ...)
13. return (narg_string, w[0])
]]></artwork>
      <t>After <tt>v</tt> rounds the single remaining entry <tt>w[0]</tt> is <tt>f(r[1], ..., r[v])</tt>, where <tt>r[i]</tt> is the challenge of round <tt>i</tt>. The NARG string is the concatenation of the round messages.</t>
      <artwork><![CDATA[
SumcheckVerify(session_id, v, S, narg_string, y)

Inputs:

- session_id, v, as in SumcheckProve
- S, the claimed sum
- narg_string, the NARG string
- y, the evaluation f(r[1], ..., r[v]), supplied by the caller

Output: accept or reject

 1. state := Init(session_id)
 2. state.Absorb(SerializeUint(v, 2^32) || SerializeField(S, p, 1))
 3. for i in 1, ..., v:
 4.    ((a0, a1), narg_string) := DeserializeField(narg_string, p, 2)
 5.    fail if 2 * a0 + a1 != S
 6.    state.Absorb(SerializeField((a0, a1), p, 2))
 7.    r := LE2IP(state.Squeeze(Ns)) mod p
 8.    S := a0 + a1 * r
 9. fail if narg_string != ""
10. fail if S != y
11. return accept
]]></artwork>
      <t>The test vectors instantiate <tt>p = 2^31 - 1</tt>, <tt>v = 4</tt>, and the witness <tt>w = (1, 2, 4, ..., 2^15)</tt>, giving <tt>S = 65535</tt>. The vectors report the NARG string as <tt>Narg</tt> and <tt>f(r[1], ..., r[v])</tt> as <tt>FinalEvaluation</tt>.</t>
    </section>
    <section anchor="test-vectors">
      <name>Test Vectors</name>
      <t>Each test vector is a block of lines of the form <tt>Key = Value</tt>, and no key repeats within a vector. A value is either an integer, written in decimal or in hexadecimal with the prefix <tt>0x</tt>, or a byte string, written in lowercase hexadecimal. The empty byte string is written <tt>""</tt>.</t>
      <t>Two rules govern how a value is laid out, and they are the whole grammar:</t>
      <ol spacing="normal" type="1"><li>
          <t>A value is written inline after <tt>Key = </tt> when it fits the document width. Otherwise it is written on the lines that follow, indented by two spaces, and the value is the concatenation of those lines with no separator. Byte strings wrap at a whole 32 bytes per line, so that a 32-byte value occupies exactly one line and a 64-byte value exactly two.</t>
        </li>
        <li>
          <t>A sequence-valued field always uses the indented form, one item per line, each item introduced by <tt>- </tt>. An item too long for a line is itself wrapped, and its continuation lines carry a further two spaces of indentation.</t>
        </li>
      </ol>
      <t>So an indented line beginning <tt>- </tt> starts a new item, and any other indented line continues the value above it.</t>
      <t>Every vector carries <tt>Id</tt>, a stable name of the form <tt>fiat-shamir/&lt;suite&gt;/&lt;vector&gt;</tt> by which this document and a test harness refer to it, and <tt>Function</tt>, the operation the remaining keys describe. The hash suite is identified with key <tt>Hash</tt> (<xref target="suites"/>). A vector carrying <tt>Expected = reject</tt> indicates a negative test; a vector with no <tt>Expected</tt> is a functional test, whose expectation is the output value it carries. The key <tt>ByteOrder</tt> marks the vectors exercising a non-default serialization (<xref target="serialize-field"/>).</t>
      <t>A machine-readable (JSON) copy of every vector below is part of this specification's repo. The two carry the same records: because no key repeats and sequences are explicit, each <tt>~~~</tt> block corresponds to one JSON object, key for key.</t>
      <section anchor="tv-codec">
        <name>Codec test vectors</name>
        <t>This section contains vectors for the encoding, decoding, serialization, and deserialization functions.</t>
        <section anchor="byte-string-serialization-serializevarlenstring">
          <name>Byte-string serialization: <tt>SerializeVarLenString</tt></name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/serialize_varlen
Function = SerializeVarLenString
Input = 70726f6f66
Output = 0500000070726f6f66
]]></artwork>
        </section>
        <section anchor="serializeuint-unsigned-integer-serialization">
          <name><tt>SerializeUint</tt>: unsigned-integer serialization.</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/serialize_uint
Function = SerializeUint
Modulus =
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  43
Value = 0xdeadbeef
Output =
  efbeadde00000000000000000000000000000000000000000000000000000000
]]></artwork>
        </section>
        <section anchor="deserializefield-used-to-deserialize-a-degree-2-element-of-the-field-of-characteristic-2256-189-the-default-little-endian-serialization">
          <name><tt>DeserializeField</tt>, used to deserialize a degree-2 element of the field of characteristic <tt>2^256 - 189</tt> (the default, little-endian serialization).</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/deserialize_field
Function = DeserializeField
Modulus =
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  43
ExtensionDegree = 2
Input =
  efbeadde00000000000000000000000000000000000000000000000000000000
  42ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Coordinates =
  - 0xdeadbeef
  - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff42
]]></artwork>
        </section>
        <section anchor="the-empty-byte-string-may-be-encoded-as-a-variable-length-string">
          <name>The empty byte string may be encoded as a variable-length string.</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/varlen_empty
Function = SerializeVarLenString
Input = ""
Output = 00000000
]]></artwork>
        </section>
        <section anchor="decoding-is-infallible-and-distribution-preserving">
          <name>Decoding is infallible and distribution-preserving</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/decode_uint_wraparound
Function = DecodeUint
Modulus =
  0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325
  51
Input =
  512563fcc2cab9f3849e17a7adfae6bcffffffffffffffff00000000ffffffff
  00000000000000000000000000000000
Challenge = 0x00
]]></artwork>
        </section>
        <section anchor="field-serialization-of-the-p-256-scalar-field-happens-via-i2osp">
          <name>Field serialization of the P-256 scalar field happens via <tt>I2OSP</tt>.</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/serialize_field_be
Function = SerializeField
ByteOrder = big-endian
Modulus =
  0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325
  51
Value = 0xdeadbeef
Output =
  00000000000000000000000000000000000000000000000000000000deadbeef
]]></artwork>
        </section>
        <section anchor="the-modulus-itself-is-not-accepted-as-a-valid-serialization">
          <name>The modulus itself is not accepted as a valid serialization.</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/deserialize_uint_reject_modulus
Function = DeserializeUint
Modulus =
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  43
Input =
  43ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Expected = reject
]]></artwork>
        </section>
        <section anchor="deserialization-fails-for-inputs-shorter-than-ns-bytes">
          <name>Deserialization fails for inputs shorter than <tt>Ns</tt> bytes</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/deserialize_uint_reject_short
Function = DeserializeUint
Modulus =
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  43
Input =
  efbeadde000000000000000000000000000000000000000000000000000000
Expected = reject
]]></artwork>
        </section>
        <section anchor="when-deserializing-field-extension-elements-all-coordinates-must-be-validated">
          <name>When deserializing field extension elements, all coordinates must be validated</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/deserialize_field_reject_second_coordinate
Function = DeserializeField
Modulus =
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  43
ExtensionDegree = 2
Input =
  42ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Expected = reject
]]></artwork>
        </section>
        <section anchor="a-payload-one-byte-shorter-than-its-length-prefix-is-rejected">
          <name>A payload one byte shorter than its length prefix is rejected.</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/deserialize_varlen_reject_truncated
Function = DeserializeVarLenString
Input = 0500000070726f6f
Expected = reject
]]></artwork>
        </section>
        <section anchor="the-maximal-length-prefix-232-1-is-rejected">
          <name>The maximal length prefix 2^32 - 1 is rejected.</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/deserialize_varlen_reject_overflow
Function = DeserializeVarLenString
Input = ffffffffdeadbeef
Expected = reject
]]></artwork>
        </section>
        <section anchor="the-example-protocol-example-sumcheck-where-the-first-prover-message-is-an-invalid-serialization-p-the-modulus-is-added-to-the-canonical-encoding">
          <name>The example protocol (<xref target="example-sumcheck"/>), where the first prover message is an invalid serialization (<tt>p</tt>, the modulus, is added to the canonical encoding)</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/sumcheck_reject_noncanonical_coefficient
Function = Sumcheck
Modulus = 0x7fffffff
NumVariables = 4
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
ClaimedSum = 0xffff
Narg =
  5455008055550000b8eefc2728ccf677b7aabd44c1001d074205d5576c3d307d
Expected = reject
]]></artwork>
        </section>
        <section anchor="an-invalid-narg-string-for-the-example-protocol-example-sumcheck-where-a-prover-message-does-not-satisfy-verification">
          <name>An invalid NARG string for the example protocol (<xref target="example-sumcheck"/>), where a prover message does not satisfy verification</name>
          <artwork><![CDATA[
Id = fiat-shamir/codec/sumcheck_reject_round_identity
Function = Sumcheck
Modulus = 0x7fffffff
NumVariables = 4
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
ClaimedSum = 0xffff
Narg =
  5655000055550000b8eefc2728ccf677b7aabd44c1001d074205d5576c3d307d
Expected = reject
]]></artwork>
        </section>
      </section>
      <section anchor="tv-shake128">
        <name>SHAKE128 test vectors</name>
        <t>This section contains vectors for the XOF duplex sponge instantiated with the SHAKE128 suite (<xref target="suite-shake128"/>).</t>
        <section anchor="squeeze-a-32-byte-string-after-initialization">
          <name>Squeeze a 32-byte string after initialization</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/init_squeeze
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - squeeze 32
Output =
  63e1b3543377fab6fb8cf0f7698a9980ca0211d5bc4aba213dd7a6ef7dd63cfa
]]></artwork>
        </section>
        <section anchor="absorb-the-byte-string-hello-world-then-squeeze-64-bytes">
          <name>Absorb the byte string <tt>hello world</tt>, then squeeze 64 bytes</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/absorb_squeeze
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 68656c6c6f20776f726c64
  - squeeze 64
Output =
  f627ff348dfee50d2aa5918a2621a0c1daf74c7ef930d49b5ea6eae73455e8c7
  56d433cbde0ade711bdd55d7ed5de38bb9adea8b2eec4402a0df090c16371413
]]></artwork>
        </section>
        <section anchor="absorb-is-associative-absorbabc-is-equivalent-to-absorbab-absorbc">
          <name>Absorb is associative: <tt>Absorb("abc")</tt> is equivalent to <tt>Absorb("ab"); Absorb("c")</tt></name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/absorb_split
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 6162
  - absorb 63
  - squeeze 32
Output =
  a629c32a309dda7605798fd07ce20ab14c76635446868eb46e20b6dfd1dd9e41
]]></artwork>
        </section>
        <section anchor="squeeze-is-associative-squeeze16-16-is-equivalent-to-squeeze16-squeeze16">
          <name>Squeeze is associative: <tt>Squeeze(16 + 16)</tt> is equivalent to <tt>Squeeze(16) || Squeeze(16)</tt></name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/stream
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 616263
  - squeeze 16
  - squeeze 16
Output =
  a629c32a309dda7605798fd07ce20ab14c76635446868eb46e20b6dfd1dd9e41
]]></artwork>
        </section>
        <section anchor="absorb-of-the-empty-string-is-a-no-op">
          <name>Absorb of the empty string is a no-op</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/empty_absorb
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 616263
  - squeeze 32
  - absorb ""
  - squeeze 32
Output =
  a629c32a309dda7605798fd07ce20ab14c76635446868eb46e20b6dfd1dd9e41
  d88e36c20e053248b90967a90051ba319688a10783c2ce174602eccc02e8d1a6
]]></artwork>
        </section>
        <section anchor="absorb-and-squeeze-can-be-interleaved">
          <name>Absorb and squeeze can be interleaved</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/interleave
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 00010203040506070809
  - squeeze 16
  - absorb 6d6f72652064617461
  - squeeze 16
Output =
  2da3c7e3a65c6e92901e8b668c43917eb9f02e9988e66d5ce2fbd833a0ecb93e
]]></artwork>
        </section>
        <section anchor="absorbing-a-byte-string-of-length-longer-than-the-rate">
          <name>Absorbing a byte string of length longer than the rate.</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/multiblock
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb ababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    bababababababababababababababababababababababababab
  - squeeze 600
Output =
  d0dc63443a117b76b09845af3347a6dbc29d0ff381ad093e3cfea3a326abbd0d
  a81bfc7dd6220f785900a6d04d508439cc65107c8eb75909f277a6f2740ae55f
  c684b851b66662c22252b6bb8028b5f7402b0beafb391835613a6c3d8116323d
  bdcb4494a198ae886821fca3d2af345227ea06c5c2cdb131c90d3fe58eedf090
  a55bb5a8edc614ab99da6c4ed8fe95a6c289c18dc61918a9abaa4f3ed2358711
  7ced29b33bfb87351d4ffc562add96d384fffbcb7cfb4d4d2125bf809cb85b33
  a3f9b7541c5d3d3f435f7d0a837f92f6878276ca3c833ecc1691f923602e9b8c
  8adb9528d8857d7189384eabbab50f0706b82b53db1c92857c2aa84a3527ce4b
  fcfbdbe02ad953b8517c4b91d36b45f81df67e10e4e9a7c7c064aa9e7f593710
  10eab4fd71c7aebcf00a793e469a78c658dd9f2c1d5ed2e3110939c11e916c1f
  51c47553b1bbceeea92649c9bcc7e5538dab18ca95c298b540b6798c065cd2b4
  13fe3915534a5dc6e7100e012b8c53fccc1018cc24570ca09c8e1c8f6e4e523d
  db7b6dcf313b6e98bb4abc94b8063eac8fdbbce945c35dd021a91e8227aeb165
  02a5a6e9e1d85fbd13b6e1e523e8a24040bbb9ddab5e29315780a57d9ef0d758
  b66e0076704f456dec1fc11577fe3644e53ff70a99a912758c289f225ad64e24
  6af9d895d91e6972b18421ccaa2aed6f843870b9dda07d1e975e51c04d58e7ba
  d60c0b8934fec80d4468816793879bc34d831e2689b77525439837fd15f797ed
  3b78ccdfdec6a5574111de3e243464c77c1d7fa76fb170e3722315e70fbf855a
  33281e8b6c15029202d0bb34749b962cc314515c748b74f4
]]></artwork>
        </section>
        <section anchor="squeeze-at-the-rate-boundary">
          <name>Squeeze at the rate boundary</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/rate_block
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1
    e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4
    04142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616
    2636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838
    485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a
    6a7
  - squeeze 167
  - squeeze 2
Output =
  edae25852c909e4acea18d96ddd407e475eeaa7070ff591b49450c7a3ed21b7d
  0bd0ee62ab0c242e636c435b37c38ae6804a179ff434bed773c8d596cd66b928
  b0429247b19cbfc246bb1abd3b741841b21ad0234ba7738abe64ab93914bf5ad
  58a362d86f64d72b8f8603a888421a29769bb77579185409013a271ac258cd71
  a71aedf2801ba6eb4784636e9bfacca229a78aa8dc72af770380a1a981120b37
  16595564c520292578
]]></artwork>
        </section>
        <section anchor="a-zero-length-squeeze-between-absorbs-is-a-no-op">
          <name>A zero-length squeeze between absorbs is a no-op</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/squeeze_zero
Function = DuplexSponge
Hash = SHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 616263
  - squeeze 0
  - absorb 646566
  - squeeze 32
Output =
  fc876a5ffbdc960106af16ca50e3b17b14a172f985f3a6f5df09c9a649ebf588
]]></artwork>
        </section>
        <section anchor="derive-a-session-identifier-from-an-application-tag">
          <name>Derive a session identifier from an application tag</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/derive_sid
Function = DeriveSessionID
Hash = SHAKE128
Tag = 696e7465726f702d746573742d763030
Output =
  b508aca89eecac56cd33e4a28f817f43f849d035922f354173ae8466628308cf
]]></artwork>
        </section>
        <section anchor="squeeze-and-reduce-a-p-256-scalar-challenge-decodeuint">
          <name>Squeeze and reduce a P-256 scalar challenge (<tt>DecodeUint</tt>)</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/decode_uint
Function = DecodeUint
Hash = SHAKE128
Modulus =
  0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325
  51
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 08000000696e7374616e6365
  - squeeze 48
Output =
  7124d02b7cdfec99c4033dfd05624cfe2ff3af2c0e71656f770e676bd36de622
  8f85fcb39f34f7bfc24c9f54ab35ddba
Challenge =
  0xf860997c65f8dabecbcc3459a7b89bf69301b19fa1a0e036eb0d132724436d
  4f
]]></artwork>
        </section>
        <section anchor="the-sumcheck-protocol-example-example-sumcheck-over-mersenne31">
          <name>The sumcheck protocol example (<xref target="example-sumcheck"/>) over Mersenne31.</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/sumcheck
Function = Sumcheck
Hash = SHAKE128
Modulus = 0x7fffffff
NumVariables = 4
Tag = 73756d636865636b
SessionId =
  0568cefdf774622a3854d82934915fb3e38bc89dc44b6d673fc91b972c886fc2
Witness =
  - 1
  - 2
  - 4
  - 8
  - 16
  - 32
  - 64
  - 128
  - 256
  - 512
  - 1024
  - 2048
  - 4096
  - 8192
  - 16384
  - 32768
ClaimedSum = 0xffff
Narg =
  555500005555000023e362696ba9283c90a3362a74953379afc3b041d3eb126f
FinalEvaluation = 0x3ebfb3b3
]]></artwork>
        </section>
        <section anchor="a-narg-string-with-trailing-bytes-is-rejected">
          <name>A NARG string with trailing bytes is rejected</name>
          <artwork><![CDATA[
Id = fiat-shamir/shake128/sumcheck_reject_trailing_bytes
Function = Sumcheck
Hash = SHAKE128
Modulus = 0x7fffffff
NumVariables = 4
Tag = 73756d636865636b
SessionId =
  0568cefdf774622a3854d82934915fb3e38bc89dc44b6d673fc91b972c886fc2
ClaimedSum = 0xffff
Narg =
  555500005555000023e362696ba9283c90a3362a74953379afc3b041d3eb126f
  00
Expected = reject
]]></artwork>
        </section>
      </section>
      <section anchor="tv-turboshake128">
        <name>TurboSHAKE128 test vectors</name>
        <t>This section contains vectors for the XOF duplex sponge instantiated with the TurboSHAKE128 suite (<xref target="suite-turboshake128"/>).</t>
        <section anchor="squeeze-a-32-byte-string-after-initialization-1">
          <name>Squeeze a 32-byte string after initialization</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/init_squeeze
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - squeeze 32
Output =
  7ad8a3af35a3083c055e4a953ff001cdd9eeb1198f4be7a3a9ec5a209434619b
]]></artwork>
        </section>
        <section anchor="absorb-the-byte-string-hello-world-then-squeeze-64-bytes-1">
          <name>Absorb the byte string <tt>hello world</tt>, then squeeze 64 bytes</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/absorb_squeeze
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 68656c6c6f20776f726c64
  - squeeze 64
Output =
  8b804d7a8c524c242a94e86f7ddfec329d90e29c1f584a98812e63029a0bdb07
  5b12c545bf9e2aa17c88673b6d9df4b08e728dc47f7d7094cee59a0d7d989634
]]></artwork>
        </section>
        <section anchor="absorb-is-associative-absorbabc-is-equivalent-to-absorbab-absorbc-1">
          <name>Absorb is associative: <tt>Absorb("abc")</tt> is equivalent to <tt>Absorb("ab"); Absorb("c")</tt></name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/absorb_split
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 6162
  - absorb 63
  - squeeze 32
Output =
  51acee1ee6f0c6a0c5a33b625ac9eaea54bc6b9b1cb85f9b2ef843e73631792e
]]></artwork>
        </section>
        <section anchor="squeeze-is-associative-squeeze16-16-is-equivalent-to-squeeze16-squeeze16-1">
          <name>Squeeze is associative: <tt>Squeeze(16 + 16)</tt> is equivalent to <tt>Squeeze(16) || Squeeze(16)</tt></name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/stream
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 616263
  - squeeze 16
  - squeeze 16
Output =
  51acee1ee6f0c6a0c5a33b625ac9eaea54bc6b9b1cb85f9b2ef843e73631792e
]]></artwork>
        </section>
        <section anchor="absorb-of-the-empty-string-is-a-no-op-1">
          <name>Absorb of the empty string is a no-op</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/empty_absorb
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 616263
  - squeeze 32
  - absorb ""
  - squeeze 32
Output =
  51acee1ee6f0c6a0c5a33b625ac9eaea54bc6b9b1cb85f9b2ef843e73631792e
  599e1dfb1bf60638046f82f5bfa28bcfcabf1404b200647d184ead03e51fbf01
]]></artwork>
        </section>
        <section anchor="absorb-and-squeeze-can-be-interleaved-1">
          <name>Absorb and squeeze can be interleaved</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/interleave
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 00010203040506070809
  - squeeze 16
  - absorb 6d6f72652064617461
  - squeeze 16
Output =
  f2745534347564bed146c95655122f14636bcc58f768296be8494208db29b6be
]]></artwork>
        </section>
        <section anchor="absorbing-a-byte-string-of-length-longer-than-the-rate-1">
          <name>Absorbing a byte string of length longer than the rate.</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/multiblock
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb ababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    babababababababababababababababababababababababababababababababababa
    bababababababababababababababababababababababababab
  - squeeze 600
Output =
  0ef6787d725638e19364c25a2ba879af55a4e1c97bff52919e64cd37a218db44
  a475f9d7ef0e88d87b443fe6590f12fc90c41c546c92cbeb3480e679d6e1ea37
  fc1e10e3e41b15e80aea4745ad9ad31c22857ae360fb66848daab7df8f6135ef
  cc940c4cc6431617cca6c05aa9b8bdf041538206ef912c0861dc07e219875509
  24c848cb788532637cf6e7fb1a3ea233fc335077e4910e8d7da15fe89250f284
  58ec17ecf448e05cf660ca4ffd1fdcb4379570d3a871aa759bb4d763d60d3e1b
  36ab8efcd8cd6fcca8fa67a5071ab21a1d31e4610f7ca8825b5e81f22433c495
  862b642c009823c312fd60fcdcd888af9c6c554da3a370946fa7bfa66ac54480
  b9a36d73fa6ee73ccb78b425de22814667742864608a06fa7534b053a68905ff
  532089b6fc0d597671ae4da685b96b1ac5d2513c0fc944d11155ed43461559a1
  2b984fb0cb45b105d9f2391a137d104f7da6c82fcfe375143bf512824685913f
  2bf61613b1a2a8f55f86d1282aa36c02384381335927259361c9e5875dbe1314
  af82aa65264ff009f525d4f0aedcf80cb908e308132113311d0e9a6783f27a13
  93ae28c10914018e263020dc97f219ebdae4118a79c318bef2d3766452075e35
  79f4b1cddbb80a5bca83a2f1fbec44e9d487925ba23cbfce111ba865e0fdb164
  589c66cbb757865d1bfb4540c01dece5b4180eef4262efc24c4ae3f76c4497a5
  3fb7f38a0de18a7053ab59b59b180ad53e3d2318661783682298d54b9f9ee6e3
  3b2be660295ccdd7d6cc976e21827c66880a0fbcc202743cd1ea0b7351755ee4
  b8a0b140bbc4f6a45eb6b05798721094cebe00e08f4f7bde
]]></artwork>
        </section>
        <section anchor="squeeze-at-the-rate-boundary-1">
          <name>Squeeze at the rate boundary</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/rate_block
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1
    e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4
    04142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616
    2636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838
    485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a
    6a7
  - squeeze 167
  - squeeze 2
Output =
  dc4b6f89697ec7e56ad210e6244a3ff25dab91ebd60981761db8f83db3a3a781
  ab43ffd7f325c98b912746b65d233fb5b99fd923cbff5e327b75436afd035c42
  ac9953ca4d686e30e5729aa460b813adf96c16917471679a4de36b19c452aef4
  47f93f4574ddcf09bdf6410774b426ffe415ff8eb2be44c8301ae071b534895b
  0ab66aa0136ffe9656c607bb6e1acaea4069454e297ec0ad4eab437c25455c88
  aeb77d6f33f7b578e9
]]></artwork>
        </section>
        <section anchor="a-zero-length-squeeze-between-absorbs-is-a-no-op-1">
          <name>A zero-length squeeze between absorbs is a no-op</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/squeeze_zero
Function = DuplexSponge
Hash = TurboSHAKE128
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 616263
  - squeeze 0
  - absorb 646566
  - squeeze 32
Output =
  61d3fecc576c3faafb92db1cb22b60794075a024df9626436394c7b852ade899
]]></artwork>
        </section>
        <section anchor="derive-a-session-identifier-from-an-application-tag-1">
          <name>Derive a session identifier from an application tag</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/derive_sid
Function = DeriveSessionID
Hash = TurboSHAKE128
Tag = 696e7465726f702d746573742d763030
Output =
  4326208c9e56ae847be9356ca7c4447c752a9d7326a44a6cbee0c0dfc69505ac
]]></artwork>
        </section>
        <section anchor="squeeze-and-reduce-a-p-256-scalar-challenge-decodeuint-1">
          <name>Squeeze and reduce a P-256 scalar challenge (<tt>DecodeUint</tt>)</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/decode_uint
Function = DecodeUint
Hash = TurboSHAKE128
Modulus =
  0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325
  51
SessionId =
  000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Operations =
  - absorb 08000000696e7374616e6365
  - squeeze 48
Output =
  82a031e31b103ac01253ba3aae215f650a06a4bb24963a05ee1f8c0b82eae90d
  7bd36ea8cb560a91604ae8a97eb0d564
Challenge =
  0xc2088b455016d0126fcdd76335a79566e7fd8379db1de019871d459bfee955
  8b
]]></artwork>
        </section>
        <section anchor="the-sumcheck-protocol-example-example-sumcheck-over-mersenne31-1">
          <name>The sumcheck protocol example (<xref target="example-sumcheck"/>) over Mersenne31.</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/sumcheck
Function = Sumcheck
Hash = TurboSHAKE128
Modulus = 0x7fffffff
NumVariables = 4
Tag = 73756d636865636b
SessionId =
  abcbcae1f2f90d02b7e6417dbb2ffe162ab00477453eac3ce83d4e7e61000280
Witness =
  - 1
  - 2
  - 4
  - 8
  - 16
  - 32
  - 64
  - 128
  - 256
  - 512
  - 1024
  - 2048
  - 4096
  - 8192
  - 16384
  - 32768
ClaimedSum = 0xffff
Narg =
  55550000555500006ff9a71d4decf758430dfb69f9c6b5359d8ab2744b13d83d
FinalEvaluation = 0x654028db
]]></artwork>
        </section>
        <section anchor="a-narg-string-with-trailing-bytes-is-rejected-1">
          <name>A NARG string with trailing bytes is rejected</name>
          <artwork><![CDATA[
Id = fiat-shamir/turboshake128/sumcheck_reject_trailing_bytes
Function = Sumcheck
Hash = TurboSHAKE128
Modulus = 0x7fffffff
NumVariables = 4
Tag = 73756d636865636b
SessionId =
  abcbcae1f2f90d02b7e6417dbb2ffe162ab00477453eac3ce83d4e7e61000280
ClaimedSum = 0xffff
Narg =
  55550000555500006ff9a71d4decf758430dfb69f9c6b5359d8ab2744b13d83d
  00
Expected = reject
]]></artwork>
        </section>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+29aXvcxpko+p2/AiN/CCl3t7AvdJx7qM3SxFpGdOwkHkdd
AAokot6m0U2KkTV/5z73ub/gfp4/dt+lqlBAo0nKkmPnHGvOidlYClVvvftW
4/H4YFNvZvLYufO4Fpvx6bmY12vnm7VYNNVyPReberm4c1CIjTxbrq+OnXpR
LQ8OymWxEHN4q1yLajOu15tqXFTrs3GFgzQ0yNgNDpptPq+bBsbYXK3g8aev
vnl8sNjOc7k+Pihh0OODYrlo5KLZNsfOZr2VBxfHTnAg1lLAlPDxOweXy/Wb
s/Vyu4IrD9ZXq83Sebxcb+d3Dt7IK7hZHh84Y+cfcr103iyWlzNZnkm8ci6a
84MLudjCVxxneATH4YndeSUbKdbFufMVPoc35qKewQ1c1v+q5aaaLNdneB2f
guvnm82qOb53Dx/DS/WFnOjH7uGFe/l6ednIezgAvndWb863Obw5n4s3cn2v
D7qmPpuL8Wq93CyL5azBV2YAoWZjf4xenfBQk3p50yA79639mZxv5rM7Bwdi
uzlfwnaM4YOOU21nM97aO8/q4lzOpPNivf6f/+8O3YW1iUX9D8KKY+fB81en
dFkqWM3/13K93k4WcgPjLhh9Lgj6p09OgmN6VqMbXBkHzulGLEoBW+i8lOv5
dkMjj++LRpbOE9g/B247j95uJDyVz+T4xXaz2m6cx9tFgU82PK2NWJ9JgJMG
0+JittrmzWRRN5vJ2fLiHv6BV+49fvry9N7zp6ffTPCvie/6k1VZ4QQfPfB6
E3z0wPGOnUezWb3a1IXzYLu+kA6jz9larM6vhj9+eXk5aWRxRogAf3jjC/0R
xyGcdyoxayT91sB36N9Y/dcBMgN60MBpHCBF51FV1UUtF5vOHBhfnUOY7VdH
BwdInhbYcZG+G3YX9mxZbgGUX4sNLEsqYD+sAanEzDmtzxZis11L8/WPBnHY
Wz0APaSfjVzXssEpawDcwVfuwBzhrTtDAEIMhNvPCU9guk8XDSxru5HOsrLg
hVjzjSzOF8vZ8uzKOcTpHOGAD174URcaJ85+xuc8Xi/nzsPtaibfOqer5eJM
7sE4uVrXi82kFsWa9h3WGN2Lgnh36dG1+26R38lMNg0sBNjag3OAk7hz3dM7
xHr68sXzrx5112ohDiA0L+gmWnoji0K8mWykmN+rapjTvQenj8fuxNtZmufd
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
5leaGxMivXsHOtvZmJ9ihkKo3SMoxI1ZsyRpOW62NfIs/Mwad7vRm1Mj0TX1
opCKq46Lel3A0wCihkClWbYm+EE9q8HPgaKimQC+AtPIgaPSrgkg3/O53KiV
g1Vey0UJeNDZPNCL5QREhjFBgYaNlQorRc0T5rQCdNgArpEPnHDJqcgsk8os
mzinxH/RFfz+vQGuogcH41Gb9VYrQOzDwyAR6Ut9FO6CFabIC4LtxD9ALelK
kOaI9Bmw2Btc/gh41gaVlwYkBTPMAhbAWgnKImZD7PWCyfz3f/+3I0RzcXbw
+fgT/Pv84EfGqZcKeRpJsbrXdYm8FkmkgDnCShZw48jZ8+9HGOYT/PuIYRQ0
PtfDtOtwPgAcf/gR9DrA7R8/8Ww+4p9++SOHufjgYTr49bl94XMeRqPHtQAG
iLLi/737A7xGF05yMNpzXBkOM4THn3/4bHDnWqJkdL7lUm0Q/3i4i/U/ZZjB
+8yhX8+bs++9H/YNY+/U8DD9f7eAze6/HbC3O+Xt2amfcTafDMRaIl8L5E8J
Yvi1d5jf92H8o7JjGcS/xwun/7WV8h8SBvi5ZzMMi32P3QqL/V8xFvv/u2Dx
PiD/8ljs/4JYPBm42f7Td//Fhrn+3weR5pvxP4P7/TTSxLn9b0Ga+4D8y5Mm
gfifTZo2+u2VDObxW+PNjcPcToW8cZhP8E8Ngwb4a2WmH3/Zuk0PLQhNJj9c
Y099IusOzMWDd8fOZ1XdTcxUvgKKmXx55/mwV0bbxfvdXXfef2qL1Bik32rX
yrd7bFILxjtw/DS7iaN4E6e7Z7ifrZ9GHl43DTOKP1HO911n9vHt5/JpVnSb
f7b9OjzKLezrjjH9c87ltv/2P/kho1zsvbMzik0Qnw9cHlxT37TuWNA/2tBt
hefPOZfb/vsnQLdrP//UFfWRtLV6/8+G7o7tPLSoz4eW2Rmlr5PYNq9WWGyt
5HYr+mlzue2/fy7u+p8cd/3fcLdnMX9i3PV/Kdy93rC8/olf2Sg96+BaqOyX
9t0NsmxKQwI34P/QHv3Euexd7c6z++/8PBRA5ld/Vdfj3DAF2CblDzvOntuv
6KfM5eP/4SjBxHm1XezNCbnlKJ9mLre0kK6xXXdDHd/uW8g1k1a2txXr6Bo5
ow8ZpYt5w2btDaN8Crh8Gutzn8Fs0GWPyWzu385ofr7cSI5WW5H7cikpPcZZ
SFliFoHKhaJnZqLZ7OYbTHtUP+W8JpMQc7YV8O2NhIEpml/qdIHdfADOsuPk
Q0phofwkGmaMEXF4d62TJSaYAfcNpXhweRUlXy0XF1gIg0Fwyp2y0mk4K+WN
vHKwWrNx7ty9++xPp9/cvXtnpP92nr8wv189+o8/PX316KH+ffrk5OuvOz/s
p3Xmif2rO9qDF8+ePXr+sB0Q7joDl5+d/IX+xOXAzxcvv3n64vkJfnlnRQQv
2KNcsZXVWqqsrw4Q7z946XghwPLfXj1+4Hte9v69+pF6SQg/Ls+lyhpaLmZX
6ids+BWmeUmxxkHEbOYUYoXVeQ1lODbnmKaHOWgThqyYnS0phYJTsEziyO5O
0Lx1clPpbBv0Ub282pwDQs/qN4CMjdzCw8DxJ84jzHcxqTOiKORqgwus6oVJ
3+YPAprNqUxIpYBttmtML11IR2cFc4KmyoieOC/QvBVt5tmFWNdC5UUX9QrW
RjkpPF05k8UGk0sFZXY2y6KmHDv7s7gdbeod5XAIzPVgAFVLzJPFtQKBmQSY
LdY9bs7Xy+0ZZWp0IIVI/plz/wqTETmrayPP4FMHBydAQzA1yndz0nFebzAJ
uj5joNBTziHmQMOkN5zMhSmRd+kt9hXdvcvJWQBJXGUjQaYiRJYVjQ0AOlk4
0+fTsfUOv2FfgKcxvWZzjo8y6cv5ChPhum9dAm5sJAx45870C2f61vnxR+dq
StmKmC61XGDx2qKTD2uN0MAbU1rE9Aq+MoVPHr49mgIeACxVgpyaBmAbTX9g
FBwEXsYi7ebwee/1/krhdarmZlgcHNy3ZyMoObOUb3U+MD46wXpus0fO1HV+
/6VT4//8Hf9HzXkEs/i+do6dv//Qm8Dh352xUx/paWzzdia4euKAzUZd0UuD
uWwwladmrjetR079uTdyJpPJyPn72IMFP7VzAenzLnz++Q8G+lW9Bs4OAGgh
Bx80E63bJ3e3FveT0UuNy8vkV3Da9QaL7CYGZdutYGS6exf4VlW/BXSkVPDO
Q4ghMJkr58svHUKZf0xJvDXLeW9n4cahBObPUzwi5CW9XOGf/sy4WkuJqF+N
aCTMc91cLp2SQFto7jDi5eoBYGbISDB3VFLmncOj6Z2wH8TfS0zYgjk4TT1f
zaRjfbvzbG+5OUPt60eHCMUc6DY8wlXD9T5XR9GoHMCELyrZjiUjjoDp+UeK
Zr5+5D99SQQj1tLooYCl96xXWXpyFdVqXc/rDaVqX8ug0BvuzICyZ3IsFyWw
T14QSFhcvzUPHhx5NaWvLeQZ5cYZZjVdTB2sNebSjakfxX+7nOpU7uklE8Vo
6Fs8e8bBStSzhlBm4fzhS4dHmdgAsOaxg478scHpsZAiNrNvtRSHONArPjh4
SrKJckhRvA6PS5l6xCgWzu95vvD8JaOfklc9xnZwwP0HjvE+Dnxp862DA29C
YEAo4Jguir8WGgf+BN9zvnSYDcJMwTxBSqjxC67iHJdj7/ggJGManv6+pqDD
AnPPcZiDiO4s8GI1Wy7XhwvnHt44OognSvTiewQRBRbeAAWWY+ftaK8guWxX
+GGAw6UvYGUuLnJnScyYcF2Bmj2++7nzFld3l4aocclq+guePOuylGZqOHsu
N5cSZZmr6Os58FmkXGbncOF7+CgIGJbfDztZuKSqVaKQtyjZ2JMS3a+LoIoA
le/fTfVEgVxT5ivxISRZ/RzVgVXbWTshB3OtJesJncxhYJeHrcbl7Etf1vVA
U/Z9TJudIhymMGDMF8vZBTFm/Da2UKDZMDCVbT81RRZio263Mo/u8Nf2Fetg
rKtUqle7RJVga+pH7t41S3z3jrsVYGI+Dz0XK4QU6YXY98MQIlIl8Yr+LUWx
YN8IggHVdcyoHBcrW/hNVXe3cBpaae8ZXUWkUrj1VsAEAQ1J+r97x20CcKKw
HaoIq/0eVsmYkefiCg0EAfcAvdb17IqhMZMC4IMvz7AIZSPqbr0EQVyZcgR8
ygQG5mfKa+5iivPdu8yqVss113ywoFCTUgoKJvvT9BC5zOxImVZqKZgWogAz
D4fjV42oBYW6RBamFciyXoMmPrvCDGplYraEQtOHzdVyWI/LCwF0XAHvx2cF
qZxoMDkdPHbmW1CFGvi7qa6UJV1Tqf/5cqYmvOmU7RhDd7Zs0DSCxZ7VqIhc
b7/y0rFo5R+aqjgXnHkGV2E3XGPvbFo7lxEa0Jajn1jdA3NHAtD6fOB39Fii
H/MUY71o2xggHDbybVsNqtO999d9wGRBKfgCi3Pgg+eY1g4In+sCC6s4oVOf
YSqOaOLjuuTCgBNSzWw+oReiPQyNqkDr+8/4rRaJ+pzgtuO0MxRgRNXIgLEg
hfkoqYMjUjg3NYykmeRrU1jwGpVN85EClQJJrAFeJB0PNcyrFVdQKGLl6o5O
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
lV3VcDgwUz3GIPF2UPuniFRFwCjhLJwm8rVY/UQ3B9sTryAfM0OTneY7Nv4u
Mh53s3ArTKaEt9UJjuQU/h3XBvUcwPrcRP1If1ZnuLWLpud9Gg95n3YFrLTb
/VitEefsDO46pfa7ofZZ2JO+k8FqRSjX1C2q56P5nbKlx2Tx6UomiW6qTm4k
t0gY9NcMJ+UctbgBaD7TR0mZDnXMe7Ss757ty9Zn92g227dIWam9IpLOOZvs
cLJ6MKgP2q40dK0Nudws75aOUFFGnNU/xz4f+RImMlaHZrBoVg8RHBz7gEWa
afeUkzsqBneHTz6+rBt9diQ5wMaWA2y3Q6OV6IDSUMOt9T+1x2YO+84oy+hR
21eje9YidopsOzOzTU5ZHfsONhnpM6TaE+2bcyreVaFKPqaMsh9M7wp4SRqX
xZUj5ngg5j847KBRrMDGSpxigsbeTJoi8F5ZKLmUllg+rd/C8JraVXa0qvQJ
YRpN1e1u2ytiw5AXhFUprZ+259Wl4U1qieoehi7WnQ8Y5wjuGybk0OCHaGo+
Wy42Z8u5XF+h82JdF2+OsJ3zuYm2Lggi/LGJc9jSQp8VmN5aPLp9ntiluNLd
0BgmSB4tVMwKRAf4zX9t0bJYL5ebCYjvgQT7oUC2PkBktZZtccXTXtVuNz+J
O1zsLV9pi4RUiwG7jfDgUSw65EdCVbXgUM0QOKcdK8qosxQOsXsCxiF3Lu8e
gYGMjcibW3EPNXKosTGx7WynxtzcGv2w1w29EXSeLx2SvrhYFv3Q23y76TlR
VzYsOpHW3Z4Uu5vQ5h7dqo3DRpxZCX12myxSrLhh2QwBs9b1epyTIDktDKtz
Oy5Bk1RamBRfVfXL26++22yWa1K92y3mftvsiTTlHm376MHyDGBw3QMSmn2b
aho24Ce12G3PyiAUJzmuz+Sbti2aTRLoqpHbconTOGLHKvcz6LWUAI5HrWmB
fRAWA5cCEiuR6xZ6pLb1LB9SuEs7ncphxvPOiVHWgT1D1MHRI3NGi8o4NScD
dyVBLzkHi6kFqVJtG6Nm+E00PbYsD/cf2G0dywef6raPRtbDzXN15mKbcMsf
pLOAG2xgq9webc0hdZTE3AEgNHaTt56RC65F7x54yj5s+/zwmaw2xhKSb8nt
faZKivAv01sJW+YSjbFQazPQzXTGVm88PTHMDCQaUv2NdkIPxrdt9cJG/dE6
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
5efdqOuSNf5/lshZmslQAQA=

-->

</rfc>
