# Signed Ledger Checkpoint — exact API and trust policy Prepared 25 October 2026 before Signed code. Root ratified the API and layered conclusions; general strict-key dependency profile below supersedes the initial public-fixture-only proposal. Shared INTEGRITY-BYTE-CONTRACT.md is frozen and takes precedence on C/E bytes. No custom cryptographic primitive or curve arithmetic is permitted. ## Scope and executable key profile Authenticate exact checkpoint C bytes using pure Ed25519. Preserve separate signature mathematics, current key authority and independently expected payload binding. This package does not recompute ledger history, determine accounting correctness, establish non-equivocation, retain an external anchor or independently timestamp signing. created_at is signed but signer-asserted. Executable profile `strict-main-subgroup-ed25519-v1`: support general ordinary Ed25519 public keys, with canonical nonidentity main-subgroup point validation of A and signature R through vetted libraries. Python uses pinned PyNaCl1.6.2's patched libsodium crypto_core_ed25519_is_valid_point(A/R), then detached VerifyKey verification. TS uses pinned @noble/curves2.4.0 Point.fromBytes(bytes,false), assertValidity(), isTorsionFree() and !isSmallOrder(), strict verify zip215:false, AND actual WebCrypto import/verify on C. No custom curve arithmetic or handwritten small-order blocklist. Invalid A is fail/INVALID_PUBLIC_KEY in signature and authority; invalid R/scalar/equation is fail/INVALID_SIGNATURE. Missing either required backend/check is indeterminate/CRYPTO_UNAVAILABLE; a verifiable invalid result still dominates indeterminate. This profile is deliberately stricter than some permissive Ed25519 verification interpretations; identity/small/mixed-order or noncanonical points cannot pass. Public RFC8032 seeds remain demonstration signing fixtures only; verification is not hardcoded to those keys. Dependencies were authorized by root and installed ONLY in .tmp/d30-crypto: PyNaCl1.6.2 plus task-local transitive CFFI, npm @noble/curves2.4.0 and esbuild0.25.12. No global/project manifest is changed. Package lock, pip installation report and exact artifact hashes are copied as provenance. PyNaCl1.6.2's official changelog identifies libsodium1.0.20-stable2025-12-31 with the mixed-order valid-point fix; this stable build must not be confused with vulnerable unpatched1.0.20. The point-validator regression is tested directly. @noble/curves2.4.0 is the current official release; its docs expose strict parsing and subgroup/small-order checks, not custom arithmetic written here. Installed Python3.11.3/cryptography40.0.2, Node22.22.0 and actual Chromium WebCrypto all accepted identity A=01||31zero, R=01||31zero, S=32zero on message hello. W3C WebCrypto Level2 §25 explicitly notes implementation differences in small-order checks. At the start of the diagnostic investigation those extra dependencies were absent; the actual pinned dependencies above were subsequently installed task-locally. These observations constrain the profile; they are not a general security assessment of those libraries. ## API and exact inputs `verify_signed_checkpoint(request,envelope,trust_registry)` / async `verifySignedCheckpoint(request,envelope,trustRegistry)`. Python uses pinned PyNaCl/libsodium; TypeScript uses pinned noble point/strict-signature validation and actual global WebCrypto Ed25519 in Node/browser. Missing/unsupported crypto gives indeterminate. Both learner modules have no sibling runtime imports; the declared pinned cryptographic libraries are required external dependencies. Helpers `encode_checkpoint(checkpoint)` / `encodeCheckpoint`, `encode_envelope(envelope)` / `encodeEnvelope` validate then return bytes (raise/throw on malformed input). `sign_demo_checkpoint(checkpoint,key_id,public_test_seed_hex)` / async equivalent is explicitly limited to the two published seeds, returning an envelope, never creating a trust-registry entry. Signing C does not prehash C. Request exact fields: `schema_version='d30-signed-checkpoint-verification-v1',stream_id,ledger_id,entity_id,verification_at,policy='current-trust-at-verification-v1',expected_checkpoint`. Scope identifiers Stage0 ASCII1..64; verification_at strict real Gregorian UTC millisecond year0001..9999. expected_checkpoint is null or the exact checkpoint schema from the shared contract. An expected checkpoint is independently trusted host input; matching caller-supplied copies cannot establish real retained binding. A nonnull expected checkpoint must match requested scope and created_at<=verification_at; otherwise INVALID_REQUEST. At the maximum history profile checkpoint count4096/sequence8192 is allowed. Actual source relationship remains an adapter obligation. Envelope exactly shared five fields; checkpoint exactly shared eleven fields. algorithm Ed25519 only, signature lowercase128hex. Unknown fields, malformed numbers/clocks/IDs, count/size mismatch, invalid count/sequence relation, malformed digests and unsigned metadata reject before cryptography. Both root vectors C=300bytes and E=524bytes must match byte-for-byte. Object delivery order is irrelevant; strings are never normalized. As scope identifiers are ASCII, Unicode framing primitive tests are independently covered by shared S vectors, not smuggled into checkpoint IDs. Trust registry is null or exactly: `schema_version='d30-checkpoint-trust-registry-v1',stream_id,ledger_id,entity_id,observed_at,receipt_ref,keys`. Scope/receipt identifiers strict ASCII; observed_at strict clock. This is a trusted current policy snapshot supplied independently by the host. observed_at>=verification_at is required for current-as-of coverage; an older registry is indeterminate TRUST_SNAPSHOT_STALE, while signature mathematics may still be evaluated. No freshness interval is invented. At most64 unique key IDs; duplicates make the entire registry malformed/indeterminate. keys are exact `{key_id,algorithm:'Ed25519',public_key_hex,valid_from,valid_until,revoked_at}`. public_key_hex exactly64lowerhex. valid_from=valid_from. No embedded envelope public key is accepted. The same key bytes under two authorized labels are allowed; key ID/authority is host policy, and E binds the actual selected label. Current conservative authority requires `valid_from<=created_at pass/SIGNATURE_VALID; false -> fail/INVALID_SIGNATURE; missing key -> indeterminate/KEY_MATERIAL_MISSING; invalid public point -> fail/INVALID_PUBLIC_KEY; backend missing/unsupported/runtime operation unavailable -> indeterminate/CRYPTO_UNAVAILABLE. A verifiable false signature remains fail even if authority/binding is missing or stale. No custom R/S or curve arithmetic; vetted point/scalar/equation checks enforce the stricter profile. The trusted runtime adapter may be unavailable in tests, never a caller-supplied success Boolean. - Authority: registry missing -> indeterminate/TRUST_REGISTRY_MISSING; malformed -> indeterminate/INVALID_TRUST_REGISTRY; matching key missing -> indeterminate/KEY_NOT_FOUND; registry scope mismatch -> fail/TRUST_SCOPE_MISMATCH; invalid public point -> fail/INVALID_PUBLIC_KEY; revoked -> fail/KEY_REVOKED; not valid at claimed creation -> fail/KEY_NOT_VALID_AT_CREATED; not valid at verification -> fail/KEY_NOT_CURRENT; old registry observation -> indeterminate/TRUST_SNAPSHOT_STALE; otherwise pass/KEY_AUTHORIZED. Trusted scope/time denial still evaluates independently of signature. - Binding: submitted checkpoint scope differs from request -> fail/CHECKPOINT_SCOPE_MISMATCH; submitted created_at>verification_at -> fail/CHECKPOINT_FROM_FUTURE; expected null -> indeterminate/EXPECTED_CHECKPOINT_MISSING; exact full checkpoint equals independently expected -> pass/EXPECTED_CHECKPOINT_MATCH; otherwise fail/EXPECTED_CHECKPOINT_MISMATCH. Every C field is included, including checkpoint ID and creation metadata. A validly re-signed changed payload still fails retained expected binding. Overall fail if any layer fails, precedence binding then signature then authority for top-level code; preserve all diagnostics. Otherwise indeterminate if any layer is indeterminate, precedence signature then authority then binding. Otherwise pass/TRUSTED_CHECKPOINT_BOUND. This pass means exact signed payload authentication under the supplied trusted policy plus full expected-payload correspondence; it never means full ledger verification PASS. Missing digest backend also prevents overall pass with code CRYPTO_UNAVAILABLE even if an unusual host supplies a separate verifier. Structural error codes INVALID_REQUEST, INVALID_ENVELOPE and INVALID_CHECKPOINT have status fail. ## Required independent cases before derivatives Root independent C/E/full-prefix vectors and RFC8032 TEST1/TEST2 signatures; normal valid/rotated key; every signed field changed with original signature; changed field re-signed but expected old; wrong ordinary public key; missing registry/key; explicit empty expected; stale registry with invalid signature fail dominance; created/verification interval equality and inclusive revocation; future revocation; untrusted embedded key rejected; unknown field/schema/algorithm; strict money/count/digest/clock/ID boundaries; object-order invariance; maximum counts; public seed signing exact vectors; unavailable actual crypto path; identity/small-order/mixed-order/noncanonical public keys fail, identity/noncanonical R/S under ordinary keys invalid; detached branches/input immutability. Before-code expected outputs include all fields and exact framing, not just status. ## Source roles RFC8032 January 2017 informational §§3–5,7.1,8: pure Ed25519 and official fixtures, not a trust-store or timestamp policy. Verified erratum5968 (27 January 2026) aligns scalar range0<=S