Version 5.1 — April 2026 — iscproof.io
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.
{
"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
}
}
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)
MUST use ed25519
MUST sign hex_decode(root) — the 32-byte hash, not the hex string
signature = ed25519_sign(private_key, hex_decode(root))
A verifier MUST perform these checks in order:
| Step | Check | Error Code |
|---|---|---|
| 1 | Pack is valid JSON | PACK_CORRUPT |
| 2 | version >= 5 | UNSUPPORTED_VERSION |
| 3 | Recompute root, compare to stored | ROOT_MISMATCH |
| 4 | Verify ed25519 signature over root bytes | SIGNATURE_INVALID |
| 5 | Verify RFC 3161 TSA token (if present) | TSA_INVALID |
| Code | Meaning |
|---|---|
PACK_CORRUPT | Pack cannot be parsed as JSON |
UNSUPPORTED_VERSION | Pack version < 5 |
ROOT_MISMATCH | Recomputed root does not match stored root |
SIGNATURE_INVALID | ed25519 signature verification failed |
TSA_MISSING | TSA token not present in pack |
TSA_INVALID | TSA token failed RFC 3161 verification |
SEAL_NOT_FOUND | No seal record found for given identifier |
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.
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