Metadata-Version: 2.4
Name: alelyon-verify
Version: 0.2.1
Summary: Verify a Certified Number Envelope by replay against your own copy of the inputs, under a key you pin out of band.
Author: Alelyon
License-Expression: Apache-2.0
Project-URL: Specification, https://github.com/TLace03/famMain/blob/main/docs/cne/SPEC-cne-v0.md
Keywords: transparency-log,attestation,merkle,ed25519,verifiable-computation,rfc6962,conformance
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=42
Requires-Dist: numpy>=1.26
Requires-Dist: pandas>=2.0
Provides-Extra: native
Requires-Dist: alelyon-vector>=0.1; extra == "native"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Dynamic: license-file

# alelyon-verify

Verify a **Certified Number Envelope** (CNE) by replaying it against your own copy
of the inputs, under a key you pinned out of band.

A CNE is a signed receipt for a computed number. It carries the program, the
result, a decomposed error budget, a commitment to every input it consumed, and —
when the issuer anchored it — proofs binding those commitments into an append-only
transparency log. This package re-derives the number and its storage-quantization
width from **your** data and checks every field. It needs the issuer's public key
and your data; it never needs the issuer's engine, store, or cooperation.

Verification is free and open, permanently. The engine that *produces* certificates
is a separate, commercial thing.

## Install

```sh
pip install alelyon-verify
```

To verify a **width** as well as a signature and a scalar, you also need the
deterministic kernel:

```sh
pip install 'alelyon-verify[native]'
```

That is not a nicety. A CNE's width is a near-cancellation quantity that reproduces
bit-for-bit only on the substrate that produced it. Without the kernel this package
still checks the signature, every input digest, the scalar to a relative tolerance
of 1e-9, the transparency anchors, and every forgery class — it simply leaves the
width **unverified** and says so, rather than pretending. See §8.1 of the
specification.

## Use

```python
from alelyon.verify import verify_envelope

result = verify_envelope(cne, {("price", "SYN"): my_series},
                         public_key_hex=key_i_pinned_out_of_band)
result["ok"]            # True only if authentic AND re-derived AND the bound matched
result["width_trust"]   # "transparency-anchored" | "authenticated" | "unverified" | "refusal"
result["reason_classes"]  # stable, spec-frozen identifiers — safe to branch on
result["reasons"]       # prose for humans — not stable, do not branch on
```

From the command line:

```sh
alelyon-verify version
alelyon-verify selftest
alelyon-verify verify --envelope cne.json --data mine.json --key <64 hex>
```

`verify` exits 0 when the envelope verifies and 1 when it does not, so it composes
into a script without anyone having to read prose.

The `--data` file is the same shape the vectors use:

```json
{"price|SYN": {"index": [1704153600.0, 1704240000.0], "values": [100.1, 100.4]}}
```

## Check this package against its own tests

```sh
alelyon-verify selftest
```

That runs the bundled conformance suite: golden envelopes that must verify, and
forgery vectors that must not — each tracing to a defect that shipped or was caught
in this program's history, including the two that survived a first fix (a `delta`
field omitted at capture, and the same claim spelled out as an explicit `0.0`).
Every case is a plain JSON file under `alelyon/verify/vectors/`, readable and
runnable by an implementation in any language.

## A pinned key is mandatory

`ok=True` is unreachable without `public_key_hex`. Verifying an envelope against
the key embedded *in that same envelope* authenticates nothing — an attacker signs
their own forgery and it checks out. The key has to reach you by some path the
envelope did not travel.

## What a verified envelope does and does not tell you

**It tells you:** this data is what the number was computed over; the number
re-derives from it; the storage-quantization width re-derives too; the stated
decomposition's tier, level and assumptions are consistent with the replay; and,
when anchored, the per-row quantization steps match signed capture leaves whose
inclusion in the log is proven under the pinned key.

**It does not tell you the data is true.** This detects revision, not invention. A
producer who fabricates data at capture signs a receipt that verifies perfectly.
The guarantee is about arithmetic and storage error, not about truth.

**It does not cover the sampling, provider, or model terms.** Those are separate,
separately named slots in the budget. The verifier carries the sampling term; it
does not recompute it. At the default 24-bit capture, sampling error typically
dominates quantization by ~1e4 — the certificate names which term dominates rather
than summing them into one number.

**A co-signing witness is independent only if someone other than the signer runs
it.** `checks.witness = true` means the witness key you pinned signed that root. It
does not, by itself, mean an independent party did. The guarantee comes from the
deployment, not from the function.

## Specification

`SPEC-cne-v0.md` ships inside this distribution and is the normative description of
the format: canonical JSON and its injectivity rules, the digest byte layouts, the
frozen leaf-hash construction, RFC-6962 tree/inclusion/consistency, the signed tree
head and co-signature schemas, the deterministic kernel's numeric semantics, the
verify algorithm's exact `ok` semantics, the reason-class vocabulary, and the
versioning policy.

It is written so a second implementation can be built from the document rather than
by reading this code. It is candid about the places that is hard — notably that the
signing encoding depends on Python's float `repr`, and that reproducing NumPy's
PCG64 generator is a prerequisite for re-deriving a width.

## License

Apache-2.0.
