Skip to main content

hash-frx

FRX-native hash primitives — algebraic permutations and byte hashes, each written to lower to a single fused kernel.

hash-frx sits between FRX — Fractalyze's fork of JAX — and everything that hashes: the proving blocks in zorch, the signature schemes in sig-frx, and any other FRX consumer. FRX provides tracing and codegen, lowered through Fractalyze XLA, its fork of stock XLA that adds native field and elliptic-curve types.

Design philosophy

  • Two seams, no concrete hash in the consumer. Permutation is a fixed-width permutation over a single dtype — a field one for the algebraic hashes (Poseidon, Poseidon2), a machine word for the bit-oriented ones (Keccak-f[1600]); ByteHash maps a batch of equal-length byte messages to digests (SHA-256, BLAKE3, SHA-3). A consumer reads width/dtype or digest_size and calls permute/digest — it never names the hash it runs on.
  • Fusion by construction. A permutation call, a digest call, and each sponge absorb/squeeze lower to one fused kernel by construction — a lax.composite marker an XLA emitter recognizes — never by a per-primitive compiler pattern-match.
  • Application-agnostic. No proving scheme, signature scheme, or blockchain leaks in. Domain separation, parameter choice, and padding conventions belong to the consumer.
  • Byte-exact with the standard. A byte hash reproduces its specification exactly (SHA-256 = FIPS 180-4, BLAKE3 = the BLAKE3 spec, SHA-3/SHAKE = FIPS 202), verified against the published test vectors.

Installation

Releases are on PyPI, so nothing else has to be configured:

pip install hash-frx

Dev builds also publish to the Fractalyze package index on every green build of main. They are timestamped X.Y.Z.devYYYYMMDDHHMMSS and exist so a consuming workspace can pin the exact build it tested against, which means naming both the index and the version:

pip install hash-frx==0.1.0.dev20260730045722 \
    --extra-index-url https://fractalyze.github.io/pypi/simple/

Both carry the runtime tree only — the testing/ packages, including the reference fixtures, are not package API.

A Bazel consumer takes the module directly and needs no wheel:

bazel_dep(name = "hash_frx", version = "0.0.0")
git_override(
    module_name = "hash_frx",
    commit = "<sha>",
    remote = "https://github.com/fractalyze/hash-frx.git",
)

Status

Bootstrapping. The symmetric layer is being extracted from zorch/hash and extended with BLAKE3 and the Keccak family; zorch then consumes this repo. Work is tracked on the issues.

Development

Python 3.11. frxlib publishes cp311 wheels only, and both the hermetic Bazel toolchain and .python-version pin that version.

Bazel is the build, and the whole suite is one command — the same one CI's CPU leg runs:

bazel test //...

Tests are backend-agnostic and default to CPU (.bazelrc sets FRX_PLATFORMS=cpu), so a plain run is deterministic on any machine. Run them on the device to exercise the fusion markers — that leg is the only one that reports a lost marker, because an unrecognized marker still produces the right bytes:

bazel test --test_env=FRX_PLATFORMS=cuda \
    --test_env=XLA_PYTHON_CLIENT_PREALLOCATE=false //...

cuda is strict — there is no CPU fallback — so a green run really did execute on the device. Preallocation is off because Bazel runs the test actions concurrently against the one device, and each process would otherwise claim most of its memory.

For interactive work outside Bazel, the same pinned toolchain in a virtualenv:

python3.11 -m venv .venv && . .venv/bin/activate
pip install -r requirements.in \
    --extra-index-url https://fractalyze.github.io/pypi/simple/

The extra index carries the frx builds and the CUDA plugin wheels, which are too large for PyPI's per-file limit. requirements.in holds the pins; regenerate the lock with bazel run //:requirements.update instead of editing it by hand.

Install the git hooks with both stages named. Plain pre-commit install wires only the pre-commit stage, which leaves the commit-message linter inactive — formatting hooks fire while a malformed commit message sails through to CI:

pre-commit install --install-hooks --hook-type pre-commit --hook-type commit-msg

Commit messages follow Conventional Commits: a valid type, a lowercase summary with no trailing period, a header of at most 80 characters, and a body on everything but docs. Scope is free-form. The same linter runs in CI over the pull request title and every commit in it.

The rest of the dev loop — backend selection, the CUDA version the GPU path requires, running against an unreleased Fractalyze XLA, and the compile-cache rule — is in docs/reference/development.md.

Documentation

  • Task-indexed hub: docs/README.md — indexes the seams, constructions, and implementations by what you are trying to do, and states the fusion contract they all share.
  • Contributing with Claude Code: CLAUDE.md — the same map, plus the two rules every change must respect.

License

Licensed under the Apache License, Version 2.0 (see LICENSE).

Download files

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

Source Distribution

hash_frx-0.1.0.tar.gz (84.4 kB view details)

Uploaded Source

Built Distribution

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

hash_frx-0.1.0-py3-none-any.whl (98.8 kB view details)

Uploaded Python 3

File details

Details for the file hash_frx-0.1.0.tar.gz.

File metadata

  • Download URL: hash_frx-0.1.0.tar.gz
  • Upload date:
  • Size: 84.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hash_frx-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8f16265ad948f88e9bd182896c81d0aa4fe01dec53a0d4b9b0fdb9de74315913
MD5 8502c483a3de659921bb8f7c383a0616
BLAKE2b-256 1b6564fbe771f346edd7a193911a6d83387e51b565f5f4bfbd96db25a2a68334

See more details on using hashes here.

Provenance

The following attestation bundles were made for hash_frx-0.1.0.tar.gz:

Publisher: release.yml on fractalyze/hash-frx

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

File details

Details for the file hash_frx-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: hash_frx-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 98.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hash_frx-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 89897cdef2da4453c8bd40e4876602a6dfcf50b088379c5cf697bab077f35b93
MD5 c32045c1310a9b9adb5629a2aeb4f56a
BLAKE2b-256 9036bddecae3879c47b7fe856f0e2476698b904824af5008312b6b96e0c45531

See more details on using hashes here.

Provenance

The following attestation bundles were made for hash_frx-0.1.0-py3-none-any.whl:

Publisher: release.yml on fractalyze/hash-frx

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 Sentry Error logging StatusPage Status page