VerifyLink Infrastructure

The protocol behind every seal.

VerifyLink uses standard, well-understood cryptography. No proprietary magic. No black-box trust. Anyone can verify anything VLI has ever sealed — with or without us.

How a seal is made: input data → JCS canonicalization → SHA-256 → Ed25519 sign → Merkle leaf

Standard cryptography

Four primitives, all standards.

No proprietary curves, no novel hashes. Audited by tens of thousands of cryptographers.

Signature Ed25519 Signatures that prove who created the record. Modern, fast, NIST-approved.
Ed25519 spec & code
NIST FIPS 186-5 (2023)
RFC 8032
Curve: Edwards25519
Public key: 32 bytes
Signature: 64 bytes
clearkey verify --pubkey ed25519:... bundle.json
Hash SHA-256 Cryptographic fingerprints. The same hash function that secures Bitcoin and TLS.
Hashing example
FIPS PUB 180-4
Output: 32 bytes / 256 bits
Collision-resistant
sha256(jcs(payload)) → bundle.contentHash
Canonical RFC 8785 JCS Canonical JSON. Same data → same bytes → same hash, every time, on every system.
Why canonicalization matters
Without JCS, {"a":1,"b":2} and {"b":2,"a":1}
hash differently — same data, different proof.

With JCS (RFC 8785):
- Keys sorted lexicographically
- Numbers in shortest form
- Strings UTF-8 escaped consistently
- Whitespace removed
Log Merkle trees Tamper-evident logs. Add one record and the whole tree's fingerprint changes.
Inclusion proof structure
{
  "leafIndex": 4127,
  "treeSize": 81234,
  "leafHash": "sha256:...",
  "auditPath": ["sha256:...", "sha256:...", "sha256:..."],
  "rootHash": "sha256:..."
}

Bundle anatomy

Every VLI seal is a bundle.

payload + metadata + signature + merkle_proof
Show the JCS bundle schema
{
  "payload": { /* the thing being sealed */ },
  "metadata": {
    "issuer": "did:vli:org:abc",
    "issuedAt": "2026-04-27T17:35:00Z",
    "schema": "vli/v1"
  },
  "signature": {
    "alg": "Ed25519",
    "keyId": "did:vli:org:abc#key-1",
    "value": "sig:..."
  },
  "registry": {
    "logId": "verifylinkinfra-prod",
    "leafIndex": 4127,
    "rootHash": "sha256:...",
    "auditPath": [...]
  }
}

Verification

How verification works.

Three checks. All pass → the seal is valid. Any one fails → the bundle is tampered or fake.

  1. Hash the payload

    Apply RFC 8785 JCS canonicalization, then SHA-256. Compare to bundle.contentHash.

  2. Verify the Ed25519 signature

    Look up the publisher's public key (or keyId in DID). Check signature.value against contentHash.

  3. Confirm registry inclusion

    Walk the Merkle proof from leaf to rootHash. Match against the registry's signed tree head.

ClearKey CLI

Verify anything, anywhere, with no account.

curl https://verifylinkinfra.com/install.sh | bash
clearkey verify ./bundle.json

ClearKey is open source (Apache 2.0). The math doesn't need our servers. If we vanish tomorrow, every seal we've ever made is still verifiable.

Design choices

Why these primitives?

When the math underpinning trust must hold for decades, the boring, audited choice is the right one.

Why Standard crypto, not proprietary Standard primitives have been audited, attacked, and refined by tens of thousands of cryptographers over decades. Picking anything other than what the rest of the internet picked is a liability.
Why Ed25519 over RSA / ECDSA Faster, smaller keys and signatures, and avoids the implementation pitfalls (timing attacks, weak nonces) that have repeatedly burned RSA and ECDSA deployments. SSH and TLS 1.3 picked it for the same reasons.
Why Merkle trees over central timestamps A timestamp from an authority means "trust me." A Merkle inclusion proof means "I can prove it without trusting anyone." That's notary vs. transparency log — and infrastructure should pick the second.