Skip to content

Repository files navigation

py-jam-erasure-bindings

Native Python bindings for the Graypaper 0.7.2 Appendix H erasure transform. The package has no Python runtime dependencies and no dependency on PyJAMaz. It exposes Python functions; no public Rust crate API is supported.

Install and use

python -m pip install py-jam-erasure-bindings==0.1.0

CPython 3.12, 3.13, and 3.14 use the same cp312-abi3 binary on each supported platform: Linux x86_64/ARM64 (manylinux2014) and macOS x86_64/ARM64 (11.0+). Published wheels need no Rust compiler. Building the source distribution needs Rust 1.82 or newer and a C toolchain; CI uses Rust 1.85.0.

from jam_erasure import encode_shards, recover_shards

data = b"Appendix H"
shards = encode_shards(data, 2, 4)  # Tiny: 2 originals, 4 recovery shards
padded = recover_shards(2, 4, [(2, shards[2]), (5, shards[5])])
assert padded[:len(data)] == data
assert padded[len(data):] == bytes(len(padded) - len(data))

Binding contract

  • encode_shards(data, original_count, recovery_count) -> list[bytes] accepts the existing PyO3 byte-vector inputs. data must be non-empty. Both shard counts must be positive and supported by reed-solomon-simd=3.1.0.
  • Input is zero-padded to a multiple of 2 * original_count. Output is systematic-first: original_count contiguous data shards followed by recovery_count parity shards. Shard size is 2 * ceil(len(data) / (2 * original_count)).
  • recover_shards(original_count, recovery_count, shards) -> bytes requires exactly original_count (global_index, shard_bytes) pairs. Indexes are unique and lie in 0 .. original_count + recovery_count - 1; order is immaterial. Shards must share a non-zero even size. The result includes zero padding and does not take an original-length argument.
  • Tiny uses (2, 4) and Full uses (342, 681). Both may be used in one process; there is no ambient profile setting. This low-level API retains its original behavior, including accepting other count combinations supported by the backend.
  • Native validation/backend failures and caught unwinding panics become ValueError; PyO3 argument conversion retains TypeError/OverflowError. Computation releases the Python GIL.

Callers own protocol length limits before allocation, empty-blob conventions, selection of a threshold set from extra shards, original-length/padding checks, and commitment authentication. In PyJAMaz these remain in pyjamaz.erasure and its availability layer. This binding recovers bytes; recovery alone does not authenticate them. No shard data is read from disk or the network.

Specification and evidence

Normative source: Graypaper 0.7.2, Appendix H, including H.1–H.3 prose and the referenced little-endian E2 encoding. The implementation preserves the existing per-two-byte-column transform; applying the backend once to multi-word shards changes protocol bytes.

Rules Implementation Evidence
H.1–H.2; zero padding prose encode_impl splits padded input; recover_impl joins systematic data test_boundaries_and_padding, all W3F cases
H.3 transposition Per-word encode/decode loops; Tiny tables derive the identical linear map from the pinned backend Rust batched_lanes_match_appendix_h_column_reference, W3F encoding
H.4 systematic-first chunks encode_impl returns original shards then recovery shards test_w3f_encoding_vectors for six Tiny and six Full fixtures
H.5 indexed recovery recover_impl validates threshold cardinality/indexes and reconstructs each column test_w3f_recovery_vectors with systematic, recovery-only and mixed selections; malformed-input tests
H.6–H.7 field polynomial Pinned reed-solomon-simd=3.1.0, polynomial 0x1002D Every W3F encoded byte and recovered input
H.8–H.9 Cantor basis and LE words/indexes Pinned backend plus two-byte slicing and little-endian Tiny tables W3F vectors and Rust independent per-column comparison
H.10–H.11 interpolation and evaluation Pinned backend encode/decode calls W3F parity/recovery cases and Rust recovery-only roundtrip

The complete-systematic fast path, deterministic selection from surplus shards, and rejection of nonzero reconstructed padding remain caller responsibilities. All twelve fixtures retain their source commit and license. No protocol interpretation or compatibility setting is introduced by extraction.

Build and validate

python -m venv .venv
.venv/bin/python -m pip install '.[dev]'
cargo test --locked
.venv/bin/python -m pytest -q
.venv/bin/python -m build
.venv/bin/python scripts/check_artifacts.py dist

PEP-517 builds use release optimization, thin LTO, one codegen unit, a committed Cargo lock, and abi3-py312; CI sets a portable CPU target. The source distribution includes the Rust source, Cargo lock, tests, fixture provenance, and license texts. Fixtures and tests are excluded from the binary wheel.

Publishing

The release workflow builds all four platform wheels from an sdist and tests installed binaries outside the checkout on CPython 3.12, 3.13, and 3.14. A matching vVERSION or pypi/vVERSION tag publishes only after all seventeen validation jobs pass. The pypi GitHub environment uses the organization secret PYPI_API_TOKEN; it must have permission to publish this PyPI project. Token values are never committed or printed. Package author/contact metadata is JAMdot Technologies devops@jamdot.tech.

The original GitHub-only v0.1.0 tag is retained as extraction evidence. The first PyPI release uses pypi/v0.1.0, which includes the corrected author contact and its newly built artifacts. Do not use the earlier GitHub assets as PyPI release artifacts. The artifact checker enforces the approved author email.

If publishing fails after successful validation, run release.yml manually with the original release_run_id and release_tag. Recovery verifies the repository, workflow, tag commit, all required jobs, and immutable artifact IDs before downloading and checking the exact artifacts. It does not rebuild or move tags, and does not silently skip previously uploaded files.

Native upgrades require a new package release, lockfile review, regression evidence, and an explicit consumer dependency change. Builds use --locked and portable CPU targets. See PROVENANCE.md for source history and licensing.

About

JAM Appendix H erasure coding Python bindings over the pinned Rust reed-solomon-simd backend

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages