Skip to main content

A package for the Shake extendable-output functions (XOFs)

Project description

License MIT GitHub CI Documentation Status

xoflib

A Python package for the Shake extendable-output functions (XOFs): Shake128, Shake256 and the turbo variants. Built using pyO3 bindings for the sha3 crate.

Algorithms

We currently have pyO3 bindings for the four XOF available in the sha3 crate:

Documentation

For more detailed documentation see the xoflib package documentation

Example Usage

For the Shake128 and Shake256 XOF, the intended usage is to first define a shake object, which is then finalized to product the XOF or Sponge:

>>> from xoflib import Shake128
>>> shake128 = Shake128(b"a new XOF library")
>>> shake128.absorb(b"written using pyO3 bindings")
>>> xof = shake128.finalize()
>>> xof.read(16).hex()
'1301cd080b034973e961d585330b9e0c'
>>> xof.read(16).hex()
'1af56b984d09bce5a6c07da3f3b953bd'

The TurboShake128 and TurboShake256 XOFs additionally require a domain separation:

>>> from xoflib import TurboShake256
>>> domain_sep = 123 # should be between (1, 127)
>>> turbo256 = TurboShake256(domain_sep)
>>> turbo256.absorb(b"Turbo mode")
>>> xof = turbo256.finalize()
>>> xof.read(16).hex()
'798984af20ecc1e9e593410c23f0fe67'
>>> xof.read(16).hex()
'5aa0168bc689e89a35111d43842de214'

Sponges can also be constructed directly:

>>> from xoflib import shake128, Shake128
>>> sponge1 = Shaker128(b"a new XOF library").finalize()
>>> sponge2 = shake128(b"a new XOF library")
>>> assert sponge1.read(10) == sponge2.read(10)

Motivation

For most hashing needs, the hashlib module is appropriate. However, the package maintainers have decided to not support Shake as an XOF and simply treat it as another hash with digest. This means that if a user reads n bytes and then wishes for the next m bytes of output, they must generate n + m bytes from a digest() call and then slice the output for the last m bytes.

This can be an issue for cryptographic protocols, such as the post-quantum protocols ML-KEM (Kyber) and ML-DSA (Dilithium), which rely on Shake128 and Shake256 to continuously read bytes for rejection sampling.

The purpose of this package is to implement XOF for their intended use case, with absorb(), finalize() and read() methods, which allow for the correct instantiation of the XOF as well as efficient sampling of bytes.

Tests

We rely on the testing of the sha3 crate for correctness of the Shake implementations. For API testing and consistency with hashlib we include some unittests for the XOFs exposed in our module: tests/test_xoflib.py

Rough Benchmarking

We find that xoflib performs equally with hashlib and is faster than the XOFs available pycryptodome.

xoflib has the additional memory cost benefit as calling c bytes to be read from our XOF n times only needs c bytes of memory for each call, where as hashlib requires the potentially colossal amount of n * c bytes of memory which are then iterated over.

We include two timings for hashlib -- one naive where n * c bytes are requested and iterated over slicing over bytes and a second which uses a wrapper by David Buchanan from this comment which helps with the API but has the same memory usage issues.

All times are derived by timing the computation of c_0 ^ c_1 ^ ... c_(n-1) for n chunks of c bytes:

def benchmark_xof(shake, absorb, c, n):
    xof = shake(absorb).finalize()
    res = bytes([0] * c)
    for _ in range(n):
        chunk = xof.read(c)
        res = xor_bytes(res, chunk)
    return res
================================================================================
 Benchmarking Shake256: 
================================================================================
Requesting 1 bytes from XOF 10000 times
xoflib: 0.69s
hashlib (single call): 0.65s
hashlib (streaming): 0.82s
pycryptodome: 1.82s

Requesting 100 bytes from XOF 10000 times
xoflib: 6.65s
hashlib (single call): 6.57s
hashlib (streaming): 6.98s
pycryptodome: 7.83s

Requesting 1000 bytes from XOF 1000 times
xoflib: 6.05s
hashlib (single call): 5.90s
hashlib (streaming): 6.15s
pycryptodome: 6.15s

Requesting 10000 bytes from XOF 1000 times
xoflib: 5.82s
hashlib (single call): 5.77s
hashlib (streaming): 6.37s
pycryptodome: 5.85s

Requesting 32 bytes from XOF 100000 times
xoflib: 2.71s
hashlib (single call): 2.63s
hashlib (streaming): 2.89s
pycryptodome: 3.83s

For more information, see the file benchmarks/benchmark_xof.py.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xoflib-0.1.0.tar.gz (17.2 kB view hashes)

Uploaded Source

Built Distributions

xoflib-0.1.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl (450.8 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ x86-64

xoflib-0.1.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl (471.7 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ i686

xoflib-0.1.0-pp310-pypy310_pp73-musllinux_1_2_armv7l.whl (553.8 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ ARMv7l

xoflib-0.1.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl (469.2 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ ARM64

xoflib-0.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (279.5 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

xoflib-0.1.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (346.6 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ s390x

xoflib-0.1.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (318.1 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ppc64le

xoflib-0.1.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (291.5 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

xoflib-0.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (289.9 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

xoflib-0.1.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl (293.4 kB view hashes)

Uploaded PyPy manylinux: glibc 2.5+ i686

xoflib-0.1.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl (450.9 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ x86-64

xoflib-0.1.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl (472.9 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ i686

xoflib-0.1.0-pp39-pypy39_pp73-musllinux_1_2_armv7l.whl (554.2 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ ARMv7l

xoflib-0.1.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl (469.0 kB view hashes)

Uploaded PyPy musllinux: musl 1.2+ ARM64

xoflib-0.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (279.8 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

xoflib-0.1.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (347.2 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ s390x

xoflib-0.1.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (317.5 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ppc64le

xoflib-0.1.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (291.9 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

xoflib-0.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (289.9 kB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

xoflib-0.1.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl (295.0 kB view hashes)

Uploaded PyPy manylinux: glibc 2.5+ i686

xoflib-0.1.0-cp312-none-win_amd64.whl (147.4 kB view hashes)

Uploaded CPython 3.12 Windows x86-64

xoflib-0.1.0-cp312-none-win32.whl (140.9 kB view hashes)

Uploaded CPython 3.12 Windows x86

xoflib-0.1.0-cp312-cp312-musllinux_1_2_x86_64.whl (451.0 kB view hashes)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

xoflib-0.1.0-cp312-cp312-musllinux_1_2_i686.whl (472.3 kB view hashes)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

xoflib-0.1.0-cp312-cp312-musllinux_1_2_armv7l.whl (553.9 kB view hashes)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARMv7l

xoflib-0.1.0-cp312-cp312-musllinux_1_2_aarch64.whl (469.2 kB view hashes)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

xoflib-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (279.9 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

xoflib-0.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl (335.6 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ s390x

xoflib-0.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (317.1 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ppc64le

xoflib-0.1.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (291.6 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARMv7l

xoflib-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (290.2 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

xoflib-0.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl (294.0 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.5+ i686

xoflib-0.1.0-cp312-cp312-macosx_11_0_arm64.whl (246.4 kB view hashes)

Uploaded CPython 3.12 macOS 11.0+ ARM64

xoflib-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl (248.7 kB view hashes)

Uploaded CPython 3.12 macOS 10.12+ x86-64

xoflib-0.1.0-cp311-none-win_amd64.whl (149.4 kB view hashes)

Uploaded CPython 3.11 Windows x86-64

xoflib-0.1.0-cp311-none-win32.whl (142.8 kB view hashes)

Uploaded CPython 3.11 Windows x86

xoflib-0.1.0-cp311-cp311-musllinux_1_2_x86_64.whl (450.3 kB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

xoflib-0.1.0-cp311-cp311-musllinux_1_2_i686.whl (472.3 kB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

xoflib-0.1.0-cp311-cp311-musllinux_1_2_armv7l.whl (554.7 kB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARMv7l

xoflib-0.1.0-cp311-cp311-musllinux_1_2_aarch64.whl (467.8 kB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

xoflib-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (279.3 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

xoflib-0.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl (342.3 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ s390x

xoflib-0.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (316.9 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ppc64le

xoflib-0.1.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (292.4 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARMv7l

xoflib-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (288.8 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

xoflib-0.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl (293.2 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.5+ i686

xoflib-0.1.0-cp311-cp311-macosx_11_0_arm64.whl (245.9 kB view hashes)

Uploaded CPython 3.11 macOS 11.0+ ARM64

xoflib-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl (248.9 kB view hashes)

Uploaded CPython 3.11 macOS 10.12+ x86-64

xoflib-0.1.0-cp310-none-win_amd64.whl (149.6 kB view hashes)

Uploaded CPython 3.10 Windows x86-64

xoflib-0.1.0-cp310-none-win32.whl (142.9 kB view hashes)

Uploaded CPython 3.10 Windows x86

xoflib-0.1.0-cp310-cp310-musllinux_1_2_x86_64.whl (450.8 kB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

xoflib-0.1.0-cp310-cp310-musllinux_1_2_i686.whl (471.5 kB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

xoflib-0.1.0-cp310-cp310-musllinux_1_2_armv7l.whl (554.3 kB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARMv7l

xoflib-0.1.0-cp310-cp310-musllinux_1_2_aarch64.whl (468.6 kB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

xoflib-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (279.8 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

xoflib-0.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl (345.9 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ s390x

xoflib-0.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (317.6 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ppc64le

xoflib-0.1.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (292.1 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARMv7l

xoflib-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (289.6 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

xoflib-0.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl (293.4 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.5+ i686

xoflib-0.1.0-cp310-cp310-macosx_11_0_arm64.whl (246.3 kB view hashes)

Uploaded CPython 3.10 macOS 11.0+ ARM64

xoflib-0.1.0-cp39-none-win_amd64.whl (150.1 kB view hashes)

Uploaded CPython 3.9 Windows x86-64

xoflib-0.1.0-cp39-none-win32.whl (143.2 kB view hashes)

Uploaded CPython 3.9 Windows x86

xoflib-0.1.0-cp39-cp39-musllinux_1_2_x86_64.whl (451.5 kB view hashes)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

xoflib-0.1.0-cp39-cp39-musllinux_1_2_i686.whl (473.0 kB view hashes)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

xoflib-0.1.0-cp39-cp39-musllinux_1_2_armv7l.whl (556.0 kB view hashes)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARMv7l

xoflib-0.1.0-cp39-cp39-musllinux_1_2_aarch64.whl (470.6 kB view hashes)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

xoflib-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (280.5 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

xoflib-0.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl (345.7 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ s390x

xoflib-0.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (318.3 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ppc64le

xoflib-0.1.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (293.6 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARMv7l

xoflib-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (291.8 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

xoflib-0.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl (294.4 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.5+ i686

xoflib-0.1.0-cp39-cp39-macosx_11_0_arm64.whl (246.2 kB view hashes)

Uploaded CPython 3.9 macOS 11.0+ ARM64

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page