# Keccak Module

A thin layer over assembly implementations of (intentionally few) optimized Keccak for ARMv8 and x86_64.
The code is adapted from the output of the scripts written by the [cryptogams](https://github.com/dot-asm/cryptogams) project. See [#copyright-notice] for a copy of the licence. You can find the original text at [their repository](https://github.com/dot-asm/cryptogams/blob/680f98c1765a7cb89c193db169ed048599f92186/LICENSE).

> [!NOTE]
> This library is not endorsed nor supported by the original _Cryptogams_ team.
> The code has been modified to integrate to Rust in the simplest possible way and to avoid the need of extra toolchains to build the project.

## Goals

The goal of this module is to have an efficient implementation of Keccak256 for Ethrex, reusing audited code as much as possible, while keeping complexity as low as possible.
To achieve low complexity, we leave explicitly out of scope implementing `Digest`, having implementations for all variants of CPUs (we keep a selected subset of those provided by _Cryptogams_) and compile-time translation of source files.
The module exposes only the following:
```rust
pub fn keccak_hash(data: impl AsRef<[u8]>) -> [u8; 32];
struct Keccak256;
impl Keccak256 {
    fn new() -> Self;
    fn update(&self, impl AsRef<[u8]>) -> Self;
    fn finalize(self) -> [u8; 32];
}
impl Default for Keccak256;
```
There are no feature flags. If building for `x86_64`, it will link an optimized assembly implementation. Because it uses generic `x86_64` code, no fallback is needed.
If building for `ARMv8`, it will link an optimized implementation using generic `ARMv8` instructions.
In both cases we chose the baseline instruction sets. This was not due to compatibility, which can be handled with dynamic dispatch, but because in the case of `ARMv8` using specialized `SHA3` instructions showed no improvement, and in `x86_64` using `AVX2` actually showed a regression of 30% in throughput.
For other architectures, it falls back to `tiny_keccak`. This is specially necessary for proving, as the ZKVMs are RISC-V based, but they are not guaranteed to support all of its extensions. We may revisit adding assembly versions for them at a later time.

## Code Generation

The implementation is currently rather manual:
- Code is generated by running the scripts in the _Cryptogams_ project (currently at commit `680f98c1765a7cb89c193db169ed048599f92186`), as follows:
```shell
$ cd cryptogams/arm
$ ./keccak1600-armv8.pl linux64 keccak1600-armv8.s
$ cd ../x86_64
$ ./keccak1600-x86_64.pl linux64 keccak1600-x86_64.s
```
- The x86 can be directly imported by the Rust compiler with the current options, but the ARM code requires a few changes, commented at the top of the `keccak1600-armv8.s` file.

## Copyright Notice

Copyright (c) 2006, CRYPTOGAMS by <appro@openssl.org>
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 copyright notices,
	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 CRYPTOGAMS nor the names of its
	copyright holder and contributors may be used to endorse or
	promote products derived from this software without specific
	prior written permission.

ALTERNATIVELY, provided that this notice is retained in full, this
product may be distributed under the terms of the GNU General Public
License (GPL), in which case the provisions of the GPL apply INSTEAD OF
those given above.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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
OWNER OR CONTRIBUTORS 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.
