Cryptographic Specifications
The cryptographic primitives, wire formats, and proof structures that make TRAI evidence court-defensible and machine-verifiable.
Ed25519 + ML-DSA-65 Hybrid Signature
TRAI uses a hybrid signature scheme combining classical Ed25519 with post-quantum ML-DSA-65 (per FIPS 204). This provides both current security and forward protection against quantum computing threats.
| Component | Standard | Implementation |
|---|---|---|
| Ed25519 | FIPS 186-5 / RFC 8032 | ed25519-dalek crate. 32-byte private key, 64-byte signature. |
| ML-DSA-65 | FIPS 204 (final Aug 2024) | ml-dsa >= 0.1.0-rc.5. NIST post-quantum standard. 3 Jan-2026 CVEs patched. |
| Hybrid binding | Custom (hybrid-ed25519-mldsa65-jcs-2026) | Both signatures are computed over the same content hash. Verification requires both to pass. |
| Migration path | NIST NSM-10 + FIPS 204 | Hybrid is current SOTA. PQC-only (drop Ed25519 half) targeted for 2028-01-01 per NIST guidance. |
Production requirement: ML-DSA-65 signing requires an external HSM/KMS
(AWS KMS or Thales Luna). The dev EphemeralEd25519Signer is NOT for production
and only supports Ed25519 without post-quantum hybrid.
COSE_Sign1 Envelope (RFC 9052)
Every TRAI evidence envelope is wrapped in a COSE_Sign1 structure per RFC 9052. This is the canonical wire format for signed evidence.
Structure
COSE_Sign1 = [
protected: bstr .cbor( # Protected headers
1: alg, # Algorithm identifier
"hash": content_hash, # BLAKE3 hash of content
"pkfp": primary_key_fingerprint,
"tsa_token": rfc3161_token, # Timestamp token (optional)
"scitt_receipt": receipt # SCITT receipt (optional)
),
unprotected: empty, # Empty for TRAI
payload: bstr, # Content being signed
signature: bstr # Ed25519 + ML-DSA-65 hybrid
] Algorithm identifiers
| Algorithm | COSE ID | Description |
|---|---|---|
EdDSA | -8 | Ed25519 only (dev mode) |
ML-DSA-65 | -48 (TBD) | Post-quantum only (future) |
hybrid-ed25519-mldsa65-jcs-2026 | Custom | Hybrid Ed25519 + ML-DSA-65 (production) |
Wire format
The COSE_Sign1 envelope is serialized as CBOR (Concise Binary Object
Representation). The trustlayer envelope JSON (trustlayer.json)
carries 18 fields and is stable across v1.x.
# Trustlayer envelope (JSON, ~3 KB)
{
"schema_version": "1.0",
"disclosure_type": "ai_generated_text",
"content_hash": "blake3:...",
"signer_org_id": "...",
"timestamp_authority": "Actalis Italia",
"scitt_inclusion_proof": { ... },
"chain_position": 42,
"chain_id": "tenant:org:disclosure_type",
"created_at": "2026-07-14T12:00:00Z",
"algorithm": "hybrid-ed25519-mldsa65-jcs-2026",
...
} RFC 3161 Timestamp Format
Every evidence envelope includes an RFC 3161 timestamp token from a Time-Stamp Authority. This proves the content existed at a specific point in time, signed by a trusted third party.
| Environment | TSA | Qualified? | Notes |
|---|---|---|---|
| Production | Actalis Italia | Yes (eIDAS-qualified) | EU Long-Term Trust List. 3 fingerprints hardcoded in app/constants.py. |
| Production (alt) | DigiCert / Sectigo | Yes (eIDAS-qualified) | Alternative qualified TSAs. Buyer provisions own credentials. |
| Dev/Staging | FreeTSA | No | Clearly labeled. Not suitable for production evidence. |
Timestamp token structure
TimeStampToken ::= SEQUENCE {
status PKIStatusInfo,
token MessageImprint, # SHA-256 of the COSE_Sign1 protected header
tstInfo TSTInfo { # RFC 3161 TSTInfo
version INTEGER (v1),
policy OBJECT IDENTIFIER,
messageImprint HASH { algo: SHA-256, value: bstr },
serialNumber INTEGER,
genTime GeneralizedTime,
accuracy Accuracy OPTIONAL,
ordering BOOLEAN DEFAULT FALSE,
nonce INTEGER OPTIONAL,
tsa [0] GeneralName OPTIONAL,
extensions [1] Extensions OPTIONAL
}
} SCITT Receipt (RFC 9943)
SCITT (Supply Chain Integrity, Transparency and Trust) receipts provide cryptographic proof that a signed statement was registered in a transparency log. TRAI implements RFC 9943 with RFC 9162 Merkle inclusion proofs.
Receipt structure
SCITT_Receipt ::= SEQUENCE {
log_id OBJECT IDENTIFIER, # Transparency log identifier
inclusion_proof MerkleInclusionProof {
leaf_hash HASH, # BLAKE3(leaf_data)
log_index INTEGER, # Position in the log
tree_size INTEGER, # Total entries at time of proof
audit_path SEQUENCE OF HASH, # Merkle audit path
root_hash HASH # Root hash of the Merkle tree
},
signature BIT STRING # Log operator's signature over the proof
} RFC 9162 Merkle inclusion proof
The inclusion proof demonstrates that the leaf hash (containing the COSE_Sign1 envelope) was included in the Merkle tree at the claimed position. Verification requires:
- Recompute the leaf hash from the signed statement
- Walk the audit path from leaf to root using the provided hashes
- Compare the computed root hash with the stored root hash
- Verify the log operator's signature over the inclusion proof
Not yet live: The SCITT receipt format and Merkle inclusion proofs
are implemented and tested (tests/scitt_cross_validation.rs). However,
production transparency log anchoring is a roadmap item (Q4 2026). Dev mode uses
mock SCITT.
BLAKE3 Hash Chain
Each evidence event is appended to a BLAKE3 hash chain scoped to the tenant's organization ID. This ensures sequential ordering and makes tampering with historical records detectable.
Chain structure
ChainEntry {
chain_id: "tenant:{org_id}:{disclosure_type}",
sequence: 42, # Position in chain
previous_hash: blake3(entry_41), # Hash of previous entry
current_hash: blake3(current_data), # Hash of this entry's data
timestamp: RFC3161_token,
org_id: OrgId, # Newtype wrapper
} Chain verification
# Verify chain integrity
for i in 1..chain.len() {
assert_eq!(
chain[i].previous_hash,
chain[i-1].current_hash,
"Chain break at position {}", i
);
}
The chain is scoped per-tenant using the pattern
tenant:{org_id}:{disclosure_type}. Each tenant maintains
independent chains for different disclosure types.
PDF Certificate Layout
The TRAI PDF certificate is a hand-rolled PDF 1.4 document (implemented
in tl-pdf-core, replacing printpdf 0.9.1 to eliminate
9 transitive RUSTSECs).
Layout specification
| Section | Content | Font |
|---|---|---|
| Header | Certificate title, TRAI mark, generation timestamp | Helvetica Bold 14pt |
| L1 Summary | Disclosure type, signer, verification status, chain position | Helvetica 10pt |
| Cryptographic Details | Algorithm, key fingerprint, hash value, TSA response details | Courier 8pt (monospace) |
| L2 Raw CWT | Base64-encoded COSE_Sign1 protected header | Courier 7pt (monospace) |
| L3 Verification Steps | Step-by-step verification instructions | Helvetica 9pt |
| QR Code | Embedded QR linking to /v1/verify/{cert_id} | Generated via reportlab.graphics.barcode.qr.QrCodeWidget |
| Footer | Hash chain position, previous hash, chain ID | Courier 7pt (monospace) |
PDF generation pipeline
trai-evidencefinalizes the COSE_Sign1 envelopetl-pdf-corerenders the A4 PDF with all sections- QR code is embedded via
reportlab - Visible watermark stamp is applied when
token_idsare supplied - PDF is persisted to
PDF_OUTPUT_DIRand served via/packets/{id}/pdf
Cryptographic specifications are subject to change as standards evolve. The implementations in the source code are the authoritative reference. All claims are independently verifiable against the test suites and source code.