Xoodyak
Accelerated Xoodyak - A Lightweight Cryptographic Scheme
Install / Use
/learn @itzmeanjan/XoodyakREADME
xoodyak
Accelerated Xoodyak - A Lightweight Cryptographic Scheme
Overview
After implementing ascon & tinyjambu -- two finalists of NIST Light Weight Cryptography standardization competition, I've picked up xoodyak, which is another finalist of NIST LWC call. Xoodyak cryptograhic suite, as submitted in NIST LWC call, offers following two features
- Cryptographic Hashing
- Authenticated Encryption with Associated Data ( AEAD )
Algorithm | What does it do ? | Input | Output --- | :-- | --: | --: Xoodyak Hash | Computes cryptographically secure digest of message | N (>=0) -bytes message | 32 -bytes digest Xoodyak AEAD Encrypt | Encrypts message while authenticating both message and associated data | 16 -bytes secret key, 16 -bytes public message nonce, N (>=0) -bytes associated data and M (>=0) -bytes plain text | M (>=0) -bytes encrypted text and 16 -bytes authentication tag Xoodyak AEAD Decrypt | Decrypts message while verifying authenticity of both message and associated data | 16 -bytes secret key, 16 -bytes public message nonce, 16 -bytes authentication tag, N (>=0) -bytes associated data and M (>=0) -bytes encrypted text | M (>=0) -bytes plain text and boolean verification flag
Note Decrypting party can verify authenticity & integrity of encrypted message and associated data by asserting truth value in boolean flag returned from
decrypt(...)routine. If verification flag is not truth value, decrypted text is not released.
Warning Associated data is never encrypted.
In this repository, I'm keeping a zero-dependency, header-only and easy-to-use C++ library ( using C++20 features ), which implements Xoodyak specification. Along with that I also maintain Python wrapper API, which under the hood makes use of C-ABI conformant shared library object.
To learn more about AEAD, see here
If interested in my work on
ascon, see here
If interested in my work on
tinyjambu, see here
Note Xoodyak specification, which I followed during this implementation, lives here
Prerequisites
- Ensure you've C++ compiler such as
clang++/g++, with C++20 standard library
$ clang++ --version
Ubuntu clang version 14.0.0-1ubuntu1
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ g++ --version
g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0
- You should also have system development utilities such as
make,cmake,git&unzip
$ make --version
GNU Make 4.3
$ cmake --version
cmake version 3.22.1
$ git --version
git version 2.34.1
$ unzip -v
UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP.
-
For benchmarking Xoodyak implementation on CPU, you'll need to have
google-benchmarkheaders and library installed; follow this -
For ensuring conformance with KATs ( as submitted to NIST LWC call ), you need to have
python3, along with dependencies which can be easily installed usingpip
$ python3 --version
Python 3.10.8
# If you don't have pip installed
$ sudo apt-get install python3-pip
# Download Python dependencies
$ python3 -m pip install -r wrapper/python/requirements.txt --user
Note It can be a better idea to isolate Xoodyak Python API dependency installation from system Python installation, using
virtualenv
# install virtualenv itself
python3 -m pip install --user virtualenv
pushd wrapper/python
# create virtualenv enabled workspace
python3 -m virtualenv .
# activate virtual environment
source bin/activate
# install all dependencies inside virtual environment
python3 -m pip install -r requirements.txt
# work inside virtual environment
# when done, issue following command
# ...
deactivate
popd
Testing
For testing functional correctness of Xoodyak cryptographic suite implementation, I've written following tests
- [ test_aead ] : Given 16 -bytes random secret key, 16 -bytes random public message nonce, N (>=0) -bytes random associated data & M (>=0) -bytes random plain text
- Ensure, in ideal condition, everything works as expected, while executing encrypt -> decrypt -> byte-by-byte comparison of plain & decrypted text
- Same as above point, just that before attempting decryption, to check that claimed security properties are working as expected in this implementation, mutation of secret key/ nonce/ tag/ encrypted data/ associated data ( even a single bit flip is sufficient ) is performed, while asserting that verified decryption attempt must fail ( read boolean verification flag must not be truth value ).
- [ test_kat ] : Given Known Answer Tests as submitted with Xoodyak package in NIST LWC call, this implementation computed results are asserted against KATs, to ensure correctness & conformance to specified standard. Both Xoodyak Hash & AEAD are checked.
# Just issue
make # test_aead + test_kat
SSE2=1 make # if target CPU has SSE2
# --- Or you may ---
make test_aead # tests functional correctness of AEAD
SSE2=1 make test_aead # if target CPU has SSE2
make test_kat # tests correctness and conformance with standard
SSE2=1 make test_kat # if target CPU has SSE2
Benchmarking
For benchmarking following implementations of Xoodyak cryptographic suite, on CPU
- Xoodoo[12] permutation
- Xoodyak cryptographic hash function
- Xoodyak Authenticated Encryption
- Xoodyak Verified Decryption
issue
make benchmark # must have `google-benchmark` library and header
SSE2=1 make benchmark # if target CPU has SSE2
On Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz ( compiled with GCC )
2023-01-09T16:46:47+00:00
Running ./bench/a.out
Run on (128 X 1343.45 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x64)
L1 Instruction 32 KiB (x64)
L2 Unified 1280 KiB (x64)
L3 Unified 55296 KiB (x2)
Load Average: 0.30, 0.10, 0.03
-----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
-----------------------------------------------------------------------------------------
bench_xoodyak::hash/64 792 ns 792 ns 884350 bytes_per_second=77.1079M/s
bench_xoodyak::hash/128 1408 ns 1408 ns 497356 bytes_per_second=86.6982M/s
bench_xoodyak::hash/256 2644 ns 2644 ns 264858 bytes_per_second=92.3503M/s
bench_xoodyak::hash/512 5113 ns 5113 ns 136861 bytes_per_second=95.4947M/s
bench_xoodyak::hash/1024 10044 ns 10044 ns 69715 bytes_per_second=97.2304M/s
bench_xoodyak::hash/2048 19912 ns 19913 ns 35153 bytes_per_second=98.0851M/s
bench_xoodyak::hash/4096 39644 ns 39645 ns 17660 bytes_per_second=98.5307M/s
bench_xoodyak::encrypt/32/64 605 ns 605 ns 1156776 bytes_per_second=151.371M/s
bench_xoodyak::decrypt/32/64 606 ns 606 ns 1154334 bytes_per_second=150.965M/s
bench_xoodyak::encrypt/32/128 953 ns 953 ns 733726 bytes_per_second=160.148M/s
bench_xoodyak::decrypt/32/128 958 ns 958 ns 729611 bytes_per_second=159.307M/s
bench_xoodyak::encrypt/32/256 1551 ns 1551 ns 451123 bytes_per_second=177.068M/s
bench_xoodyak::decrypt/32/256 1556 ns 1556 ns 451385 bytes_per_second=176.484M/s
bench_xoodyak::encrypt/32/512 2823 ns 2823 ns 247997 bytes_per_second=183.789M/s
bench_xoodyak::decrypt/32/512 2837 ns 2837 ns 246746 bytes_per_second=182.886M/s
bench_xoodyak::encrypt/32/1024 5252 ns 5252 ns 133334 bytes_per_second=191.759M/s
bench_xoodyak::decrypt/32/1024 5298 ns 5297 ns 131890 bytes_per_second=190.109M/s
bench_xoodyak::encrypt/32/2048 10232 ns 10232 ns 68414 bytes_per_second=193.864M/s
bench_xoodyak::decrypt/32/2048 10326 ns 10326 ns 67752 bytes_per_second=192.103M/s
bench_xoodyak::encrypt/32/4096 20099 ns 20099 ns 34825 bytes_per_second=195.871M/s
bench_xoodyak::decrypt/32/4096 20251 ns 20251 ns 34560 bytes_per_second=194.395M/s
On Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz ( compiled with Clang )
2023-01-09T16:47:33+00:00
Running ./bench/a.out
Run on (128 X 2722.43 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x64)
L1 Instruction 32 KiB (x64)
L2 Unified 1280 KiB (x64)
L3 Unified 55296 KiB (x2)
Load Average: 0.38, 0.16, 0.06
-----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
-----------------------------------------------------------------------------------------
bench_xoodyak::hash/64 434 ns 434 ns 1613281 bytes_per_second=140.674M/s
bench_xoodyak::hash/128 781 ns 781 ns 896393 bytes_per_second=156.346M/s
bench_xoodyak::hash/256 1474 ns 1474 ns 474787 bytes_per_second=165.625M/s
bench_xoodyak::hash/512 2861 ns 2861 ns 244530 bytes_per_second=170.677M/s
bench_xoodyak::hash/1024 5636 ns 5637 ns 124155 bytes_per_second=173.255M/s
bench_xoodyak::hash/2048 11186 ns 11186 ns 62585 bytes_per_second=174.608M/s
bench_xoodyak::hash/4096 22287 ns 22286 ns 31399 bytes_per_second=175.275M/s
bench_xoodyak::encrypt/32/64 468 ns 468 ns 14940
