Skip to main content

WOTS+ hash-based signatures in Python with optional Rust acceleration

Project description

hashsigs (Python)

Python package for WOTS+ with optional Rust acceleration from hashsigs-rs.

Quickstart (recommended)

Create a project-local virtual environment named .hashsigs and run all tests:

# from the repo root
python3 -m venv .hashsigs
source .hashsigs/bin/activate
python -m pip install -U pip pytest pytest-cov

# Ensure Rust toolchain (required to build the optional extension)
# macOS: also ensure Xcode CLT: xcode-select --install
rustup --version || brew install rust
cargo --version

# Install dev deps and try to build rust extension (quote extras in zsh)
pip install -v -e '.[rust,dev]'
# Install keccak provider (required for vectors when falling back to Python)
pip install pycryptodome
# or: pip install pysha3

# Quick check the extension is present (optional)
python -c "import hashsigs._rust as m; print('rust ext ok:', m)"

# Lint + type + tests with coverage; this is the full suite
pytest -q --cov=hashsigs --cov-report=term-missing

If the Rust toolchain is not available, the above will fail on the rust-backed vector tests. See the “Test options” section for alternatives.

Test options

You can choose between three categories:

  • All Tests (vectors + rust-backed + lint + type + coverage) — fails if keccak or rust ext are missing

    • pip install -e '.[rust,dev]' && pip install pycryptodome
    • pytest -q
  • Basic (pure Python functionality only; requires keccak provider, but no Rust extension)

    • pip install -e '.[dev]' pycryptodome
    • HASHSIGS_BUILD_RUST=0 pytest -q -m "not requires_rust"
  • Basic (no keccak) — internal consistency tests only using hashlib.sha3_256; no vectors

    • pip install -e '.[dev]'
    • pytest -q -m "not vectors"

Troubleshooting

  • pysha3 build fails on Python 3.13 (macOS) with missing pystrhex.h

    • Symptom: fatal error: 'pystrhex.h' file not found when building _pysha3
    • Fix: install pycryptodome instead (preferred). Example: pip install pycryptodome
    • Alternative: use Python 3.11/3.12 where pysha3 wheels may exist, or wait for pysha3 to add 3.13 support
  • Rust extension won’t build/import

    • Ensure Rust toolchain is installed: curl https://sh.rustup.rs -sSf | sh (or brew install rust)
    • On macOS, ensure Xcode Command Line Tools are installed: xcode-select --install
    • Clean and rebuild in your venv:
      • pip uninstall -y hashsigs; pip install -e .[rust,dev]
      • python -c "import hashsigs._rust as m; print('rust ext ok', m)"
    • If it still fails, you can run Basic tests while you investigate: HASHSIGS_BUILD_RUST=0 pytest -q -m "not requires_rust"

Usage example

from hashsigs import WOTSPlus

# Prefer the Rust backend if available; falls back to Python keccak provider if not
wots = WOTSPlus.keccak256(prefer_rust=True)

# Derive a keypair from a 32-byte seed
seed = bytes([1]) * 32
pk, sk = wots.generate_key_pair(seed)

# Sign and verify a 32-byte message
msg = bytes([2]) * 32
sig = wots.sign(sk, msg)
assert wots.verify(pk, msg, sig)
print("Signature verifies!")

Quick self-check (from shell)

Run a one-liner to confirm the package imports, the Rust extension is available (optional), and basic operations work:

python - <<'PY'
from hashsigs import WOTSPlus
try:
    import hashsigs._rust as _
    print('Rust extension: available')
except Exception:
    print('Rust extension: not available (falling back to Python)')

wots = WOTSPlus.keccak256(prefer_rust=True)
seed = bytes([1]) * 32
pk, sk = wots.generate_key_pair(seed)
msg = bytes([2]) * 32
sig = wots.sign(sk, msg)
print('verify:', wots.verify(pk, msg, sig))
PY

Rust backend

We now depend on the public crate and repository:

The Python bindings (PyO3) will attempt to build against the published crate during installation. If the build fails, the package still installs and falls back to pure Python.

License

AGPL-3.0-or-later; see COPYING

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

hashsigs-0.0.1-py3-none-any.whl (19.6 kB view details)

Uploaded Python 3

hashsigs-0.0.1-cp311-cp311-win_amd64.whl (145.7 kB view details)

Uploaded CPython 3.11Windows x86-64

hashsigs-0.0.1-cp311-cp311-macosx_11_0_universal2.whl (249.5 kB view details)

Uploaded CPython 3.11macOS 11.0+ universal2 (ARM64, x86-64)

File details

Details for the file hashsigs-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: hashsigs-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 19.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for hashsigs-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2f34b1ff26cd245109f133e9c220b48d6236ebc2d5fa8d31e1e91cd938c4d545
MD5 6dd09663621c93fa05fca1261930bc97
BLAKE2b-256 7e51ab250c4c61d2d44e16748486f7d082685134eca934ee11c6e4a1e9f2e737

See more details on using hashes here.

Provenance

The following attestation bundles were made for hashsigs-0.0.1-py3-none-any.whl:

Publisher: publish.yml on QuipNetwork/hashsigs-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hashsigs-0.0.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: hashsigs-0.0.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 145.7 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for hashsigs-0.0.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 751dc64eb5d4e16dc0431cc9d2eadfd1b23e326fb23fa97e8338631377ac60e6
MD5 aabe4e89abf00b17ea81b02c85979b0a
BLAKE2b-256 2632b97eb2c6c9f38390b1721cd0cd1321f0c16bec5ef63f19a6973fa9007db1

See more details on using hashes here.

Provenance

The following attestation bundles were made for hashsigs-0.0.1-cp311-cp311-win_amd64.whl:

Publisher: publish.yml on QuipNetwork/hashsigs-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hashsigs-0.0.1-cp311-cp311-macosx_11_0_universal2.whl.

File metadata

File hashes

Hashes for hashsigs-0.0.1-cp311-cp311-macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 f5953b345693b1bce60bed72c6ece5f7dc21f616a35e0ef0ab2ad9a34e94ed09
MD5 98190dbd21bd7758708e4342766f1c85
BLAKE2b-256 490971b6a7901c8b156e825c7547c53f0d752cfe61d7db143b65c0efa948741f

See more details on using hashes here.

Provenance

The following attestation bundles were made for hashsigs-0.0.1-cp311-cp311-macosx_11_0_universal2.whl:

Publisher: publish.yml on QuipNetwork/hashsigs-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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