rfc9861xml2.original.xml | rfc9861.xml | |||
---|---|---|---|---|
<?xml version="1.0" encoding="US-ASCII"?> | <?xml version='1.0' encoding='UTF-8'?> | |||
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [ | ||||
<!ENTITY rfc2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC | ||||
.2119.xml"> | ||||
<!ENTITY rfc8174 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC | ||||
.8174.xml"> | ||||
]> | ||||
<?rfc toc="yes"?> | ||||
<?rfc symrefs="yes"?> | ||||
<?rfc compact="yes"?> | ||||
<?rfc subcompact="no"?> | ||||
<?rfc strict="no"?> | ||||
<?rfc rfcedstyle="yes"?> | ||||
<?rfc comments="yes"?> | ||||
<?rfc inline="yes"?> | ||||
<rfc category="info" docName="draft-irtf-cfrg-kangarootwelve-17" ipr="trust20090 | ||||
2"> | ||||
<front> | ||||
<title abbrev="KangarooTwelve">KangarooTwelve and TurboSHAKE</title> | ||||
<!-- If the author is acting as editor, use the <role=editor> attribute--> | <!DOCTYPE rfc [ | |||
<!ENTITY nbsp " "> | ||||
<!ENTITY zwsp "​"> | ||||
<!ENTITY nbhy "‑"> | ||||
<!ENTITY wj "⁠"> | ||||
]> | ||||
<!-- see RFC2223 for guidelines regarding author names --> | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="info" docName="draft-i rtf-cfrg-kangarootwelve-17" number="9861" consensus="true" ipr="trust200902" obs oletes="" updates="" submissionType="IRTF" xml:lang="en" tocInclude="true" symRe fs="true" sortRefs="true" version="3"> | |||
<author fullname="Benoît Viguier" initials="B" surname="Viguier"> | <front> | |||
<title abbrev="KangarooTwelve and TurboSHAKE">KangarooTwelve and TurboSHAKE< | ||||
/title> | ||||
<seriesInfo name="RFC" value="9861"/> | ||||
<author fullname="Benoît Viguier" initials="B" surname="Viguier"> | ||||
<organization>ABN AMRO Bank</organization> | <organization>ABN AMRO Bank</organization> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<street>Groenelaan 2</street> | <street>Groenelaan 2</street> | |||
<city>Amstelveen</city> | <city>Amstelveen</city> | |||
<country>The Netherlands</country> | <country>Netherlands</country> | |||
</postal> | </postal> | |||
<email>cs.ru.nl@viguier.nl</email> | <email>cs.ru.nl@viguier.nl</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author fullname="David Wong" initials="D" surname="Wong" role="editor"> | <author fullname="David Wong" initials="D" surname="Wong" role="editor"> | |||
<organization>zkSecurity</organization> | <organization>zkSecurity</organization> | |||
<address> | <address> | |||
<email>davidwong.crypto@gmail.com</email> | <email>davidwong.crypto@gmail.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author fullname="Gilles Van Assche" initials="G" surname="Van Assche" role= "editor"> | <author fullname="Gilles Van Assche" initials="G" surname="Van Assche" role= "editor"> | |||
<organization>STMicroelectronics</organization> | <organization>STMicroelectronics</organization> | |||
<address> | <address> | |||
<email>gilles.vanassche@st.com</email> | <email>gilles.vanassche@st.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author fullname="Quynh Dang" initials="Q" surname="Dang" role="editor"> | <author fullname="Quynh Dang" initials="Q" surname="Dang" role="editor"> | |||
<organization abbrev="NIST">National Institute of Standards and Technology </organization> | <organization abbrev="NIST">National Institute of Standards and Technology </organization> | |||
<address> | <address> | |||
<email>quynh.dang@nist.gov</email> | <email>quynh.dang@nist.gov</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author fullname="Joan Daemen" initials="J" surname="Daemen" role="editor"> | <author fullname="Joan Daemen" initials="J" surname="Daemen" role="editor"> | |||
<organization>Radboud University</organization> | <organization>Radboud University</organization> | |||
<address> | <address> | |||
<email>joan@cs.ru.nl</email> | <email>joan@cs.ru.nl</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<!-- <author fullname="Stanislav V. Smyshlyaev" initials="S" surname="Smyshl | ||||
yaev"> | ||||
<organization>CryptoPro</organization> | ||||
<address> | ||||
<email>smyshsv@gmail.com</email> | ||||
</address> | ||||
</author> --> | ||||
<!-- <author fullname="John Mattsson" initials="J" surname="Mattsson"> | ||||
<organization>Ericsson</organization> | ||||
<address> | ||||
<email>john.mattsson@ericsson.com</email> | ||||
</address> | ||||
</author> --> | ||||
<!-- month and day will be generated automatically by XL2RFC; | ||||
be sure the year is current.--> | ||||
<date year="2025" /> | ||||
<!--WG name at the upperleft corner of the doc, | <date year="2025" month="September"/> | |||
IETF is fine for non-WG IETF submissions --> | ||||
<workgroup>Crypto Forum</workgroup> | <workgroup>Crypto Forum</workgroup> | |||
<keyword>Keccak</keyword> | <keyword>Keccak</keyword> | |||
<keyword>Sakura</keyword> | <keyword>Sakura</keyword> | |||
<keyword>KangarooTwelve</keyword> | <keyword>KangarooTwelve</keyword> | |||
<keyword>TurboSHAKE</keyword> | <keyword>TurboSHAKE</keyword> | |||
<keyword>Cryptographic Hash</keyword> | <keyword>Cryptographic Hash</keyword> | |||
<keyword>eXtendable Output Function</keyword> | <keyword>eXtendable Output Function</keyword> | |||
<abstract> | <abstract> | |||
<t>This document defines four eXtendable Output Functions (XOF), | <t>This document defines four eXtendable-Output Functions (XOFs), | |||
hash functions with output of arbitrary length, named TurboSHAKE128, | hash functions with output of arbitrary length, named TurboSHAKE128, | |||
TurboSHAKE256, KT128 and KT256.</t> | TurboSHAKE256, KT128, and KT256.</t> | |||
<t>All four functions provide efficient and secure hashing primitives, | ||||
<t>All four functions provide efficient and secure hashing primitives, | ||||
and the last two are able to exploit the parallelism of the implementation | and the last two are able to exploit the parallelism of the implementation | |||
in a scalable way.</t> | in a scalable way.</t> | |||
<t>This document is a product of the Crypto Forum Research Group. | ||||
<t>This document is a product of the Crypto Forum Research Group. | ||||
It builds up on the definitions of the permutations and of the | It builds up on the definitions of the permutations and of the | |||
sponge construction in [FIPS 202], and is meant to serve as a stable reference | sponge construction in NIST FIPS 202 and is meant to serve as a stable referen ce | |||
and an implementation guide.</t> | and an implementation guide.</t> | |||
</abstract> | ||||
</abstract> | </front> | |||
</front> | <middle> | |||
<section numbered="true" toc="default"> | ||||
<middle> | <name>Introduction</name> | |||
<section title="Introduction"> | <t>This document defines the TurboSHAKE128, TurboSHAKE256 <xref target="TU | |||
RBOSHAKE" format="default"/>, | ||||
<t>This document defines the TurboSHAKE128, TurboSHAKE256 <xref target="TURB | KT128, and KT256 <xref target="KT" format="default"/> eXtendable-Output Func | |||
OSHAKE"></xref>, | tions (XOFs), | |||
KT128 and KT256 <xref target="KT"></xref> eXtendable Output Functions (XOF), | i.e., hash function generalizations that can return an output of arbitrary l | |||
i.e., a hash function generalization that can return an output of arbitrary | ength. | |||
length. | Both TurboSHAKE128 and TurboSHAKE256 are based on a Keccak-p permutation s | |||
Both TurboSHAKE128 and TurboSHAKE256 are based on a Keccak-p permutation spe | pecified in <xref target="FIPS202" format="default"/> and have a higher speed th | |||
cified in <xref | an the SHA-3 and SHAKE functions.</t> | |||
target="FIPS202"></xref> and have a higher speed than the SHA-3 and SHAKE fu | <t>TurboSHAKE is a sponge function family that makes use of Keccak-p[n_r=1 | |||
nctions.</t> | 2,b=1600], a round-reduced | |||
version of the permutation used in SHA-3. Similarly to the SHAKE's security, | ||||
<t>TurboSHAKE is a sponge function family that makes use of Keccak-p[n_r=12, | it proposes two security strengths: | |||
b=1600], a round-reduced | ||||
version of the permutation used in SHA-3. Similarly to the SHAKE's, it propo | ||||
ses two security strengths: | ||||
128 bits for TurboSHAKE128 and 256 bits for TurboSHAKE256. | 128 bits for TurboSHAKE128 and 256 bits for TurboSHAKE256. | |||
Halving the number of rounds compared to the original SHAKE functions makes TurboSHAKE roughly two times | Halving the number of rounds compared to the original SHAKE functions makes TurboSHAKE roughly two times | |||
faster.</t> | faster.</t> | |||
<t> | ||||
<t> | ||||
KangarooTwelve applies tree hashing on top of TurboSHAKE and comprises two f unctions, KT128 and KT256. | KangarooTwelve applies tree hashing on top of TurboSHAKE and comprises two f unctions, KT128 and KT256. | |||
Note that <xref target="KT"></xref> only defined KT128 under the name Kangar ooTwelve. | Note that <xref target="KT" format="default"/> only defined KT128 under the name KangarooTwelve. | |||
KT256 is defined in this document. | KT256 is defined in this document. | |||
</t> | </t> | |||
<t> | ||||
<t> | ||||
The SHA-3 and SHAKE functions process data in a serial manner and are strong ly | The SHA-3 and SHAKE functions process data in a serial manner and are strong ly | |||
limited in exploiting available parallelism in modern CPU architectures. | limited in exploiting available parallelism in modern CPU architectures. | |||
Similar to ParallelHash <xref target="SP800-185"></xref>, KangarooTwelve spl its | Similar to ParallelHash <xref target="SP800-185" format="default"/>, Kangaro oTwelve splits | |||
the input message into fragments. It then applies TurboSHAKE on each of them | the input message into fragments. It then applies TurboSHAKE on each of them | |||
separately before applying TurboSHAKE again on the combination of the first | separately before applying TurboSHAKE again on the combination of the first | |||
fragment and the digests. | fragment and the digests. | |||
More precisely, KT128 uses TurboSHAKE128 and KT256 uses TurboSHAKE256. | More precisely, KT128 uses TurboSHAKE128 and KT256 uses TurboSHAKE256. | |||
They make use of Sakura coding for ensuring soundness of the tree hashing | They make use of Sakura coding for ensuring soundness of the tree hashing | |||
mode <xref target="SAKURA"/>. | mode <xref target="SAKURA" format="default"/>. | |||
The use of TurboSHAKE in KangarooTwelve makes it faster than ParallelHash.</ t> | The use of TurboSHAKE in KangarooTwelve makes it faster than ParallelHash.</ t> | |||
<t>The security of TurboSHAKE128, TurboSHAKE256, KT128, and KT256 builds o | ||||
<t>The security of TurboSHAKE128, TurboSHAKE256, KT128 and KT256 builds on t | n the public | |||
he public | ||||
scrutiny that Keccak has received since its | scrutiny that Keccak has received since its | |||
publication <xref target="KECCAK_CRYPTANALYSIS"/><xref target="TURBOSHAKE"/> | publication <xref target="KECCAK_CRYPTANALYSIS" format="default"/> <xref tar | |||
.</t> | get="TURBOSHAKE" format="default"/>.</t> | |||
<t>With respect to functions defined in <xref target="FIPS202" format="def | ||||
<t>With respect to <xref target="FIPS202"></xref> and <xref target="SP800-18 | ault"/> and <xref target="SP800-185" format="default"/>, TurboSHAKE128, TurboSHA | |||
5"></xref> | KE256, KT128, and KT256 feature the following advantages:</t> | |||
functions, TurboSHAKE128, TurboSHAKE256, KT128 and KT256 feature the followi | <ul spacing="normal"> | |||
ng advantages:</t> | <li> | |||
<t>Unlike SHA3-224, SHA3-256, SHA3-384, and SHA3-512, the TurboSHAKE a | ||||
<t><list style="symbols"> | nd | |||
<t>Unlike SHA3-224, SHA3-256, SHA3-384, SHA3-512, the TurboSHAKE and | ||||
KangarooTwelve functions have an extendable output.</t> | KangarooTwelve functions have an extendable output.</t> | |||
</li> | ||||
<t>Unlike any <xref target="FIPS202"></xref> defined function, similarly to | <li> | |||
functions defined in <xref target="SP800-185"></xref>, KT128 and KT256 | <t>Unlike any functions in <xref target="FIPS202" format="default"/>, | |||
and similar to | ||||
functions in <xref target="SP800-185" format="default"/>, KT128 and KT256 | ||||
allow the use of a customization string.</t> | allow the use of a customization string.</t> | |||
</li> | ||||
<t>Unlike any <xref target="FIPS202"></xref> and <xref target="SP800-185"></ | <li> | |||
xref> | <t>Unlike any functions in <xref target="FIPS202" format="default"/> a | |||
functions but ParallelHash, KT128 and KT256 exploit available parallelism.</ | nd <xref target="SP800-185" format="default"/> except for ParallelHash, KT128 an | |||
t> | d KT256 exploit available parallelism.</t> | |||
</li> | ||||
<t>Unlike ParallelHash, KT128 and KT256 do not have overhead when | <li> | |||
<t>Unlike ParallelHash, KT128 and KT256 do not have overhead when | ||||
processing short messages.</t> | processing short messages.</t> | |||
</li> | ||||
<t>The permutation in the TurboSHAKE functions has half | <li> | |||
<t>The permutation in the TurboSHAKE functions has half | ||||
the number of rounds compared to the one in the SHA-3 and SHAKE functions, | the number of rounds compared to the one in the SHA-3 and SHAKE functions, | |||
making them faster than any function defined in <xref target="FIPS202"></xre f>. | making them faster than any function defined in <xref target="FIPS202" forma t="default"/>. | |||
The KangarooTwelve functions immediately benefit from the same speedup, impr oving over | The KangarooTwelve functions immediately benefit from the same speedup, impr oving over | |||
<xref target="FIPS202"></xref> and <xref target="SP800-185"></xref>.</t> | <xref target="FIPS202" format="default"/> and <xref target="SP800-185" forma | |||
</list></t> | t="default"/>.</t> | |||
</li> | ||||
<t>With respect to SHA-256 and SHA-512 and other <xref target="FIPS180"/> fu | </ul> | |||
nctions, TurboSHAKE128, TurboSHAKE256, KT128 and KT256 feature the following adv | <t>With respect to SHA-256, SHA-512, and other functions defined in <xref | |||
antages:</t> | target="FIPS180" format="default"/>, TurboSHAKE128, TurboSHAKE256, KT128, and KT | |||
256 feature the following advantages:</t> | ||||
<t><list style="symbols"> | <ul spacing="normal"> | |||
<t>Unlike <xref target="FIPS180"/> functions, the TurboSHAKE and KangarooTwe | <li> | |||
lve functions have an extendable output.</t> | <t>Unlike any functions in <xref target="FIPS180" format="default"/>, | |||
the TurboSHAKE and KangarooTwelve functions have an extendable output.</t> | ||||
<t>The TurboSHAKE functions produce output at the same rate as they process | </li> | |||
input, whereas SHA-256 and SHA-512, when used in a mask generation function (MGF | <li> | |||
) construction, produce output half as fast as they process input.</t> | <t>The TurboSHAKE functions produce output at the same rate as they pr | |||
ocess input, whereas SHA-256 and SHA-512, when used in a mask generation functio | ||||
<t>Unlike the SHA-256 and SHA-512 functions, TurboSHAKE128, TurboSHAKE256, K | n (MGF) construction, produce output half as fast as they process input.</t> | |||
T128 and KT256 do not suffer from the length extension weakness.</t> | </li> | |||
<li> | ||||
<t>Unlike any <xref target="FIPS180"></xref> functions, TurboSHAKE128, Turbo | <t>Unlike the SHA-256 and SHA-512 functions, TurboSHAKE128, TurboSHAKE | |||
SHAKE256, KT128 and KT256 use a round function with algebraic degree 2, which ma | 256, KT128, and KT256 do not suffer from the length extension weakness.</t> | |||
kes them more suitable to masking techniques for protections against side-channe | </li> | |||
l attacks.</t> | <li> | |||
</list></t> | <t>Unlike any functions in <xref target="FIPS180" format="default"/>, | |||
TurboSHAKE128, TurboSHAKE256, KT128, and KT256 use a round function with algebra | ||||
<t>This document represents the consensus of the Crypto Forum Research Group | ic degree 2, which makes them more suitable to masking techniques for protection | |||
(CFRG) | s against side-channel attacks.</t> | |||
in the IRTF. It is not an IETF product and is not a standard.</t> | </li> | |||
</ul> | ||||
<section title="Conventions"> | <t>This document represents the consensus of the Crypto Forum Research Gro | |||
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | up | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | (CFRG) in the IRTF. It has been reviewed by two members of the Crypto Review | |||
document are to be interpreted as described in BCP 14 <xref target="RFC211 | Panel, as well as by several members of the CFRG. It is not an IETF product | |||
9"></xref> <xref target="RFC8174"></xref> | and is not a standard. | |||
when, and only when, they appear in all capitals, as shown here.</t> | </t> | |||
<section numbered="true" toc="default"> | ||||
<t>The following notations are used throughout the document:</t> | <name>Conventions</name> | |||
<t> | ||||
<t><list style="hanging"> | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQU | |||
<t hangText="`...`">denotes a string of bytes given in | IRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | |||
hexadecimal. For example, `0B 80`.</t> | NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14> | |||
RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | ||||
<t hangText="|s|">denotes the length of a byte string `s`. | "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to | |||
For example, |`FF FF`| = 2.</t> | be interpreted as | |||
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | ||||
<t hangText="`00`^b">denotes a byte string consisting of the concatenati | when, and only when, they appear in all capitals, as shown here. | |||
on | </t> | |||
of b bytes `00`. For example, `00`^7 = `00 00 00 00 00 00 00`.</t> | <t>The following notations are used throughout the document:</t> | |||
<ul spacing="normal"> | ||||
<t hangText="`00`^0">denotes the empty byte-string.</t> | <li>`...` denotes a string of bytes given in | |||
hexadecimal. For example, `0B 80`.</li> | ||||
<t hangText="a||b">denotes the concatenation of two strings a and b. | <li>|s| denotes the length of a byte string `s`. | |||
For example, `10`||`F1` = `10 F1`</t> | For example, |`FF FF`| = 2.</li> | |||
<li>`00`^b denotes a byte string consisting of the concatenation | ||||
<t hangText="s[n:m]">denotes the selection of bytes from n (inclusive) t | of b bytes `00`. For example, `00`^7 = `00 00 00 00 00 00 00`.</li> | |||
o m | <li>`00`^0 denotes the empty byte string.</li> | |||
(exclusive) of a string s. The indexing of a byte-string starts at 0. | <li>a||b denotes the concatenation of two strings, a and b. | |||
For example, for s = `A5 C6 D7`, s[0:1] = `A5` and s[1:3] = `C6 D7`.</t> | For example, `10`||`F1` = `10 F1`.</li> | |||
<li>s[n:m] denotes the selection of bytes from n (inclusive) to m | ||||
<t hangText="s[n:]">denotes the selection of bytes from n to the end of | (exclusive) of a string s. The indexing of a byte string starts at 0. | |||
For example, for s = `A5 C6 D7`, s[0:1] = `A5` and s[1:3] = `C6 D7`.</li | ||||
> | ||||
<li>s[n:] denotes the selection of bytes from n to the end of | ||||
a string s. | a string s. | |||
For example, for s = `A5 C6 D7`, s[0:] = `A5 C6 D7` and s[2:] = `D7`.</t | For example, for s = `A5 C6 D7`, s[0:] = `A5 C6 D7` and s[2:] = `D7`.</l | |||
> | i> | |||
</list></t> | </ul> | |||
<t>In the following, x and y are byte strings of equal length:</t> | ||||
<t>In the following, x and y are byte strings of equal length:</t> | <ul spacing="normal"> | |||
<li>x^=y denotes x takes the value x XOR y.</li> | ||||
<t><list style="hanging"> | <li>x & y denotes x AND y.</li> | |||
<t hangText="x^=y"> denotes x takes the value x XOR y.</t> | </ul> | |||
<t>In the following, x and y are integers:</t> | ||||
<t hangText="x & y"> denotes x AND y.</t> | <ul spacing="normal"> | |||
</list></t> | <li>x+=y denotes x takes the value x + y.</li> | |||
<li>x-=y denotes x takes the value x - y.</li> | ||||
<t>In the following, x and y are integers:</t> | <li>x**y denotes the exponentiation of x by y.</li> | |||
<li>x mod y denotes the remainder of the division of x by y.</li> | ||||
<t><list style="hanging"> | <li>x / y denotes the integer dividend of the division of x by y.</li> | |||
<t hangText="x+=y"> denotes x takes the value x + y.</t> | </ul> | |||
</section> | ||||
<t hangText="x-=y"> denotes x takes the value x - y.</t> | ||||
<t hangText="x**y"> denotes the exponentiation of x by y.</t> | ||||
<t hangText="x mod y"> denotes the remainder of the division of x by y.< | ||||
/t> | ||||
<t hangText="x / y"> denotes the integer dividend of the division of x b | ||||
y y.</t> | ||||
</list></t> | ||||
</section> | </section> | |||
</section> | <section numbered="true" toc="default"> | |||
<name>TurboSHAKE</name> | ||||
<section title="TurboSHAKE"> | <section anchor="TurboSHAKE_Interface" numbered="true" toc="default"> | |||
<section anchor="TurboSHAKE_Interface" title="Interface"> | <name>Interface</name> | |||
<t>TurboSHAKE is a family of eXtendable Output Functions (XOF). | <t>TurboSHAKE is a family of eXtendable-Output Functions (XOFs). | |||
Internally, it makes use of the sponge construction, parameterized by tw o integers, the rate and the capacity, that sum to the permutation width (here, 1600 bits). | Internally, it makes use of the sponge construction, parameterized by tw o integers, the rate and the capacity, that sum to the permutation width (here, 1600 bits). | |||
The rate gives the number of bits processed or produced per call to the | The rate gives the number of bits processed or produced per call to the | |||
permutation, whereas the capacity determines the security level, see <xref targe | permutation, whereas the capacity determines the security level; see <xref targe | |||
t="FIPS202"/> for more details. | t="FIPS202" format="default"/> for more details. | |||
This document focuses on only two instances, namely, TurboSHAKE128 and T | This document focuses on only two instances, namely TurboSHAKE128 and Tu | |||
urboSHAKE256. | rboSHAKE256. | |||
(Note that the original definition includes a wider range of instances p | (Note that the original definition includes a wider range of instances p | |||
arameterized by their capacity <xref target="TURBOSHAKE"/>.) | arameterized by their capacity <xref target="TURBOSHAKE" format="default"/>.) | |||
</t> | </t> | |||
<t> | ||||
<t> | A TurboSHAKE instance takes a byte string M, an <bcp14>OPTIONAL</bcp14> by | |||
An instance of TurboSHAKE takes as input parameters a byte-string M, an OP | te D, and a positive integer L as input parameters, where:</t> | |||
TIONAL byte D and a positive integer L | <ul spacing="normal"> | |||
where<list style="hanging"> | <li>M byte string is the message,</li> | |||
<t hangText="M"> byte-string, is the Message and</t> | <li>D byte in the range [`01`, `02`, .. , `7F`] is an <bcp14>OPTIONAL< | |||
<t hangText="D"> byte in the range [`01`, `02`, .. , `7F`], is an OPTION | /bcp14> domain separation byte, and</li> | |||
AL Domain separation byte and</t> | <li>L positive integer is the requested number of output bytes.</li> | |||
<t hangText="L"> positive integer, is the requested number of output byt | </ul> | |||
es.</t> | <t> | |||
</list></t> | Conceptually, an XOF can be viewed as a hash function with an infinitely l | |||
ong output truncated to L bytes. | ||||
<t> | This means that calling an XOF with the same input parameters but two diff | |||
Conceptually, a XOF can be viewed as a hash function with an infinitely lo | erent lengths yields outputs such that the shorter one is a prefix of the longer | |||
ng output truncated to L bytes. | one. | |||
This means that calling a XOF with the same input parameters but two diffe | ||||
rent lengths yields outputs such that the shorter one is a prefix of the longer | ||||
one. | ||||
Specifically, if L1 < L2, then TurboSHAKE(M, D, L1) is the same as the first L1 bytes of TurboSHAKE(M, D, L2). | Specifically, if L1 < L2, then TurboSHAKE(M, D, L1) is the same as the first L1 bytes of TurboSHAKE(M, D, L2). | |||
</t> | </t> | |||
<t>By default, the domain separation byte is `1F`. For an API that | ||||
<t>By default, the Domain separation byte is `1F`. For an API that | does not support a domain separation byte, D <bcp14>MUST</bcp14> be the `1 | |||
does not support a domain separation byte, D MUST be the `1F`.</t> | F`.</t> | |||
<t> | <t> | |||
The TurboSHAKE instance produces output that is a hash of the (M, D) coupl e. | The TurboSHAKE instance produces output that is a hash of the (M, D) coupl e. | |||
If D is fixed, this becomes a hash of the Message M. | If D is fixed, this becomes a hash of the message M. | |||
However, a protocol that requires a number of independent hash functions c an choose different values for D to implement these. | However, a protocol that requires a number of independent hash functions c an choose different values for D to implement these. | |||
Specifically, for any distinct values D1 and D2, TurboSHAKE(M, D1, L1) and | Specifically, for distinct values D1 and D2, TurboSHAKE(M, D1, L1) and Tur | |||
TurboSHAKE(M, D2, L2) yield independent hashes of M. | boSHAKE(M, D2, L2) yield independent hashes of M. | |||
</t> | </t> | |||
<t> | ||||
<t> | Note that an implementation <bcp14>MAY</bcp14> propose an incremental inpu | |||
Note that an implementation MAY propose an incremental input interface whe | t interface where the input string M is given in pieces. | |||
re the input string M is given in pieces. | If so, the output <bcp14>MUST</bcp14> be the same as if the function was c | |||
If so, the output MUST be the same as if the function was called with M eq | alled with M equal to the concatenation of the different pieces in the order the | |||
ual to the concatenation of the different pieces in the order they were given. | y were given. | |||
Independently, an implementation MAY propose an incremental output interfa | Independently, an implementation <bcp14>MAY</bcp14> propose an incremental | |||
ce where the output string is requested in pieces of given lengths. | output interface where the output string is requested in pieces of given length | |||
When the output is formed by concatenating the pieces in the requested ord | s. | |||
er, it MUST be the same as if the function was called with L equal to the sum of | When the output is formed by concatenating the pieces in the requested ord | |||
the given lengths. | er, it <bcp14>MUST</bcp14> be the same as if the function was called with L equa | |||
</t> | l to the sum of the given lengths. | |||
</t> | ||||
</section> | </section> | |||
<section numbered="true" toc="default"> | ||||
<section title="Specifications"> | <name>Specifications</name> | |||
<t>TurboSHAKE makes use of the permutation Keccak-p[1600,n_r=12], | <t>TurboSHAKE makes use of the permutation Keccak-p[1600,n_r=12], | |||
i.e., the permutation used in SHAKE and SHA-3 functions reduced | i.e., the permutation used in SHAKE and SHA-3 functions reduced | |||
to its last n_r=12 rounds and specified in FIPS 202, Sections | to its last n_r=12 rounds as specified in FIPS 202; see Sections | |||
3.3 and 3.4 <xref target="FIPS202"></xref>. | 3.3 and 3.4 of <xref target="FIPS202" format="default"/>. | |||
KP denotes this permutation.</t> | KP denotes this permutation.</t> | |||
<t>Similarly to SHAKE128, TurboSHAKE128 is a sponge function | ||||
<t>Similarly to SHAKE128, TurboSHAKE128 is a sponge function | ||||
calling this permutation KP with a rate of 168 bytes | calling this permutation KP with a rate of 168 bytes | |||
or 1344 bits. It follows that TurboSHAKE128 has a capacity of | or 1344 bits. It follows that TurboSHAKE128 has a capacity of | |||
1600 - 1344 = 256 bits or 32 bytes. Respectively to SHAKE256, TurboSHAKE25 6 makes use | 1600 - 1344 = 256 bits or 32 bytes. Respectively to SHAKE256, TurboSHAKE25 6 makes use | |||
of a rate of 136 bytes or 1088 bits, and has a capacity of 512 bits or 64 | of a rate of 136 bytes or 1088 bits and has a capacity of 512 bits or 64 b | |||
bytes.</t> | ytes.</t> | |||
<t><figure><artwork><![CDATA[ | ||||
+-------------+--------------+ | ||||
| Rate | Capacity | | ||||
+----------------+-------------+--------------+ | ||||
| TurboSHAKE128 | 168 Bytes | 32 Bytes | | ||||
| | | | | ||||
| TurboSHAKE256 | 136 Bytes | 64 Bytes | | ||||
+----------------+-------------+--------------+]]></artwork> | ||||
</figure></t> | ||||
<t>We now describe the operations inside TurboSHAKE128.<list style="symbol | <table> | |||
s"> | <thead> | |||
<t>First the input M' is formed by appending the domain separation byte | <tr> | |||
D to the message M.</t> | <td></td> | |||
<th>Rate</th> | ||||
<th>Capacity</th> | ||||
</tr> | ||||
</thead> | ||||
<tbody> | ||||
<tr> | ||||
<th>TurboSHAKE128</th> | ||||
<td>168 Bytes</td> | ||||
<td>32 Bytes</td> | ||||
</tr> | ||||
<tr> | ||||
<th>TurboSHAKE256</th> | ||||
<td>136 Bytes</td> | ||||
<td>64 Bytes</td> | ||||
</tr> | ||||
</tbody> | ||||
</table> | ||||
<t> | <t>We now describe the operations inside TurboSHAKE128.</t> | |||
If the length of M' is not a multiple of 168 bytes then it is padded w | <ul spacing="normal"> | |||
ith zeros at the end to make it a multiple of 168 bytes. | <li> | |||
If M' is already a multiple of 168 bytes then no padding is added. | <t>First, the input M' is formed by appending the domain separation | |||
Then a byte `80` is XORed to the last byte of the padded input M' | byte D to the message M.</t> | |||
</li> | ||||
<li> | ||||
<t> | ||||
If the length of M' is not a multiple of 168 bytes, then it is padded | ||||
with zeros at the end to make it a multiple of 168 bytes. | ||||
If M' is already a multiple of 168 bytes, then no padding is added. | ||||
Then, a byte `80` is XORed to the last byte of the padded input M' | ||||
and the resulting string is split into a sequence of 168-byte blocks. | and the resulting string is split into a sequence of 168-byte blocks. | |||
</t> | </t> | |||
</li> | ||||
<t>M' never has a length of 0 bytes due to the presence of the domain se | <li> | |||
paration byte.</t> | <t>M' never has a length of 0 bytes due to the presence of the domai | |||
n separation byte.</t> | ||||
<t>As defined by the sponge construction, the process operates on a stat | </li> | |||
e | <li> | |||
and consists of two phases: the absorbing phase that processes the padde | <t>As defined by the sponge construction, the process operates on a | |||
d input M' | state | |||
and the squeezing phase that produces the output.</t> | and consists of two phases: the absorbing phase, which processes the pad | |||
ded input M', | ||||
<t>In the absorbing phase the state is initialized to all-zero. The | and the squeezing phase, which produces the output.</t> | |||
</li> | ||||
<li> | ||||
<t>In the absorbing phase, the state is initialized to all zero. The | ||||
message blocks are XORed into the first 168 bytes of the state. | message blocks are XORed into the first 168 bytes of the state. | |||
Each block absorbed is followed with an application of KP to the state.< /t> | Each block absorbed is followed with an application of KP to the state.< /t> | |||
</li> | ||||
<t> In the squeezing phase the output is formed by taking the first 168 | <li> | |||
bytes of the state, | <t> In the squeezing phase, the output is formed by taking the first | |||
168 bytes of the state, | ||||
applying KP to the state, and repeating as many times as is necessary. </t> | applying KP to the state, and repeating as many times as is necessary. </t> | |||
</list></t> | </li> | |||
</ul> | ||||
<t>TurboSHAKE256 performs the same steps but makes use of 136-byte blocks wi | <t>TurboSHAKE256 performs the same steps but makes use of 136-byte block | |||
th respect | s with respect | |||
to the padding, absorbing, and squeezing phases.</t> | to the padding, absorbing, and squeezing phases.</t> | |||
<t> | ||||
<t> | The definition of the TurboSHAKE functions equivalently implements the pad10 | |||
The definition of the TurboSHAKE functions equivalently implements the pad10 | *1 rule; see Section 5.1 of <xref target="FIPS202" format="default"/> for a defi | |||
*1 rule; see Section 5.1 of <xref target="FIPS202"/> for a definition of pad10*1 | nition of pad10*1. | |||
. | ||||
While M can be empty, the D byte is always present and is in the `01`-`7F` r ange. | While M can be empty, the D byte is always present and is in the `01`-`7F` r ange. | |||
This last byte serves as domain separation and integrates the first bit of p adding | This last byte serves as domain separation and integrates the first bit of p adding | |||
of the pad10*1 rule (hence it cannot be `00`). | of the pad10*1 rule (hence, it cannot be `00`). | |||
Additionally, it must leave room for the second bit of padding | Additionally, it must leave room for the second bit of padding | |||
(hence it cannot have the MSB set to 1), should it be the last byte of the b | (hence, it cannot have the most significant bit (MSB) set to 1), should it b | |||
lock. | e the last byte of the block. | |||
For more details, refer to Section 6.1 of <xref target="KT"></xref> and Sect | For more details, refer to Section 6.1 of <xref target="KT" format="default" | |||
ion 3 of <xref target="TURBOSHAKE"></xref>.</t> | /> and Section 3 of <xref target="TURBOSHAKE" format="default"/>.</t> | |||
<t>The pseudocode versions of TurboSHAKE128 and TurboSHAKE256 are provid | ||||
<t>The pseudocode versions of TurboSHAKE128 and TurboSHAKE256 are provided r | ed in Appendices <xref target="TSHK128_PC" format="counter"/> and <xref target=" | |||
espectively in <xref target="TSHK128_PC"/> and <xref target="TSHK256_PC"/>.</t> | TSHK256_PC" format="counter"/>, respectively.</t> | |||
</section> | ||||
</section> | </section> | |||
</section> | <section numbered="true" toc="default"> | |||
<name>KangarooTwelve: Tree Hashing over TurboSHAKE</name> | ||||
<section title="KangarooTwelve: Tree hashing over TurboSHAKE"> | <section numbered="true" toc="default"> | |||
<name>Interface</name> | ||||
<section title="Interface"> | <t>KangarooTwelve is a family of eXtendable-Output Functions (XOFs) cons | |||
<t>KangarooTwelve is a family of eXtendable Output Functions (XOF) consist | isting of the KT128 and KT256 instances. | |||
ing of the KT128 and KT256 instances. | A KangarooTwelve instance takes two byte strings (M, C) and a positive int | |||
A KangarooTwelve instance takes as input parameters two byte-strings (M, C | eger L as input parameters, where:</t> | |||
) and a positive integer L | <ul spacing="normal"> | |||
where <list style="hanging"> | <li>M byte string is the message,</li> | |||
<t hangText="M"> byte-string, is the Message and</t> | <li>C byte string is an <bcp14>OPTIONAL</bcp14> customization string, | |||
<t hangText="C"> byte-string, is an OPTIONAL Customization string and</t> | and</li> | |||
<t hangText="L"> positive integer, the requested number of output bytes.</ | <li>L positive integer is the requested number of output bytes.</li> | |||
t> | </ul> | |||
</list></t> | <t>The customization string <bcp14>MAY</bcp14> serve as domain separatio | |||
n. | ||||
<t>The Customization string MAY serve as domain separation. | It is typically a short string such as a name or an identifier (e.g., UR | |||
It is typically a short string such as a name or an identifier (e.g. URI | I, | |||
, | Original Dialog Identifier (ODI), etc.). | |||
ODI...). | It can serve the same purpose as TurboSHAKE's D input parameter (see <xr | |||
It can serve the same purpose as TurboSHAKE's D input parameter (see <xr | ef target="TurboSHAKE_Interface" format="default"/>) but with a larger range. | |||
ef target="TurboSHAKE_Interface"/>), but with a larger range. | ||||
</t> | </t> | |||
<t>By default, the customization string is the empty string. For an API | ||||
<t>By default, the Customization string is the empty string. For an API | that | |||
that | does not support a customization string parameter, C <bcp14>MUST</bcp14> | |||
does not support a customization string parameter, C MUST be the empty s | be the empty string.</t> | |||
tring.</t> | <t>Note that an implementation <bcp14>MAY</bcp14> propose an interface w | |||
ith the input and/or output provided incrementally, as specified in <xref target | ||||
<t>Note that an implementation MAY propose an interface with the input a | ="TurboSHAKE_Interface" format="default"/>.</t> | |||
nd/or output provided incrementally as specified in <xref target="TurboSHAKE_Int | </section> | |||
erface"/>.</t> | <section numbered="true" toc="default"> | |||
</section> | <name>Specification of KT128</name> | |||
<section title="Specification of KT128"> | ||||
<t>On top of the sponge function TurboSHAKE128, KT128 uses a | <t>On top of the sponge function TurboSHAKE128, KT128 uses a | |||
Sakura-compatible tree hash mode <xref target="SAKURA"></xref>. | Sakura-compatible tree hash mode <xref target="SAKURA" format="default"/ | |||
First, merge M and the OPTIONAL C to a single input string S in a | >. | |||
reversible way. length_encode( |C| ) gives the length in bytes of C as a | First, merge M and the <bcp14>OPTIONAL</bcp14> C to a single input strin | |||
byte-string. | g S in a | |||
See <xref target="RE"/>.</t> | reversible way. length_encode( |C| ) gives the length in bytes of C | |||
as a | ||||
byte string. | ||||
See <xref target="RE" format="default"/>.</t> | ||||
<t><figure><artwork><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
S = M || C || length_encode( |C| ) ]]></artwork></figure></t> | S = M || C || length_encode( |C| )]]></artwork> | |||
<t>Then, split S into n chunks of 8192 bytes.</t> | <t>Then, split S into n chunks of 8192 bytes.</t> | |||
<t><figure><artwork><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
S = S_0 || .. || S_(n-1) | S = S_0 || .. || S_(n-1) | |||
|S_0| = .. = |S_(n-2)| = 8192 bytes | |S_0| = .. = |S_(n-2)| = 8192 bytes | |||
|S_(n-1)| <= 8192 bytes ]]></artwork></figure></t> | |S_(n-1)| <= 8192 bytes]]></artwork> | |||
<t>From S_1 .. S_(n-1), compute the 32-byte Chaining Values CV_1 .. CV_( | <t>From S_1 .. S_(n-1), compute the 32-byte chaining values CV_1 .. CV_( | |||
n-1). | n-1). | |||
In order to be optimally efficient, this computation MAY exploit the | In order to be optimally efficient, this computation <bcp14>MAY</bcp14> | |||
parallelism available on the platform such as SIMD instructions.</t> | exploit the | |||
parallelism available on the platform, such as single instruction, multi | ||||
ple data (SIMD) instructions.</t> | ||||
<t><figure><artwork><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
CV_i = TurboSHAKE128( S_i, `0B`, 32 )]]></artwork></figure></t> | CV_i = TurboSHAKE128( S_i, `0B`, 32 )]]></artwork> | |||
<t>Compute the final node: FinalNode. | <t>Compute the final node: FinalNode.</t> | |||
<list style="symbols"> | ||||
<t>If |S| <= 8192 bytes, FinalNode = S</t> | ||||
<t>Otherwise compute FinalNode as follows:</t> | ||||
</list></t> | ||||
<t><figure><artwork><![CDATA[ | <ul spacing="normal"> | |||
<li> | ||||
<t>If |S| <= 8192 bytes, FinalNode = S.</t> | ||||
</li> | ||||
<li> | ||||
<t>Otherwise, compute FinalNode as follows:</t> | ||||
</li> | ||||
</ul> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
FinalNode = S_0 || `03 00 00 00 00 00 00 00` | FinalNode = S_0 || `03 00 00 00 00 00 00 00` | |||
FinalNode = FinalNode || CV_1 | FinalNode = FinalNode || CV_1 | |||
.. | .. | |||
FinalNode = FinalNode || CV_(n-1) | FinalNode = FinalNode || CV_(n-1) | |||
FinalNode = FinalNode || length_encode(n-1) | FinalNode = FinalNode || length_encode(n-1) | |||
FinalNode = FinalNode || `FF FF`]]></artwork></figure></t> | FinalNode = FinalNode || `FF FF`]]></artwork> | |||
<t>Finally, the KT128 output is retrieved: | <t>Finally, the KT128 output is retrieved:</t> | |||
<list style="symbols"> | <ul spacing="normal"> | |||
<t>If |S| <= 8192 bytes, from TurboSHAKE128( FinalNode, `07`, L ) | <li><t>If |S| <= 8192 bytes, from TurboSHAKE128( FinalNode, `07`, L | |||
</t> | )</t> | |||
</list></t> | ||||
<t><figure> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
<artwork><![CDATA[ | KT128( M, C, L ) = TurboSHAKE128( FinalNode, `07`, L )]]></artwork> | |||
KT128( M, C, L ) = TurboSHAKE128( FinalNode, `07`, L )]]> | </li> | |||
</artwork></figure></t> | ||||
<t><list style="symbols"> | <li><t>Otherwise, from TurboSHAKE128( FinalNode, `06`, L )</t> | |||
<t>Otherwise from TurboSHAKE128( FinalNode, `06`, L )</t> | ||||
</list></t> | ||||
<t><figure> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
<artwork><![CDATA[ | KT128( M, C, L ) = TurboSHAKE128( FinalNode, `06`, L )]]></artwork> | |||
KT128( M, C, L ) = TurboSHAKE128( FinalNode, `06`, L )]]> | </li> | |||
</artwork></figure></t> | </ul> | |||
<t>The following figure illustrates the computation flow of KT128 | <t>The following figure illustrates the computation flow of KT128 | |||
for |S| <= 8192 bytes:</t> | for |S| <= 8192 bytes:</t> | |||
<t><figure><artwork><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
+--------------+ TurboSHAKE128(.., `07`, L) | +--------------+ TurboSHAKE128(.., `07`, L) | |||
| S |-----------------------------> output | | S |-----------------------------> output | |||
+--------------+]]></artwork></figure></t> | +--------------+]]></artwork> | |||
<t>The following figure illustrates the computation flow of KT128 | ||||
<t>The following figure illustrates the computation flow of KT128 | for |S| > 8192 bytes and where TurboSHAKE128 and length_encode( x& | |||
for |S| > 8192 bytes and where TurboSHAKE128 and length_encode( x& | nbsp;) are | |||
#160;) are | abbreviated as TSHK128 and l_e( x ), respectively:</t> | |||
abbreviated as respectively TSHK128 and l_e( x ) :</t> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
<t><figure><artwork><![CDATA[ | ||||
+--------------+ | +--------------+ | |||
| S_0 | | | S_0 | | |||
+--------------+ | +--------------+ | |||
|| | || | |||
+--------------+ | +--------------+ | |||
| `03`||`00`^7 | | | `03`||`00`^7 | | |||
+--------------+ | +--------------+ | |||
|| | || | |||
+---------+ TSHK128(..,`0B`,32) +--------------+ | +---------+ TSHK128(..,`0B`,32) +--------------+ | |||
| S_1 |---------------------->| CV_1 | | | S_1 |---------------------->| CV_1 | | |||
skipping to change at line 470 ¶ | skipping to change at line 430 ¶ | |||
+---------+ +--------------+ | +---------+ +--------------+ | |||
|| | || | |||
+--------------+ | +--------------+ | |||
| l_e( n-1 ) | | | l_e( n-1 ) | | |||
+--------------+ | +--------------+ | |||
|| | || | |||
+--------------+ | +--------------+ | |||
| `FF FF` | | | `FF FF` | | |||
+--------------+ | +--------------+ | |||
| TSHK128(.., `06`, L) | | TSHK128(.., `06`, L) | |||
+--------------------> output]]></artw | +--------------------> output]]></artw | |||
ork></figure></t> | ork> | |||
<t>A pseudocode version is provided in <xref target="KT128_PC"/>.</t> | ||||
<t>The table below gathers the values of the domain separation | <t>A pseudocode version is provided in <xref target="KT128_PC" format="d | |||
efault"/>.</t> | ||||
<t>The table below gathers the values of the domain separation | ||||
bytes used by the tree hash mode:</t> | bytes used by the tree hash mode:</t> | |||
<t><figure><artwork><![CDATA[ | <table> | |||
+--------------------+------------------+ | <thead> | |||
| Type | Byte | | <tr> | |||
+--------------------+------------------+ | <th>Type</th> | |||
| SingleNode | `07` | | <th>Byte</th> | |||
| | | | </tr> | |||
| IntermediateNode | `0B` | | </thead> | |||
| | | | <tbody> | |||
| FinalNode | `06` | | <tr> | |||
+--------------------+------------------+]]></artwork> | <td>SingleNode</td> | |||
</figure></t> | <td>`07`</td> | |||
</section> | </tr> | |||
<tr> | ||||
<section anchor="RE" title="length_encode( x )"> | <td>IntermediateNode</td> | |||
<td>`0B`</td> | ||||
</tr> | ||||
<tr> | ||||
<td>FinalNode</td> | ||||
<td>`06`</td> | ||||
</tr> | ||||
</tbody> | ||||
</table> | ||||
<t>The function length_encode takes as inputs a non-negative integer x | </section> | |||
<section anchor="RE" numbered="true" toc="default"> | ||||
<name>length_encode( x )</name> | ||||
<t>The function length_encode takes as inputs a non-negative integer x | ||||
< 256**255 and outputs a string of bytes x_(n-1) || .. || x_0 || n wher e</t> | < 256**255 and outputs a string of bytes x_(n-1) || .. || x_0 || n wher e</t> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
<t><figure> | x = sum of 256**i * x_i for i from 0 to n-1]]></artwork> | |||
<artwork><![CDATA[ | <t>and where n is the smallest non-negative integer such that x < 256 | |||
x = sum of 256**i * x_i for i from 0 to n-1]]></artwork></figure></t> | **n. | |||
<t>and where n is the smallest non-negative integer such that x < 256** | ||||
n. | ||||
n is also the length of x_(n-1) || .. || x_0.</t> | n is also the length of x_(n-1) || .. || x_0.</t> | |||
<t>For example, length_encode(0) = `00`, length_encode(12) = `0C 01`, an | ||||
<t>As example, length_encode(0) = `00`, length_encode(12) = `0C 01` and | d | |||
length_encode(65538) = `01 00 02 03`</t> | length_encode(65538) = `01 00 02 03`.</t> | |||
<t>A pseudocode version is as follows, where { b } denotes the byte of n | ||||
<t>A pseudocode version is as follows where { b } denotes the byte of nume | umerical value b.</t> | |||
rical value b.</t> | <sourcecode type="pseudocode"><![CDATA[ | |||
<t><figure><artwork><![CDATA[ | ||||
length_encode(x): | length_encode(x): | |||
S = `00`^0 | S = `00`^0 | |||
while x > 0 | while x > 0 | |||
S = { x mod 256 } || S | S = { x mod 256 } || S | |||
x = x / 256 | x = x / 256 | |||
S = S || { |S| } | S = S || { |S| } | |||
return S | return S | |||
end]]></artwork></figure></t> | end]]></sourcecode> | |||
</section> | ||||
</section> | <section numbered="true" toc="default"> | |||
<name>Specification of KT256</name> | ||||
<section title="Specification of KT256"> | <t>KT256 is specified exactly like KT128, with two differences:</t> | |||
<t>KT256 is specified exactly like KT128, with two differences:</t> | <ul spacing="normal"> | |||
<list style="symbols"> | <li> | |||
<t>All the calls to TurboSHAKE128 in KT128 are replaced with calls to Tu | <t>All the calls to TurboSHAKE128 in KT128 are replaced with calls t | |||
rboSHAKE256 in KT256.</t> | o TurboSHAKE256 in KT256.</t> | |||
<t>The chaining values CV_1 to CV_(n-1) are 64-byte long in KT256 and ar | </li> | |||
e computed as follows:</t> | <li> | |||
</list> | <t>The chaining values CV_1 to CV_(n-1) are 64 bytes long in KT256 a | |||
<t><figure><artwork><![CDATA[ | nd are computed as follows:</t> | |||
CV_i = TurboSHAKE256( S_i, `0B`, 64 )]]></artwork></figure></t> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
CV_i = TurboSHAKE256( S_i, `0B`, 64 )]]></artwork> | ||||
<t>A pseudocode version is provided in <xref target="KT256_PC"/>.</t> | </li> | |||
</ul> | ||||
<t>A pseudocode version is provided in <xref target="KT256_PC" format="d | ||||
efault"/>.</t> | ||||
</section> | ||||
</section> | </section> | |||
</section> | <section numbered="true" toc="default"> | |||
<name>Message Authentication Codes</name> | ||||
<section title="Message authentication codes"> | <t>Implementing a Message Authentication Code (MAC) with KT128 or KT256 <b | |||
<t>Implementing a MAC with KT128 or KT256 MAY use a hash-then-MAC constructi | cp14>MAY</bcp14> use a hash-then-MAC construction. | |||
on. | ||||
This document defines and recommends a method called HopMAC:</t> | This document defines and recommends a method called HopMAC:</t> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
<t><figure> | ||||
<artwork><![CDATA[ | ||||
HopMAC128(Key, M, C, L) = KT128(Key, KT128(M, C, 32), L) | HopMAC128(Key, M, C, L) = KT128(Key, KT128(M, C, 32), L) | |||
HopMAC256(Key, M, C, L) = KT256(Key, KT256(M, C, 64), L)]]></artwork> | HopMAC256(Key, M, C, L) = KT256(Key, KT256(M, C, 64), L)]]></artwork> | |||
</figure></t> | <t>Similarly to Hashed Message Authentication Code (HMAC), HopMAC consists | |||
of two calls: an inner call compressing the | ||||
<t>Similarly to HMAC, HopMAC consists of two calls: an inner call compressin | message M and the optional customization string C to a digest | |||
g the | ||||
message M and the optional customization string C to a digest, | ||||
and an outer call computing the tag from the key and the digest.</t> | and an outer call computing the tag from the key and the digest.</t> | |||
<t>Unlike HMAC, the inner call to KangarooTwelve in HopMAC is keyless | ||||
<t>Unlike HMAC, the inner call to KangarooTwelve in HopMAC is keyless | and does not require additional protection against side channel attacks (S | |||
and does not require additional protection against side channel attacks (S | CAs). | |||
CA). | ||||
Consequently, in an implementation that has to protect the HopMAC key | Consequently, in an implementation that has to protect the HopMAC key | |||
against SCA only the outer call does need protection, | against an SCA, only the outer call needs protection, | |||
and this amounts to a single execution of the underlying permutation (assu ming the key length is at most 69 bytes).</t> | and this amounts to a single execution of the underlying permutation (assu ming the key length is at most 69 bytes).</t> | |||
<t>In any case, TurboSHAKE128, TurboSHAKE256, KT128, and KT256 | ||||
<t>In any case, TurboSHAKE128, TurboSHAKE256, KT128 and KT256 | <bcp14>MAY</bcp14> be used to compute a MAC with the key | |||
MAY be used to compute a MAC with the key | reversibly prepended or appended to the input. For instance, one <bcp14>MA | |||
reversibly prepended or appended to the input. For instance, one MAY | Y</bcp14> | |||
compute a MAC on short messages simply calling KT128 with the | compute a MAC on short messages simply calling KT128 with the | |||
key as the customization string, i.e., MAC = KT128(M, Key, L).</t> | key as the customization string, i.e., MAC = KT128(M, Key, L).</t> | |||
</section> | </section> | |||
<section numbered="true" toc="default"> | ||||
<section title="Test vectors"> | <name>Test Vectors</name> | |||
<t>Test vectors are based on the repetition of the pattern `00 01 02 .. F9 | ||||
<t>Test vectors are based on the repetition of the pattern `00 01 02 .. F9 F | FA` | |||
A` | ||||
with a specific length. ptn(n) defines a string by repeating the pattern | with a specific length. ptn(n) defines a string by repeating the pattern | |||
`00 01 02 .. F9 FA` as many times as necessary and truncated to n bytes e.g. | `00 01 02 .. F9 FA` as many times as necessary and truncated to n bytes, for | |||
</t> | example: | |||
</t> | ||||
<t><figure><artwork><![CDATA[ Pattern for a length of 17 bytes: | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
Pattern for a length of 17 bytes: | ||||
ptn(17) = | ptn(17) = | |||
`00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10`]]></artwork></figure> | `00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10`]]></artwork> | |||
</t> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
Pattern for a length of 17**2 bytes: | ||||
<t><figure><artwork><![CDATA[ Pattern for a length of 17**2 bytes: | ||||
ptn(17**2) = | ptn(17**2) = | |||
`00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | `00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F | 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F | |||
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F | 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F | |||
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F | 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F | |||
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F | 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F | |||
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F | 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F | |||
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F | 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F | |||
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F | 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F | |||
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F | 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F | |||
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F | 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F | |||
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF | A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF | |||
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF | B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF | |||
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF | C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF | |||
D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF | D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF | |||
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF | E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF | |||
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA | F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA | |||
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F | 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F | |||
20 21 22 23 24 25`]]></artwork></figure></t> | 20 21 22 23 24 25`]]></artwork> | |||
<t><figure><artwork><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
TurboSHAKE128(M=`00`^0, D=`1F`, 32): | TurboSHAKE128(M=`00`^0, D=`1F`, 32): | |||
`1E 41 5F 1C 59 83 AF F2 16 92 17 27 7D 17 BB 53 | `1E 41 5F 1C 59 83 AF F2 16 92 17 27 7D 17 BB 53 | |||
8C D9 45 A3 97 DD EC 54 1F 1C E4 1A F2 C1 B7 4C` | 8C D9 45 A3 97 DD EC 54 1F 1C E4 1A F2 C1 B7 4C` | |||
TurboSHAKE128(M=`00`^0, D=`1F`, 64): | TurboSHAKE128(M=`00`^0, D=`1F`, 64): | |||
`1E 41 5F 1C 59 83 AF F2 16 92 17 27 7D 17 BB 53 | `1E 41 5F 1C 59 83 AF F2 16 92 17 27 7D 17 BB 53 | |||
8C D9 45 A3 97 DD EC 54 1F 1C E4 1A F2 C1 B7 4C | 8C D9 45 A3 97 DD EC 54 1F 1C E4 1A F2 C1 B7 4C | |||
3E 8C CA E2 A4 DA E5 6C 84 A0 4C 23 85 C0 3C 15 | 3E 8C CA E2 A4 DA E5 6C 84 A0 4C 23 85 C0 3C 15 | |||
E8 19 3B DF 58 73 73 63 32 16 91 C0 54 62 C8 DF` | E8 19 3B DF 58 73 73 63 32 16 91 C0 54 62 C8 DF` | |||
skipping to change at line 663 ¶ | skipping to change at line 620 ¶ | |||
`8D EE AA 1A EC 47 CC EE 56 9F 65 9C 21 DF A8 E1 | `8D EE AA 1A EC 47 CC EE 56 9F 65 9C 21 DF A8 E1 | |||
12 DB 3C EE 37 B1 81 78 B2 AC D8 05 B7 99 CC 37` | 12 DB 3C EE 37 B1 81 78 B2 AC D8 05 B7 99 CC 37` | |||
TurboSHAKE128(M=`FF`, D=`30`, 32): | TurboSHAKE128(M=`FF`, D=`30`, 32): | |||
`55 31 22 E2 13 5E 36 3C 32 92 BE D2 C6 42 1F A2 | `55 31 22 E2 13 5E 36 3C 32 92 BE D2 C6 42 1F A2 | |||
32 BA B0 3D AA 07 C7 D6 63 66 03 28 65 06 32 5B` | 32 BA B0 3D AA 07 C7 D6 63 66 03 28 65 06 32 5B` | |||
TurboSHAKE128(M=`FF FF FF`, D=`7F`, 32): | TurboSHAKE128(M=`FF FF FF`, D=`7F`, 32): | |||
`16 27 4C C6 56 D4 4C EF D4 22 39 5D 0F 90 53 BD | `16 27 4C C6 56 D4 4C EF D4 22 39 5D 0F 90 53 BD | |||
A6 D2 8E 12 2A BA 15 C7 65 E5 AD 0E 6E AF 26 F9` | A6 D2 8E 12 2A BA 15 C7 65 E5 AD 0E 6E AF 26 F9` | |||
]]></artwork></figure></t> | ]]></artwork> | |||
<t><figure><artwork><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
TurboSHAKE256(M=`00`^0, D=`1F`, 64): | TurboSHAKE256(M=`00`^0, D=`1F`, 64): | |||
`36 7A 32 9D AF EA 87 1C 78 02 EC 67 F9 05 AE 13 | `36 7A 32 9D AF EA 87 1C 78 02 EC 67 F9 05 AE 13 | |||
C5 76 95 DC 2C 66 63 C6 10 35 F5 9A 18 F8 E7 DB | C5 76 95 DC 2C 66 63 C6 10 35 F5 9A 18 F8 E7 DB | |||
11 ED C0 E1 2E 91 EA 60 EB 6B 32 DF 06 DD 7F 00 | 11 ED C0 E1 2E 91 EA 60 EB 6B 32 DF 06 DD 7F 00 | |||
2F BA FA BB 6E 13 EC 1C C2 0D 99 55 47 60 0D B0` | 2F BA FA BB 6E 13 EC 1C C2 0D 99 55 47 60 0D B0` | |||
TurboSHAKE256(M=`00`^0, D=`1F`, 10032), last 32 bytes: | TurboSHAKE256(M=`00`^0, D=`1F`, 10032), last 32 bytes: | |||
`AB EF A1 16 30 C6 61 26 92 49 74 26 85 EC 08 2F | `AB EF A1 16 30 C6 61 26 92 49 74 26 85 EC 08 2F | |||
20 72 65 DC CF 2F 43 53 4E 9C 61 BA 0C 9D 1D 75` | 20 72 65 DC CF 2F 43 53 4E 9C 61 BA 0C 9D 1D 75` | |||
skipping to change at line 753 ¶ | skipping to change at line 710 ¶ | |||
`F3 FE 12 87 3D 34 BC BB 2E 60 87 79 D6 B7 0E 7F | `F3 FE 12 87 3D 34 BC BB 2E 60 87 79 D6 B7 0E 7F | |||
86 BE C7 E9 0B F1 13 CB D4 FD D0 C4 E2 F4 62 5E | 86 BE C7 E9 0B F1 13 CB D4 FD D0 C4 E2 F4 62 5E | |||
14 8D D7 EE 1A 52 77 6C F7 7F 24 05 14 D9 CC FC | 14 8D D7 EE 1A 52 77 6C F7 7F 24 05 14 D9 CC FC | |||
3B 5D DA B8 EE 25 5E 39 EE 38 90 72 96 2C 11 1A` | 3B 5D DA B8 EE 25 5E 39 EE 38 90 72 96 2C 11 1A` | |||
TurboSHAKE256(M=`FF FF FF`, D=`7F`, 64): | TurboSHAKE256(M=`FF FF FF`, D=`7F`, 64): | |||
`AB E5 69 C1 F7 7E C3 40 F0 27 05 E7 D3 7C 9A B7 | `AB E5 69 C1 F7 7E C3 40 F0 27 05 E7 D3 7C 9A B7 | |||
E1 55 51 6E 4A 6A 15 00 21 D7 0B 6F AC 0B B4 0C | E1 55 51 6E 4A 6A 15 00 21 D7 0B 6F AC 0B B4 0C | |||
06 9F 9A 98 28 A0 D5 75 CD 99 F9 BA E4 35 AB 1A | 06 9F 9A 98 28 A0 D5 75 CD 99 F9 BA E4 35 AB 1A | |||
CF 7E D9 11 0B A9 7C E0 38 8D 07 4B AC 76 87 76` | CF 7E D9 11 0B A9 7C E0 38 8D 07 4B AC 76 87 76` | |||
]]></artwork></figure></t> | ]]></artwork> | |||
<t><figure><artwork><![CDATA[ KT128(M=`00`^0, C=`00`^0, 32): | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
KT128(M=`00`^0, C=`00`^0, 32): | ||||
`1A C2 D4 50 FC 3B 42 05 D1 9D A7 BF CA 1B 37 51 | `1A C2 D4 50 FC 3B 42 05 D1 9D A7 BF CA 1B 37 51 | |||
3C 08 03 57 7A C7 16 7F 06 FE 2C E1 F0 EF 39 E5` | 3C 08 03 57 7A C7 16 7F 06 FE 2C E1 F0 EF 39 E5` | |||
KT128(M=`00`^0, C=`00`^0, 64): | KT128(M=`00`^0, C=`00`^0, 64): | |||
`1A C2 D4 50 FC 3B 42 05 D1 9D A7 BF CA 1B 37 51 | `1A C2 D4 50 FC 3B 42 05 D1 9D A7 BF CA 1B 37 51 | |||
3C 08 03 57 7A C7 16 7F 06 FE 2C E1 F0 EF 39 E5 | 3C 08 03 57 7A C7 16 7F 06 FE 2C E1 F0 EF 39 E5 | |||
42 69 C0 56 B8 C8 2E 48 27 60 38 B6 D2 92 96 6C | 42 69 C0 56 B8 C8 2E 48 27 60 38 B6 D2 92 96 6C | |||
C0 7A 3D 46 45 27 2E 31 FF 38 50 81 39 EB 0A 71` | C0 7A 3D 46 45 27 2E 31 FF 38 50 81 39 EB 0A 71` | |||
KT128(M=`00`^0, C=`00`^0, 10032), last 32 bytes: | KT128(M=`00`^0, C=`00`^0, 10032), last 32 bytes: | |||
skipping to change at line 827 ¶ | skipping to change at line 785 ¶ | |||
KT128(M=ptn(8192 bytes), C=`00`^0, 32): | KT128(M=ptn(8192 bytes), C=`00`^0, 32): | |||
`48 F2 56 F6 77 2F 9E DF B6 A8 B6 61 EC 92 DC 93 | `48 F2 56 F6 77 2F 9E DF B6 A8 B6 61 EC 92 DC 93 | |||
B9 5E BD 05 A0 8A 17 B3 9A E3 49 08 70 C9 26 C3` | B9 5E BD 05 A0 8A 17 B3 9A E3 49 08 70 C9 26 C3` | |||
KT128(M=ptn(8192 bytes), C=ptn(8189 bytes), 32): | KT128(M=ptn(8192 bytes), C=ptn(8189 bytes), 32): | |||
`3E D1 2F 70 FB 05 DD B5 86 89 51 0A B3 E4 D2 3C | `3E D1 2F 70 FB 05 DD B5 86 89 51 0A B3 E4 D2 3C | |||
6C 60 33 84 9A A0 1E 1D 8C 22 0A 29 7F ED CD 0B` | 6C 60 33 84 9A A0 1E 1D 8C 22 0A 29 7F ED CD 0B` | |||
KT128(M=ptn(8192 bytes), C=ptn(8190 bytes), 32): | KT128(M=ptn(8192 bytes), C=ptn(8190 bytes), 32): | |||
`6A 7C 1B 6A 5C D0 D8 C9 CA 94 3A 4A 21 6C C6 46 | `6A 7C 1B 6A 5C D0 D8 C9 CA 94 3A 4A 21 6C C6 46 | |||
04 55 9A 2E A4 5F 78 57 0A 15 25 3D 67 BA 00 AE`]]></artwork></figure></t> | 04 55 9A 2E A4 5F 78 57 0A 15 25 3D 67 BA 00 AE`]]></artwork> | |||
<t><figure><artwork><![CDATA[ KT256(M=`00`^0, C=`00`^0, 64): | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
KT256(M=`00`^0, C=`00`^0, 64): | ||||
`B2 3D 2E 9C EA 9F 49 04 E0 2B EC 06 81 7F C1 0C | `B2 3D 2E 9C EA 9F 49 04 E0 2B EC 06 81 7F C1 0C | |||
E3 8C E8 E9 3E F4 C8 9E 65 37 07 6A F8 64 64 04 | E3 8C E8 E9 3E F4 C8 9E 65 37 07 6A F8 64 64 04 | |||
E3 E8 B6 81 07 B8 83 3A 5D 30 49 0A A3 34 82 35 | E3 E8 B6 81 07 B8 83 3A 5D 30 49 0A A3 34 82 35 | |||
3F D4 AD C7 14 8E CB 78 28 55 00 3A AE BD E4 A9` | 3F D4 AD C7 14 8E CB 78 28 55 00 3A AE BD E4 A9` | |||
KT256(M=`00`^0, C=`00`^0, 128): | KT256(M=`00`^0, C=`00`^0, 128): | |||
`B2 3D 2E 9C EA 9F 49 04 E0 2B EC 06 81 7F C1 0C | `B2 3D 2E 9C EA 9F 49 04 E0 2B EC 06 81 7F C1 0C | |||
E3 8C E8 E9 3E F4 C8 9E 65 37 07 6A F8 64 64 04 | E3 8C E8 E9 3E F4 C8 9E 65 37 07 6A F8 64 64 04 | |||
E3 E8 B6 81 07 B8 83 3A 5D 30 49 0A A3 34 82 35 | E3 E8 B6 81 07 B8 83 3A 5D 30 49 0A A3 34 82 35 | |||
3F D4 AD C7 14 8E CB 78 28 55 00 3A AE BD E4 A9 | 3F D4 AD C7 14 8E CB 78 28 55 00 3A AE BD E4 A9 | |||
skipping to change at line 939 ¶ | skipping to change at line 898 ¶ | |||
KT256(M=ptn(8192 bytes), C=ptn(8189 bytes), 64): | KT256(M=ptn(8192 bytes), C=ptn(8189 bytes), 64): | |||
`74 E4 78 79 F1 0A 9C 5D 11 BD 2D A7 E1 94 FE 57 | `74 E4 78 79 F1 0A 9C 5D 11 BD 2D A7 E1 94 FE 57 | |||
E8 63 78 BF 3C 3F 74 48 EF F3 C5 76 A0 F1 8C 5C | E8 63 78 BF 3C 3F 74 48 EF F3 C5 76 A0 F1 8C 5C | |||
AA E0 99 99 79 51 20 90 A7 F3 48 AF 42 60 D4 DE | AA E0 99 99 79 51 20 90 A7 F3 48 AF 42 60 D4 DE | |||
3C 37 F1 EC AF 8D 2C 2C 96 C1 D1 6C 64 B1 24 96` | 3C 37 F1 EC AF 8D 2C 2C 96 C1 D1 6C 64 B1 24 96` | |||
KT256(M=ptn(8192 bytes), C=ptn(8190 bytes), 64): | KT256(M=ptn(8192 bytes), C=ptn(8190 bytes), 64): | |||
`F4 B5 90 8B 92 9F FE 01 E0 F7 9E C2 F2 12 43 D4 | `F4 B5 90 8B 92 9F FE 01 E0 F7 9E C2 F2 12 43 D4 | |||
1A 39 6B 2E 73 03 A6 AF 1D 63 99 CD 6C 7A 0A 2D | 1A 39 6B 2E 73 03 A6 AF 1D 63 99 CD 6C 7A 0A 2D | |||
D7 C4 F6 07 E8 27 7F 9C 9B 1C B4 AB 9D DC 59 D4 | D7 C4 F6 07 E8 27 7F 9C 9B 1C B4 AB 9D DC 59 D4 | |||
B9 2D 1F C7 55 84 41 F1 83 2C 32 79 A4 24 1B 8B`]]></artwork></figure></t> | B9 2D 1F C7 55 84 41 F1 83 2C 32 79 A4 24 1B 8B`]]></artwork> | |||
</section> | </section> | |||
<section anchor="IANA" numbered="true" toc="default"> | ||||
<section anchor="IANA" title="IANA Considerations"> | <name>IANA Considerations</name> | |||
<t> In the Named Information Hash Algorithm Registry, k12-256 refers to the | <t> In the "Named Information Hash Algorithm Registry", k12-256 refers to | |||
hash | the hash | |||
function obtained by evaluating KT128 on the input message with default C (t he empty string) | function obtained by evaluating KT128 on the input message with default C (t he empty string) | |||
and L = 32 bytes (256 bits). Similarly, k12-512 refers to the hash function obtained by evaluating | and L = 32 bytes (256 bits). Similarly, k12-512 refers to the hash function obtained by evaluating | |||
KT256 on the input message with default C (the empty string) and L = 64 byt es (512 bits). </t> | KT256 on the input message with default C (the empty string) and L = 64 byt es (512 bits). </t> | |||
<t> In the "COSE Algorithms" registry, IANA has added the following entries for TurboSHAKE and KangarooTwelve:</t> | ||||
<t> In the COSE Algorithms registry, the following entries are assigned to T | <table> | |||
urboSHAKE and KangarooTwelve:</t> | <thead> | |||
<tr> | ||||
<t><figure><artwork><![CDATA[ | <th>Name</th> | |||
+---------------+-------+-------------------+--------------+ | <th>Value</th> | |||
| Name | Value | Description | Capabilities | | <th>Description</th> | |||
+---------------+-------+-------------------+--------------+ | <th>Capabilities</th> | |||
| TurboSHAKE128 | -261 | TurboSHAKE128 XOF | [kty] | | </tr> | |||
| | | | | | </thead> | |||
| TurboSHAKE256 | -262 | TurboSHAKE256 XOF | [kty] | | <tbody> | |||
| | | | | | <tr> | |||
| KT128 | -263 | KT128 XOF | [kty] | | <td>TurboSHAKE128</td> | |||
| | | | | | <td>-261</td> | |||
| KT256 | -264 | KT256 XOF | [kty] | | <td>TurboSHAKE128 XOF</td> | |||
+---------------+-------+-------------------+--------------+ ]]></artwor | <td>[kty]</td> | |||
k> | </tr> | |||
</figure></t> | <tr> | |||
</section> | <td>TurboSHAKE256</td> | |||
<td>-262</td> | ||||
<td>TurboSHAKE256 XOF</td> | ||||
<td>[kty]</td> | ||||
</tr> | ||||
<tr> | ||||
<td>KT128</td> | ||||
<td>-263</td> | ||||
<td>KT128 XOF</td> | ||||
<td>[kty]</td> | ||||
</tr> | ||||
<tr> | ||||
<td>KT256</td> | ||||
<td>-264</td> | ||||
<td>KT256 XOF</td> | ||||
<td>[kty]</td> | ||||
</tr> | ||||
</tbody> | ||||
</table> | ||||
<section anchor="Security" title="Security Considerations"> | </section> | |||
<t>This document is meant to serve as a stable reference and an | <section anchor="Security" numbered="true" toc="default"> | |||
implementation guide for the KangarooTwelve and TurboSHAKE eXtendable Output | <name>Security Considerations</name> | |||
Functions. | <t>This document is meant to serve as a stable reference and an | |||
The security assurance of these functions relies on the cryptanalysis of red | implementation guide for the KangarooTwelve and TurboSHAKE eXtendable-Output | |||
uced-round versions of Keccak and they have the same claimed security strength a | Functions. | |||
s their corresponding SHAKE functions.</t> | The security assurance of these functions relies on the cryptanalysis of red | |||
uced-round versions of Keccak, and they have the same claimed security strength | ||||
as their corresponding SHAKE functions.</t> | ||||
<t><figure><artwork><![CDATA[ | <table> | |||
+-------------------------------+ | <thead> | |||
| security claim | | <tr> | |||
+-----------------+-------------------------------+ | <td></td> | |||
| TurboSHAKE128 | 128 bits (same as SHAKE128) | | <th>Security Claim</th> | |||
| | | | </tr> | |||
| KT128 | 128 bits (same as SHAKE128) | | </thead> | |||
| | | | <tbody> | |||
| TurboSHAKE256 | 256 bits (same as SHAKE256) | | <tr> | |||
| | | | <th>TurboSHAKE128</th> | |||
| KT256 | 256 bits (same as SHAKE256) | | <td>128 bits (same as SHAKE128)</td> | |||
+-----------------+-------------------------------+]]></artwork> | </tr> | |||
</figure></t> | <tr> | |||
<th>KT128</th> | ||||
<td>128 bits (same as SHAKE128)</td> | ||||
</tr> | ||||
<tr> | ||||
<th>TurboSHAKE256</th> | ||||
<td>256 bits (same as SHAKE256)</td> | ||||
</tr> | ||||
<tr> | ||||
<th>KT256</th> | ||||
<td>256 bits (same as SHAKE256)</td> | ||||
</tr> | ||||
</tbody> | ||||
</table> | ||||
<t> | <t>To be more precise, KT128 is made of two layers:</t> | |||
To be more precise, KT128 is made of two layers: | <ul spacing="normal"> | |||
<list style="symbols"> | <li> | |||
<t>The inner function TurboSHAKE128. | <t>The inner function TurboSHAKE128. | |||
The security assurance of this layer relies on cryptanalysis. | The security assurance of this layer relies on cryptanalysis. | |||
The TurboSHAKE128 function is exactly Keccak[r=1344, c=256] (as in SHAKE128) | The TurboSHAKE128 function is exactly Keccak[r=1344, c=256] (as in SHAKE128) | |||
reduced to 12 rounds. | reduced to 12 rounds. | |||
Any cryptanalysis of reduced-round Keccak is also cryptanalysis of reduced-r ound TurboSHAKE128 | Any cryptanalysis of reduced-round Keccak is also cryptanalysis of reduced-r ound TurboSHAKE128 | |||
(provided the number of rounds attacked is not higher than 12).</t> | (provided the number of rounds attacked is not higher than 12).</t> | |||
<t>The tree hashing over TurboSHAKE128. This layer is a mode on top | </li> | |||
<li> | ||||
<t>The tree hashing over TurboSHAKE128. This layer is a mode on top | ||||
of TurboSHAKE128 that does not introduce any vulnerability thanks to | of TurboSHAKE128 that does not introduce any vulnerability thanks to | |||
the use of Sakura coding proven secure in <xref target="SAKURA"/>.</t> | the use of Sakura coding proven secure in <xref target="SAKURA" format="defa | |||
</list></t> | ult"/>.</t> | |||
<t>This reasoning is detailed and formalized in <xref target="KT"/>.</t> | </li> | |||
</ul> | ||||
<t>KT256 is structured as KT128, except that it uses TurboSHAKE256 as inner | <t>This reasoning is detailed and formalized in <xref target="KT" format=" | |||
function. | default"/>.</t> | |||
<t>KT256 is structured as KT128, except that it uses TurboSHAKE256 as the | ||||
inner function. | ||||
The TurboSHAKE256 function is exactly Keccak[r=1088, c=512] (as in SHAKE256) | The TurboSHAKE256 function is exactly Keccak[r=1088, c=512] (as in SHAKE256) | |||
reduced to 12 rounds, and the same reasoning on cryptanalysis applies.</t> | reduced to 12 rounds, and the same reasoning on cryptanalysis applies.</t> | |||
<t>TurboSHAKE128 and KT128 aim at 128-bit security. | ||||
<t>TurboSHAKE128 and KT128 aim at 128-bit security. | To achieve 128-bit security strength, L, the chosen output length, <bcp14>MU | |||
To achieve 128-bit security strength, the output L MUST be chosen long | ST</bcp14> be large | |||
enough so that there are no generic attacks that violate 128-bit security. | enough so that there are no generic attacks that violate 128-bit security. | |||
So for 128-bit (second) preimage security the output should be at least 128 | So for 128-bit (second) preimage security, the output should be at least 128 | |||
bits, | bits; | |||
for 128 bits of security against multi-target preimage attacks with T target | for 128 bits of security against multi-target preimage attacks with T target | |||
s | s, | |||
the output should be at least 128+log_2(T) bits | the output should be at least 128+log_2(T) bits; | |||
and for 128-bit collision security the output should be at least 256 bits. | and for 128-bit collision security, the output should be at least 256 bits. | |||
Furthermore, when the output length is at least 256 bits, TurboSHAKE128 and | Furthermore, when the output length is at least 256 bits, TurboSHAKE128 and | |||
KT128 achieve NIST's post-quantum security level 2 <xref target="NISTPQ"/>.< | KT128 achieve NIST's post-quantum security level 2 <xref target="NISTPQ" for | |||
/t> | mat="default"/>.</t> | |||
<t>Similarly, TurboSHAKE256 and KT256 aim at 256-bit security. | ||||
<t>Similarly, TurboSHAKE256 and KT256 aim at 256-bit security. | To achieve 256-bit security strength, L, the chosen output length, <bcp14>MU | |||
To achieve 256-bit security strength, the output L MUST be chosen long | ST</bcp14> be large | |||
enough so that there are no generic attacks that violate 256-bit security. | enough so that there are no generic attacks that violate 256-bit security. | |||
So for 256-bit (second) preimage security the output should be at least 256 | So for 256-bit (second) preimage security, the output should be at least 256 | |||
bits, | bits; | |||
for 256 bits of security against multi-target preimage attacks with T target | for 256 bits of security against multi-target preimage attacks with T target | |||
s | s, | |||
the output should be at least 256+log_2(T) bits | the output should be at least 256+log_2(T) bits; | |||
and for 256-bit collision security the output should be at least 512 bits. | and for 256-bit collision security, the output should be at least 512 bits. | |||
Furthermore, when the output length is at least 512 bits, TurboSHAKE256 and | Furthermore, when the output length is at least 512 bits, TurboSHAKE256 and | |||
KT256 achieve NIST's post-quantum security level 5 <xref target="NISTPQ"/>.< | KT256 achieve NIST's post-quantum security level 5 <xref target="NISTPQ" for | |||
/t> | mat="default"/>.</t> | |||
<t> | ||||
<t> | Unlike the SHA-256 and SHA-512 functions, TurboSHAKE128, TurboSHAKE256, KT12 | |||
Unlike the SHA-256 and SHA-512 functions, TurboSHAKE128, TurboSHAKE256, KT12 | 8, and KT256 do not suffer from the length extension weakness and therefore do n | |||
8 and KT256 do not suffer from the length extension weakness, and therefore do n | ot require the use of the HMAC construction, for instance, when used for MAC com | |||
ot require the use of the HMAC construction for instance when used for MAC compu | putation <xref target="FIPS198" format="default"/>. | |||
tation <xref target="FIPS198"/>. | ||||
Also, they can naturally be used as a key derivation function. | Also, they can naturally be used as a key derivation function. | |||
The input must be an injective encoding of secret and diversification mate rial, and the output can be taken as the derived key(s). | The input must be an injective encoding of secret and diversification mate rial, and the output can be taken as the derived key(s). | |||
The input does not need to be uniformly distributed, e.g., it can be a sha red secret produced by | The input does not need to be uniformly distributed, e.g., it can be a sha red secret produced by | |||
the Diffie-Hellman or ECDH protocol, but it needs to have sufficient min-e ntropy. | the Diffie-Hellman or Elliptic Curve Diffie-Hellman (ECDH) protocol, but i t needs to have sufficient min-entropy. | |||
</t> | </t> | |||
<t>Lastly, as KT128 and KT256 use TurboSHAKE with three values for D, | ||||
namely 0x06, 0x07, and 0x0B, | ||||
protocols that use both KT128 and TurboSHAKE128 or both KT256 and TurboSHAKE | ||||
256 | ||||
<bcp14>SHOULD</bcp14> avoid using these three values for D.</t> | ||||
</section> | ||||
<t>Lastly, as KT128 and KT256 use TurboSHAKE with three values for D, | ||||
namely 0x06, 0x07, and 0x0B. | ||||
Protocols that use both KT128 and TurboSHAKE128, or both KT256 and TurboSHAK | ||||
E256, | ||||
SHOULD avoid using these three values for D.</t> | ||||
</section> | ||||
<!-- | ||||
<section title="Contributors"> | ||||
<t><cref>[TEMPLATE TODO] This optional section can be used to mention cont | ||||
ributors to your internet draft.</cref></t> | ||||
</section> --> | ||||
</middle> | </middle> | |||
<back> | ||||
<back> | <references> | |||
<name>References</name> | ||||
<references> | ||||
<name>Normative References</name> | ||||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2 | ||||
119.xml"/> | ||||
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8 | ||||
174.xml"/> | ||||
<!-- References Section --> | <reference anchor="FIPS202" target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST. | |||
<references title="Normative References"> | FIPS.202.pdf"> | |||
&rfc2119; | <front> | |||
&rfc8174; | <title>SHA-3 Standard: Permutation-Based Hash and Extendable-Output Function | |||
<reference anchor="FIPS202"> | s</title> | |||
<front> | <author> | |||
<title>FIPS PUB 202 - SHA-3 Standard: Permutation-Based Hash and | <organization abbrev="NIST">National Institute of Standards and Technology | |||
Extendable-Output Functions</title> | </organization> | |||
<author> | </author> | |||
<organization>National Institute of Standards and Technology | <date month="August" year="2015"/> | |||
</organization> | </front> | |||
</author> | <seriesInfo name="NIST FIPS" value="202"/> | |||
<date month="August" year="2015"></date> | <seriesInfo name="DOI" value="10.6028/NIST.FIPS.202"/> | |||
</front> | </reference> | |||
<seriesInfo name="WWW" value="http://dx.doi.org/10.6028/NIST.FIPS.202" /> | ||||
</reference> | ||||
<reference anchor="SP800-185"> | ||||
<front> | ||||
<title>NIST Special Publication 800-185 SHA-3 Derived Functions: | ||||
cSHAKE, KMAC, TupleHash and ParallelHash</title> | ||||
<author> | ||||
<organization>National Institute of Standards and Technology | ||||
</organization> | ||||
</author> | ||||
<date month="December" year="2016"></date> | ||||
</front> | ||||
<seriesInfo name="WWW" value="https://doi.org/10.6028/NIST.SP.800-185" /> | ||||
</reference> | ||||
</references> | ||||
<references title="Informative References"> | <reference anchor="SP800-185"> | |||
<front> | ||||
<title>SHA-3 Derived Functions: | ||||
cSHAKE, KMAC, TupleHash and ParallelHash</title> | ||||
<author fullname="John Kelsey" surname="Kelsey"> | ||||
<organization>Information Technology Laboratory</organization> | ||||
</author> | ||||
<author fullname="Shu-jen Chang" surname="Chang"> | ||||
<organization>Information Technology Laboratory</organization> | ||||
</author> | ||||
<author fullname="Ray Perlner" surname="Perlner"> | ||||
<organization>Information Technology Laboratory</organization> | ||||
</author> <date month="December" year="2016"/> | ||||
</front> | ||||
<seriesInfo name="NIST SP" value="800-185"/> | ||||
<seriesInfo name="DOI" value="10.6028/NIST.SP.800-185"/> | ||||
<refcontent>National Institute of Standards and Technology</refcontent | ||||
> | ||||
</reference> | ||||
<reference anchor="TURBOSHAKE"> | </references> | |||
<front> | <references> | |||
<title>TurboSHAKE</title> | <name>Informative References</name> | |||
<author initials="G." surname="Bertoni" fullname="Guido Bertoni"/> | ||||
<author initials="J." surname="Daemen" fullname="Joan Daemen"/> | ||||
<author initials="S." surname="Hoffert" fullname="Seth Hoffert"/> | ||||
<author initials="M." surname="Peeters" fullname="Michael Peeters"/> | ||||
<author initials="G." surname="Van Assche" fullname="Gilles Van Assche"/> | ||||
<author initials="R." surname="Van Keer" fullname="Ronny Van Keer"/> | ||||
<author initials="B." surname="Viguier" fullname="Benoît Viguier"/> | ||||
<date month="March" year="2023"/> | ||||
</front> | ||||
<seriesInfo name="WWW" value="http://eprint.iacr.org/2023/342"/> | ||||
</reference> | ||||
<reference anchor="KT"> | <reference anchor="TURBOSHAKE" target="http://eprint.iacr.org/2023/342"> | |||
<front> | <front> | |||
<title>KangarooTwelve: fast hashing based on Keccak-p</title> | <title>TurboSHAKE</title> | |||
<author initials="G." surname="Bertoni" fullname="Guido Bertoni"/> | <author initials="G." surname="Bertoni" fullname="Guido Bertoni"/> | |||
<author initials="J." surname="Daemen" fullname="Joan Daemen"/> | <author initials="J." surname="Daemen" fullname="Joan Daemen"/> | |||
<author initials="M." surname="Peeters" fullname="Michael Peeters"/> | <author initials="S." surname="Hoffert" fullname="Seth Hoffert"/> | |||
<author initials="G." surname="Van Assche" fullname="Gilles Van Assche"/> | <author initials="M." surname="Peeters" fullname="Michael Peeters"/> | |||
<author initials="R." surname="Van Keer" fullname="Ronny Van Keer"/> | <author initials="G." surname="Van Assche" fullname="Gilles Van Assc | |||
<author initials="B." surname="Viguier" fullname="Benoît Viguier"/> | he"/> | |||
<date month="July" year="2018"/> | <author initials="R." surname="Van Keer" fullname="Ronny Van Keer"/> | |||
</front> | <author initials="B." surname="Viguier" fullname="Benoît Viguier"/> | |||
<seriesInfo name="WWW" value="https://link.springer.com/chapter/10.1007/978- | <date month="March" year="2023"/> | |||
3-319-93387-0_21"/> | </front> | |||
<seriesInfo name="WWW" value="http://eprint.iacr.org/2016/770.pdf"/> | <refcontent>Cryptology ePrint Archive, Paper 2023/342</refcontent> | |||
</reference> | </reference> | |||
<reference anchor="SAKURA"> | <reference anchor="KT" target="https://link.springer.com/chapter/10.1007 | |||
<front> | /978-3-319-93387-0_21"> | |||
<title>Sakura: a flexible coding for tree hashing</title> | <front> | |||
<author initials="G." surname="Bertoni" fullname="Guido Bertoni"/> | <title>KangarooTwelve: Fast Hashing Based on Keccak-p</title> | |||
<author initials="J." surname="Daemen" fullname="Joan Daemen"/> | <author initials="G." surname="Bertoni" fullname="Guido Bertoni"/> | |||
<author initials="M." surname="Peeters" fullname="Michael Peeters"/> | <author initials="J." surname="Daemen" fullname="Joan Daemen"/> | |||
<author initials="G." surname="Van Assche" fullname="Gilles Van Assche"/> | <author initials="M." surname="Peeters" fullname="Michael Peeters"/> | |||
<date month="June" year="2014"/> | <author initials="G." surname="Van Assche" fullname="Gilles Van Assc | |||
</front> | he"/> | |||
<seriesInfo name="WWW" value="https://link.springer.com/chapter/10.1007/978- | <author initials="R." surname="Van Keer" fullname="Ronny Van Keer"/> | |||
3-319-07536-5_14"/> | <author initials="B." surname="Viguier" fullname="Benoît Viguier"/> | |||
<seriesInfo name="WWW" value="http://eprint.iacr.org/2013/231.pdf"/> | <date month="June" year="2018"/> | |||
</reference> | </front> | |||
<refcontent>Applied Cryptography and Network Security (ACNS 2018), Lec | ||||
ture Notes in Computer Science, vol. 10892, pp. 400-418</refcontent> | ||||
<seriesInfo name="DOI" value="10.1007/978-3-319-93387-0_21"/> | ||||
</reference> | ||||
<reference anchor="KECCAK_CRYPTANALYSIS"> | <reference anchor="SAKURA" target="https://link.springer.com/chapter/10. | |||
<front> | 1007/978-3-319-07536-5_14"> | |||
<title>Summary of Third-party cryptanalysis of Keccak</title> | <front> | |||
<author> | <title>Sakura: a Flexible Coding for Tree Hashing</title> | |||
<organization>Keccak Team</organization> | <author initials="G." surname="Bertoni" fullname="Guido Bertoni"/> | |||
</author> | <author initials="J." surname="Daemen" fullname="Joan Daemen"/> | |||
<date year="2022"/> | <author initials="M." surname="Peeters" fullname="Michael Peeters"/> | |||
</front> | <author initials="G." surname="Van Assche" fullname="Gilles Van Assc | |||
<seriesInfo name="WWW" value="https://www.keccak.team/third_party.html"/> | he"/> | |||
</reference> | <date year="2014"/> | |||
</front> | ||||
<refcontent>Applied Cryptography and Network Security (ACNS 2014), Lec | ||||
ture Notes in Computer Science, vol. 8479, pp. 217-234</refcontent> | ||||
<seriesInfo name="DOI" value="10.1007/978-3-319-07536-5_14"/> | ||||
</reference> | ||||
<reference anchor="XKCP"> | <reference anchor="KECCAK_CRYPTANALYSIS" target="https://www.keccak.team | |||
<front> | /third_party.html"> | |||
<title>eXtended Keccak Code Package</title> | <front> | |||
<author initials="G." surname="Bertoni" fullname="Guido Bertoni"/> | <title>Summary of Third-party cryptanalysis of Keccak</title> | |||
<author initials="J." surname="Daemen" fullname="Joan Daemen"/> | <author> | |||
<author initials="M." surname="Peeters" fullname="Michael Peeters"/> | <organization>Keccak Team</organization> | |||
<author initials="G." surname="Van Assche" fullname="Gilles Van Assche"/ | </author> | |||
> | </front> | |||
<author initials="R." surname="Van Keer" fullname="Ronny Van Keer"/> | </reference> | |||
<date month="December" year="2022"/> | ||||
</front> | ||||
<seriesInfo name="WWW" value="https://github.com/XKCP/XKCP"/> | ||||
</reference> | ||||
<reference anchor="NISTPQ"> | <reference anchor="XKCP" target="https://github.com/XKCP/XKCP"> | |||
<front> | <front> | |||
<title>Submission Requirements and Evaluation Criteria for the Post-Quantu | <title>eXtended Keccak Code Package</title> | |||
m Cryptography Standardization Process</title> | <author/> | |||
<author> | <date month="December" year="2022"/> | |||
<organization>National Institute of Standards and Technology | </front> | |||
</organization> | <refcontent>commit 64404bee</refcontent> | |||
</author> | </reference> | |||
<date month="December" year="2016"></date> | ||||
</front> | ||||
<seriesInfo name="WWW" value="https://csrc.nist.gov/CSRC/media/Projects/Post | ||||
-Quantum-Cryptography/documents/call-for-proposals-final-dec-2016.pdf" /> | ||||
</reference> | ||||
<reference anchor="FIPS180"> | <reference anchor="NISTPQ" target="https://csrc.nist.gov/CSRC/media/Proj | |||
<front> | ects/Post-Quantum-Cryptography/documents/call-for-proposals-final-dec-2016.pdf"> | |||
<title>Secure Hash Standard (SHS)</title> | <front> | |||
<author> | <title>Submission Requirements and Evaluation Criteria for the Post- | |||
<organization>National Institute of Standards and Technology (NIST)</org | Quantum Cryptography Standardization Process</title> | |||
anization> | <author> | |||
</author> | <organization abbrev="NIST">National Institute of Standards and Te | |||
<date year="2015" month="August"/> | chnology | |||
</front> | </organization> | |||
<seriesInfo name="FIPS PUB" value="180-4"/> | </author> | |||
<seriesInfo name="WWW" value="https://doi.org/10.6028/NIST.FIPS.180-4"/> | </front> | |||
</reference> | </reference> | |||
<reference anchor="FIPS198"> | <reference anchor="FIPS180" target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST. | |||
<front> | FIPS.180-4.pdf"> | |||
<title>The Keyed-Hash Message Authentication Code (HMAC)</title> | <front> | |||
<author> | <title>Secure Hash Standard</title> | |||
<organization>National Institute of Standards and Technology (NIST)</org | <author> | |||
anization> | <organization abbrev="NIST">National Institute of Standards and Technology | |||
</author> | </organization> | |||
<date year="2008" month="July"/> | </author> | |||
</front> | <date month="August" year="2015"/> | |||
<seriesInfo name="FIPS PUB" value="198-1"/> | </front> | |||
<seriesInfo name="WWW" value="https://doi.org/10.6028/NIST.FIPS.198-1"/> | <seriesInfo name="NIST FIPS" value="180-4"/> | |||
</reference> | <seriesInfo name="DOI" value="10.6028/NIST.FIPS.180-4"/> | |||
</reference> | ||||
</references> | <reference anchor="FIPS198" target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST. | |||
FIPS.198-1.pdf"> | ||||
<front> | ||||
<title>The Keyed-Hash Message Authentication Code (HMAC)</title> | ||||
<author> | ||||
<organization abbrev="NIST">National Institute of Standards and Technology | ||||
</organization> | ||||
</author> | ||||
<date month="July" year="2008"/> | ||||
</front> | ||||
<seriesInfo name="NIST FIPS" value="198-1"/> | ||||
<seriesInfo name="DOI" value="10.6028/NIST.FIPS.198-1"/> | ||||
</reference> | ||||
<section anchor="pseudocode" title="Pseudocode"> | </references> | |||
<t>The sub-sections of this appendix contain pseudocode definitions of | </references> | |||
TurboSHAKE128, TurboSHAKE256 and KangarooTwelve. | <section anchor="pseudocode" numbered="true" toc="default"> | |||
<name>Pseudocode</name> | ||||
<t>The subsections of this appendix contain pseudocode definitions of | ||||
TurboSHAKE128, TurboSHAKE256, and KangarooTwelve. | ||||
Standalone Python versions are also available in the Keccak Code Package | Standalone Python versions are also available in the Keccak Code Package | |||
<xref target="XKCP"></xref> and in <xref target="KT"></xref> | <xref target="XKCP" format="default"/> and in <xref target="KT" format="defa | |||
</t> | ult"/> | |||
</t> | ||||
<section anchor="Keccak_PC" title="Keccak-p[1600,n_r=12]"> | <section anchor="Keccak_PC" numbered="true" toc="default"> | |||
<name>Keccak-p[1600,n_r=12]</name> | ||||
<t><figure><artwork><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
KP(state): | KP(state): | |||
RC[0] = `8B 80 00 80 00 00 00 00` | RC[0] = `8B 80 00 80 00 00 00 00` | |||
RC[1] = `8B 00 00 00 00 00 00 80` | RC[1] = `8B 00 00 00 00 00 00 80` | |||
RC[2] = `89 80 00 00 00 00 00 80` | RC[2] = `89 80 00 00 00 00 00 80` | |||
RC[3] = `03 80 00 00 00 00 00 80` | RC[3] = `03 80 00 00 00 00 00 80` | |||
RC[4] = `02 80 00 00 00 00 00 80` | RC[4] = `02 80 00 00 00 00 00 80` | |||
RC[5] = `80 00 00 00 00 00 00 80` | RC[5] = `80 00 00 00 00 00 00 80` | |||
RC[6] = `0A 80 00 00 00 00 00 00` | RC[6] = `0A 80 00 00 00 00 00 00` | |||
RC[7] = `0A 00 00 80 00 00 00 80` | RC[7] = `0A 00 00 80 00 00 00 80` | |||
RC[8] = `81 80 00 80 00 00 00 80` | RC[8] = `81 80 00 80 00 00 00 80` | |||
skipping to change at line 1249 ¶ | skipping to change at line 1239 ¶ | |||
# iota | # iota | |||
lanes[0][0] ^= RC[round] | lanes[0][0] ^= RC[round] | |||
state = `00`^0 | state = `00`^0 | |||
for y from 0 to 4 | for y from 0 to 4 | |||
for x from 0 to 4 | for x from 0 to 4 | |||
state = state || lanes[x][y] | state = state || lanes[x][y] | |||
return state | return state | |||
end | end | |||
]]></artwork></figure></t> | ]]></sourcecode> | |||
<t>where ROL64(x, y) is a rotation of the 'x' 64-bit word toward the bit | ||||
<t>where ROL64(x, y) is a rotation of the 'x' 64-bit word toward the bits | s | |||
with higher indexes by 'y' positions. The 8-bytes byte-string x is | with higher indexes by 'y' positions. The 8-bytes byte string x is | |||
interpreted as a 64-bit word in little-endian format. | interpreted as a 64-bit word in little-endian format. | |||
</t> | </t> | |||
</section> | </section> | |||
<section anchor="TSHK128_PC" numbered="true" toc="default"> | ||||
<name>TurboSHAKE128</name> | ||||
<section anchor="TSHK128_PC" title="TurboSHAKE128"> | <sourcecode type="pseudocode"><![CDATA[ | |||
<t><figure><artwork><![CDATA[ | ||||
TurboSHAKE128(message, separationByte, outputByteLen): | TurboSHAKE128(message, separationByte, outputByteLen): | |||
offset = 0 | offset = 0 | |||
state = `00`^200 | state = `00`^200 | |||
input = message || separationByte | input = message || separationByte | |||
# === Absorb complete blocks === | # === Absorb complete blocks === | |||
while offset < |input| - 168 | while offset < |input| - 168 | |||
state ^= input[offset : offset + 168] || `00`^32 | state ^= input[offset : offset + 168] || `00`^32 | |||
state = KP(state) | state = KP(state) | |||
offset += 168 | offset += 168 | |||
skipping to change at line 1286 ¶ | skipping to change at line 1276 ¶ | |||
# === Squeeze === | # === Squeeze === | |||
output = `00`^0 | output = `00`^0 | |||
while outputByteLen > 168 | while outputByteLen > 168 | |||
output = output || state[0:168] | output = output || state[0:168] | |||
outputByteLen -= 168 | outputByteLen -= 168 | |||
state = KP(state) | state = KP(state) | |||
output = output || state[0:outputByteLen] | output = output || state[0:outputByteLen] | |||
return output | return output | |||
]]></artwork></figure></t> | ]]></sourcecode> | |||
</section> | </section> | |||
<section anchor="TSHK256_PC" numbered="true" toc="default"> | ||||
<section anchor="TSHK256_PC" title="TurboSHAKE256"> | <name>TurboSHAKE256</name> | |||
<t><figure><artwork><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
TurboSHAKE256(message, separationByte, outputByteLen): | TurboSHAKE256(message, separationByte, outputByteLen): | |||
offset = 0 | offset = 0 | |||
state = `00`^200 | state = `00`^200 | |||
input = message || separationByte | input = message || separationByte | |||
# === Absorb complete blocks === | # === Absorb complete blocks === | |||
while offset < |input| - 136 | while offset < |input| - 136 | |||
state ^= input[offset : offset + 136] || `00`^64 | state ^= input[offset : offset + 136] || `00`^64 | |||
state = KP(state) | state = KP(state) | |||
offset += 136 | offset += 136 | |||
skipping to change at line 1318 ¶ | skipping to change at line 1308 ¶ | |||
# === Squeeze === | # === Squeeze === | |||
output = `00`^0 | output = `00`^0 | |||
while outputByteLen > 136 | while outputByteLen > 136 | |||
output = output || state[0:136] | output = output || state[0:136] | |||
outputByteLen -= 136 | outputByteLen -= 136 | |||
state = KP(state) | state = KP(state) | |||
output = output || state[0:outputByteLen] | output = output || state[0:outputByteLen] | |||
return output | return output | |||
]]></artwork></figure></t> | ]]></sourcecode> | |||
</section> | </section> | |||
<section anchor="KT128_PC" numbered="true" toc="default"> | ||||
<section anchor="KT128_PC" title="KT128"> | <name>KT128</name> | |||
<t><figure><artwork><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
KT128(inputMessage, customString, outputByteLen): | KT128(inputMessage, customString, outputByteLen): | |||
S = inputMessage || customString | S = inputMessage || customString | |||
S = S || length_encode( |customString| ) | S = S || length_encode( |customString| ) | |||
if |S| <= 8192 | if |S| <= 8192 | |||
return TurboSHAKE128(S, `07`, outputByteLen) | return TurboSHAKE128(S, `07`, outputByteLen) | |||
else | else | |||
# === Kangaroo hopping === | # === Kangaroo hopping === | |||
FinalNode = S[0:8192] || `03` || `00`^7 | FinalNode = S[0:8192] || `03` || `00`^7 | |||
offset = 8192 | offset = 8192 | |||
numBlock = 0 | numBlock = 0 | |||
while offset < |S| | while offset < |S| | |||
blockSize = min( |S| - offset, 8192) | blockSize = min( |S| - offset, 8192) | |||
CV = TurboSHAKE128(S[offset : offset + blockSize], `0B`, 32) | CV = TurboSHAKE128(S[offset : offset+blockSize], `0B`, 32) | |||
FinalNode = FinalNode || CV | FinalNode = FinalNode || CV | |||
numBlock += 1 | numBlock += 1 | |||
offset += blockSize | offset += blockSize | |||
FinalNode = FinalNode || length_encode( numBlock ) || `FF FF` | FinalNode = FinalNode || length_encode( numBlock ) || `FF FF` | |||
return TurboSHAKE128(FinalNode, `06`, outputByteLen) | return TurboSHAKE128(FinalNode, `06`, outputByteLen) | |||
end | end | |||
]]></artwork></figure></t> | ]]></sourcecode> | |||
</section> | </section> | |||
<section anchor="KT256_PC" numbered="true" toc="default"> | ||||
<section anchor="KT256_PC" title="KT256"> | <name>KT256</name> | |||
<t><figure><artwork><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
KT256(inputMessage, customString, outputByteLen): | KT256(inputMessage, customString, outputByteLen): | |||
S = inputMessage || customString | S = inputMessage || customString | |||
S = S || length_encode( |customString| ) | S = S || length_encode( |customString| ) | |||
if |S| <= 8192 | if |S| <= 8192 | |||
return TurboSHAKE256(S, `07`, outputByteLen) | return TurboSHAKE256(S, `07`, outputByteLen) | |||
else | else | |||
# === Kangaroo hopping === | # === Kangaroo hopping === | |||
FinalNode = S[0:8192] || `03` || `00`^7 | FinalNode = S[0:8192] || `03` || `00`^7 | |||
offset = 8192 | offset = 8192 | |||
numBlock = 0 | numBlock = 0 | |||
while offset < |S| | while offset < |S| | |||
blockSize = min( |S| - offset, 8192) | blockSize = min( |S| - offset, 8192) | |||
CV = TurboSHAKE256(S[offset : offset + blockSize], `0B`, 64) | CV = TurboSHAKE256(S[offset : offset+blockSize], `0B`, 64) | |||
FinalNode = FinalNode || CV | FinalNode = FinalNode || CV | |||
numBlock += 1 | numBlock += 1 | |||
offset += blockSize | offset += blockSize | |||
FinalNode = FinalNode || length_encode( numBlock ) || `FF FF` | FinalNode = FinalNode || length_encode( numBlock ) || `FF FF` | |||
return TurboSHAKE256(FinalNode, `06`, outputByteLen) | return TurboSHAKE256(FinalNode, `06`, outputByteLen) | |||
end | end | |||
]]></artwork></figure></t> | ]]></sourcecode> | |||
</section> | </section> | |||
</section> | </section> | |||
</back> | </back> | |||
</rfc> | </rfc> | |||
End of changes. 128 change blocks. | ||||
758 lines changed or deleted | 778 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |