ISCProof Specification

Version 5.1 — April 2026 — iscproof.io

1. Overview

ISCProof defines a protocol for generating portable, verifiable artifact evidence packs. A pack binds a content hash, a timestamp, and a cryptographic signature into a single verifiable unit.

2. Pack Schema

{
  "pack_version": "5.1",       // string, MUST be present
  "version": 5,                // integer, MUST be >= 5
  "profile": "iscproof/document",
  "content_id": "...",         // unique identifier
  "content_hash": {
    "alg": "sha256",
    "digest": "..."            // hex-encoded SHA-256 of content
  },
  "parent": "",                // hash of parent pack or empty
  "claims": [],                // array, extensible
  "sealed_at": "2026-04-08T..Z", // ISO 8601 UTC
  "root": "...",               // hex SHA-256 of canonical payload
  "signatures": [{
    "alg": "ed25519",
    "public_key": "...",       // hex
    "fingerprint": "...",      // first 8 bytes of sha256(public_key)
    "signature": "..."         // hex ed25519 signature over root bytes
  }],
  "tsa": {                     // SHOULD be present
    "present": true,
    "provider": "freetsa",
    "time": "2026-04-08T..Z",
    "algorithm": "sha256",
    "token_b64": "..."         // base64 RFC 3161 timestamp token
  }
}

3. Canonicalization

The canonical payload is computed as follows:

MUST set root to empty string ""

MUST set signatures[0].signature to empty string ""

MUST remove tsa field if present

MUST serialize with serde_json::to_string() (alphabetical key order)

canonical_payload = JSON(pack, root="", signature="", no tsa)
root = sha256(canonical_payload)

4. Signing

MUST use ed25519

MUST sign hex_decode(root) — the 32-byte hash, not the hex string

signature = ed25519_sign(private_key, hex_decode(root))

5. Verification Algorithm

A verifier MUST perform these checks in order:

StepCheckError Code
1Pack is valid JSONPACK_CORRUPT
2version >= 5UNSUPPORTED_VERSION
3Recompute root, compare to storedROOT_MISMATCH
4Verify ed25519 signature over root bytesSIGNATURE_INVALID
5Verify RFC 3161 TSA token (if present)TSA_INVALID

6. Error Codes

CodeMeaning
PACK_CORRUPTPack cannot be parsed as JSON
UNSUPPORTED_VERSIONPack version < 5
ROOT_MISMATCHRecomputed root does not match stored root
SIGNATURE_INVALIDed25519 signature verification failed
TSA_MISSINGTSA token not present in pack
TSA_INVALIDTSA token failed RFC 3161 verification
SEAL_NOT_FOUNDNo seal record found for given identifier

7. Trust Model

Signing keys are published at iscproof.io/keys.

A verifier SHOULD check the signing key fingerprint against the published registry.

TSA tokens SHOULD be verified against the TSA provider's certificate chain.

8. Guarantees

ISCProof guarantees:

✓ This content existed at this time

✓ This content has not been modified since sealing

✓ The time was independently confirmed by a third-party TSA

ISCProof does not guarantee:

✗ The identity of who created the seal

✗ The correctness or quality of the content