Metadata-Version: 2.5
Name: sha3bit
Version: 0.4.0
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

    python3 -m pip install sha3bit

## CLI usage

### Get help

````
python3 -m sha3bit.cli --help
usage: cli.py [-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

optional arguments:
-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 algorythm
--sha3-256            Use SHA3-256 algorythm
--sha3-384            Use SHA3-384 algorythm
--sha3-512            Use SHA3-512 algorythm
--shake-128           Use SHAKE-128 algorythm
--shake-256           Use SHAKE-256 algorythm
--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)

````
python3 -m sha3bit.cli --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:
````
python3 -m sha3bit.cli --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:
````
python3 -m sha3bit.cli --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':
````
python3 -m sha3bit.cli --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':
````
python3 -m sha3bit.cli --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':
````
python3 -m sha3bit.cli --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':
````
python3 -m sha3bit.cli --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.

````
python3 -m sha3bit.cli --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

    cd docs
    pipenv shell
    make clean doctest html

## Update pipenv for the doc

    cd docs
    pipenv shell
    #use pip to update whatever ou want
    pip freeze > requirements.txt
    pipenv update
    
## Build the package
Build is done using `hatchling`. The script `build` allows to build for different version of python3:

    ./build python3.12


## 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`

    ./lint
