Metadata-Version: 2.5
Name: sha3bit
Version: 0.4.1
Summary: SHA3 with bit granularity for message input length
Project-URL: Homepage, https://github.com/sebastien-riou/sha3bit
Project-URL: Bug Tracker, https://github.com/sebastien-riou/sha3bit/issues
Author: Sebastien Riou
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.12
Requires-Dist: bitarray
Description-Content-Type: text/markdown

# sha3bit

| | |
| --- | --- |
| CI/CD | [![CI - Test](https://github.com/sebastien-riou/sha3bit/actions/workflows/test.yml/badge.svg)](https://github.com/sebastien-riou/sha3bit/actions/workflows/test.yml) [![CD - Build](https://github.com/sebastien-riou/sha3bit/actions/workflows/build.yml/badge.svg)](https://github.com/sebastien-riou/sha3bit/actions/workflows/build.yml) [![Documentation Status](https://readthedocs.org/projects/sha3bit/badge/?version=latest)](https://sha3bit.readthedocs.io/en/latest/?badge=latest)|
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/sha3bit.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/sha3bit/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/sha3bit.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/sha3bit/) |
| Meta | [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)  [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v0.json)](https://github.com/charliermarsh/ruff) [![code style - Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/python/mypy) [![License - apache-2.0](https://img.shields.io/badge/license-apache--2.0-blue)](https://spdx.org/licenses/) |


Pure python implementation of SHA3 with features which are often lacking:
- Bit granularity for message input length
- Import/export API to "persist" the state in the middle of a hash computation
- Real `squeez` function in addition of hashlib's `digest`
- Builtin logging to see compression function IOs or even internal steps
- TurboSHAKE and KangarooTwelve (KT128 and KT256 from RFC 9861), and the Keccak permutation with a reduced number of rounds

[User documentation](https://sha3bit.rtfd.io) is hosted on readthedocs.

## Installation

### Command line tool
Install with [pipx](https://pipx.pypa.io), it puts the `sha3bit` command in its own isolated environment:

    pipx install sha3bit

The message is given as a hex string:

    $ sha3bit --sha3-256 616263
    3A 98 5D A7 4F E2 25 B2 04 5C 17 2D 6B D3 90 BD 85 5F 08 6E 3E 9D 52 5B 46 BF E2 45 11 43 15 32

See [CLI usage](#cli-usage) for more examples.

If `pipx` is missing, on Debian/Ubuntu: `sudo apt install pipx && pipx ensurepath`.

### Python API
Add it to your project with [pipenv](https://pipenv.pypa.io):

    pipenv install sha3bit

If `pipenv` is missing: `pipx install pipenv`.

## CLI usage

### Get help

````
sha3bit --help
usage: sha3bit [-h] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--bit-length BIT_LENGTH]
               (--sha3-224 | --sha3-256 | --sha3-384 | --sha3-512 | --shake-128 | --shake-256)
               [--digest-size DIGEST_SIZE]
               message

sha3bit.cli

positional arguments:
  message               Message to hash, as a hex string

options:
  -h, --help            show this help message and exit
  --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
  --bit-length BIT_LENGTH
                        Bit length of message
  --sha3-224            Use SHA3-224 algorithm
  --sha3-256            Use SHA3-256 algorithm
  --sha3-384            Use SHA3-384 algorithm
  --sha3-512            Use SHA3-512 algorithm
  --shake-128           Use SHAKE-128 algorithm
  --shake-256           Use SHAKE-256 algorithm
  --digest-size DIGEST_SIZE
                        Output size in bytes
````

### SHA3-256 of hex string
This compute the SHA3-256 of the message "abc" (which is '61 62 63' in ASCII)

````
sha3bit --sha3-256 616263
3A 98 5D A7 4F E2 25 B2 04 5C 17 2D 6B D3 90 BD 85 5F 08 6E 3E 9D 52 5B 46 BF E2 45 11 43 15 32
````

You can also separate the bytes:
````
sha3bit --sha3-256 '61 62 63'
3A 98 5D A7 4F E2 25 B2 04 5C 17 2D 6B D3 90 BD 85 5F 08 6E 3E 9D 52 5B 46 BF E2 45 11 43 15 32
````

Commas are supported:
````
sha3bit --sha3-256 '0x61, 0x62, 0x63'
3A 98 5D A7 4F E2 25 B2 04 5C 17 2D 6B D3 90 BD 85 5F 08 6E 3E 9D 52 5B 46 BF E2 45 11 43 15 32
````

### Bit length capability

SHA3-256 of single bit message '0':
````
sha3bit --sha3-256 '00' --bit-length=1
1B 2E 61 92 35 78 E3 5F 3B 46 29 E0 4A 0F F3 B7 3D AA 57 1A E0 11 30 D9 C1 6E F7 DA 7A 4C FD C2
````

SHA3-256 of single bit message '1':
````
sha3bit --sha3-256 '01' --bit-length=1
83 F6 62 16 D2 CC 76 9E 15 3B AF CE 01 81 B6 1A 47 1B 4C 6A 21 3F C6 F5 9A 42 98 5F 97 6F 33 FE    
````

SHA3-256 of two bits message '10':
````
sha3bit --sha3-256 '01' --bit-length=2
35 89 C9 5B A0 B3 CF C5 DE 7C 86 88 41 3F DA 5A 2D 5A 55 BB B1 06 90 04 69 F6 C5 E4 17 0E C9 59
````

SHA3-256 of two bits message '01':
````
sha3bit --sha3-256 '02' --bit-length=2
48 59 15 F6 3F CF 56 7B 8C 3D FA FE F3 68 D1 90 AE DB 8A 60 F5 52 2B E7 7F 2D AA B8 3B 75 7C 35
````

### Dumping intermediate values
You can control the verbosity of the output using the `--log-level` argument.
- `--log-level=INFO` will display inputs/outputs of the compression function.
- `--log-level=DEBUG` will display all internal steps of the compression function.

````
sha3bit --sha3-256 616263 --log-level=INFO
process block:
               0                         1                         2                         3                         4              
0   61 62 63 06 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
1   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 80   
2   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
3   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
4   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
f1600 input:
               0                         1                         2                         3                         4              
0   61 62 63 06 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
1   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 80   00 00 00 00 00 00 00 00   
2   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
3   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
4   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00   
f1600 output:
               0                         1                         2                         3                         4              
0   3A 98 5D A7 4F E2 25 B2   27 3E 60 D6 AA C8 97 20   42 F7 4E A5 81 05 13 BF   EF 21 46 A8 DC 39 12 63   C8 BE 38 B9 5C 3E C5 5F   
1   04 5C 17 2D 6B D3 90 BD   F7 B1 3F 62 61 C5 F2 31   BF F8 A9 CD CE FC 92 30   BD E1 5F 39 66 78 3F 4B   C1 3C BC AC DC 22 FC 02   
2   85 5F 08 6E 3E 9D 52 5B   9C DF 04 F2 F3 74 DF 8F   62 08 F0 4A 2A 8B 8B 1A   8A 7D C6 FF 1B F9 BE 30   C3 6C 4B 8C 92 94 80 66   
3   46 BF E2 45 11 43 15 32   AC C4 86 B1 8D 83 5E 9F   05 A7 0C D9 90 CC C4 60   C9 06 DD D6 3D 51 72 D2   7D 1A 16 AE 29 51 C2 D5   
4   D1 36 F6 22 FB 92 10 F8   A2 BA 11 BC 04 1C 0A A8   4E 1E 85 54 32 79 24 1F   85 B5 EC 0A 60 AF A3 25   41 10 E9 96 9E 9C D8 B5   
-----------------------------------------------------------------------------------------------------------------------------------
digest: 3A 98 5D A7 4F E2 25 B2 04 5C 17 2D 6B D3 90 BD 85 5F 08 6E 3E 9D 52 5B 46 BF E2 45 11 43 15 32
````

## Python3 usage
### One liner 

    >>> from sha3bit import sha3_256
    >>> print(sha3_256("abc".encode()).hexdigest())
    '3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532'

### Bit length capability

    >>> from sha3bit import sha3_256
    >>> print(sha3_256(b'\x00',bitlen=1).hexdigest())
    '1b2e61923578e35f3b4629e04a0ff3b73daa571ae01130d9c16ef7da7a4cfdc2'

### Import/export

    >>> from sha3bit import sha3_256
    >>> h1 = sha3_256("a".encode())
    >>> state = h1.export_state()
    >>> h2 = sha3_256.import_state(state)
    >>> h2.update("bc".encode())
    >>> print(h2.hexdigest())
    '3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532'

### TurboSHAKE and KangarooTwelve

    >>> from sha3bit import kangaroo12_128, kangaroo12_256, turboshake_128
    >>> turboshake_128(b'', domain=0x1F).hexdigest(32)
    '1e415f1c5983aff2169217277d17bb538cd945a397ddec541f1ce41af2c1b74c'
    >>> kangaroo12_128(b'', custom=b'').hexdigest(32)
    '1ac2d450fc3b4205d19da7bfca1b37513c0803577ac7167f06fe2ce1f0ef39e5'
    >>> kangaroo12_256(b'', custom=b'').hexdigest(64)
    'b23d2e9cea9f4904e02bec06817fc10ce38ce8e93ef4c89e6537076af8646404e3e8b68107b8833a5d30490aa33482353fd4adc7148ecb782855003aaebde4a9'

## Test with `pytest`

    pytest-3

## Test without `pytest`
Tests can run without creating/installing the package:

    python3 -m test.test


you can also run each test separately:

    python3 -m test.test_api
    python3 -m test.test_api_xof
    python3 -m test.test_api_xof_absorb
    python3 -m test.test_cavp
    python3 -m test.test_cavp_xof
    python3 -m test.test_f1600
    python3 -m test.test_hardcoded
    python3 -m test.test_kangaroo12
    python3 -m test.test_keccak_rounds
    python3 -m test.test_sha3_vs_hashlib
    python3 -m test.test_shake_vs_hashlib
    python3 -m test.test_turboshake

## Generate the doc

    pipenv sync --dev
    pipenv run make -C docs clean doctest html

## Update pipenv

The root `Pipfile` has the runtime dependency (`bitarray`, as in `pyproject.toml`) in `[packages]`, so the doc and the tests can run from the source tree, and the tools for building, linting and the doc in `[dev-packages]`. CI and Read the Docs install the versions pinned in `Pipfile.lock`, so commit it after updating:

    pipenv update --dev
    
## Build the package
Build is done using `hatchling`.

    pipenv sync --dev
    pipenv run ./build


## Create a new version
Version is managed by `hatch-vcs`, you just need to create a tag in github. 

## Launch linters
They use the configuration from `pyproject.toml`

    pipenv sync --dev
    pipenv run ./lint
