Technology

Proof you verify yourself. No PriviNet servers or accounts required.

Lumra signs each event the moment it arrives, chains it so tampering is detectable, and exports a ProofPack that anyone can check offline with a standalone tool. Here is exactly how it works, and exactly what it does not claim.

Design partners Read the verifier
The three verbs

Sign. Chain. Verify.

Sign

The moment it arrives

Every event is signed the moment it arrives. Where the edge device can sign at the source with its own key, Lumra preserves that device signature and re-verifies it independently. The production signing key lives in a hardware security module and never leaves it.

Chain

Ordered by our clock

Signed record digests are linked into a tamper-evident hash chain, ordered by the time the server received them. A backdated payload cannot quietly reorder history.

Verify

Out of our hands

Any record exports as a ProofPack and can be checked later, offline, by anyone, with a standalone verifier that contacts no PriviNet system.

The precise promise: integrity you do not have to trust us for. A ProofPack proves a record was not altered after signing and was signed by PriviNet's published key. It does not claim to prove when the underlying event occurred, and we make no promises about court admissibility.

Signing and key custody

The root of trust is the key.

Production key

Held in an HSM, non-extractable

Records and ProofPack manifests are signed with ECDSA P-256 (SHA-256), key id kms-1944107aa98ec035, held in a Google Cloud KMS hardware security module, FIPS 140-2 Level 3, non-extractable. Our servers can request a signature. They can never read or copy the private key. A full compromise of the application server yields no signing key.

Fail-closed

Honest about a downgrade

If the HSM is briefly unreachable, production does not silently downgrade. A record signed by the software fallback key is labeled software_key in the record itself, and is never passed off as HSM-signed. The verifier surfaces that distinction to the reader.

Fallback key

Retired, but honored

The prior software key, Ed25519, key id sw-77396abcd4102123, is not compromised. It still verifies every record it signed before the 2026-07-06 cutover, and remains listed as an availability fallback. Old ProofPacks keep verifying.

Published trust root

Confirm the key yourself

Every PriviNet signing key is published out-of-band at privinet.net/keys.txt, machine-readable at /keys.json. A ProofPack counts as signed by PriviNet only if its signing key matches that list, a published directory pinned inside the verifier itself, so a swapped directory fails the check.

Provenance

Not every source carries the same weight. We grade each one.

The sharp question a claims examiner or opposing expert asks is not "is it signed" but "who signed it, and when." A record a device signed at capture is stronger evidence than one Lumra sealed when it arrived. Both are useful; they are not equal, and pretending they are is how evidence stories fall apart under scrutiny. So every Lumra record carries one of five signing states, the verifier confirms which applies, and the ProofPack prints it in plain language. Intake-sealed data is never presented as if a device had signed it.

Implementation status: source-signed, cloud-signed, and unverified states are exercised in the product and test paths. Gateway-signed and vendor-preserved states require the relevant integration. The exact deployed revision is identified during controlled onboarding; a taxonomy in code is not represented as a completed customer integration.

The honest boundary

What Lumra does not prove.

Lumra proves less than a magic box would, and says so. Here is the boundary, stated before opposing counsel finds it for you.

Integrity

How records are hashed and chained.

Canonical hashing

Normalized before hashing

Digests are computed over canonical JSON: sorted keys, fixed separators, ensure_ascii false, UTF-8. A reformatted but identical file still verifies. Any change to a meaningful value fails. We describe it that way rather than claiming every raw byte is bound, because canonical whitespace is deliberately normalized.

Composite digest

Domain-separated

Each event hash binds the payload, the analysis, and the evidence window under a domain-separation context string. Digests from one context cannot be replayed into another.

Ordering

Server time, not client time

The hash chain and incident timelines order by the server-assigned receipt time, not the client-supplied timestamp. A backdated payload cannot reorder the ledger.

Timing and retention

An independent clock. Write-once storage.

RFC 3161 time evidence

The token covers a digest, not a story

When a timestamp token is present, the package retains its status and imprint so the standalone verifier can check what digest it covers. Missing, delayed, failed, or unconfirmed time evidence is reported rather than hidden. A token time does not prove the sensor reading, the claimed observation time, or complete capture.

WORM archive

Write once. Read many.

Court exhibits are archived to write-once, read-many Cloud Storage with object versioning and a multi-year retention policy. Once written, an exhibit cannot be silently overwritten or deleted within the retention window.

The bundle

What is inside a ProofPack.

A ProofPack is the portable, self-contained evidence bundle. It includes:

  • A printable HTML court exhibit and a machine-readable JSON record.
  • The signature over the event, plus any preserved device (source) signature.
  • A whole-document manifest signature that binds the display bundle, the signing metadata, the input digests, and the anchor status together, so the human-readable page cannot say one thing while the sealed data says another.
  • The independent RFC-3161 timestamp anchor status.
  • An Evidence Trust Assessment: enumerated, versioned checks recorded as facts, not a score. Because it rides inside the bundle, the manifest signature binds it too.
  • A pre-filled FRE 902(13)/(14) self-authentication certification template.

The analysis inside a ProofPack is framed as decision-support and documentation, not a determination of fact, liability, or medical diagnosis.

Evidence Trust Assessment

Enumerated trust signals, not a verdict.

Every ProofPack carries an Evidence Trust Assessment: a fixed, versioned set of deterministic checks that either fired or did not. It is not a score, not a machine opinion, and not a judgment about what happened. It is a record of which signals were present, so a reader can weigh the evidence rather than take a label on faith.

Read it plainly: when nothing is flagged, the assessment says so by name, listing the checks that ran and did not fire, so silence is explicit rather than assumed. Each check names the ruleset version that produced it. The assessment rides inside each ProofPack's sealed bundle, so the manifest signature binds it and the standalone verifier's manifest check rejects any later edit to it. It is context for a human decision, never a determination of fact or liability.

The standalone verifier

Do not take our word for it. Run it.

The verifier is a single Python file, verify_proofpack.py, that contacts no PriviNet system. It needs Python 3.9+, one common crypto library, cryptography or pynacl, and OpenSSL to verify RFC-3161 timestamp signatures. Without OpenSSL, timestamp status is INDETERMINATE, never a pass. The digest checks run on the standard library alone. It checks:

Current verifier: 1.3.2. SHA-256: fe9c7bb5085e7b6e6bff71388cc71a6f54cc93e264002ea381c0eb8e3c6cdf2c.

  1. the printable bundle matches the sealed canonical inputs, which catches a doctored display;
  2. recomputes component digests over canonical payload, analysis, and evidence window;
  3. recomputes the domain-separated composite event digest;
  4. verifies the record signature, auto-detecting P-256 or Ed25519;
  5. confirms the signing key is on PriviNet's published list, and flags a software-key record as not HSM-custodied;
  6. verifies the manifest binding, re-verifies any device signature against the sealed payload, and confirms the timestamp anchor was not stripped or swapped.
$ python verify_proofpack.py proofpack.json
# recompute every digest, check every signature, no network
Step 1-2  component + composite digests recomputed
Step 3    record signature valid over event_hash
Step 4    key recognized: kms-1944107aa98ec035 (HSM)
Step 5    manifest binds the sealed content
Step 6    independent RFC-3161 timestamp present
✓ RESULT: INTEGRITY VERIFIED, AND SIGNED BY PRIVINET

Try it yourself, no account: download the verifier and a sample ProofPack, confirm the key in the key directory, install cryptography, ensure openssl is on your PATH for timestamp verification, and run it. Change any sealed value and watch it fail.

What "verified" means, plainly: it proves the record was not altered after signing and was signed by PriviNet's published key. It does not prove when the underlying event occurred.

Primitives and standards

Established cryptography, applied end to end.

ECDSA P-256 (SHA-256)Production record and manifest signatures, HSM-held key.
FIPS 140-2 Level 3 HSMCustody of the non-extractable production signing key (Google Cloud KMS).
Ed25519Source-device signatures and the retired-but-honored software fallback key.
SHA-256 over canonical JSONComponent digests and the domain-separated composite event hash.
RFC-3161Independent third-party timestamp anchoring, bound into the manifest.
WORM object storageWrite-once evidence archive with multi-year retention.
FRE 902(13)/(14)Pre-filled self-authentication certification template in each ProofPack.

Established primitives, applied end to end. The value is where they are applied, from the source to independent verification, not in inventing new cryptography.

Honest status

Built today, and what is on the roadmap.

Production: HSM-signed per-event records and existing ProofPack path Isolated staging: tenant-authenticated case packages and receipt-batch anchoring Public release: standalone verifier 1.3.2 with separately supplied non-production trust Release candidate: TTN-native retry identity; PostgreSQL concurrency acceptance remains a deployment check Research branch: optional EU qualified-timestamp profile, default off and INDETERMINATE Not completed: human cryptographic audit, QTSP integration, paying pilot evidence

Production and staging are intentionally separated. The production service continues to expose the older per-event ProofPack path. The Gate 3 case-package and receipt-batch workflow passed an isolated staging rehearsal, but has not been represented as production. A pilot release must name and verify the exact deployed revision.

The standalone verifier is the public trust boundary. Version 1.3.2 rejects altered protected content and requires non-production trust to be supplied separately. OpenSSL is required for RFC 3161 token verification. This is independent machine verification, not a human cryptographic or legal audit.

The TTN path is a release candidate. Complete original uplink JSON can be sealed through the raw adapter, and ordinary TTN retries receive a deterministic tenant-scoped identity when the sender supplies none. Disposable-PostgreSQL concurrency remains part of deployment acceptance and is not silently described as passed.

The EU profile is in development. It binds a closed batch root to an RFC 3161 request and retains the response and service identity for later validation. No real token from the prospective qualified service has been independently validated, and authenticated historical trusted-list and revocation validation remains incomplete. The only honest qualification result today is INDETERMINATE.

See a real ProofPack, then verify it yourself.

Pull a sandbox ProofPack from the public demo lane, no account needed, and run the standalone verifier against it. No call required.