Protocol Specification¶
This document describes the Diogenes protocol in detail: the key lifecycle, signing flow, verification layers, transparency log structure, and data formats.
Key Registration Protocol¶
Key Pair Generation¶
Participants generate key pairs locally. Diogenes supports three algorithms:
| Algorithm | Identifier | Notes |
|---|---|---|
| Ed25519 | ed25519 |
Recommended. EdDSA over Curve25519. |
| ECDSA P-256 | ecdsa-p256 |
Compatible with Web Crypto API for browser-based signing. |
| RSA-2048 | rsa-2048 |
Legacy compatibility only. |
The fingerprint is computed as the SHA-256 hash of the public key's DER-encoded SubjectPublicKeyInfo bytes, hex-encoded with a sha256: prefix.
Registration Event¶
When a key is registered, the following event is appended to the transparency log:
{
"event_type": "key_registration",
"payload": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMC...\n-----END PUBLIC KEY-----",
"pseudonym": "Alice Scholar",
"key_algorithm": "ed25519",
"expiration_date": "2027-01-15T00:00:00Z"
}
}
The server computes the fingerprint from the public key and creates both a log entry (with hash chain linkage) and a key record.
Key Succession Protocol¶
Key succession allows a key holder to replace their active key with a new one, maintaining identity continuity.
Flow:
- The holder generates a new key pair.
- The holder authenticates as the old key (challenge-response or JWT).
- The holder submits a succession request with the old fingerprint and new public key.
- The server verifies authentication, creates a log entry, registers the new key, and marks the old key as "succeeded" with a pointer to the new fingerprint.
Recovery succession allows succession of expired keys. The holder must prove knowledge of the old key through a recovery-eligible challenge.
Key Revocation Protocol¶
Revocation permanently disables a key. Signatures made before revocation remain verifiable.
Flow:
- The holder authenticates as the key to be revoked.
- The server verifies the key is active.
- A revocation event is appended to the log.
- The key status is set to "revoked".
Recovery tokens cannot be used for revocation (security constraint).
Attestation Signing Protocol¶
Diogenes uses client-side signing. The private key never leaves the client. The server only receives the public key and the signature.
Signing Flow¶
sequenceDiagram
participant C as Client
participant S as Server
Note over C: 1. Compute document SHA-256
Note over C: 2. Build manifest JSON
Note over C: 3. Deterministic serialization
Note over C: 4. Sign with private key
C->>S: POST /api/v1/attestations
{manifest, public_key_pem,
signature, attestation_type}
Note over S: 5. Parse public key
Note over S: 6. Verify signature
Note over S: 7. Register key (if new)
Note over S: 8. Record attestation event
S->>C: {attestation, fingerprint,
pseudonym, log_entry_id}
Deterministic Payload¶
The signing payload is the deterministic JSON serialization of the manifest:
This ensures that the same manifest always produces the same byte sequence for signing, regardless of JSON formatting differences.
Attestation Types¶
| Type | Value | Description |
|---|---|---|
| Authorship | authorship |
The signer authored or co-authored the document. |
| Editorial Review | editorial_review |
The signer reviewed and approved editorially. |
| Peer Review | peer_review |
The signer reviewed for scholarly/technical accuracy. |
| Publication | publication |
The signer (institution) published the document. |
Password Protection¶
Keys can optionally have a password registered. When a password is set, attestation submissions must include the password. This provides a second factor beyond key possession.
Manifest Format¶
A manifest is a JSON document that binds a document's metadata to its attestation graph:
{
"document": {
"title": "Example Document",
"content_hash": "sha256:abc123..."
},
"attestations": [
{
"id": "att-001",
"type": "authorship",
"scope": { "content_hash": "sha256:abc123..." },
"signer_key_fingerprint": "sha256:def456...",
"signature_algorithm": "ed25519",
"signature": "base64-encoded-signature",
"timestamp": "2026-01-15T10:30:00Z",
"intent_statement": "I authored this document."
}
]
}
The content_hash is the SHA-256 hex digest of the source document's bytes. The manifest hash is computed separately from the content hash and used for log references.
Verification Protocol¶
Layer 1: Cryptographic Verification¶
- Parse and validate the manifest structure.
- For each attestation: a. Look up the signer's public key by fingerprint. b. Reconstruct the deterministic signing payload. c. Verify the signature using the public key and stated algorithm.
- Verify the source hash matches the manifest's content hash.
Layer 2: Key Status Verification¶
- For each signer key: a. Check that the key was registered before the attestation timestamp. b. Check the current key status (active, succeeded, revoked, expired). c. For succeeded keys, verify the succession chain is valid.
- Flag any attestations signed by revoked or unregistered keys.
Layer 3: Subjective Trust Assessment¶
- Load the verifier's trust configuration (trust anchors, depth limits, decay parameters).
- For each signer key: a. Traverse the endorsement graph from the signer to the verifier's trust anchors. b. Compute trust score based on path length, endorsement categories, and decay. c. Apply the verifier's minimum trust threshold.
- Report trust assessment per attestation.
Layer 3 is optional and verifier-defined. Different verifiers may reach different trust conclusions for the same document.
Transparency Log Structure¶
Hash Chain¶
Each log entry links to its predecessor via the previous_hash field:
Entry 1: previous_hash=null, entry_hash=H(payload||null)
Entry 2: previous_hash=H1, entry_hash=H(payload||H1)
Entry 3: previous_hash=H2, entry_hash=H(payload||H2)
The entry hash is computed as:
Event Types¶
| Event Type | Description |
|---|---|
key_registration |
New key registered |
key_succession |
Key replaced by successor |
key_revocation |
Key revoked |
attestation |
Document attestation recorded |
endorsement_offer |
Endorsement offered |
endorsement_acceptance |
Endorsement accepted |
endorsement_withdrawal |
Endorsement withdrawn |
acceptance_revocation |
Endorsement acceptance revoked |
endorser_revocation_alert |
Alert about a compromised key |
Temporal Anchoring¶
Log entries can be anchored to Bitcoin via OpenTimestamps:
- The server submits the latest entry hash to the OTS service.
- The OTS service returns a proof that can be verified against the Bitcoin blockchain.
- The proof is stored alongside the log entry.
This provides a timestamp that does not depend on server-controlled clocks.
Merkle Tree Heads¶
The log supports signed tree heads for efficient audit:
- All entry hashes are arranged in a Merkle tree.
- The tree root is signed by the operator key.
- Auditors can verify entry inclusion via Merkle proofs without downloading the full log.
Endorsement Protocol¶
Offer¶
{
"event_type": "endorsement_offer",
"payload": {
"endorser_fingerprint": "sha256:...",
"endorsed_fingerprint": "sha256:...",
"category": "x-diogenes:human_attestation",
"valid_until": "2027-01-15"
}
}
Acceptance¶
The endorsed party accepts, activating the endorsement after the activation delay period.
Categories¶
| Category | Description |
|---|---|
x-diogenes:human_attestation |
Personal knowledge of the key holder's identity. |
x-diogenes:institutional_endorsement |
Organizational/institutional verification of identity. |
Sybil Defense Mechanisms¶
- Endorsement capacity: Each key has a limited number of endorsements it can issue, proportional to its own trust level.
- Activation delay: Endorsements do not become active immediately, providing time to detect compromises.
- Over-capacity discounting: When a key exceeds its capacity, all its endorsements are discounted.
- Privilege threshold: Keys must reach a minimum trust threshold before they can endorse others.