Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • car/libdap-crypto
1 result
Show changes
Showing
with 2742 additions and 0 deletions
_list: Makefile.build support/Build/ToGlobalMakefile.xsl
bin/.build/Makefile: bin/.build/Makefile.expanded
mkdir -p $(dir $@)
xsltproc --xinclude -o $@ support/Build/ToGlobalMakefile.xsl $<
bin/.build/Makefile.expanded: Makefile.build
mkdir -p $(dir $@)
xsltproc --xinclude -o $@ support/Build/ExpandProducts.xsl $<
-include bin/.build/Makefile
.PHONY: clean
clean:
rm -rf bin/
<?xml version="1.0"?>
<!--
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<build all="all" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="lib/HighLevel.build"/>
<xi:include href="lib/LowLevel.build"/>
<xi:include href="lib/Ketje.build"/>
<xi:include href="lib/Keyak.build"/>
<xi:include href="tests/SUPERCOP/SUPERCOP.build"/>
<xi:include href="tests/NIST_LWC/NIST_LWC.build"/>
<xi:include href="doc/HOWTO-customize.build"/>
<!-- For the name of the targets, please see the end of this file. -->
<fragment name="common">
<h>lib/common/align.h</h>
<h>lib/common/brg_endian.h</h>
</fragment>
<!-- *** Utilities *** -->
<!-- To run many tests -->
<fragment name="KeccakTests" inherits="All">
<c>tests/UnitTests/main.c</c>
<c>tests/UnitTests/testSnP.c</c>
<h>tests/UnitTests/testSnP.inc</h>
<h>tests/UnitTests/testSnP.h</h>
<c>tests/UnitTests/testPlSnP.c</c>
<h>tests/UnitTests/testPlSnP.inc</h>
<h>tests/UnitTests/testPlSnP.h</h>
<c>tests/UnitTests/testSponge.c</c>
<h>tests/UnitTests/testSponge.inc</h>
<h>tests/UnitTests/testSponge.h</h>
<c>tests/UnitTests/testDuplex.c</c>
<h>tests/UnitTests/testDuplex.inc</h>
<h>tests/UnitTests/testDuplex.h</h>
<c>tests/UnitTests/testMotorist.c</c>
<h>tests/UnitTests/testMotorist.inc</h>
<h>tests/UnitTests/testMotorist.h</h>
<c>tests/UnitTests/testKeyakv2.c</c>
<h>tests/UnitTests/testKeyakv2.inc</h>
<h>tests/UnitTests/testKeyakv2.h</h>
<c>tests/UnitTests/testKetjev2.c</c>
<h>tests/UnitTests/testKetjev2.h</h>
<h>tests/UnitTests/testKetjev2.inc</h>
<c>tests/UnitTests/genKAT.c</c>
<h>tests/UnitTests/genKAT.h</h>
<c>tests/UnitTests/testPerformance.c</c>
<h>tests/UnitTests/timing.h</h>
<h>tests/UnitTests/testPerformance.h</h>
<h>tests/UnitTests/timingSnP.inc</h>
<h>tests/UnitTests/timingPlSnP.inc</h>
<h>tests/UnitTests/timingSponge.inc</h>
<h>tests/UnitTests/timingKeyak.inc</h>
<c>tests/UnitTests/testKeccakPRG.c</c>
<h>tests/UnitTests/testKeccakPRG.inc</h>
<h>tests/UnitTests/testKeccakPRG.h</h>
<c>tests/UnitTests/testKangarooTwelve.c</c>
<h>tests/UnitTests/testKangarooTwelve.h</h>
<c>tests/UnitTests/testKravatte.c</c>
<h>tests/UnitTests/testKravatte.h</h>
<c>tests/UnitTests/testKravatteModes.c</c>
<h>tests/UnitTests/testKravatteModes.h</h>
<c>tests/UnitTests/testSP800-185.c</c>
<h>tests/UnitTests/testSP800-185.h</h>
<gcc>-lm</gcc>
</fragment>
<!-- To compute a hash of a file -->
<fragment name="KeccakSum" inherits="FIPS202 SP800-185 KangarooTwelve">
<c>util/KeccakSum/KeccakSum.c</c>
<c>util/KeccakSum/base64.c</c>
<h>util/KeccakSum/base64.h</h>
</fragment>
<!-- To make a library -->
<fragment name="libkeccak.a" inherits="All"/>
<fragment name="libkeccak.so" inherits="All"/>
<!-- *** CAESAR-related targets *** -->
<fragment name="crypto_aead_test">
<h>tests/SUPERCOP/test_crypto_aead.h</h>
<c>tests/SUPERCOP/test_crypto_aead.c</c>
</fragment>
<!-- *** Xoo *** -->
<fragment name="XooTests" inherits="XooAll">
<c>tests/UnitTests/testXooMain.c</c>
<c>tests/UnitTests/testXooSnP.c</c>
<h>tests/UnitTests/testXooSnP.inc</h>
<h>tests/UnitTests/testXooSnP.h</h>
<c>tests/UnitTests/testXooPlSnP.c</c>
<h>tests/UnitTests/testXooPlSnP.inc</h>
<h>tests/UnitTests/testXooPlSnP.h</h>
<c>tests/UnitTests/testXoofff.c</c>
<h>tests/UnitTests/testXoofff.h</h>
<c>tests/UnitTests/testXoofffModes.c</c>
<h>tests/UnitTests/testXoofffModes.h</h>
<c>tests/UnitTests/testXoodyak.c</c>
<h>tests/UnitTests/testXoodyak.h</h>
<c>tests/UnitTests/testXooPerformance.c</c>
<h>tests/UnitTests/testXooPerformance.h</h>
<h>tests/UnitTests/timing.h</h>
<h>tests/UnitTests/timingXooSnP.inc</h>
<h>tests/UnitTests/timingXooPlSnP.inc</h>
<h>lib/low/common/SnP-Relaned.h</h>
<c>lib/high/Keccak/KeccakSpongeWidth1600.c</c>
<h>lib/high/Keccak/KeccakSpongeWidth1600.h</h>
<gcc>-lm</gcc>
</fragment>
<!-- To make a library -->
<fragment name="libXoo.a" inherits="XooAll"/>
<fragment name="libXoo.so" inherits="XooAll"/>
<!-- *** Targets *** -->
<fragment name="serial-fallbacks" inherits="1600times2on1 1600times4on1 1600times8on1"/>
<!-- Reference implementations -->
<fragment name="reference" inherits="reference200 reference400 reference800 reference1600 serial-fallbacks Ket-SnP XooReference XooOptimizedTimes4_On1 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1">
<c>tests/UnitTests/displayIntermediateValues.c</c>
<h>tests/UnitTests/displayIntermediateValues.h</h>
<define>KeccakReference</define>
<gcc>-O</gcc>
</fragment>
<!-- Reference implementations dedicated to 32-bit platforms
(i.e., featuring bit interleaving for Keccak-p[1600]) -->
<fragment name="reference32bits" inherits="reference200 reference400 reference800 reference1600-32bits serial-fallbacks Ket-SnP">
<c>tests/UnitTests/displayIntermediateValues.c</c>
<h>tests/UnitTests/displayIntermediateValues.h</h>
<define>KeccakReference</define>
<define>KeccakReference32BI</define>
<gcc>-O</gcc>
</fragment>
<!-- Compact implementations -->
<fragment name="compact" inherits="compact200 reference400 compact800 compact1600 serial-fallbacks Ket-SnP"/>
<!-- Generically optimized 32-bit implementations -->
<fragment name="generic32" inherits="no_parallel reference200 reference400 optimized800u2 inplace1600bi serial-fallbacks Ket-SnP XooOptimized32 XooOptimizedTimes4_On1 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1"/>
<!-- Generically optimized 32-bit implementations, featuring lane complementing -->
<fragment name="generic32lc" inherits="reference200 reference400 optimized800lcu2 inplace1600bi serial-fallbacks Ket-SnP"/>
<!-- Generically optimized 64-bit implementations -->
<fragment name="generic64" inherits="reference200 reference400 optimized800ufull optimized1600ufull serial-fallbacks Ket-SnP"/>
<!-- Generically optimized 64-bit implementations, featuring lane complementing -->
<fragment name="generic64lc" inherits="reference200 reference400 optimized800lcufull optimized1600lcufull serial-fallbacks Ket-SnP"/>
<!-- Assembler optimized 64-bit implementations -->
<fragment name="asmX86-64" inherits="reference200 reference400 reference800 optimized1600AsmX86-64 serial-fallbacks Ket-SnP"/>
<!-- Assembler optimized 64-bit implementations -->
<fragment name="asmX86-64shld" inherits="reference200 reference400 reference800 optimized1600AsmX86-64shld serial-fallbacks Ket-SnP"/>
<!-- Implementations selected for the Nehalem microarchitecture -->
<fragment name="Nehalem" inherits="reference200 reference400 optimized800lcufull optimized1600lcufull SIMD128-SSE2u2 1600times4on2 1600times8on2 Ket-SnP XooOptimizedSIMD128 XooOptimizedTimes4_SIMD128 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1"/>
<!-- Implementations selected for the Sandy Bridge microarchitecture -->
<fragment name="SandyBridge" inherits="reference200 reference400 optimized800lcufull optimized1600lcufullshld SIMD128-SSE2ufull 1600times4on2 1600times8on2 Ket-SnP"/>
<!-- Implementations selected for the Bulldozer microarchitecture -->
<fragment name="Bulldozer" inherits="reference200 reference400 optimized800lcufull optimized1600XOPufull SIMD128-XOPufull 1600times4on2 1600times8on2 Ket-SnP"/>
<!-- Implementations selected for the Haswell and Skylake microarchitectures -->
<fragment name="Haswell" inherits="reference200 reference400 optimized800lcufull optimized1600AVX2 SIMD128-SSE2u2 SIMD256-AVX2u12 1600times8on4 Ket-SnP XooOptimizedSIMD128 XooOptimizedTimes4_SIMD128 XooOptimizedTimes8_AVX2 XooOptimizedTimes16_On1"/>
<!-- Implementations selected for the SkylakeX microarchitecture -->
<fragment name="SkylakeX" inherits="reference200 reference400 optimized800lcufull optimized1600AVX512a SIMD512-2-AVX512u12 SIMD512-4-AVX512u12 SIMD512-8-AVX512u12 Ket-SnP XooOptimizedSIMD512 XooOptimizedTimes4_AVX512 XooOptimizedTimes8_AVX512 XooOptimizedTimes16_AVX512"/>
<!-- Implementations selected for ARMv6 -->
<fragment name="ARMv6" inherits="optimized200ARMv6M optimized400ARMv6M optimized800ARMv6Mu2 optimized1600ARMv6Mu2 serial-fallbacks Ket-optimizedLE XooOptimizedARMv6 XooOptimizedTimes4_On1 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1"/>
<!-- Implementations selected for ARMv6M -->
<fragment name="ARMv6M" inherits="optimized200ARMv6M optimized400ARMv6M optimized800ARMv6Mu2 optimized1600ARMv6Mu2 serial-fallbacks Ket-optimizedLE XooOptimizedARMv6M XooOptimizedTimes4_On1 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1"/>
<!-- Implementations selected for ARMv7M -->
<fragment name="ARMv7M" inherits="optimized200ARMv7M optimized400ARMv7M optimized800ARMv7Mu2 inplace1600ARMv7M serial-fallbacks Ket-ARMv7M XooOptimizedARMv7M XooOptimizedTimes4_On1 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1"/>
<!-- Implementations selected for ARMv7A -->
<fragment name="ARMv7A" inherits="reference200 reference400 optimized800ARMv7Au2 optimized1600ARMv7A 1600times2ARMV7A 1600times4on2 1600times8on2 Ket-optimizedLE XooOptimizedARMv7A XooOptimizedTimes4_On1 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1"/>
<!-- Implementations selected for ARMv8A -->
<fragment name="ARMv8A" inherits="reference200 reference400 optimized800ARMv8A optimized1600ARMv8A serial-fallbacks Ket-optimizedLE"/>
<!-- Implementations selected for 8-bit AVR -->
<fragment name="AVR8" inherits="optimized200AVR8 optimized400AVR8 optimized800AVR8 optimized1600AVR8 serial-fallbacks Ket-SnP XooOptimizedAVR8 XooOptimizedTimes4_On1 XooOptimizedTimes8_On1 XooOptimizedTimes16_On1"/>
<!-- Target names are of the form x/y where x is taken from the first set and y from the second set. -->
<group all="Keccak">
<product delimiter="/">
<factor set="reference reference32bits compact generic32 generic32lc generic64 generic64lc asmX86-64 asmX86-64shld Nehalem SandyBridge Bulldozer Haswell SkylakeX ARMv6 ARMv6M ARMv7M ARMv7A ARMv8A AVR8"/>
<factor set="KeccakTests KeccakSum libkeccak.a libkeccak.so"/>
</product>
</group>
<!-- Reference implementations -->
<fragment name="Xreference" inherits="XooReference no_parallel">
<define>XooReference</define>
<gcc>-O</gcc>
</fragment>
<fragment name="Xoptimized32" inherits="XooOptimized32 no_parallel"/>
<group all="Xoodoo">
<product delimiter="/">
<factor set="reference generic32 Nehalem Haswell SkylakeX ARMv6 ARMv6M ARMv7M ARMv7A AVR8"/>
<factor set="XooTests libXoo.a libXoo.so"/>
</product>
</group>
<group all="Xoodyak">
<product delimiter="/">
<factor set="Xreference Xoptimized32 XSIMD128 XSIMD512 XARMv6M XARMv7M"/>
<factor set="Xoodyak_aead_kat Xoodyak_hash_kat Xoodyak_aead_pack Xoodyak_hash_pack"/>
</product>
</group>
</build>
# What is the XKCP?
The **eXtended Keccak Code Package** (or the **Xoodoo and Keccak Code Package**, in both cases abbreviated as **XKCP**) gathers different free and open-source implementations of the [Keccak sponge function family](https://keccak.team/keccak.html)
and closely related variants, such as
* the SHAKE extendable-output functions and SHA-3 hash functions from [FIPS 202][fips202_standard],
* the cSHAKE, KMAC, ParallelHash and TupleHash functions from [NIST SP 800-185][sp800_185_standard],
* the [Ketje v2][caesar_ketje] and [Keyak v2][caesar_keyak] authenticated encryption schemes,
* the fast [KangarooTwelve][k12] extendable-output function,
* the [Kravatte](https://keccak.team/kravatte.html) pseudo-random function and its modes,
as well as the [Xoodoo][XoodooCookbook] permutation and
* the [Xoofff][XoodooCookbook] pseudo-random function and its modes (experimental),
* the [Xoodyak][XoodooCookbook] scheme (submission to the NIST lightweight crypto standardization process).
# What does the XKCP contain?
First, the services available in this package are divided into high-level and low-level services. In a nutshell, the low level corresponds to Keccak-_f_[1600] and basic state manipulation, while the high level contains the constructions and the modes for, e.g., sponge functions, hashing or authenticated encryption. For more details, please see the section "_How is the code organized?_" below.
Then, the XKCP also contains some utilities for testing and illustration purposes.
Finally, the project contains some standalone implementations.
## High-level services
When used as a library or directly from the sources, the XKCP offers the high-level services documented in the following header files:
* [`SimpleFIPS202`](lib/high/Keccak/FIPS202/SimpleFIPS202.h), the six approved FIPS 202 instances (SHAKE128, SHAKE256 and the SHA-3 hash functions) through simple functions.
* [`KeccakHash`](lib/high/Keccak/FIPS202/KeccakHash.h), the six approved FIPS 202 instances, as well as any Keccak instance based on Keccak-_f_[1600]. This more advanced interface proposes a message queue (init-update-final) and supports bit-level inputs if needed.
* [`SP800-185`](lib/high/Keccak/SP800-185/SP800-185.h), the functions (cSHAKE, KMAC, ParallelHash and TupleHash) in the official NIST SP 800-185 standard.
* [`KeccakSponge`](doc/KeccakSponge-documentation.h), all Keccak sponge functions, with or without a message queue.
* [`KeccakDuplex`](doc/KeccakDuplex-documentation.h), all Keccak duplex objects.
* [`KeccakPRG`](doc/KeccakPRG-documentation.h), a pseudo-random number generator based on Keccak duplex objects.
* [`Keyakv2`](doc/Keyak-documentation.h), the authenticated encryption schemes River, Lake, Sea, Ocean and Lunar Keyak.
* [`Ketjev2`](doc/Ketje-documentation.h), the lightweight authenticated encryption schemes Ketje Jr, Ketje Sr, Ketje Minor and Ketje Major.
* [`KangarooTwelve`](lib/high/KangarooTwelve/KangarooTwelve.h), the fast hashing mode based on Keccak-_p_[1600, 12] and Sakura coding.
* [`Kravatte`](lib/high/Kravatte/Kravatte.h) and [`KravatteModes`](lib/high/Kravatte/KravatteModes.h), the pseudo-random function Kravatte, as well as the modes on top of it (SANE, SANSE, WBC and WBC-AE).
* [`Xoofff`](lib/high/Xoofff/Xoofff.h) and [`XoofffModes`](lib/high/Xoofff/XoofffModes.h), the pseudo-random function Xoofff, as well as the modes on top of it (SANE, SANSE, WBC and WBC-AE).
* [`Xoodyak`](doc/Xoodyak-documentation.h), the lightweight cryptographic scheme Xoodyak that can be used for hashing, encryption, MAC computation and authenticated encryption.
## Low-level services
The low-level services implement the different permutations Keccak-_f_[200 to 1600] and Keccak-_p_[200 to 1600]. Note that these two permutation families are closely related. In Keccak-_p_ the number of rounds is a parameter while in Keccak-_f_ it is fixed. As Keccak-_f_ are just instances of Keccak-_p_, we focus on the latter here.
The low-level services provide an opaque representation of the state together with functions to add data into and extract data from the state. Together with the permutations themselves, the low-level services implement what we call the **state and permutation** interface (abbreviated **SnP**). For parallelized implementation, we similarly use the **parallel** state and permutation interface or **PlSnP**.
* In [`lib/low/`](lib/low/), one can find implementations of the following permutations for different platforms.
+ [`lib/low/KeccakP-200/`](lib/low/KeccakP-200/) for Keccak-_p_[200].
+ [`lib/low/KeccakP-400/`](lib/low/KeccakP-400/), for Keccak-_p_[400].
+ [`lib/low/KeccakP-800/`](lib/low/KeccakP-800/), for Keccak-_p_[800].
+ [`lib/low/KeccakP-1600/`](lib/low/KeccakP-1600/), for Keccak-_p_[1600]. This is the one used in the six approved FIPS 202 instances.
+ [`lib/low/Xoodoo/`](lib/low/Xoodoo/), for Xoodoo.
* In addition, one can find the implementation of parallelized permutations. There are both implementations based on SIMD instructions and "fallback" implementations relying on a parallelized with a lower degree implementation or on a serial one.
In both cases, the hierarchy first selects a permutation (or a permutation and a degree of parallelism) and then a given implementation. E.g., one finds in [`lib/low/KeccakP-1600-times4/`](lib/low/KeccakP-1600-times4/) the implementations of 4 parallel instances of Keccak-_p_[1600] and in [`lib/low/KeccakP-1600-times4/SIMD256/`](lib/low/KeccakP-1600-times4/SIMD256/) a 256-bit SIMD implementation.
The documentation of the low-level services can be found in [`SnP-documentation.h`](doc/SnP-documentation.h) and [`PlSnP-documentation.h`](doc/PlSnP-documentation.h).
## Utilities
The package contains:
* The possibility to create a static library **`libkeccak.a`** or a dynamic library **`libkeccak.so`**;
* [**Self-tests**](tests/UnitTests/main.c) that ensure that the implementation is working properly;
* [**KeccakSum**](util/KeccakSum/KeccakSum.c) that computes a hash of the file (or multiple files) given in parameter.
The self-tests contain also benchmarking code to measure the performance of the different functions. This is invoked with `KeccakTests -s`.
Note that on ARM processors, you may need to include the Kernel-PMU module, see [`Kernel-pmu.md`](support/Kernel-PMU/Kernel-pmu.md) for more details.
## Standalone implementations
The XKCP also provides a number of standalone implementations, including:
* a very [compact](https://keccak.team/2015/tweetfips202.html) C code of the FIPS 202 (SHA-3) standard in [`Standalone/CompactFIPS202/C/`](Standalone/CompactFIPS202/C/);
* a compact implementation in Python in [`Standalone/CompactFIPS202/Python/`](Standalone/CompactFIPS202/Python/);
* the reference code of KangarooTwelve in Python in [`Standalone/KangarooTwelve/Python/`](Standalone/KangarooTwelve/Python/).
# Under which license is the XKCP distributed?
Most of the source and header files in the XKCP are released to the **public domain** and associated to the [CC0](http://creativecommons.org/publicdomain/zero/1.0/) deed. The exceptions are the following:
* [`lib/common/brg_endian.h`](lib/common/brg_endian.h) is copyrighted by Brian Gladman and comes with a BSD 3-clause license;
* [`tests/UnitTests/genKAT.c`](tests/UnitTests/genKAT.c) is based on [SHA-3 contest's code by Larry Bassham, NIST](http://csrc.nist.gov/groups/ST/hash/sha-3/documents/KAT1.zip), which he licensed under a BSD 3-clause license;
* [`tests/UnitTests/timing.h`](tests/UnitTests/timing.h) is based on code by Doug Whiting, which he released to the public domain;
* [`KeccakP-1600-AVX2.s`](lib/low/KeccakP-1600/OptimizedAVX2/KeccakP-1600-AVX2.s) is licensed under the [CRYPTOGAMS license](http://www.openssl.org/~appro/cryptogams/) (BSD-like);
* [`support/Kernel-PMU/enable_arm_pmu.c`](support/Kernel-PMU/enable_arm_pmu.c) is licensed under the GNU General Public License by Bruno Pairault.
# How can I build the XKCP?
To build, the following tools are needed:
* *GCC*
* *GNU make*
* *xsltproc*
The different targets are defined in [`Makefile.build`](Makefile.build). This file is expanded into a regular makefile using *xsltproc*. To use it, simply type, e.g.,
> `make generic64/KeccakTests`
to build KeccakTests generically optimized for 64-bit platforms. The name before the slash indicates the platform, while the part after the slash is the executable to build. As another example, the static (resp. dynamic) library is built by typing `make generic64/libkeccak.a` (resp. `.so`) or similarly with `generic64` replaced with the appropriate platform name. An alternate C compiler can be specified via the `CC` environment variable.
Instead of building an executable with *GCC*, one can choose to select the files needed and make a package. For this, simply append `.pack` to the target name, e.g.,
> `make generic64/KeccakTests.pack`
This creates a `.tar.gz` archive with all the necessary files to build the given target.
The list of targets can be found at the end of [`Makefile.build`](Makefile.build) or by running `make` without parameters.
## Microsoft Visual Studio support (experimental)
The XKCP offers support for the creation of Microsoft Visual Studio (VS) project files. To get a project file for a given target, simply append `.vcxproj` to the target name, e.g.,
> `make generic32/KeccakTests.vcxproj`
This is still somehow experimental, but it should be easy to extend/adapt by someone with more experience with VS. (*Help welcome!*) In particular, please note the current limitations:
- The generated project files current target Win32 only, but this should be easy to adapt for 64-bit support. See the file [`ToVCXProj.xsl`](support/Build/ToVCXProj.xsl).
- The assembly code, as used in some targets, follows the GCC syntax and at this point cannot be used directly with VS.
# How do I build/extract just the part I need?
If you wish to make a custom target that integrates the cryptographic functions you need and nothing else, or if you just wish to get the source files to integrate them in another project, you can do this by following the steps described in [`doc/HOWTO-customize.build`](doc/HOWTO-customize.build). Some examples illustrate the process.
# How is the code organized?
The code is organized as illustrated in the following figure:
![Layers](doc/figures/Layers.png)
At the top, the high-level cryptographic services are implemented in plain C, without any specific optimizations. At the bottom, the low-level services implement the permutations and the state input/output functions, which can be optimized for a given platform. The interface between the two layers is called **SnP**.
The idea is to have a single, portable, code base for the high level and the possibility to dedicate the low level to certain platforms for best performance.
The modes and constructions can be found in [`lib/high/`](lib/high/), while the permutations are stored in [`lib/low/`](lib/low/).
The situation is similar for parallelized services, as illustrated on the following figure. The interface is adapated to the parallelism and is called **PlSnP**, with the implementations in [`lib/low/`](lib/low/).
![Parallel layers](doc/figures/ParallelLayers.png)
*Disclaimer*: the above figures aim at illustrative purposes only, as not all modes, constructions or permutations are currently implemented in the XKCP or represented on the figures.
# Where can I find more information?
About the XKCP, we gave some presentations on its motivation and structure, e.g.,
* at [FOSDEM in February 2017][FOSDEM2017] ([slides][slidesAtFOSDEM2017]),
* at [SPEED-B in October 2016][SPEEDB] ([slides][slidesAtSPEEDB]) ([paper][paperAtSPEEDB]),
* at the [SHA-3 Workshop in Santa Barbara in August 2014][SHA3workshop2014] ([slides][KCPslides]).
The XKCP follows an improved version of the structure proposed in the note ["A software interface for Keccak"][keccakinterface].
More information on the cryptographic aspects can be found:
* on Keccak at [`keccak.team`](https://keccak.team/keccak.html)
* on the FIPS 202 standard at [`csrc.nist.gov`](http://csrc.nist.gov/groups/ST/hash/sha-3/fips202_standard_2015.html)
* on the NIST SP 800-185 standard at [`keccak.team`](https://keccak.team/2016/sp_800_185.html)
* on Ketje at [`keccak.team`](https://keccak.team/ketje.html)
* on Keyak at [`keccak.team`](https://keccak.team/keyak.html)
* on KangarooTwelve at [`keccak.team`](https://keccak.team/kangarootwelve.html)
* on cryptographic sponge functions at [`keccak.team`](https://keccak.team/sponge_duplex.html)
* on Kravatte at [`keccak.team`](https://keccak.team/kravatte.html)
* on Xoodoo, Xoofff and Xoodyak at [`eprint.iacr.org`](https://eprint.iacr.org/2018/767)
* on the Farfalle construction at [`keccak.team`](https://keccak.team/farfalle.html)
# How can I contribute?
We welcome contributions in various forms, e.g., general feedback, bug reports, improvements and optimized implementations on your favorite platforms. The best is to do this through GitHub. Alternatively, you can send us a mail at `all` _-at-_ `keccak` _-dot-_ `team`.
# How can I use the standard FIPS 202 functions?
If you need to implement the standard FIPS 202 functions, the functions in [`SimpleFIPS202.h`](lib/high/Keccak/FIPS202/SimpleFIPS202.h) provide an easy way to get started. If a message queue and/or bit-level inputs are needed, then the macros in [`KeccakHash.h`](lib/high/Keccak/FIPS202/KeccakHash.h) can be helpful.
## Differences between Keccak and the standard FIPS 202 functions
Compared to the (plain) Keccak sponge function, the [FIPS 202 standard][fips202_standard] adds suffixes to ensure that the hash functions (SHA-3) and the XOFs (SHAKE) are domain separated (i.e., so that their outputs are unrelated even with equal inputs), as well as to make the SHAKE functions compatible with the [Sakura][sakura] tree hashing coding.
[sakura]: https://keccak.team/files/Sakura.pdf "Sakura: a flexible coding for tree hashing"
A brief summary:
* For the SHA-3 functions, append the bits "01" to the message prior to applying the pad10*1 rule.
* For the SHAKE functions, append the bits "1111" to the message prior to applying the pad10*1 rule.
When they refer to the functions in the [FIPS 202 standard][fips202_standard], the test cases in [`tests/TestVectors/`](tests/TestVectors/) include these suffixes.
# Acknowledgments
- `genKAT.c` based on the SHA-3 contest's genKAT.c by Larry Bassham, NIST
- `brg_endian.h` by Brian Gladman
- `timing.h` based on code by Doug Whiting
- `lib/low/KeccakP-1600/OptimizedAVX2/KeccakP-1600-AVX2.s` by Andy Polyakov and Ronny Van Keer
- `TweetableFIPS202.c` by D. J. Bernstein, Peter Schwabe and Gilles Van Assche
- `lib/low/KeccakP-800/Optimized64AsmARM/*` by Andre C. de Moraes
And thanks to all contributors!
***
The Keccak and Xoodoo designers: Guido Bertoni, Joan Daemen, Seth Hoffert,
Michaël Peeters, Gilles Van Assche, and Ronny Van Keer.
[keccakinterface]: https://keccak.team/files/NoteSoftwareInterface.pdf
[SHA3workshop2014]: http://csrc.nist.gov/groups/ST/hash/sha-3/Aug2014/index.html
[KCPslides]: http://csrc.nist.gov/groups/ST/hash/sha-3/Aug2014/documents/vanassche_keccak_code.pdf
[FOSDEM2017]: https://fosdem.org/2017/schedule/event/keccak/
[slidesAtFOSDEM2017]: https://fosdem.org/2017/schedule/event/keccak/attachments/slides/1692/export/events/attachments/keccak/slides/1692/KeccakAtFOSDEM2017.pdf
[fips202_standard]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf "FIPS 202 standard"
[sp800_185_standard]: https://doi.org/10.6028/NIST.SP.800-185 "NIST SP 800-185 standard"
[caesar_ketje]: https://keccak.team/ketje.html
[caesar_keyak]: https://keccak.team/keyak.html
[k12]: https://keccak.team/kangarootwelve.html
[SPEEDB]: http://ccccspeed.win.tue.nl/
[paperAtSPEEDB]: http://ccccspeed.win.tue.nl/papers/KeccakSoftware.pdf
[slidesAtSPEEDB]: http://ccccspeed.win.tue.nl/presentations/KeccakSoftware-slides.pdf
[XoodooCookbook]: https://eprint.iacr.org/2018/767
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#ifdef VERBOSE
#include <stdio.h>
#endif
void Keccak(int rate, int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen);
#ifdef TestAtBitLevel
void performTestBitLevel(unsigned int rate, unsigned int capacity, unsigned char *checksum)
{
#define inputByteSize 512
#define outputByteSize 512
unsigned char input[inputByteSize];
unsigned char output[outputByteSize];
unsigned char acc[outputByteSize];
unsigned int inputBitLength;
/* Acumulated test vector */
memset(acc, 0x00, sizeof(acc));
for(inputBitLength = 0; inputBitLength <= (inputByteSize*8); inputBitLength += (inputBitLength < 1600) ? 1 : 8) {
unsigned int i;
unsigned int inputByteLengthCeiling = (inputBitLength + 7) / 8;
/* Preparing some input value */
for(i=0; i<inputByteLengthCeiling; i++)
input[i] = inputBitLength - i;
if ((inputBitLength % 8) != 0)
input[inputByteLengthCeiling-1] &= (1 << (inputBitLength % 8)) - 1;
if ((inputBitLength % 8) == 0) {
Keccak(rate, capacity, input, inputBitLength/8, 0x01, output, outputByteSize);
}
else {
unsigned char delimitedSuffix = input[inputByteLengthCeiling-1] | (1 << (inputBitLength % 8));
Keccak(rate, capacity, input, inputBitLength/8, delimitedSuffix, output, outputByteSize);
}
#ifdef VERBOSE
printf("Keccak[r=%d, c=%d]\n", rate, capacity);
printf("Input of %d bits:", inputBitLength);
for(i=0; i<inputByteLengthCeiling; i++)
printf(" %02x", (int)input[i]);
printf("\n");
printf("Output of %d bits:", outputByteSize*8);
for(i=0; i<outputByteSize; i++)
printf(" %02x", (int)output[i]);
printf("\n\n");
#endif
for (i = 0; i < outputByteSize; i++)
acc[i] ^= output[i];
Keccak(1344, 256, acc, outputByteSize, 0x1F, acc, outputByteSize);
}
memcpy(checksum, acc, outputByteSize);
#ifdef VERBOSE
{
unsigned int i;
printf("Keccak[r=%d, c=%d]\n", rate, capacity);
printf("Checksum: ", outputByteSize);
for(i=0; i<outputByteSize; i++)
printf("\\x%02x", (int)checksum[i]);
printf("\n\n");
}
#endif
}
void testKeccakInstanceBitLevel(unsigned int rate, unsigned int capacity, const unsigned char *expected)
{
unsigned char checksum[outputByteSize];
performTestBitLevel(rate, capacity, checksum);
assert(memcmp(expected, checksum, outputByteSize) == 0);
#undef inputByteSize
#undef outputByteSize
}
#endif
void performTestByteLevel(unsigned int rate, unsigned int capacity, unsigned char delimitedSuffix, unsigned int outputByteLength, unsigned char *checksum)
{
#define inputByteSize 1024
#define outputByteSize 512
unsigned char input[inputByteSize];
unsigned char output[outputByteSize];
unsigned char acc[outputByteSize];
unsigned int inputByteLength;
assert(outputByteLength <= outputByteSize);
/* Acumulated test vector */
memset(acc, 0x00, sizeof(acc));
for(inputByteLength = 0; inputByteLength <= inputByteSize; inputByteLength++) {
unsigned int i;
/* Preparing some input value */
for(i=0; i<inputByteLength; i++)
input[i] = inputByteLength - i;
Keccak(rate, capacity, input, inputByteLength, delimitedSuffix, output, outputByteLength);
#ifdef VERBOSE
printf("Keccak[r=%d, c=%d] with suffix=%02x\n", rate, capacity, delimitedSuffix);
printf("Input of %d bytes:", inputByteLength);
for(i=0; i<inputByteLength; i++)
printf(" %02x", (int)input[i]);
printf("\n");
printf("Output of %d bytes:", outputByteLength);
for(i=0; i<outputByteLength; i++)
printf(" %02x", (int)output[i]);
printf("\n\n");
#endif
for (i = 0; i < outputByteLength; i++)
acc[i] ^= output[i];
Keccak(1344, 256, acc, outputByteLength, 0x1F, acc, outputByteLength);
}
memcpy(checksum, acc, outputByteLength);
#ifdef VERBOSE
{
unsigned int i;
printf("Keccak[r=%d, c=%d] with suffix=%02x and %d bytes of output\n", rate, capacity, delimitedSuffix, outputByteLength);
printf("Checksum: ", outputByteLength);
for(i=0; i<outputByteLength; i++)
printf("\\x%02x", (int)checksum[i]);
printf("\n\n");
}
#endif
}
void testKeccakInstanceByteLevel(unsigned int rate, unsigned int capacity, unsigned char delimitedSuffix, unsigned int outputByteLength, const unsigned char *expected)
{
unsigned char checksum[outputByteSize];
performTestByteLevel(rate, capacity, delimitedSuffix, outputByteLength, checksum);
assert(memcmp(expected, checksum, outputByteLength) == 0);
#undef inputByteSize
#undef outputByteSize
}
int genKAT_main();
int main()
{
testKeccakInstanceByteLevel(1344, 256, 0x1F, 168, "\xc0\x96\x67\xb2\x04\xfe\x18\xea\x1b\x10\x93\x15\xd6\xd8\x80\x9a\xe6\xd4\x1f\xc2\x13\x07\x55\x1d\x65\x2d\xfa\x8e\x12\x93\xb8\x09\xa7\x3e\x14\x3a\x6f\xb9\x52\x61\x79\xbd\x34\xe9\x8b\x16\xd1\x60\x94\x83\xc2\x89\x3e\x71\x44\x0f\xa0\x7a\x54\x9c\xeb\x6d\x7f\xbe\xd8\x76\x39\x01\x9c\x4a\x2e\x25\x07\xaa\x36\x0d\x54\xf2\x78\x68\xc0\xd3\x49\x5c\x9f\xaa\x56\x65\xba\x8c\xb2\x59\x30\x46\x2a\x5a\x14\x29\xb1\x6f\xc7\xd4\x1e\xe2\xbd\xb6\xe4\x62\x39\x30\x6e\xb3\xd5\xc8\xd8\x73\xfe\x6c\x71\xc9\x3e\x40\x4e\x60\x61\x64\xa5\x6e\x59\x30\xe5\xe3\xbb\x11\x16\x0e\x2d\xb0\xab\x95\xce\xfd\x09\xa8\x08\xf9\xfd\xf1\x31\x47\x4b\x3b\xb5\x79\xcf\x6b\x98\xe7\xeb\x44\xaa\xd2\x3a\x31\x83\x15\x39\xb7"); /* SHAKE128 */
testKeccakInstanceByteLevel(1088, 512, 0x1F, 136, "\x37\xf9\xa2\x05\xb9\x2e\xdf\x89\xb8\x18\xa6\x89\xd2\xa9\x2d\x93\xb8\x63\x8e\x21\x61\x24\x38\x2a\x9f\xe6\x08\xfe\xf0\x0c\x6a\x54\xbe\x60\xa7\x09\x36\xfa\x49\xa6\x11\xf8\xc8\x10\x96\xdf\x18\x51\x01\x29\x34\xfe\xb4\xd4\xf3\x2c\x95\x03\xb6\xa1\x97\xa4\x7f\xf5\xe1\xa5\xc8\x18\x6f\x1e\xc6\xef\xe9\x90\x07\x89\x2b\xb1\xde\x0a\xe0\x42\xf0\x31\x35\xd0\x51\x30\x19\x2e\x04\xc3\xf9\x92\x4d\x94\x40\x63\xe1\x07\x12\xf5\xf5\x7e\xb4\xba\xcf\x40\x78\xff\x35\xda\x99\x3e\x94\x97\xfc\x46\xdb\x2c\x4c\xa1\x76\x0b\x06\x15\xf4\xd6\xf5\x4b\x32\x66\x27\xb5\xf1\x48"); /* SHAKE256 */
testKeccakInstanceByteLevel(1152, 448, 0x06, 28, "\xf3\x61\xcb\xd5\x9b\x84\x1d\x8e\x0c\xdb\xd4\x06\x1e\xb5\x7a\xea\x75\x1d\x34\x36\x01\x23\x6e\xef\x0c\x5d\x81\x7b"); /* SHA3-224 */
testKeccakInstanceByteLevel(1088, 512, 0x06, 32, "\x99\xa3\xc2\x65\xcf\xdd\x51\x68\x40\xd1\x78\x46\xd7\x53\xf6\x3e\x5f\xbf\x2e\xce\x47\x51\xa3\xf0\x59\x35\x29\x0b\x56\x19\x0f\xcb"); /* SHA3-256 */
testKeccakInstanceByteLevel( 832, 768, 0x06, 48, "\x06\xdf\x16\xce\x63\xd3\xcc\x5f\xf6\xae\xc8\x8e\x2f\x49\xa6\xe9\x53\x88\x12\xfc\xdd\x04\xfe\x88\x09\x5a\x41\x93\x76\xd3\x74\xf5\x5f\x09\x45\xa1\x5f\xaa\x20\x5c\x8f\x12\x8e\xcb\xbe\xe2\xb0\x10"); /* SHA3-384 */
testKeccakInstanceByteLevel( 576, 1024, 0x06, 64, "\x9a\xdb\x76\x33\xcc\xb6\x44\xe7\x16\x19\x93\x6a\xa5\xac\x2e\xd1\x01\x51\xa5\x2c\xcf\xc6\xf7\x0d\x6d\xd7\x50\x9f\x57\x35\x9e\x27\xd4\xa2\x62\x24\xab\xc7\x87\xfc\xcd\x62\x74\x9d\x20\x61\x7f\x87\x29\xb3\x3e\x9b\x89\x51\x0c\xba\x20\x8a\x55\x98\xeb\x3b\xf5\x61"); /* SHA3-512 */
#ifdef TestAtBitLevel
testKeccakInstanceBitLevel(576, 1024, "\x18\x6b\x69\x2f\xaa\x41\x4a\x9d\x8a\xf1\x0e\x9c\x2a\xfc\x99\x2d\x38\x16\xac\xfe\xed\x37\xc9\x42\x89\x9c\xd9\x0d\x75\xce\x64\x0c\x7d\xb3\xfb\xe5\xde\x15\x7e\x26\x72\x35\xd1\x1e\xfc\x00\x26\xfd\x9b\x57\x3c\x21\xeb\xdd\xad\x42\x26\x72\x22\xbf\x39\x4e\x2a\xdc\x00\x26\x36\x72\xbc\xf7\xb0\xef\x54\x0e\x33\xdf\xfa\x56\xdb\xa4\xe0\xc4\x22\xa1\xfa\xe0\xcd\x5a\x8b\x15\x7f\x34\x27\x53\x8f\x2f\x2a\x0c\xfe\xf7\x06\x7f\x8f\x42\x4a\xea\x31\x20\x2c\x63\x11\x8d\x72\x14\x14\xd9\xfb\x1a\x32\xb4\xbd\x6a\xbe\xf5\x2c\xa0\xfd\x1e\x85\xc2\xcc\x6f\x09\x86\xca\x70\x0a\x35\xe8\x2e\xfe\xb3\xa3\x9e\x25\xec\x4f\x2c\xd4\x87\x34\x03\x4d\xc8\x3f\x39\x2f\xa1\xfd\x6d\xe1\xd8\xab\x73\x97\x01\xb1\x60\xd7\x74\x03\x19\x75\x24\x71\xe4\x5a\x80\x8e\xb5\x15\x40\x24\xd2\x28\x5f\xc7\x42\xc9\xbf\xeb\x49\x9b\x7f\x1d\x73\x8c\xa0\x7f\x6b\xf8\x40\xc5\x78\x11\x11\xcc\x88\xf5\x9f\x31\xe7\xe5\x7d\xff\xb1\x31\x5f\x58\x31\xb4\xf3\x8c\xaa\xeb\x1e\xd6\x19\xc2\xb0\x65\x02\xb5\x74\xfe\xa2\x6c\xa2\x69\xb2\x20\xdb\x8e\x69\x1f\x8e\x67\xdf\x4b\x38\x28\xa7\x49\xa2\x57\x97\x8a\x69\x3c\x3f\x72\x23\xcb\xf1\x7d\x11\x7e\x6a\xd7\xc4\x12\xfd\xd7\x22\x07\xd7\xaf\x22\x42\xa4\xd8\x75\x79\x89\x1b\x4a\x48\x1a\xec\x81\x61\x83\x06\xbc\x9f\x15\x1e\xa3\x44\xfb\xd6\x4d\xb0\x2a\xa2\x57\x4c\x85\x45\x29\xd4\x43\xd0\xe4\x4a\x7a\x21\xbf\x2f\x9c\xe3\x41\x9e\x61\x7a\x0f\x00\xd8\x76\x3e\x69\x30\x6c\x20\x3b\x5a\x80\x1b\x59\x08\x26\x0a\x69\x86\xb4\x07\x69\xc1\x56\xad\x79\x7d\x3f\xe0\xed\x0c\xad\xa1\x21\x10\x30\x43\x11\x39\xad\xc0\xde\x25\x52\x4c\x9b\xcd\xf1\xaa\x2d\x21\x75\xf2\xfc\xc0\xab\xdf\x70\xac\xbc\x8e\x11\x48\x0c\x30\xf5\xc4\xe8\x7e\xe3\x08\x16\x55\x23\x0f\x3a\xc5\x06\xe4\xc2\x4b\xcb\xd7\xb8\x90\x83\x9e\x9f\x8e\xf8\x9a\x4a\xd0\x7a\xfd\x31\x10\xf0\x2c\x99\x2e\xdf\xf8\x99\x56\x0c\x08\x37\x1c\x7c\x78\x07\xd8\x0c\x97\x76\x75\xd1\x7b\x17\x41\xcb\xcf\xb3\x39\x51\x3b\x4c\xeb\x3f\x05\x79\x67\xf2\x0c\x59\x7d\xba\x4e\xb4\x07\x2d\xfa\xc9\x27\x42\xc4\x40\x91\xae\xed\xd7\xc7\x5e\x58\xd4\xa6\x27\x68\x0d\x67\xc6\xcc\x79\x2d\xa9\x95\x17\x34\x3a\xb7\xeb\x05\x4b\x60\x37\x56\xab\x0d\x31\x18\xb2\x05\x40\xa0\x62\x13"); /* Keccak[r=576, c=1024] */
testKeccakInstanceBitLevel(832, 768, "\xf7\x65\xbd\xf7\xa9\x55\xff\xe0\xf1\x75\xc8\x7b\x0e\xdc\xf2\xa0\x49\x57\xc8\x76\xd6\x40\x1f\xbd\x0f\x7a\xbd\x7a\x82\xef\x44\xc7\x13\x69\x09\x29\xc3\x30\x6f\x0f\x10\xe9\x41\xd3\x04\x59\x93\x45\x53\x28\x6c\xf6\xd4\x7b\x97\x38\xf7\x18\xce\x07\xee\x40\x66\xcb\x4f\x10\xcf\x0f\xeb\xc1\x41\xca\x70\x49\xc6\xa7\xa7\xec\xd1\x2d\xe8\xad\xcf\x78\xe6\x1a\x73\xbf\xec\x0e\x56\x0c\x79\x61\xa3\xbd\xc0\x10\x19\x64\x9f\x78\x89\x94\xb1\xff\x71\xcb\x0a\x07\xaa\x9a\xb5\x16\xce\x2c\xa8\x3b\xf5\x59\xa2\xbe\x52\x09\xd4\x26\xaf\x13\x9a\x0f\x41\x53\x35\xa4\xdd\xed\x0c\x8a\x9c\x3a\x9b\x64\xef\x72\xa9\xa6\x98\x05\xd1\xb8\xb0\xe4\xe1\x21\x01\xc0\xea\xe1\x6c\x15\x2d\x49\x5e\xea\xd3\xc5\x76\xc0\xd5\x54\x9d\xa7\x6d\xc1\x00\x30\x80\x83\xf9\x0c\xb5\x75\x66\xba\xb4\x65\xf2\xc5\xd4\x76\x1e\x0f\xeb\x21\x72\xb0\x8d\xd3\x81\x10\x00\x18\x39\x6f\x47\x9e\x80\xdc\xc1\x04\x94\x97\xbc\x4d\xaa\xe9\x4d\x6e\x92\x2a\xcc\xb8\x55\xf2\x8c\x5b\xed\xea\xe8\x09\x0d\x64\xcc\xfe\xd1\xfb\x5e\x24\x3c\xdf\x19\x56\xf3\xd4\x24\x3a\x9b\x5f\x02\x90\x3d\x33\xdb\xea\xb7\xbb\xe2\xf1\xf7\xec\x72\xe9\x67\xad\x94\x38\x28\xeb\x26\x66\x46\x3b\x00\x07\xa1\x88\xd7\x0e\x04\x3c\x8f\x5c\xa1\x1e\xf7\x1b\xcf\x28\x10\x1a\x46\x98\x26\xbe\xcd\x3a\x66\x81\x81\x65\xae\xa4\x4b\x00\xae\xf0\xb9\x4d\x4b\x29\x86\xff\x3c\x1c\x01\xbe\x74\x65\x09\xed\x96\x17\xd7\xb7\x30\x39\x05\x4f\x78\xe5\x15\x33\x44\xa5\x78\x9d\xe6\x1f\x4f\x1f\xa3\x32\xa1\xcf\xc4\x2e\xf2\x05\x3e\xa4\x16\x88\x62\x6d\xe5\xd6\x24\x2d\x21\xa1\x6e\xd8\x79\x90\x58\xc7\x7d\x63\xd6\x18\x58\xf4\xd7\xb1\x36\x3f\x69\x12\x85\xa4\xbb\xe3\xda\x32\x3c\xd8\x70\xf8\xda\x30\xaa\x53\xae\x2b\xa6\xde\xe8\x51\xfb\x11\x17\xfd\x41\x52\x27\x7f\xab\x07\x8c\x69\x90\x60\x88\x4e\xab\xae\x5c\x32\x19\x3a\xb6\x46\xda\x38\xf1\x81\xef\xfa\x47\x46\x86\xce\x71\x38\x51\xf2\x38\x20\x3d\x81\x64\x23\xad\xbc\x14\x23\x50\xdd\x6f\x56\x00\x50\xa8\x48\xd5\xc8\x5f\xb5\x65\x5a\xa7\x0f\xa3\xed\xc2\xdf\xb6\x12\x51\x4e\xae\xe5\x4c\xf7\xb3\x54\xc0\x93\xe1\x6a\x03\x06\xb5\x9f\xce\x73\xea\x89\x43\x40\x1b\x41\x9e\xae\x87\xdb\xeb\x35\x1f\x7b\x90\x70\xd0\x03\x9d\x74\x27\xd5\xf4\x06\xbd\x7c"); /* Keccak[r=832, c=768] */
testKeccakInstanceBitLevel(1024, 576, "\x6e\x20\xc9\xfd\xb0\x18\x81\x89\xcc\x0e\xac\x60\x18\x9d\x70\x75\x59\xe6\xc9\xa7\x05\xce\x20\xce\x96\xda\x5a\xf8\x05\x56\x1c\xdd\xd1\xdf\xe7\xfc\x17\xef\xd9\xdf\x0b\x34\xe6\x51\xdf\xd7\x65\xdd\xeb\x7d\x4b\x54\x33\x6a\xda\xde\x55\x73\x92\x51\xfb\x4a\xe7\x95\x86\x02\xb2\x75\xee\x39\xb2\x4a\x34\xaa\x32\x5c\x63\xc6\x7e\x8b\xef\x9c\x18\x9d\xe6\x83\x8d\x0a\xf7\x5b\x80\x58\x62\x8e\xf0\xfa\x0a\xee\xe0\x18\xb2\xb8\x67\x83\x31\x47\xe5\x07\x97\x79\x97\xb9\x76\x8b\xd8\x31\x13\x9d\x23\xd0\x9c\x1b\x98\xbe\xfb\x07\x57\x8b\x4d\x52\xc8\x3c\xc1\xc4\x77\xfb\x48\x2c\x05\xd5\x1b\x3f\x2e\xf2\x1d\xe5\x23\xf2\xe0\x07\x56\xda\xdc\x46\xc6\x0f\xa9\x88\xa7\xb2\xd2\x73\x8a\x73\xea\x2f\xec\x24\x5f\xdf\xb9\x91\x37\x4f\xfa\x17\xf3\x24\x75\x7e\x76\xa1\xce\x69\x47\x7b\x81\xb6\x2b\x3d\x3b\x8d\xa2\xfc\x25\x4b\x4d\x58\xd8\x56\x8e\x15\x7b\x32\xe7\x20\xb6\x15\x1c\x9b\x4f\xf8\x61\x87\x95\xc6\x39\x2f\x7c\x72\x74\xc8\x5d\xfd\x41\x3b\x11\x32\x24\x47\x88\xa4\x23\x88\x60\x3c\xf6\xc4\x00\x57\xe6\xb6\x23\xf3\x7b\x64\x64\xb6\xd7\xef\x58\xc3\x3e\x4c\x32\x86\x5b\x84\x60\x31\x36\x47\x8b\x0d\x6b\x1b\xb0\xc1\x47\x78\x16\xe9\x35\xee\x0e\x82\xc1\xaf\x7f\xa2\xfc\x2c\xf8\x37\xac\x06\x18\x59\x65\x16\xc2\xd2\x5f\x5f\x31\x25\xc7\xeb\xf8\x2b\x57\x05\xcb\xdd\x8c\x25\xef\xfc\xe1\xf6\xaf\xb3\x62\x40\x1a\xa3\xde\x86\x54\x3b\x6f\x2d\xae\x4d\x67\x03\xf7\x30\x93\x26\x04\xc0\x83\x4f\x44\x19\xd2\x82\x2d\x72\x3d\x07\xe9\xae\x14\x07\xe3\x82\x23\xa0\x7f\xc1\x54\x6b\x7b\xbe\x60\xa4\x4e\x85\x4a\xca\x94\x99\xfc\x87\x3e\xd6\x71\x95\xad\x86\xb7\xe2\x33\x47\x99\xbe\x74\x05\xf8\xd1\xb3\xaf\xa1\x4f\x6b\x05\x7b\x2b\x81\x2f\x00\x54\x79\xc8\xb0\x53\x92\x03\x3a\x19\xc0\xb2\x54\xac\xdc\x38\x15\x4e\x49\xff\x53\xbc\xac\x75\x5d\xc1\x96\xea\x5e\x9d\x35\xc8\x80\x8b\x02\x7d\x0a\xac\xa3\x85\xf2\xef\x13\x08\xbf\x0d\x89\x28\xc1\xba\xcf\x71\xfa\xca\xa6\xe9\xfe\x2b\xf0\x62\x33\x11\x5a\x63\xbf\x9b\xd4\x7b\x0c\x43\x08\x0e\xa6\x62\xaf\xb7\x20\x57\x31\x32\xd2\xb8\xe1\x56\xf8\x7f\x6c\xa6\xee\x9e\x69\x88\xb0\x9e\x00\x47\x07\xff\xf6\x58\x57\x79\x04\x34\x50\x13\x5f\xd9\x2b\x08\xae\x52\x1d\x2b\x2c\x43\x14\x86\xaa\xea"); /* Keccak[r=1024, c=576] */
testKeccakInstanceBitLevel(1088, 512, "\x49\x39\x13\x5e\xcf\x8d\x28\x1f\x3b\xfa\x00\xac\x6a\x3d\xb5\x09\x0a\xaa\x75\x5c\xb3\x16\x44\xc4\x87\xa3\xac\xf5\xa1\xfe\x29\x23\x1c\xce\x0c\x4c\x5a\xdb\x21\x8b\xc4\xc8\x8a\x1a\x6a\x53\xc1\xdd\x66\x90\x0a\xe1\x80\xc7\xb3\x45\x5b\xdc\x00\xa8\x3a\xf3\x37\xb7\xb0\xc5\x22\xac\x6f\xd1\x70\x85\xb5\x03\x65\x96\xcf\xe0\x2a\x97\x40\x64\xf9\xf4\xca\xb3\x72\x93\x6b\xfc\x9c\x91\x82\x00\x68\x58\x45\x27\xeb\xe4\x5c\x52\xf0\x5b\xe1\x88\xfd\x9c\x96\x44\xcb\xde\xe6\xb3\x50\xb9\xdc\x74\xcf\x80\x42\x12\xca\xfd\xa4\x51\x44\xe2\xc0\x3f\x29\x4e\xb2\xca\x61\x8c\xab\x10\x19\xf7\x69\x04\x16\x6d\xb6\x0f\xc3\xc0\x52\xb3\x2c\xb0\xa4\xaa\xbc\x51\x3e\xa1\x13\x4b\xc8\xe6\x37\x9c\x12\xb4\x39\xf1\x5d\x9e\x22\xb3\x1c\x71\xa7\x56\xa0\xf5\x12\xa2\xb0\x8a\xa8\xa3\xd6\x96\xce\xd2\x78\x05\x34\xa8\x31\x6c\x34\xea\x05\x1b\xda\x9f\xf3\x0b\x4b\x7e\x0d\x54\xe9\xf9\x13\x06\x5c\x05\x32\x14\xf0\x79\xc4\xf4\xc7\xec\x6c\x5d\x45\x38\x07\x52\xf1\x40\x4e\xc0\xec\xe5\x78\x6e\x8d\x54\x81\x24\x80\x29\x30\x4c\x0d\x33\x11\x83\x51\xd9\x1f\xb0\xfe\xa4\x83\x40\x11\xa5\xb1\x13\x1d\x70\x2c\xdc\x5b\x17\xae\x26\x3e\xb6\xf6\x2b\xa0\x23\x55\x5b\xda\xea\x3e\xb5\x68\xf9\x7f\x93\xed\x70\x76\xfd\xf5\xf8\x47\x1a\x67\x99\x81\x21\xec\x34\x0e\x2b\xb0\x2b\x0f\x31\xbd\x5a\x8f\xdf\x3e\x03\x89\xfc\xfe\xea\xf3\xa2\xf5\x2e\xb4\x11\xa1\xde\x7d\x20\xe7\xd3\x0a\xde\x70\x3c\xf3\x8d\xca\x6f\x4e\x28\xfd\x7d\x03\x13\x60\x43\x43\xd2\x24\x46\x80\x18\x0b\x56\x74\x98\x4e\x1f\x48\x78\xdf\x0a\x02\x5a\x26\x2c\x50\x86\x27\x71\x62\x58\x0e\x41\xb8\x75\xb5\xd8\xb9\x7e\xd7\x2a\xce\x63\xc7\xf4\x91\x69\x0f\xb8\x7e\x36\x7d\xc1\x40\x12\xb2\xca\xfd\x2c\xc5\x9b\xbb\x02\x89\x55\x50\x24\x40\xcd\xc0\x10\x10\x4c\xf2\x7d\xf2\x45\xf4\x75\x0f\xcf\x34\x02\x8a\x6d\x42\x9c\x90\x67\xc5\xe1\x48\x41\x32\x86\xbc\x82\x65\x66\x0b\xe3\x54\x6d\x09\x9e\xee\xfb\xfb\x0d\x17\x51\xec\x8d\xdc\x7d\x4c\x80\x29\xae\xab\xba\x08\x23\x28\xeb\xc5\xc5\xec\x68\x12\x99\xfe\x18\x4b\xd7\x79\xd3\xd6\x3f\x03\x27\xa4\x2e\x5e\xe9\x7a\x66\x5c\x6a\x02\xd5\xf2\x46\xa1\x3c\xc0\x9a\xd2\x5c\x2e\xb3\xba\xbe\x70\xca\x21\x31\x18\x75\x5d\xb6\x2e\x6d\x4a\xb5\x0d\xf5"); /* Keccak[r=1088, c=512] */
testKeccakInstanceBitLevel(1152, 448, "\x9c\xe4\x91\x56\xac\xbc\x4f\x28\x38\xd8\x7e\x39\x2c\xab\x5e\x20\x2e\x68\x07\x2d\x8d\xb0\x1d\x8a\x23\x8e\x59\xee\x38\xaf\x65\x72\xd5\x28\xee\xed\xf2\xa7\x08\x36\x60\xc2\xee\x52\xc1\x76\x13\x99\x82\xa8\x96\x94\xab\x50\x52\x5f\x65\xeb\x97\xa1\x6a\x18\xd9\x14\x1a\x41\x5f\x73\x23\x34\x45\xc9\xf1\x84\x9f\xea\xdd\xcf\x93\xbe\xdd\x45\x02\x79\xc2\x24\x3f\xd4\xb9\xf0\x86\xbf\x13\x26\x7e\xb8\xcd\x9f\x26\xa6\x3a\x5d\x31\xd5\x67\xce\x55\x8a\xe4\xd0\xf0\x8c\x6f\x2e\xd3\xb4\x16\xec\x75\x42\x0f\x13\x6e\x2b\x74\x60\xba\xc2\xf3\xea\x71\xb2\x26\xd5\x11\x25\xf2\x47\xb2\x95\xcd\x1c\xb3\xbe\xa1\x90\x5e\x77\x2a\xa0\x78\x39\x7a\xf3\x46\x05\xf9\xbf\xf7\x1b\x60\x52\x42\x47\x5f\x90\x50\x8a\xc3\xa8\x23\x96\x0f\x47\x22\x8d\xc6\x59\x19\xc7\xa8\xf2\xee\x5a\x1b\xdd\xda\x56\xe2\xbd\x0d\xc1\x60\x7d\x77\x7d\x4b\x9f\x29\xb3\x3e\x99\x8a\x97\x51\xf9\x47\x2e\x2f\x18\x2f\x7c\x82\xaa\x54\x16\x09\xd5\xfd\x63\xd6\x94\x90\x88\x83\x2e\xc6\x90\xdb\x03\x79\x5b\x20\x6c\x2d\x2f\xc1\xa5\x66\x20\x19\x5c\x93\x34\xa5\x08\xb6\xd4\xc6\x4e\xc3\xd6\xa0\x0d\xac\x27\xef\x57\x06\xb5\xbc\x45\x46\x79\xe3\xda\x8c\x46\xd9\x1b\x77\xe0\x64\xc0\x49\x97\xca\xe9\x24\x76\x47\xf5\x39\x5c\x49\xc9\x5c\xb0\x7e\x09\x83\x1c\x72\x46\xd1\xcf\x88\xe3\xe2\x23\x50\xf1\x5f\x91\xcb\x6e\x3d\x52\xcb\x8b\x9c\x30\xd9\x83\xcd\x77\x3e\x54\x87\x7e\x4d\x3b\x56\xbf\x38\x13\xa1\xb7\xfb\xa8\xf7\xed\xb9\x60\x58\x8d\xa9\x0f\x56\x3d\x75\xaa\xeb\x7f\x7f\xc4\x32\x75\xbc\x1d\x83\xe7\xca\xd0\x07\x21\x56\x4b\xc7\x03\x11\xde\x95\xb9\x66\x50\xd9\x50\x37\x79\x16\x2b\xc1\x23\xc7\xd4\xa9\xe7\x2b\xb0\xe2\x96\x81\xb9\x68\x29\x77\xd9\xcd\x59\x91\x6c\xfb\xde\xa3\x8d\x74\xf8\x01\xbe\xa0\xa4\x66\x91\x69\x7d\x77\x90\x0a\x4d\xa7\x7f\xa6\x9f\x0c\xf5\xf4\x07\xeb\x94\x59\xc4\x52\x03\x6a\x34\x83\xfd\xbd\x60\xb2\xae\x79\xb3\x6a\x09\xba\x53\x56\xd8\x7d\xc0\xcb\x43\x40\x39\xb5\x48\x40\xce\x48\xc5\xfe\xc8\x8f\xe3\x72\xe2\x07\x2f\xd7\xfc\xc9\x9e\xa4\x21\x55\x59\x87\x09\xfe\x81\x4f\x02\x8c\x9d\x9f\xae\x25\x9c\xfc\xaf\x9c\xb7\x45\x6b\x87\xa5\xca\xbe\x87\xf3\x00\x3b\x42\x3e\xff\x25\x53\x76\x0a\xfe\x35\x50\x9c\xcd\x62\x0f\xfa\xd4\x80\xca"); /* Keccak[r=1152, c=448] */
testKeccakInstanceBitLevel(1344, 256, "\xff\x73\xac\xa3\x1e\x3e\x53\x2c\x0e\x64\x1b\x77\xf5\xec\x39\x7c\x20\x20\xb8\x93\x20\x73\x14\xed\xb3\x90\xcd\xf9\x80\xac\x55\xd6\x9d\xd2\xf5\x41\xc4\xf6\xd9\x1a\xff\x0c\x2c\x6b\x69\x11\x96\xa3\xd9\x7a\x9d\x40\x30\x64\xf7\xde\xbc\x75\x40\xa2\xd3\xfd\x0b\xdf\xb1\x02\x90\x89\xa4\xff\x6d\x36\xca\x68\xe1\xb4\xae\xf0\x42\x35\xa8\x75\x19\xc6\x93\x7e\xc1\x3c\xce\xec\xea\x71\x17\x9d\xae\x21\x4e\xd9\xd6\xd7\xc4\x67\xc6\x59\xfa\x20\xeb\x99\xbd\xc3\xd7\x40\x55\x3c\x71\xdf\xa7\xe2\x16\x75\xd0\xa7\x81\x24\x6a\xc3\x10\x0e\xb9\x22\xb2\x04\x15\x0f\x04\x90\xa8\xb7\x68\xce\xcf\x73\x44\x80\x09\x2d\x9e\xf0\x5d\xf9\xe1\x6c\xf5\xa4\x82\x5c\x41\x07\xcd\x57\xef\xe5\xed\x1a\xd2\x47\xdc\xd8\xdd\x32\xb1\x36\xea\x31\xc6\xf9\x0a\xde\x7b\x8d\x18\x5e\xcf\x1b\xf6\x1b\x5f\xa8\xdd\xb2\x5a\xef\xed\xb8\xa3\x3b\x30\x14\xd9\x78\x40\xed\x18\x9a\xdc\xe5\x39\x80\x56\x01\xaf\xea\x2a\x3d\x31\x2f\x3c\x41\x00\x94\x22\x41\x55\xd4\x98\x12\x53\xac\x07\x35\x51\x0b\x49\x67\x7d\xc3\x13\x54\xc6\xc9\x11\x1c\xae\x92\x4b\x2a\xa1\xa4\x3d\xeb\x35\x50\x72\xe8\x48\xa1\x70\x25\xf2\xdb\x90\x95\x8b\x6a\xdf\x31\xa2\xdf\xaa\xcd\x78\x0f\x43\xa1\x44\x7d\xd7\xb3\x8f\xa1\xcb\x6e\x30\xeb\x62\x1b\xb7\x54\xf4\x4f\xb0\x34\xe6\x99\x69\x5c\xdc\x12\x13\x5a\x18\xbc\xa6\xe6\x59\xb8\x4f\x6e\x07\xac\x7b\xf5\xf3\x0f\x0d\x7c\xb1\xa8\xd1\x45\x71\x61\x5d\x0c\xc3\x50\xe8\xb1\x9b\x0f\x58\x85\x9c\xec\xfb\x74\xb2\x17\x14\xe7\xe1\xc7\x42\xd5\x61\x5b\x7b\xd4\xae\x58\x84\xf8\x94\x2e\xa8\x3e\xf4\x8b\x5f\x88\xe0\xd2\x51\x64\xff\xe6\xff\x80\x16\x06\xab\xa1\xbf\xa0\xfa\x2c\xf2\x87\x0c\x95\x60\x38\xf7\xf2\x3e\xa1\x01\x3c\x1c\xcd\xee\x45\xc6\xaa\xb5\x68\x19\xc9\x15\x44\x47\x46\x7f\x0b\xc9\x1f\xc9\x82\xd6\xac\xd2\x4d\x77\x4e\x8d\x06\x32\xd9\x61\x51\x90\x23\x99\x32\x4c\xe7\x3e\xce\x3b\x35\x5b\xc1\x14\xec\x15\xb0\x71\x95\x90\x32\x87\x36\xae\xca\xd7\xbb\xdb\xd2\x0f\xae\xb7\xc0\xc4\xa4\xdc\xeb\x78\xdd\x76\xb7\xbf\x80\x37\xc5\xdb\x63\xd2\xdf\x90\xe9\xde\xba\x94\x8f\xca\x28\x4d\x05\x7a\x9b\x86\x2e\x76\x99\x64\x74\xd5\xd5\x4e\xa5\xfc\xd8\x0d\x74\x50\x0d\x2d\x2d\xcb\x00\x69\x19\x0c\x59\xc1\xcb\xb6\xfa\x6f\xe4\xb1\x52"); /* Keccak[r=1344, c=256] */
#endif
return genKAT_main();
}
#define FOR(i,n) for(i=0; i<n; ++i)
typedef unsigned char u8;
typedef unsigned long long int u64;
typedef unsigned int ui;
void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen);
void FIPS202_SHAKE128(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1344, 256, in, inLen, 0x1F, out, outLen); }
void FIPS202_SHAKE256(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1088, 512, in, inLen, 0x1F, out, outLen); }
void FIPS202_SHA3_224(const u8 *in, u64 inLen, u8 *out) { Keccak(1152, 448, in, inLen, 0x06, out, 28); }
void FIPS202_SHA3_256(const u8 *in, u64 inLen, u8 *out) { Keccak(1088, 512, in, inLen, 0x06, out, 32); }
void FIPS202_SHA3_384(const u8 *in, u64 inLen, u8 *out) { Keccak(832, 768, in, inLen, 0x06, out, 48); }
void FIPS202_SHA3_512(const u8 *in, u64 inLen, u8 *out) { Keccak(576, 1024, in, inLen, 0x06, out, 64); }
int LFSR86540(u8 *R) { (*R)=((*R)<<1)^(((*R)&0x80)?0x71:0); return ((*R)&2)>>1; }
#define ROL(a,o) ((((u64)a)<<o)^(((u64)a)>>(64-o)))
static u64 load64(const u8 *x) { ui i; u64 u=0; FOR(i,8) { u<<=8; u|=x[7-i]; } return u; }
static void store64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]=u; u>>=8; } }
static void xor64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]^=u; u>>=8; } }
#define rL(x,y) load64((u8*)s+8*(x+5*y))
#define wL(x,y,l) store64((u8*)s+8*(x+5*y),l)
#define XL(x,y,l) xor64((u8*)s+8*(x+5*y),l)
void KeccakF1600(void *s)
{
ui r,x,y,i,j,Y; u8 R=0x01; u64 C[5],D;
for(i=0; i<24; i++) {
/*θ*/ FOR(x,5) C[x]=rL(x,0)^rL(x,1)^rL(x,2)^rL(x,3)^rL(x,4); FOR(x,5) { D=C[(x+4)%5]^ROL(C[(x+1)%5],1); FOR(y,5) XL(x,y,D); }
/*ρπ*/ x=1; y=r=0; D=rL(x,y); FOR(j,24) { r+=j+1; Y=(2*x+3*y)%5; x=y; y=Y; C[0]=rL(x,y); wL(x,y,ROL(D,r%64)); D=C[0]; }
/*χ*/ FOR(y,5) { FOR(x,5) C[x]=rL(x,y); FOR(x,5) wL(x,y,C[x]^((~C[(x+1)%5])&C[(x+2)%5])); }
/*ι*/ FOR(j,7) if (LFSR86540(&R)) XL(0,0,(u64)1<<((1<<j)-1));
}
}
void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen)
{
/*initialize*/ u8 s[200]; ui R=r/8; ui i,b=0; FOR(i,200) s[i]=0;
/*absorb*/ while(inLen>0) { b=(inLen<R)?inLen:R; FOR(i,b) s[i]^=in[i]; in+=b; inLen-=b; if (b==R) { KeccakF1600(s); b=0; } }
/*pad*/ s[b]^=sfx; if((sfx&0x80)&&(b==(R-1))) KeccakF1600(s); s[R-1]^=0x80; KeccakF1600(s);
/*squeeze*/ while(outLen>0) { b=(outLen<R)?outLen:R; FOR(i,b) out[i]=s[i]; out+=b; outLen-=b; if(outLen>0) KeccakF1600(s); }
}
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
================================================================
The purpose of this source file is to demonstrate a readable and compact
implementation of all the Keccak instances approved in the FIPS 202 standard,
including the hash functions and the extendable-output functions (XOFs).
We focused on clarity and on source-code compactness,
rather than on the performance.
The advantages of this implementation are:
+ The source code is compact, after removing the comments, that is. :-)
+ There are no tables with arbitrary constants.
+ For clarity, the comments link the operations to the specifications using
the same notation as much as possible.
+ There is no restriction in cryptographic features. In particular,
the SHAKE128 and SHAKE256 XOFs can produce any output length.
+ The code does not use much RAM, as all operations are done in place.
The drawbacks of this implementation are:
- There is no message queue. The whole message must be ready in a buffer.
- It is not optimized for performance.
The implementation is even simpler on a little endian platform. Just define the
LITTLE_ENDIAN symbol in that case.
For a more complete set of implementations, please refer to
the Keccak Code Package at https://github.com/gvanas/KeccakCodePackage
For more information, please refer to:
* [Keccak Reference] https://keccak.team/files/Keccak-reference-3.0.pdf
* [Keccak Specifications Summary] https://keccak.team/keccak_specs_summary.html
This file uses UTF-8 encoding, as some comments use Greek letters.
================================================================
*/
/**
* Function to compute the Keccak[r, c] sponge function over a given input.
* @param rate The value of the rate r.
* @param capacity The value of the capacity c.
* @param input Pointer to the input message.
* @param inputByteLen The number of input bytes provided in the input message.
* @param delimitedSuffix Bits that will be automatically appended to the end
* of the input message, as in domain separation.
* This is a byte containing from 0 to 7 bits
* These <i>n</i> bits must be in the least significant bit positions
* and must be delimited with a bit 1 at position <i>n</i>
* (counting from 0=LSB to 7=MSB) and followed by bits 0
* from position <i>n</i>+1 to position 7.
* Some examples:
* - If no bits are to be appended, then @a delimitedSuffix must be 0x01.
* - If the 2-bit sequence 0,1 is to be appended (as for SHA3-*), @a delimitedSuffix must be 0x06.
* - If the 4-bit sequence 1,1,1,1 is to be appended (as for SHAKE*), @a delimitedSuffix must be 0x1F.
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedSuffix must be 0x8B.
* @param output Pointer to the buffer where to store the output.
* @param outputByteLen The number of output bytes desired.
* @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation.
*/
void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen);
/**
* Function to compute SHAKE128 on the input message with any output length.
*/
void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
{
Keccak(1344, 256, input, inputByteLen, 0x1F, output, outputByteLen);
}
/**
* Function to compute SHAKE256 on the input message with any output length.
*/
void FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
{
Keccak(1088, 512, input, inputByteLen, 0x1F, output, outputByteLen);
}
/**
* Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes.
*/
void FIPS202_SHA3_224(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
{
Keccak(1152, 448, input, inputByteLen, 0x06, output, 28);
}
/**
* Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes.
*/
void FIPS202_SHA3_256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
{
Keccak(1088, 512, input, inputByteLen, 0x06, output, 32);
}
/**
* Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes.
*/
void FIPS202_SHA3_384(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
{
Keccak(832, 768, input, inputByteLen, 0x06, output, 48);
}
/**
* Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes.
*/
void FIPS202_SHA3_512(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
{
Keccak(576, 1024, input, inputByteLen, 0x06, output, 64);
}
/*
================================================================
Technicalities
================================================================
*/
typedef unsigned char UINT8;
typedef unsigned long long int UINT64;
typedef UINT64 tKeccakLane;
#ifndef LITTLE_ENDIAN
/** Function to load a 64-bit value using the little-endian (LE) convention.
* On a LE platform, this could be greatly simplified using a cast.
*/
static UINT64 load64(const UINT8 *x)
{
int i;
UINT64 u=0;
for(i=7; i>=0; --i) {
u <<= 8;
u |= x[i];
}
return u;
}
/** Function to store a 64-bit value using the little-endian (LE) convention.
* On a LE platform, this could be greatly simplified using a cast.
*/
static void store64(UINT8 *x, UINT64 u)
{
unsigned int i;
for(i=0; i<8; ++i) {
x[i] = u;
u >>= 8;
}
}
/** Function to XOR into a 64-bit value using the little-endian (LE) convention.
* On a LE platform, this could be greatly simplified using a cast.
*/
static void xor64(UINT8 *x, UINT64 u)
{
unsigned int i;
for(i=0; i<8; ++i) {
x[i] ^= u;
u >>= 8;
}
}
#endif
/*
================================================================
A readable and compact implementation of the Keccak-f[1600] permutation.
================================================================
*/
#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset)))
#define i(x, y) ((x)+5*(y))
#ifdef LITTLE_ENDIAN
#define readLane(x, y) (((tKeccakLane*)state)[i(x, y)])
#define writeLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) = (lane)
#define XORLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) ^= (lane)
#else
#define readLane(x, y) load64((UINT8*)state+sizeof(tKeccakLane)*i(x, y))
#define writeLane(x, y, lane) store64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane)
#define XORLane(x, y, lane) xor64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane)
#endif
/**
* Function that computes the linear feedback shift register (LFSR) used to
* define the round constants (see [Keccak Reference, Section 1.2]).
*/
int LFSR86540(UINT8 *LFSR)
{
int result = ((*LFSR) & 0x01) != 0;
if (((*LFSR) & 0x80) != 0)
/* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
else
(*LFSR) <<= 1;
return result;
}
/**
* Function that computes the Keccak-f[1600] permutation on the given state.
*/
void KeccakF1600_StatePermute(void *state)
{
unsigned int round, x, y, j, t;
UINT8 LFSRstate = 0x01;
for(round=0; round<24; round++) {
{ /* === θ step (see [Keccak Reference, Section 2.3.2]) === */
tKeccakLane C[5], D;
/* Compute the parity of the columns */
for(x=0; x<5; x++)
C[x] = readLane(x, 0) ^ readLane(x, 1) ^ readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4);
for(x=0; x<5; x++) {
/* Compute the θ effect for a given column */
D = C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1);
/* Add the θ effect to the whole column */
for (y=0; y<5; y++)
XORLane(x, y, D);
}
}
{ /* === ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) === */
tKeccakLane current, temp;
/* Start at coordinates (1 0) */
x = 1; y = 0;
current = readLane(x, y);
/* Iterate over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23 */
for(t=0; t<24; t++) {
/* Compute the rotation constant r = (t+1)(t+2)/2 */
unsigned int r = ((t+1)*(t+2)/2)%64;
/* Compute ((0 1)(2 3)) * (x y) */
unsigned int Y = (2*x+3*y)%5; x = y; y = Y;
/* Swap current and state(x,y), and rotate */
temp = readLane(x, y);
writeLane(x, y, ROL64(current, r));
current = temp;
}
}
{ /* === χ step (see [Keccak Reference, Section 2.3.1]) === */
tKeccakLane temp[5];
for(y=0; y<5; y++) {
/* Take a copy of the plane */
for(x=0; x<5; x++)
temp[x] = readLane(x, y);
/* Compute χ on the plane */
for(x=0; x<5; x++)
writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5]));
}
}
{ /* === ι step (see [Keccak Reference, Section 2.3.5]) === */
for(j=0; j<7; j++) {
unsigned int bitPosition = (1<<j)-1; /* 2^j-1 */
if (LFSR86540(&LFSRstate))
XORLane(0, 0, (tKeccakLane)1<<bitPosition);
}
}
}
}
/*
================================================================
A readable and compact implementation of the Keccak sponge functions
that use the Keccak-f[1600] permutation.
================================================================
*/
#include <string.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen)
{
UINT8 state[200];
unsigned int rateInBytes = rate/8;
unsigned int blockSize = 0;
unsigned int i;
if (((rate + capacity) != 1600) || ((rate % 8) != 0))
return;
/* === Initialize the state === */
memset(state, 0, sizeof(state));
/* === Absorb all the input blocks === */
while(inputByteLen > 0) {
blockSize = MIN(inputByteLen, rateInBytes);
for(i=0; i<blockSize; i++)
state[i] ^= input[i];
input += blockSize;
inputByteLen -= blockSize;
if (blockSize == rateInBytes) {
KeccakF1600_StatePermute(state);
blockSize = 0;
}
}
/* === Do the padding and switch to the squeezing phase === */
/* Absorb the last few bits and add the first bit of padding (which coincides with the delimiter in delimitedSuffix) */
state[blockSize] ^= delimitedSuffix;
/* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
if (((delimitedSuffix & 0x80) != 0) && (blockSize == (rateInBytes-1)))
KeccakF1600_StatePermute(state);
/* Add the second bit of padding */
state[rateInBytes-1] ^= 0x80;
/* Switch to the squeezing phase */
KeccakF1600_StatePermute(state);
/* === Squeeze out all the output blocks === */
while(outputByteLen > 0) {
blockSize = MIN(outputByteLen, rateInBytes);
memcpy(output, state, blockSize);
output += blockSize;
outputByteLen -= blockSize;
if (outputByteLen > 0)
KeccakF1600_StatePermute(state);
}
}
#include <assert.h>
#include <string.h>
typedef unsigned char u8;
typedef unsigned long long u64;
int crypto_hash_shake128(u8 *h, u64 d, const u8 *m, u64 n);
int crypto_hash_shake256(u8 *h, u64 d, const u8 *m, u64 n);
int crypto_hash_sha3224(u8 *h, const u8 *m, u64 n);
int crypto_hash_sha3256(u8 *h, const u8 *m, u64 n);
int crypto_hash_sha3384(u8 *h, const u8 *m, u64 n);
int crypto_hash_sha3512(u8 *h, const u8 *m, u64 n);
void Keccak(int rate, int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen)
{
if ((rate == 1344) && (capacity == 256) && (delimitedSuffix == 0x1F)) {
crypto_hash_shake128(output, outputByteLen, input, inputByteLen);
}
else
if ((rate == 1088) && (capacity == 512) && (delimitedSuffix == 0x1F)) {
crypto_hash_shake256(output, outputByteLen, input, inputByteLen);
}
else
if ((rate == 1152) && (capacity == 448) && (delimitedSuffix == 0x06) && (outputByteLen == 28))
crypto_hash_sha3224(output, input, inputByteLen);
else
if ((rate == 1088) && (capacity == 512) && (delimitedSuffix == 0x06) && (outputByteLen == 32))
crypto_hash_sha3256(output, input, inputByteLen);
else
if ((rate == 832) && (capacity == 768) && (delimitedSuffix == 0x06) && (outputByteLen == 48))
crypto_hash_sha3384(output, input, inputByteLen);
else
if ((rate == 576) && (capacity == 1024) && (delimitedSuffix == 0x06) && (outputByteLen == 64))
crypto_hash_sha3512(output, input, inputByteLen);
else
assert(0);
}
#define R(a, n) a << n ^ a >> 64-n
#define L(i, n) for(U i = 0; i < n; i++)
#define S(x) \
L(i, r) \
s[i/8] ^= (U) x[i] << i%8*8
#define H(i,r,p,d) \
int crypto_hash_sha3##i(C *h, const C *m, U n) \
{ \
k(r*8, m, n, p, h, d); \
return 0; \
}
#define H2(i,r,p) \
int crypto_hash_shake##i(C *h, U d, const C *m, U n) \
{ \
k(r*8, m, n, p, h, d); \
return 0; \
}
typedef unsigned long long U;
typedef unsigned char C;
void F(U *s)
{
C R = 1, r, x, y;
U t, B[5], Y;
L(n, 24)
{
L(i, 5)
{
B[i] = 0;
L(j, 5)
B[i] ^= s[i+5*j];
}
L(i,5)
{
t = B[(i+4)%5] ^ R(B[(i+1)%5], 1);
L(j, 5)
s[i+5*j] ^= t;
}
t = s[1];
y = r = 0;
x = 1;
L(j, 24)
{
r += j + 1;
Y = 2 * x + 3 * y;
x = y;
y = Y % 5;
Y = s[x+5*y];
s[x+5*y] = R(t, r % 64);
t = Y;
}
L(j, 5)
{
L(i, 5)
B[i] = s[i+5*j];
L(i, 5)
s[i+5*j] = B[i] ^ (~B[(i+1)%5] & B[(i+2)%5]);
}
L(j, 7)
if ((R = (R << 1) ^ (113 * (R >> 7))) & 2)
*s ^= 1ULL << ((1 << j) - 1);
}
}
void k(C r, const C *m, U n, C p, C *h, U d)
{
U s[25] = {0};
C t[200] = {0};
while (n >= r)
{
S(m);
F(s);
n -= r;
m += r;
}
L(i, n)
t[i] = m[i];
t[n] = p;
t[r-1] |= 128;
S(t);
L(i,d)
{
if(0 == i % r)
F(s);
h[i] = s[i%r/8] >> 8*(i%8);
}
}
H(224,18,6,28)
H(256,17,6,32)
H(384,13,6,48)
H(512,9,6,64)
H2(128,21,31)
H2(256,17,31)
// FIPS202 in 7 tweets
#define R(a,n)a<<n^a>>64-n
#define H(i,r,p,d)int crypto_hash_sha3##i(C*h,const C*m,U n){k(r*8,m,n,p,h,d);return 0;}
#define H2(i,r,p)int crypto_hash_shake##i(C*h,U d,const C*m,U n){k(r*8,m,n,p,h,d);return 0;}
#define L(i,n)for(U i=0;i<n;i++)
typedef long
long unsigned U;typedef unsigned char C;
#define S(x)L(i,r)s[i/8]^=(U)x[i]<<i%8*8
void F(U*s){C R=1,r,x,y;U t,B[5],Y;L(n,24){L(i,5){B[i]=0;L
(j,5)B[i]^=s[i+5*j];}L(i,5){t=B[(i+4)%5]^R(B[(i+1)%5],1);L(j,5)s[i+5*j]^=t;}t=s[1];y=r=0;x=1;L(j,24){r+=j+1;Y=2*x+3*y;x=y;y=Y%5;Y=s[x+5*y];s
[x+5*y]=R(t,r%64);t=Y;}L(j,5){L(i,5)B[i]=s[i+5*j];L(i,5)s[i+5*j]=B[i]^(~B[(i+1)%5]&B[(i+2)%5]);}L(j,7)if((R=(R<<1)^(113*(R>>7)))&2)*s^=1ULL
<<((1<<j)-1);}}void k(C r,const C*m,U n,C p,C*h,U d){U s[25]={0};C t[200]={0};while(n>=r){S(m);F(s);n-=r;m+=r;}L(i,n)t[i]=m[i];t[n]=p;t[r-1]
|=128;S(t);L(i,d){if(0==i%r)F(s);h[i]=s[i%r/8]>>8*(i%8);}}H(224,18,6,28)H(256,17,6,32)H(384,13,6,48)H(512,9,6,64)H2(128,21,31)H2(256,17,31)
/*
Copyright (c) 2008, Lawrence E. Bassham, National Institute of Standards and Technology (NIST),
for the original version (available at http://csrc.nist.gov/groups/ST/hash/sha-3/documents/KAT1.zip)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the NIST nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Contributions were made by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the contributed source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
void Keccak(int rate, int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen);
typedef unsigned char BitSequence;
typedef size_t BitLength;
typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn;
#define MAX_MARKER_LEN 50
#define SUBMITTER_INFO_LEN 128
typedef enum { KAT_SUCCESS = 0, KAT_FILE_OPEN_ERROR = 1, KAT_HEADER_ERROR = 2, KAT_DATA_ERROR = 3, KAT_HASH_ERROR = 4 } STATUS_CODES;
#define ExcludeExtremelyLong
#define SqueezingOutputLength 4096
STATUS_CODES genShortMsgHash(unsigned int rate, unsigned int capacity, unsigned char delimitedSuffix, unsigned int hashbitlen, unsigned int squeezedOutputLength, const char *fileName, const char *description);
int FindMarker(FILE *infile, const char *marker);
int ReadHex(FILE *infile, BitSequence *A, int Length, char *str);
void fprintBstr(FILE *fp, char *S, BitSequence *A, int L);
void convertShortMsgToPureLSB(void);
STATUS_CODES
genKAT_main(void)
{
/* The following instances are from the FIPS 202 standard. */
/* http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf */
/* */
/* Note: "SakuraSequential" translates into "input followed by 11", */
/* see https://keccak.team/files/Sakura.pdf for more details. */
/* */
genShortMsgHash(1344, 256, 0x1F, 0, 4096,
"ShortMsgKAT_SHAKE128.txt",
"Keccak(SakuraSequential|11)[r=1344, c=256], or SHAKE128 as in FIPS 202 standard");
genShortMsgHash(1088, 512, 0x1F, 0, 4096,
"ShortMsgKAT_SHAKE256.txt",
"Keccak(SakuraSequential|11)[r=1088, c=512], or SHAKE256 as in FIPS 202 standard");
genShortMsgHash(1152, 448, 0x06, 224, 0,
"ShortMsgKAT_SHA3-224.txt",
"Keccak(input|01)[r=1152, c=448] truncated to 224 bits, or SHA3-224 as in FIPS 202 standard");
genShortMsgHash(1088, 512, 0x06, 256, 0,
"ShortMsgKAT_SHA3-256.txt",
"Keccak(input|01)[r=1088, c=512] truncated to 256 bits, or SHA3-256 as in FIPS 202 standard");
genShortMsgHash(832, 768, 0x06, 384, 0,
"ShortMsgKAT_SHA3-384.txt",
"Keccak(input|01)[r=832, c=768] truncated to 384 bits, or SHA3-384 as in FIPS 202 standard");
genShortMsgHash(576, 1024, 0x06, 512, 0,
"ShortMsgKAT_SHA3-512.txt",
"Keccak(input|01)[r=576, c=1024] truncated to 512 bits, or SHA3-512 as in FIPS 202 standard");
return KAT_SUCCESS;
}
STATUS_CODES
genShortMsgHash(unsigned int rate, unsigned int capacity, unsigned char delimitedSuffix, unsigned int hashbitlen, unsigned int squeezedOutputLength, const char *fileName, const char *description)
{
int msglen, msgbytelen;
BitSequence Msg[256];
BitSequence Squeezed[SqueezingOutputLength/8];
FILE *fp_in, *fp_out;
if ((squeezedOutputLength > SqueezingOutputLength) || (hashbitlen > SqueezingOutputLength)) {
printf("Requested output length too long.\n");
return KAT_HASH_ERROR;
}
if ( (fp_in = fopen("ShortMsgKAT.txt", "r")) == NULL ) {
printf("Couldn't open <ShortMsgKAT.txt> for read\n");
return KAT_FILE_OPEN_ERROR;
}
if ( (fp_out = fopen(fileName, "w")) == NULL ) {
printf("Couldn't open <%s> for write\n", fileName);
return KAT_FILE_OPEN_ERROR;
}
fprintf(fp_out, "# %s\n", description);
do {
if ( FindMarker(fp_in, "Len = ") )
fscanf(fp_in, "%d", &msglen);
else {
break;
}
msgbytelen = (msglen+7)/8;
if ( !ReadHex(fp_in, Msg, msgbytelen, "Msg = ") ) {
printf("ERROR: unable to read 'Msg' from <ShortMsgKAT.txt>\n");
return KAT_DATA_ERROR;
}
if ((msglen % 8) == 0) {
fprintf(fp_out, "\nLen = %d\n", msglen);
fprintBstr(fp_out, "Msg = ", Msg, msgbytelen);
if (hashbitlen > 0) {
Keccak(rate, capacity, Msg, msglen/8, delimitedSuffix, Squeezed, hashbitlen/8);
fprintBstr(fp_out, "MD = ", Squeezed, hashbitlen/8);
}
else {
Keccak(rate, capacity, Msg, msglen/8, delimitedSuffix, Squeezed, squeezedOutputLength/8);
fprintBstr(fp_out, "Squeezed = ", Squeezed, squeezedOutputLength/8);
}
}
} while ( 1 );
printf("finished ShortMsgKAT for <%s>\n", fileName);
fclose(fp_in);
fclose(fp_out);
return KAT_SUCCESS;
}
/* */
/* ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) */
/* */
int
FindMarker(FILE *infile, const char *marker)
{
char line[MAX_MARKER_LEN];
int i, len;
len = (int)strlen(marker);
if ( len > MAX_MARKER_LEN-1 )
len = MAX_MARKER_LEN-1;
for ( i=0; i<len; i++ )
if ( (line[i] = fgetc(infile)) == EOF )
return 0;
line[len] = '\0';
while ( 1 ) {
if ( !strncmp(line, marker, len) )
return 1;
for ( i=0; i<len-1; i++ )
line[i] = line[i+1];
if ( (line[len-1] = fgetc(infile)) == EOF )
return 0;
line[len] = '\0';
}
/* shouldn't get here */
return 0;
}
/* */
/* ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) */
/* */
int
ReadHex(FILE *infile, BitSequence *A, int Length, char *str)
{
int i, ch, started;
BitSequence ich = '\0';
if ( Length == 0 ) {
A[0] = 0x00;
return 1;
}
memset(A, 0x00, Length);
started = 0;
if ( FindMarker(infile, str) )
while ( (ch = fgetc(infile)) != EOF ) {
if ( !isxdigit(ch) ) {
if ( !started ) {
if ( ch == '\n' )
break;
else
continue;
}
else
break;
}
started = 1;
if ( (ch >= '0') && (ch <= '9') )
ich = ch - '0';
else if ( (ch >= 'A') && (ch <= 'F') )
ich = ch - 'A' + 10;
else if ( (ch >= 'a') && (ch <= 'f') )
ich = ch - 'a' + 10;
for ( i=0; i<Length-1; i++ )
A[i] = (A[i] << 4) | (A[i+1] >> 4);
A[Length-1] = (A[Length-1] << 4) | ich;
}
else
return 0;
return 1;
}
void
fprintBstr(FILE *fp, char *S, BitSequence *A, int L)
{
int i;
fprintf(fp, "%s", S);
for ( i=0; i<L; i++ )
fprintf(fp, "%02X", A[i]);
if ( L == 0 )
fprintf(fp, "00");
fprintf(fp, "\n");
}
# -*- coding: utf-8 -*-
# Implementation by Renaud Bauvin,
# hereby denoted as "the implementer".
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
import binascii
import CompactFIPS202
import os
## Iterate through the files 'Short... and LongMsgKAT_XXX.txt' containing the
## test vectors and compare the computed values to the provided ones
## In case of difference, it stops the processing and print a message
dirTestVector=os.path.abspath(os.path.join('.'))
verbose=False
instances=[
['SHAKE128', 1344, 256, 0x1F, 0],
['SHAKE256', 1088, 512, 0x1F, 0],
['SHA3-224', 1152, 448, 0x06, 224],
['SHA3-256', 1088, 512, 0x06, 256],
['SHA3-384', 832, 768, 0x06, 384],
['SHA3-512', 576, 1024, 0x06, 512],
]
fileTypes=['Short']
def delimitedSuffixInBinary(delimitedSuffix):
binary = ''
while(delimitedSuffix != 1):
binary = binary + ('%d' % (delimitedSuffix%2))
delimitedSuffix = delimitedSuffix//2
return binary
for instance in instances:
[fileNameSuffix, r, c, delimitedSuffix, n] = instance
for fileType in fileTypes:
print('Processing file: %sMsgKAT_%s.txt...' % (fileType, fileNameSuffix))
print("Keccak[r=%d, c=%d] with '%s' suffix" % (r, c, delimitedSuffixInBinary(delimitedSuffix)))
#Open the corresponding file
try:
referenceFile=open(os.path.join(dirTestVector,fileType+('MsgKAT_%s.txt' % fileNameSuffix)), 'r')
except IOError:
print("Error: test vector files must be stored in %s" % (dirTestVector))
exit()
#Parse the document line by line (works only for Short and Long files)
for line in referenceFile:
if line.startswith('Len'):
Len=int(line.split(' = ')[1].strip('\n\r'))
if line.startswith('Msg'):
Msg=line.split(' = ')[1].strip('\n\r')
msg = bytearray(binascii.unhexlify(Msg))
msg = msg[:Len//8]
if (line.startswith('MD') or line.startswith('Squeezed')):
MD_ref=line.split(' = ')[1].strip('\n\r')
reference = bytearray(binascii.unhexlify(MD_ref))
# If line starts with 'Squeezed', use the output length from the test vector
if line.startswith('Squeezed'):
n = len(reference)*8
elif n == 0:
print("Error: the output length should be specified")
exit()
if ((Len % 8) == 0):
# Perform our own computation
computed = CompactFIPS202.Keccak(r, c, msg, delimitedSuffix, n//8)
#Compare the results
if (computed != reference):
print('ERROR: \n\t type=%s\n\t length=%d\n\t message=%s\n\t reference=%s\n\t computed=%s' % (fileNameSuffix, Len, Msg, binascii.hexlify(reference), binascii.hexlify(computed)))
exit()
print("OK\n")
referenceFile.close()
# -*- coding: utf-8 -*-
# Implementation by Gilles Van Assche, hereby denoted as "the implementer".
#
# For more information, feedback or questions, please refer to our website:
# https://keccak.team/
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
def ROL64(a, n):
return ((a >> (64-(n%64))) + (a << (n%64))) % (1 << 64)
def KeccakF1600onLanes(lanes):
R = 1
for round in range(24):
# θ
C = [lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4] for x in range(5)]
D = [C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1) for x in range(5)]
lanes = [[lanes[x][y]^D[x] for y in range(5)] for x in range(5)]
# ρ and π
(x, y) = (1, 0)
current = lanes[x][y]
for t in range(24):
(x, y) = (y, (2*x+3*y)%5)
(current, lanes[x][y]) = (lanes[x][y], ROL64(current, (t+1)*(t+2)//2))
# χ
for y in range(5):
T = [lanes[x][y] for x in range(5)]
for x in range(5):
lanes[x][y] = T[x] ^((~T[(x+1)%5]) & T[(x+2)%5])
# ι
for j in range(7):
R = ((R << 1) ^ ((R >> 7)*0x71)) % 256
if (R & 2):
lanes[0][0] = lanes[0][0] ^ (1 << ((1<<j)-1))
return lanes
def load64(b):
return sum((b[i] << (8*i)) for i in range(8))
def store64(a):
return list((a >> (8*i)) % 256 for i in range(8))
def KeccakF1600(state):
lanes = [[load64(state[8*(x+5*y):8*(x+5*y)+8]) for y in range(5)] for x in range(5)]
lanes = KeccakF1600onLanes(lanes)
state = bytearray(200)
for x in range(5):
for y in range(5):
state[8*(x+5*y):8*(x+5*y)+8] = store64(lanes[x][y])
return state
def Keccak(rate, capacity, inputBytes, delimitedSuffix, outputByteLen):
outputBytes = bytearray()
state = bytearray([0 for i in range(200)])
rateInBytes = rate//8
blockSize = 0
if (((rate + capacity) != 1600) or ((rate % 8) != 0)):
return
inputOffset = 0
# === Absorb all the input blocks ===
while(inputOffset < len(inputBytes)):
blockSize = min(len(inputBytes)-inputOffset, rateInBytes)
for i in range(blockSize):
state[i] = state[i] ^ inputBytes[i+inputOffset]
inputOffset = inputOffset + blockSize
if (blockSize == rateInBytes):
state = KeccakF1600(state)
blockSize = 0
# === Do the padding and switch to the squeezing phase ===
state[blockSize] = state[blockSize] ^ delimitedSuffix
if (((delimitedSuffix & 0x80) != 0) and (blockSize == (rateInBytes-1))):
state = KeccakF1600(state)
state[rateInBytes-1] = state[rateInBytes-1] ^ 0x80
state = KeccakF1600(state)
# === Squeeze out all the output blocks ===
while(outputByteLen > 0):
blockSize = min(outputByteLen, rateInBytes)
outputBytes = outputBytes + state[0:blockSize]
outputByteLen = outputByteLen - blockSize
if (outputByteLen > 0):
state = KeccakF1600(state)
return outputBytes
def SHAKE128(inputBytes, outputByteLen):
return Keccak(1344, 256, inputBytes, 0x1F, outputByteLen)
def SHAKE256(inputBytes, outputByteLen):
return Keccak(1088, 512, inputBytes, 0x1F, outputByteLen)
def SHA3_224(inputBytes):
return Keccak(1152, 448, inputBytes, 0x06, 224//8)
def SHA3_256(inputBytes):
return Keccak(1088, 512, inputBytes, 0x06, 256//8)
def SHA3_384(inputBytes):
return Keccak(832, 768, inputBytes, 0x06, 384//8)
def SHA3_512(inputBytes):
return Keccak(576, 1024, inputBytes, 0x06, 512//8)
# -*- coding: utf-8 -*-
# Implementation by Gilles Van Assche, hereby denoted as "the implementer".
#
# For more information, feedback or questions, please refer to our website:
# https://keccak.team/
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
import numpy as np
KECCAK_BYTES = 200
KECCAK_LANES = 25
KECCAK_PLANES_SLICES = 5
THETA_REORDER = ((4, 0, 1, 2, 3), (1, 2, 3, 4, 0))
#Iota Step Round Constants For Keccak-p(1600, 24)
IOTA_CONSTANTS = np.array([0x0000000000000001,0x0000000000008082, 0x800000000000808A,
0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
0x8000000000008080, 0x0000000080000001, 0x8000000080008008],
dtype=np.uint64)
#Lane Shifts for Rho Step
RHO_SHIFTS = np.array([[0, 36, 3, 41, 18],
[1, 44, 10, 45, 2],
[62, 6, 43, 15, 61],
[28, 55, 25, 21, 56],
[27, 20, 39, 8, 14]], dtype=np.uint64)
#Lane Re-order Mapping for Chi Step
CHI_REORDER = ((1, 2, 3, 4, 0), (2, 3, 4, 0, 1))
#Row Re-order Mapping for Pi Step
PI_ROW_REORDER = np.array([[0, 3, 1, 4, 2],
[1, 4, 2, 0, 3],
[2, 0, 3, 1, 4],
[3, 1, 4, 2, 0],
[4, 2, 0, 3, 1]])
#Column Re-order Mapping for Pi Step
PI_COLUMN_REORDER = np.array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]])
def KeccakF1600(state):
state = np.copy(np.frombuffer(state, dtype=np.uint64, count=25).reshape([5, 5], order='F'))
for round_num in range(24):
# theta_step:
# Exclusive-or each slice-lane by state based permutation value
array_shift = state << 1 | state >> 63
state ^= np.bitwise_xor.reduce(state[THETA_REORDER[0], ], 1, keepdims=True) ^ np.bitwise_xor.reduce(array_shift[THETA_REORDER[1], ], 1, keepdims=True)
# rho_step:
# Left Rotate each lane by pre-calculated value
state = state << RHO_SHIFTS | state >> np.uint64(64 - RHO_SHIFTS)
# pi_step:
# Shuffle lanes to pre-calculated positions
state = state[PI_ROW_REORDER, PI_COLUMN_REORDER]
# chi_step:
# Exclusive-or each individual lane based on and/invert permutation
state ^= ~state[CHI_REORDER[0], ] & state[CHI_REORDER[1], ]
# iota_step:
# Exclusive-or first lane of state with round constant
state[0, 0] ^= IOTA_CONSTANTS[round_num]
return bytearray(state.tobytes(order='F'))
def Keccak(rate, capacity, inputBytes, delimitedSuffix, outputByteLen):
outputBytes = bytearray()
state = bytearray([0 for i in range(200)])
rateInBytes = rate//8
blockSize = 0
if (((rate + capacity) != 1600) or ((rate % 8) != 0)):
return
inputOffset = 0
# === Absorb all the input blocks ===
while(inputOffset < len(inputBytes)):
blockSize = min(len(inputBytes)-inputOffset, rateInBytes)
for i in range(blockSize):
state[i] = state[i] ^ inputBytes[i+inputOffset]
inputOffset = inputOffset + blockSize
if (blockSize == rateInBytes):
state = KeccakF1600(state)
blockSize = 0
# === Do the padding and switch to the squeezing phase ===
state[blockSize] = state[blockSize] ^ delimitedSuffix
if (((delimitedSuffix & 0x80) != 0) and (blockSize == (rateInBytes-1))):
state = KeccakF1600(state)
state[rateInBytes-1] = state[rateInBytes-1] ^ 0x80
state = KeccakF1600(state)
# === Squeeze out all the output blocks ===
while(outputByteLen > 0):
blockSize = min(outputByteLen, rateInBytes)
outputBytes = outputBytes + state[0:blockSize]
outputByteLen = outputByteLen - blockSize
if (outputByteLen > 0):
state = KeccakF1600(state)
return outputBytes
def SHAKE128(inputBytes, outputByteLen):
return Keccak(1344, 256, inputBytes, 0x1F, outputByteLen)
def SHAKE256(inputBytes, outputByteLen):
return Keccak(1088, 512, inputBytes, 0x1F, outputByteLen)
def SHA3_224(inputBytes):
return Keccak(1152, 448, inputBytes, 0x06, 224//8)
def SHA3_256(inputBytes):
return Keccak(1088, 512, inputBytes, 0x06, 256//8)
def SHA3_384(inputBytes):
return Keccak(832, 768, inputBytes, 0x06, 384//8)
def SHA3_512(inputBytes):
return Keccak(576, 1024, inputBytes, 0x06, 512//8)
# -*- coding: utf-8 -*-
# Implementation by Gilles Van Assche, hereby denoted as "the implementer".
#
# For more information, feedback or questions, please refer to our website:
# https://keccak.team/
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
import CompactFIPS202
import base64
import binascii
import io
import sys
instance=(1344, 256, 0x1F, 264)
printAsBase64=True
for arg in sys.argv[1:]:
if (arg.startswith('--')):
if (arg == '--hex'):
printAsBase64 = False
elif (arg == '--base64'):
printAsBase64 = True
elif (arg == '--shake128'):
instance=(1344, 256, 0x1F, 264)
printAsBase64=True
elif (arg == '--shake256'):
instance=(1088, 512, 0x1F, 528)
printAsBase64=True
elif (arg == '--sha3-224'):
instance=(1152, 448, 0x06, 224)
printAsBase64=False
elif (arg == '--sha3-256'):
instance=(1088, 512, 0x06, 256)
printAsBase64=False
elif (arg == '--sha3-384'):
instance=(832, 768, 0x06, 384)
printAsBase64=False
elif (arg == '--sha3-512'):
instance=(576, 1024, 0x06, 512)
printAsBase64=False
else:
print('Unrecognized option:', arg)
else:
fileName = arg
try:
with open(fileName, 'rb') as f:
b = bytearray(f.read())
(r, c, s, n) = instance
h = CompactFIPS202.Keccak(r, c, b, s, n//8)
if (printAsBase64):
print(bytes.decode(base64.standard_b64encode(h)), '', fileName)
else:
print(bytes.decode(binascii.hexlify(h)), '', fileName)
except IOError:
pass
except:
raise
# -*- coding: utf-8 -*-
# Implementation by Gilles Van Assche, hereby denoted as "the implementer".
#
# For more information, feedback or questions, please refer to our website:
# https://keccak.team/
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
from __future__ import print_function
import K12
def generateSimpleRawMaterial(length, seed1, seed2):
seed2 = seed2 % 8
return bytes([(seed1 + 161*length - ((i%256) << seed2) - ((i%256) >> (8-seed2)) + i)%256 for i in range(length)])
customizationByteSize = 32
def performTestKangarooTwelveOneInput(inputLen, outputLen, customLen):
customizationString = generateSimpleRawMaterial(customizationByteSize, customLen, 97)[0:customLen]
inputMessage = generateSimpleRawMaterial(inputLen, outputLen, inputLen + customLen)
print("outputLen {0:5d}, inputLen {1:5d}, customLen {2:3d}".format(outputLen, inputLen, customLen))
output = K12.KangarooTwelve(inputMessage, customizationString, outputLen)
print("Kangaroo-Twelve")
print("Input of {0:d} bytes:".format(inputLen), end='')
for i in range(min(inputLen, 16)):
print(" {0:02x}".format(inputMessage[i]), end='')
if (inputLen > 16):
print(" ...", end='')
print("")
print("Output of {0:d} bytes:".format(outputLen), end='')
for i in range(outputLen):
print(" {0:02x}".format(output[i]), end='')
print("")
print("")
def performTestKangarooTwelve():
cBlockSize = 8192
outputLen = 256//8
customLen = 0
for inputLen in range(cBlockSize*9+124):
performTestKangarooTwelveOneInput(inputLen, outputLen, customLen)
outputLen = 128//8
while(outputLen <= 512//8):
inputLen = 0
while(inputLen <= (3*cBlockSize)):
customLen = 0
while(customLen <= customizationByteSize):
performTestKangarooTwelveOneInput(inputLen, outputLen, customLen)
customLen += 7
inputLen = (inputLen + 167) if (inputLen > 0) else 1
outputLen = outputLen*2
def performShortTestKangarooTwelve():
cBlockSize = 8192
outputLen = 256//8
customLen = 0
for inputLen in range(4):
performTestKangarooTwelveOneInput(inputLen, outputLen, customLen)
performTestKangarooTwelveOneInput(27121, outputLen, customLen)
#performTestKangarooTwelve()
#performShortTestKangarooTwelve()
def outputHex(s):
for i in range(len(s)):
print("{0:02x}".format(s[i]), end=' ')
print()
print()
def printTestVectors():
print("KangarooTwelve(M=empty, C=empty, 32 output bytes):")
outputHex(K12.KangarooTwelve(b'', b'', 32))
print("KangarooTwelve(M=empty, C=empty, 64 output bytes):")
outputHex(K12.KangarooTwelve(b'', b'', 64))
print("KangarooTwelve(M=empty, C=empty, 10032 output bytes), last 32 bytes:")
outputHex(K12.KangarooTwelve(b'', b'', 10032)[10000:])
for i in range(7):
C = b''
M = bytearray([(j % 251) for j in range(17**i)])
print("KangarooTwelve(M=pattern 0x00 to 0xFA for 17^{0:d} bytes, C=empty, 32 output bytes):".format(i))
outputHex(K12.KangarooTwelve(M, C, 32))
for i in range(4):
M = bytearray([0xFF for j in range(2**i-1)])
C = bytearray([(j % 251) for j in range(41**i)])
print("KangarooTwelve(M={0:d} times byte 0xFF, C=pattern 0x00 to 0xFA for 41^{1:d} bytes, 32 output bytes):".format(2**i-1, i))
outputHex(K12.KangarooTwelve(M, C, 32))
printTestVectors()
# -*- coding: utf-8 -*-
# Implementation by Gilles Van Assche, hereby denoted as "the implementer".
#
# For more information, feedback or questions, please refer to our website:
# https://keccak.team/
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
def ROL64(a, n):
return ((a >> (64-(n%64))) + (a << (n%64))) % (1 << 64)
def KeccakP1600onLanes(lanes, nrRounds):
R = 1
for round in range(24):
if (round + nrRounds >= 24):
# θ
C = [lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4] for x in range(5)]
D = [C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1) for x in range(5)]
lanes = [[lanes[x][y]^D[x] for y in range(5)] for x in range(5)]
# ρ and π
(x, y) = (1, 0)
current = lanes[x][y]
for t in range(24):
(x, y) = (y, (2*x+3*y)%5)
(current, lanes[x][y]) = (lanes[x][y], ROL64(current, (t+1)*(t+2)//2))
# χ
for y in range(5):
T = [lanes[x][y] for x in range(5)]
for x in range(5):
lanes[x][y] = T[x] ^((~T[(x+1)%5]) & T[(x+2)%5])
# ι
for j in range(7):
R = ((R << 1) ^ ((R >> 7)*0x71)) % 256
if (R & 2):
lanes[0][0] = lanes[0][0] ^ (1 << ((1<<j)-1))
else:
for j in range(7):
R = ((R << 1) ^ ((R >> 7)*0x71)) % 256
return lanes
def load64(b):
return sum((b[i] << (8*i)) for i in range(8))
def store64(a):
return bytearray((a >> (8*i)) % 256 for i in range(8))
def KeccakP1600(state, nrRounds):
lanes = [[load64(state[8*(x+5*y):8*(x+5*y)+8]) for y in range(5)] for x in range(5)]
lanes = KeccakP1600onLanes(lanes, nrRounds)
state = bytearray().join([store64(lanes[x][y]) for y in range(5) for x in range(5)])
return bytearray(state)
def F(inputBytes, delimitedSuffix, outputByteLen):
outputBytes = bytearray()
state = bytearray([0 for i in range(200)])
rateInBytes = 1344//8
blockSize = 0
inputOffset = 0
# === Absorb all the input blocks ===
while(inputOffset < len(inputBytes)):
blockSize = min(len(inputBytes)-inputOffset, rateInBytes)
for i in range(blockSize):
state[i] = state[i] ^ inputBytes[i+inputOffset]
inputOffset = inputOffset + blockSize
if (blockSize == rateInBytes):
state = KeccakP1600(state, 12)
blockSize = 0
# === Do the padding and switch to the squeezing phase ===
state[blockSize] = state[blockSize] ^ delimitedSuffix
if (((delimitedSuffix & 0x80) != 0) and (blockSize == (rateInBytes-1))):
state = KeccakP1600(state, 12)
state[rateInBytes-1] = state[rateInBytes-1] ^ 0x80
state = KeccakP1600(state, 12)
# === Squeeze out all the output blocks ===
while(outputByteLen > 0):
blockSize = min(outputByteLen, rateInBytes)
outputBytes = outputBytes + state[0:blockSize]
outputByteLen = outputByteLen - blockSize
if (outputByteLen > 0):
state = KeccakP1600(state, 12)
return outputBytes
def right_encode(x):
S = bytearray()
while(x > 0):
S = bytearray([x % 256]) + S
x = x//256
S = S + bytearray([len(S)])
return S
# inputMessage and customizationString must be of type byte string or byte array
def KangarooTwelve(inputMessage, customizationString, outputByteLen):
B = 8192
c = 256
S = bytearray(inputMessage) + bytearray(customizationString) + right_encode(len(customizationString))
# === Cut the input string into chunks of B bytes ===
n = (len(S)+B-1)//B
Si = [bytearray(S[i*B:(i+1)*B]) for i in range(n)]
if (n == 1):
# === Process the tree with only a final node ===
return F(Si[0], 0x07, outputByteLen)
else:
# === Process the tree with kangaroo hopping ===
CVi = [F(Si[i+1], 0x0B, c//8) for i in range(n-1)]
NodeStar = Si[0] + bytearray([3,0,0,0,0,0,0,0]) + bytearray().join(CVi) \
+ right_encode(n-1) + b'\xFF\xFF'
return F(NodeStar, 0x06, outputByteLen)
# -*- coding: utf-8 -*-
# Implementation by DonaldTsang
#
# For more information, feedback or questions, please refer to our website:
# https://keccak.team/
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
def ROL64(a, n):
return ((a >> (64-(n%64))) + (a << (n%64))) % (1 << 64)
def KeccakP1600onLanes(lanes, nrRounds):
R = 1
for round in range(24):
if (round + nrRounds >= 24):
# θ
C = [lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4] for x in range(5)]
D = [C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1) for x in range(5)]
lanes = [[lanes[x][y]^D[x] for y in range(5)] for x in range(5)]
# ρ and π
(x, y) = (1, 0)
current = lanes[x][y]
for t in range(24):
(x, y) = (y, (2*x+3*y)%5)
(current, lanes[x][y]) = (lanes[x][y], ROL64(current, (t+1)*(t+2)//2))
# χ
for y in range(5):
T = [lanes[x][y] for x in range(5)]
for x in range(5):
lanes[x][y] = T[x] ^((~T[(x+1)%5]) & T[(x+2)%5])
# ι
for j in range(7):
R = ((R << 1) ^ ((R >> 7)*0x71)) % 256
if (R & 2):
lanes[0][0] = lanes[0][0] ^ (1 << ((1<<j)-1))
else:
for j in range(7):
R = ((R << 1) ^ ((R >> 7)*0x71)) % 256
return lanes
def load64(b):
return sum((b[i] << (8*i)) for i in range(8))
def store64(a):
return bytearray((a >> (8*i)) % 256 for i in range(8))
def KeccakP1600(state, nrRounds):
lanes = [[load64(state[8*(x+5*y):8*(x+5*y)+8]) for y in range(5)] for x in range(5)]
lanes = KeccakP1600onLanes(lanes, nrRounds)
state = bytearray().join([store64(lanes[x][y]) for y in range(5) for x in range(5)])
return bytearray(state)
def F14(inputBytes, delimitedSuffix, outputByteLen):
outputBytes = bytearray()
state = bytearray([0 for i in range(200)])
rateInBytes = 1088//8
blockSize = 0
inputOffset = 0
# === Absorb all the input blocks ===
while(inputOffset < len(inputBytes)):
blockSize = min(len(inputBytes)-inputOffset, rateInBytes)
for i in range(blockSize):
state[i] = state[i] ^ inputBytes[i+inputOffset]
inputOffset = inputOffset + blockSize
if (blockSize == rateInBytes):
state = KeccakP1600(state, 14)
blockSize = 0
# === Do the padding and switch to the squeezing phase ===
state[blockSize] = state[blockSize] ^ delimitedSuffix
if (((delimitedSuffix & 0x80) != 0) and (blockSize == (rateInBytes-1))):
state = KeccakP1600(state, 14)
state[rateInBytes-1] = state[rateInBytes-1] ^ 0x80
state = KeccakP1600(state, 14)
# === Squeeze out all the output blocks ===
while(outputByteLen > 0):
blockSize = min(outputByteLen, rateInBytes)
outputBytes = outputBytes + state[0:blockSize]
outputByteLen = outputByteLen - blockSize
if (outputByteLen > 0):
state = KeccakP1600(state, 14)
return outputBytes
def right_encode(x):
S = bytearray()
while(x > 0):
S = bytearray([x % 256]) + S
x = x//256
S = S + bytearray([len(S)])
return S
# inputMessage and customizationString must be of type byte string or byte array
def MarsupilamiFourteen(inputMessage, customizationString, outputByteLen):
B = 8192
c = 512
S = bytearray(inputMessage) + bytearray(customizationString) + right_encode(len(customizationString))
# === Cut the input string into chunks of B bytes ===
n = (len(S)+B-1)//B
Si = [bytearray(S[i*B:(i+1)*B]) for i in range(n)]
if (n == 1):
# === Process the tree with only a final node ===
return F14(Si[0], 0x07, outputByteLen)
else:
# === Process the tree with kangaroo hopping ===
CVi = [F14(Si[i+1], 0x0B, c//8) for i in range(n-1)]
NodeStar = Si[0] + bytearray([3,0,0,0,0,0,0,0]) + bytearray().join(CVi) \
+ right_encode(n-1) + b'\xFF\xFF'
return F14(NodeStar, 0x06, outputByteLen)
// Implementation of K12, based on the reference implementation:
// https://github.com/gvanas/KeccakCodePackage/blob/master/Standalone/KangarooTwelve-reference/K12.py
//
// Some optimisations copied from https://github.com/RustCrypto/hashes/tree/master/sha3/src
//
// To the extent possible under law, the implementer has waived all copyright
// and related or neighboring rights to the source code in this file.
// http://creativecommons.org/publicdomain/zero/1.0/
// Tests are executable directly: rustc k12.rs && ./k12
//
// This is not published as a Cargo crate since more optimisations are needed
// to make this faster than standard Keccak/SHA3.
// I can't be bothered to rename!
#![allow(non_snake_case)]
use std::cmp::min;
/// Copied from `arrayref` crate
macro_rules! array_ref {
($arr:expr, $offset:expr, $len:expr) => {{
{
#[inline]
unsafe fn as_array<T>(slice: &[T]) -> &[T; $len] {
&*(slice.as_ptr() as *const [_; $len])
}
let offset = $offset;
let slice = & $arr[offset..offset + $len];
unsafe {
as_array(slice)
}
}
}}
}
macro_rules! REPEAT4 {
($e: expr) => ( $e; $e; $e; $e; )
}
macro_rules! REPEAT5 {
($e: expr) => ( $e; $e; $e; $e; $e; )
}
macro_rules! REPEAT6 {
($e: expr) => ( $e; $e; $e; $e; $e; $e; )
}
macro_rules! REPEAT24 {
($e: expr, $s: expr) => (
REPEAT6!({ $e; $s; });
REPEAT6!({ $e; $s; });
REPEAT6!({ $e; $s; });
REPEAT5!({ $e; $s; });
$e;
)
}
macro_rules! FOR5 {
($v: expr, $s: expr, $e: expr) => {
$v = 0;
REPEAT4!({
$e;
$v += $s;
});
$e;
}
}
pub const RC: [u64; 12] = [
0x000000008000808b,
0x800000000000008b,
0x8000000000008089,
0x8000000000008003,
0x8000000000008002,
0x8000000000000080,
0x000000000000800a,
0x800000008000000a,
0x8000000080008081,
0x8000000000008080,
0x0000000080000001,
0x8000000080008008,
];
// (0..24).map(|t| ((t+1)*(t+2)/2) % 64)
pub const RHO: [u32; 24] = [
1, 3, 6, 10, 15, 21,28, 36, 45, 55, 2, 14, 27,
41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
];
pub const PI: [usize; 24] = [
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23,
19, 13, 12, 2, 20, 14, 22, 9, 6, 1
];
fn KeccakP1600onLanes(lanes: &mut [u64; 25]) {
let mut C = [0u64; 5];
let (mut x, mut y): (usize, usize);
for round in 0..12 {
// θ
FOR5!(x, 1, {
C[x] = lanes[x] ^ lanes[x+5] ^ lanes[x+10] ^ lanes[x+15] ^ lanes[x+20];
});
FOR5!(x, 1, {
FOR5!(y, 5, {
lanes[x + y] ^= C[(x+4)%5] ^ C[(x+1)%5].rotate_left(1);
});
});
// ρ and π
let mut a = lanes[1];
x = 0;
REPEAT24!({
C[0] = lanes[PI[x]];
lanes[PI[x]] = a.rotate_left(RHO[x]);
}, {
a = C[0];
x += 1;
});
// χ
FOR5!(y, 5, {
FOR5!(x, 1, {
C[x] = lanes[x + y];
});
FOR5!(x, 1, {
lanes[x + y] = C[x] ^((!C[(x+1) % 5]) & C[(x+2)%5]);
});
});
// ι
lanes[0] ^= RC[round];
}
}
fn read_u64(bytes: &[u8; 8]) -> u64 {
unsafe{ *(bytes as *const [u8; 8] as *const u64) }.to_le()
}
fn write_u64(val: u64) -> [u8; 8] {
unsafe{ *(&val.to_le() as *const u64 as *const [u8; 8]) }
}
fn KeccakP1600(state: &mut [u8; 200]) {
let mut lanes = [0u64; 25];
let mut y;
for x in 0..5 {
FOR5!(y, 5, {
lanes[x + y] = read_u64(array_ref!(state, 8*(x+y), 8));
});
}
KeccakP1600onLanes(&mut lanes);
for x in 0..5 {
FOR5!(y, 5, {
let i = 8*(x+y);
state[i..i+8].copy_from_slice(&write_u64(lanes[x + y]));
});
}
}
fn F(inputBytes: &[u8], delimitedSuffix: u8, mut outputByteLen: usize) -> Vec<u8> {
let mut state = [0u8; 200];
let rateInBytes = 1344 / 8;
// === Absorb all the input blocks ===
// We unroll first loop, which allows simple copy
let mut blockSize = min(inputBytes.len(), rateInBytes);
state[0..blockSize].copy_from_slice(&inputBytes[0..blockSize]);
let mut inputOffset = blockSize;
while inputOffset < inputBytes.len() {
KeccakP1600(&mut state);
blockSize = min(inputBytes.len() - inputOffset, rateInBytes);
for i in 0..blockSize {
// TODO: is this sufficiently optimisable or better to convert to u64 first?
state[i] ^= inputBytes[i+inputOffset];
}
inputOffset += blockSize;
}
if blockSize == rateInBytes {
// TODO: condition is nearly always false; tests pass without this.
// Why is it here?
KeccakP1600(&mut state);
blockSize = 0;
}
// === Do the padding and switch to the squeezing phase ===
state[blockSize] ^= delimitedSuffix;
if ((delimitedSuffix & 0x80) != 0) && (blockSize == (rateInBytes-1)) {
// TODO: condition is almost always false — in fact tests pass without
// this block! So why is it here?
KeccakP1600(&mut state);
}
state[rateInBytes-1] ^= 0x80;
KeccakP1600(&mut state);
// === Squeeze out all the output blocks ===
let mut outputBytes = Vec::with_capacity(outputByteLen);
while outputByteLen > 0 {
blockSize = min(outputByteLen, rateInBytes);
outputBytes.extend_from_slice(&state[0..blockSize]);
outputByteLen -= blockSize;
if outputByteLen > 0 {
KeccakP1600(&mut state);
}
}
outputBytes
}
fn right_encode(mut x: usize) -> Vec<u8> {
let mut S = Vec::new();
while x > 0 {
S.push((x % 256) as u8);
x /= 256;
}
S.reverse();
let len = S.len();
S.push(len as u8);
S
}
pub fn KangarooTwelve<TA: AsRef<[u8]>, TB: AsRef<[u8]>>(inputMessage: TA,
customizationString: TB, outputByteLen: usize) -> Vec<u8>
{
let B = 8192;
let c = 256;
let mut S = Vec::new();
S.extend_from_slice(inputMessage.as_ref());
S.extend_from_slice(customizationString.as_ref());
S.extend_from_slice(&right_encode(customizationString.as_ref().len())[..]);
// === Cut the input string into chunks of B bytes ===
let n = (S.len() + B - 1) / B;
let mut Si = Vec::with_capacity(n);
for i in 0..n {
let ub = min((i+1)*B, S.len());
Si.push(&S[i*B .. ub]);
}
if n == 1 {
// === Process the tree with only a final node ===
F(Si[0], 0x07, outputByteLen)
} else {
// === Process the tree with kangaroo hopping ===
// TODO: in parallel
let mut CVi = Vec::with_capacity(n-1);
for i in 0..n-1 {
CVi.push(F(Si[i+1], 0x0B, c/8));
}
let mut NodeStar = Vec::new();
NodeStar.extend_from_slice(Si[0]);
NodeStar.extend_from_slice(&[3,0,0,0,0,0,0,0]);
for i in 0..n-1 {
NodeStar.extend_from_slice(&CVi[i][..]);
}
NodeStar.extend_from_slice(&right_encode(n-1));
NodeStar.extend_from_slice(b"\xFF\xFF");
F(&NodeStar[..], 0x06, outputByteLen)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::iter;
fn read_bytes<T: AsRef<[u8]>>(s: T) -> Vec<u8> {
fn b(c: u8) -> u8 {
match c {
b'0' ... b'9' => c - b'0',
b'a' ... b'f' => c - b'a' + 10,
b'A' ... b'F' => c - b'A' + 10,
_ => unreachable!(),
}
}
let s = s.as_ref();
let mut i = 0;
let mut v = Vec::new();
while i < s.len() {
if s[i] == b' ' || s[i] == b'\n' { i += 1; continue; }
let n = b(s[i]) * 16 + b(s[i+1]);
v.push(n);
i += 2;
}
v
}
#[test]
fn empty() {
// Source: reference paper
assert_eq!(KangarooTwelve("", "", 32), read_bytes("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"));
assert_eq!(KangarooTwelve("", "", 64), read_bytes("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 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"));
assert_eq!(KangarooTwelve("", "", 10032)[10000..], read_bytes("e8 dc 56 36 42 f7 22 8c 84
68 4c 89 84 05 d3 a8 34 79 91 58 c0 79 b1 28 80 27 7a 1d 28 e2 ff 6d")[..]);
}
#[test]
fn patM() {
let expected = [
"2b da 92 45 0e 8b 14 7f 8a 7c b6 29 e7 84 a0 58 ef ca 7c f7
d8 21 8e 02 d3 45 df aa 65 24 4a 1f",
"6b f7 5f a2 23 91 98 db 47 72 e3 64 78 f8 e1 9b 0f 37 12 05
f6 a9 a9 3a 27 3f 51 df 37 12 28 88",
"0c 31 5e bc de db f6 14 26 de 7d cf 8f b7 25 d1 e7 46 75 d7
f5 32 7a 50 67 f3 67 b1 08 ec b6 7c",
"cb 55 2e 2e c7 7d 99 10 70 1d 57 8b 45 7d df 77 2c 12 e3 22
e4 ee 7f e4 17 f9 2c 75 8f 0d 59 d0",
"87 01 04 5e 22 20 53 45 ff 4d da 05 55 5c bb 5c 3a f1 a7 71
c2 b8 9b ae f3 7d b4 3d 99 98 b9 fe",
"84 4d 61 09 33 b1 b9 96 3c bd eb 5a e3 b6 b0 5c c7 cb d6 7c
ee df 88 3e b6 78 a0 a8 e0 37 16 82",
"3c 39 07 82 a8 a4 e8 9f a6 36 7f 72 fe aa f1 32 55 c8 d9 58
78 48 1d 3c d8 ce 85 f5 8e 88 0a f8"];
for i in 0..5 /*NOTE: can be up to 7 but is slow*/ {
let len = 17usize.pow(i);
let M: Vec<u8> = (0..len).map(|j| (j % 251) as u8).collect();
let result = KangarooTwelve(M, "", 32);
assert_eq!(result, read_bytes(expected[i as usize]));
}
}
#[test]
fn patC() {
let expected = [
"fa b6 58 db 63 e9 4a 24 61 88 bf 7a f6 9a 13 30 45 f4 6e e9
84 c5 6e 3c 33 28 ca af 1a a1 a5 83",
"d8 48 c5 06 8c ed 73 6f 44 62 15 9b 98 67 fd 4c 20 b8 08 ac
c3 d5 bc 48 e0 b0 6b a0 a3 76 2e c4",
"c3 89 e5 00 9a e5 71 20 85 4c 2e 8c 64 67 0a c0 13 58 cf 4c
1b af 89 44 7a 72 42 34 dc 7c ed 74",
"75 d2 f8 6a 2e 64 45 66 72 6b 4f bc fc 56 57 b9 db cf 07 0c
7b 0d ca 06 45 0a b2 91 d7 44 3b cf"];
for i in 0..4 {
let M: Vec<u8> = iter::repeat(0xFF).take(2usize.pow(i) - 1).collect();
let len = 41usize.pow(i);
let C: Vec<u8> = (0..len).map(|j| (j % 251) as u8).collect();
let result = KangarooTwelve(M, C, 32);
assert_eq!(result, read_bytes(expected[i as usize]));
}
}
}
<?xml version="1.0"?>
<group>
<!--
# Introduction
We here explain how to create a custom build target in the Keccak Code Package. Some examples, which can be found below, illustrate the process.
Note that this file is included from Makefile.build, so the examples and anything tried here are accessible "for real" from make.
# Step 1: create a new target
First, choose a target name and add the corresponding XML tag. For the moment, we leave the inherits attribute empty:
<target name="chosenName" inherits=""/>
The name can be anything. If it ends with .a, make will attempt to build a static library with that name. Otherwise, it will build a standalone executable. In both cases, however, one can add ".pack" when invoking make (but not in the target name) to get a tarball with the source files, instead of building it.
# Step 2: select the high-level services
In a second step, select the desired cryptographic functions and add the corresponding fragment keywords to the inherits attribute (separated by a space).
Please refer to the following files for the list of supported cryptographic functions:
* Ketje/Ketje.build for the Ketje instances;
* Keyak/Keyak.build for the Keyak instances;
* HighLevel.build for everything else.
# Step 3: identify the required low-level services
Then, identify the permutations that the chosen cryptographic functions need.
Each cryptographic function implemented in the KCP depends on a given permutation. It interacts with the permutation through an interface called SnP. Some functions further can take advantage of a parallel implementation of the permutation, in which case the interface is called PlSnP. The choice of high-level services therefore determines what we need as low-level services:
* Those that require Keccak-p[200]: KetjeJr, Keccak{Sponge, Duplex, PRG}Width200
* Those that require Keccak-p[400]: KetjeSr, Keccak{Sponge, Duplex, PRG}Width400
* Those that require Keccak-p[800]: KetjeMn, RiverKeyak, Keccak{Sponge, Duplex, PRG}Width800
* Those that require Keccak-p[1600]: all others
The following targets additionally require an implementation of parallel instances of Keccak-p[1600]: SeaKeyak, OceanKeyak, LunarKeyak, KangarooTwelve, SP800-185. Instead, for KangarooTwelve and SP800-185, one can add the fragment keyword no_parallel1600 to disable the use of parallel implementations.
# Step 4: select the implementation of the low-level services
Finally, select the implementation(s) of the required permutation(s) identified in the previous step and add the corresponding fragment keywords to the inherits attribute (separated by a space).
Please refer to the file LowLevel.build for the list of supported implementations.
If Ketje is used, we still need to add an additional fragment keyword, see Ketje/Ketje.build for more details.
-->
<!-- Examples -->
<!-- Type "make PRG-AVR8.pack" to get a tarball with the sources needed to compile a pseudo-random number generator on top of Keccak-f[200] for AVR8. -->
<target name="PRG-AVR8" inherits="KeccakPRGWidth200 optimized200AVR8"/>
<!-- Type "make KetjeJr-compact8.pack" to get a tarball with the sources needed to compile KetjeJr generically optimized for 8-bit platforms. -->
<target name="KetjeJr-compact8" inherits="KetjeJr KetJr-SnP compact200"/>
<!-- Type "make libKeccak-16bits.a" to compile a library with Keccak sponge, duplex and PRG on top of Keccak-f[400], using plain reference code. Add ".pack" when invoking make to get a tarball with the source files instead. -->
<target name="libKeccak-16bits.a" inherits="KeccakSpongeWidth400 KeccakDuplexWidth400 KeccakPRG400 reference400"/>
<!-- Type "make RiverKeyak-ARMv7M.pack" to get a tarball with the sources needed to compile River Keyak on ARMv7M. -->
<target name="RiverKeyak-ARMv7M" inherits="RiverKeyak optimized800ARMv7Mu2"/>
<!-- Type "make libRiverKeyak-generic32.a" to get a library with River Keyak generically optimized for 32-bit platforms. Add ".pack" when invoking make to get a tarball with the source files instead. -->
<target name="libRiverKeyak-generic32.a" inherits="RiverKeyak optimized800lcu2"/>
<!-- Same as above, but we add a PRG and we use a compact implementation instead. -->
<target name="libRiverKeyak-PRG-compact32.a" inherits="RiverKeyak KeccakPRGWidth800 compact800"/>
<!-- Type "make libK12-AVX2.a" to build a library with KangarooTwelve with AVX2 code. Add ".pack" when invoking make to get a tarball with the source files instead. -->
<target name="libK12-AVX2.a" inherits="KangarooTwelve optimized1600AVX2 SIMD128-SSE2u2 SIMD256-AVX2u12 1600times8on4"/>
<!-- Same as above, but using a 32-bit implementation and not exploiting any parallelism. -->
<target name="libK12-32bits.a" inherits="KangarooTwelve inplace1600bi no_parallel1600"/>
<!-- Type "make FIPS202-opt64.pack" to get a tarball with the sources needed to compile the FIPS 202 functions generically optimized for 64-bit platforms. -->
<target name="FIPS202-opt64" inherits="FIPS202 optimized1600ufull"/>
</group>
/*
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
hereby denoted as "the implementer".
For more information, feedback or questions, please refer to our website:
https://keccak.team/
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
/** General information
*
* The following type and functions are not actually implemented. Their
* documentation is generic, with the prefix Prefix replaced by
* - KeccakWidth200 for a duplex object based on Keccak-f[200]
* - KeccakWidth400 for a duplex object based on Keccak-f[400]
* - KeccakWidth800 for a duplex object based on Keccak-f[800]
* - KeccakWidth1600 for a duplex object based on Keccak-f[1600]
*
* In all these functions, the rate and capacity must sum to the width of the
* chosen permutation. For instance, to use the duplex object
* Keccak[r=1346, c=254], one must use the KeccakWidth1600_Duplex* functions.
*
* The Prefix_DuplexInstance contains the duplex instance attributes for use
* with the Prefix_Duplex* functions.
* It gathers the state processed by the permutation as well as the rate,
* the position of input/output bytes in the state in case of partial
* input or output.
*/
#ifdef DontReallyInclude_DocumentationOnly
/**
* Structure that contains the duplex instance for use with the
* Prefix_Duplex* functions.
* It gathers the state processed by the permutation as well as
* the rate.
*/
typedef struct Prefix_DuplexInstanceStruct {
/** The state processed by the permutation. */
unsigned char state[SnP_stateSizeInBytes];
/** The value of the rate in bits.*/
unsigned int rate;
/** The position in the state of the next byte to be input. */
unsigned int byteInputIndex;
/** The position in the state of the next byte to be output. */
unsigned int byteOutputIndex;
} Prefix_DuplexInstance;
/**
* Function to initialize a duplex object Duplex[Keccak-f[r+c], pad10*1, r].
* @param duplexInstance Pointer to the duplex instance to be initialized.
* @param rate The value of the rate r.
* @param capacity The value of the capacity c.
* @pre One must have r+c equal to the supported width of this implementation.
* @pre 3 ≤ @a rate ≤ width, and otherwise the value of the rate is unrestricted.
* @return Zero if successful, 1 otherwise.
*/
int Prefix_DuplexInitialize(Prefix_DuplexInstance *duplexInstance, unsigned int rate, unsigned int capacity);
/**
* Function to make a duplexing call to the duplex object initialized
* with Prefix_DuplexInitialize().
* @param duplexInstance Pointer to the duplex instance initialized
* by Prefix_DuplexInitialize().
* @param sigmaBegin Pointer to the first part of the input σ given as bytes.
* Trailing bits are given in @a delimitedSigmaEnd.
* @param sigmaBeginByteLen The number of input bytes provided in @a sigmaBegin.
* @param Z Pointer to the buffer where to store the output data Z.
* @param ZByteLen The number of output bytes desired for Z.
* If @a ZByteLen*8 is greater than the rate r,
* the last byte contains only r modulo 8 bits,
* in the least significant bits.
* @param delimitedSigmaEnd Byte containing from 0 to 7 trailing bits that must be
* appended to the input data in @a sigmaBegin.
* These <i>n</i>=|σ| mod 8 bits must be in the least significant bit positions.
* These bits must be delimited with a bit 1 at position <i>n</i>
* (counting from 0=LSB to 7=MSB) and followed by bits 0
* from position <i>n</i>+1 to position 7.
* Some examples:
* - If |σ| is a multiple of 8, then @a delimitedSigmaEnd must be 0x01.
* - If |σ| mod 8 is 1 and the last bit is 1 then @a delimitedSigmaEnd must be 0x03.
* - If |σ| mod 8 is 4 and the last 4 bits are 0,0,0,1 then @a delimitedSigmaEnd must be 0x18.
* - If |σ| mod 8 is 6 and the last 6 bits are 1,1,1,0,0,1 then @a delimitedSigmaEnd must be 0x67.
* .
* @note The input bits σ are the result of the concatenation of
* the bytes given in Prefix_DuplexingFeedPartialInput()
* calls since the last call to Prefix_Duplexing(),
* the bytes in @a sigmaBegin
* and the bits in @a delimitedSigmaEnd before the delimiter.
* @pre @a delimitedSigmaEnd ≠ 0x00
* @pre @a sigmaBeginByteLen*8+<i>n</i> (+ length of previously queued data) ≤ (r-2)
* @pre @a ZByteLen ≤ ceil(r/8)
* @return Zero if successful, 1 otherwise.
*/
int Prefix_Duplexing(Prefix_DuplexInstance *duplexInstance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd);
/**
* Function to queue input data that will subsequently used in the next
* call to Prefix_Duplexing().
* @param duplexInstance Pointer to the duplex instance initialized
* by Prefix_DuplexInitialize().
* @param input Pointer to the bytes to queue.
* @param inputByteLen The number of input bytes provided in @a input.
* @pre The total number of input bytes since the last Prefix_Duplexing()
* call must not be higher than floor((r-2)/8).
* @return Zero if successful, 1 otherwise.
*/
int Prefix_DuplexingFeedPartialInput(Prefix_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen);
/**
* Function to queue input data that will subsequently used in the next
* call to Prefix_Duplexing(), where the data here consist of all-zero bytes.
* @param duplexInstance Pointer to the duplex instance initialized
* by Prefix_DuplexInitialize().
* @param inputByteLen The number of input bytes 0x00 to feed.
* @pre The total number of input bytes since the last Prefix_Duplexing()
* call must not be higher than floor((r-2)/8).
* @return Zero if successful, 1 otherwise.
*/
int Prefix_DuplexingFeedZeroes(Prefix_DuplexInstance *duplexInstance, unsigned int inputByteLen);
/**
* Function to queue input data that will subsequently used in the next
* call to Prefix_Duplexing(), with the additional pre-processing that
* the input data is first bitwise added with the output data of the previous duplexing
* call at the same offset.
* In practice, this comes down to overwriting the input data in the state
* of the duplex object.
* @param duplexInstance Pointer to the duplex instance initialized
* by Prefix_DuplexInitialize().
* @param input Pointer to the bytes to queue, before they are XORed.
* @param inputByteLen The number of input bytes provided in @a input.
* @pre The total number of input bytes since the last Prefix_Duplexing()
* call must not be higher than floor((r-2)/8).
* @return Zero if successful, 1 otherwise.
*/
int Prefix_DuplexingOverwritePartialInput(Prefix_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen);
/**
* Function to queue input data for the next call to Prefix_Duplexing() that
* is equal to the output data of the previous duplexing call at the same offset.
* In practice, this comes down to overwriting with zeroes the state
* of the duplex object.
* @param duplexInstance Pointer to the duplex instance initialized
* by Prefix_DuplexInitialize().
* @param inputByteLen The number of bytes to overwrite with zeroes.
* @pre No input data may have been queued since the last call
* to Prefix_Duplexing().
* @pre The total number of input bytes since the last Prefix_Duplexing()
* call must not be higher than floor((r-2)/8).
* @return Zero if successful, 1 otherwise.
*/
int Prefix_DuplexingOverwriteWithZeroes(Prefix_DuplexInstance *duplexInstance, unsigned int inputByteLen);
/**
* Function to fetch output data beyond those that were already output since
* the last call to Prefix_Duplexing().
* @param duplexInstance Pointer to the duplex instance initialized
* by Prefix_DuplexInitialize().
* @param output Pointer to the buffer where to store the output data.
* @param outputByteLen The number of output bytes desired.
* @pre The total number of output bytes, taken since (and including in)
* the last call to Prefix_Duplexing() cannot be higher than ceil(r/8).
* @return Zero if successful, 1 otherwise.
*/
int Prefix_DuplexingGetFurtherOutput(Prefix_DuplexInstance *duplexInstance, unsigned char *out, unsigned int outByteLen);
/**
* Function to fetch output data beyond those that were already output since
* the last call to Prefix_Duplexing(), with the additional post-processing
* that this data is bitwise added with the given input buffer
* before it is stored into the given output buffer.
* @param duplexInstance Pointer to the duplex instance initialized
* by Prefix_DuplexInitialize().
* @param input Pointer to the input buffer.
* @param output Pointer to the output buffer, which may be equal to @a input.
* @param outputByteLen The number of output bytes desired.
* @pre The total number of output bytes, taken since (and including in)
* the last call to Prefix_Duplexing() cannot be higher than ceil(r/8).
* @return Zero if successful, 1 otherwise.
*/
int Prefix_DuplexingGetFurtherOutputAndAdd(Prefix_DuplexInstance *duplexInstance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen);
#endif