auth51-checksum
The agent-identity checksum algorithm, extracted as the single shared source of truth. The same bytes hash the same way on both sides of the trust boundary:
- the authority computes it at registration (the registered checksum);
- the clients (embed/wrap) recompute it at runtime from the live agent and compare.
Because both sides run the identical algorithm, a client can verify "this is the registered, unmodified agent" without the agent self-declaring its identity, and the authority re-verifies at mint. This package is the engine behind that.
⚠️ This is a wire/registration contract. Changing the algorithm is a breaking change to every already-registered agent. Do not refactor in ways that change a single output byte; bump a version suffix instead. The conformance test (
tests/) pins this to golden vectors generated from the authority's owncrypto/agent_checksum.py, so a failure there is a release blocker.
Two algorithms (the authority accepts EITHER at mint)
v1, patchet-compat. SHA-256, bare 64-char hex.
canon = {
"id": agent_id,
"prompt": normalize_prompt_v1(prompt_template), # whitespace-collapse, NO Unicode NFC
"tools": sorted([{name, signature, description, source_code?}], by name), # is_agent dropped
"config": configuration,
}
sha256(json.dumps(canon, sort_keys=True)).hexdigest()
v2, auth51 native. SHA3-512, self-describing sha3-512:v1:<128 hex>.
canonicalize(model_dump(components)) → json.dumps(sort_keys=True) → sha3-512
where canonicalize recursively sorts dict keys and runs normalize_text on
every string (strip, \r\n→\n, collapse blank lines, strip each line, drop
empty lines, Unicode NFC). The component dict carries every tool field
(name, signature, description, source_code, is_agent), defaults included, and
that shape is part of the hash.
v3, auth51 native, identity-only. SHA3-512, self-describing
sha3-512:id1:<128 hex>.
canonicalize({agent_id, prompt_template, configuration}) → json.dumps(sort_keys=True) → sha3-512
Same canonicalization as v2, but over prompt + config only, no tools. Tools are the grant (authorization), not identity (DESIGN §13.1): adding or swapping a tool re-derives the grant, it does not change who the agent is. This is what the modern clients recompute at runtime, purely from the live prompt and config, both observable on the wire to the model, so no tool material is needed. The authority stores all three; mint accepts any.
Behavioural differences: v2 NFC-folds Unicode, v1 does not (composed vs
decomposed é collide under v2, differ under v1). And two agents with the same
{id, prompt, config} but different tools share a v3 but differ in v2. That is
what v3 is for.
Use
from auth51_checksum import AgentComponents, Tool, compute_both, matches
comp = AgentComponents(agent_id="ReviewBot", prompt_template="You are…", tools=[], configuration={})
v2, v1 = compute_both(comp) # both checksums
matches(registered_checksum, comp) # True if either matches (the client-side gate)
matches() mirrors the authority's mint-time acceptance: recompute from the live
agent, and the registered checksum is valid if it equals either algorithm.
Regenerating golden vectors
From the authority repo (its venv has pydantic):
from auth51_authority.schemas.intent import AgentComponents
from auth51_authority.crypto.agent_checksum import compute_both
# run compute_both over the fixtures, dump {name, components, v2, v1} → tests/golden.json
Ports
- Python: this package (reference implementation).
- TypeScript: for
@auth51/client(node), to be ported from the spec above and pinned against the samegolden.json. The golden vectors are the cross-language contract; any port must reproduce them exactly.
Release files for auth51-checksum 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| auth51_checksum-0.3.0.tar.gz | 17.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| auth51_checksum-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.5 kB
Release files / auth51_checksum-0.3.0.tar.gz
| Download URL | auth51_checksum-0.3.0.tar.gz |
|---|---|
| Size | 17.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0f5863b846e97c804a5dc289bcd6cde249cf97ae3d6e6cb161a26102864970d
|
|
BLAKE2b-256 checksum How to use checksums |
7cfc9825e7e4eac463bf892bde66750969e779b295f3d00fba6fe674d049106f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / auth51_checksum-0.3.0-py3-none-any.whl
| Download URL | auth51_checksum-0.3.0-py3-none-any.whl |
|---|---|
| Size | 13.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f255731c10abc7e822c1ecba8a861519383f12750c29a7f60e6b52973f1ef0a5
|
|
BLAKE2b-256 checksum How to use checksums |
1b58db649a82362b729079a749e66db043523b45f479e0a3fc0ff20a687c355e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency log