File Flow
Chronolith turns a local file into an encrypted, signed object that can be uploaded, stored, shared, and independently verified. This document explains the end-to-end flow and the on-wire structure used throughout the system.
Overview
Section titled “Overview”Every file becomes an object. An object contains:
- A signed header bundle with metadata and integrity commitments
- The encrypted file bytes
Objects are stored as .hbc files and can be uploaded, shared, and verified without exposing the plaintext.
1) Create an Object (Mac App)
Section titled “1) Create an Object (Mac App)”When a user selects a file, the app builds the object locally:
- Read the file and record basic metadata such as filename and size.
- Normalize the filename to NFC and compute a filename hash.
- Generate per-object randomness (a new salt).
- Derive a data-encryption key (DEK) from device-stored key material and the salt.
- Compute integrity commitments for the plaintext content (salted hash) and the derived key (key commitment).
- Build the header with protocol version, timestamp, identity binding, device binding, and metadata.
- Encrypt the file with XChaCha20-Poly1305 using the derived DEK and a canonical AAD.
- Compute a hash of the ciphertext.
- Sign the header bundle with the device key to bind header bytes, ciphertext hash, and the device certificate hash.
The output is a .hbc object file written to disk.
2) Object Format (.hbc)
Section titled “2) Object Format (.hbc)”An object has a compact binary layout designed for reliable parsing and verification:
HBCOBJ01 | header_len | signed_header | ciphertextThe signed header is a self-contained bundle:
header_core_len | header_core_cbor | device_cert_len | device_cert_cbor | cipher_hash | header_signatureNotes:
- Lengths are fixed-width big-endian integers.
header_core_cboranddevice_cert_cborare canonical CBOR encodings.- The ciphertext is the encrypted file bytes plus the AEAD authentication tag.
This structure enables authenticity checks without decrypting the file.
3) Signed Header and Device Certificate
Section titled “3) Signed Header and Device Certificate”The signed header bundle ties the object to a specific identity and device.
Device certificate (canonical CBOR) includes:
- Identity public key
- Device public key
- Issued-at timestamp
- Signature made by the identity key
Header signature binds:
- The canonical HeaderCore bytes
- The ciphertext hash
- The device certificate hash
This makes the header tamper-evident and ties the ciphertext to a specific device certificate.
4) HeaderCore Contents
Section titled “4) HeaderCore Contents”The HeaderCore captures the essential object metadata and cryptographic commitments. It includes:
- Protocol version and creation timestamp
- Identity public key and device certificate hash
- Encryption algorithm and AEAD nonce
- Salt and key commitment
- Plaintext hash commitment
- Filename hash and file size
The HeaderCore is encoded canonically and signed as part of the object.
5) Field Sizes and Encodings
Section titled “5) Field Sizes and Encodings”Chronolith uses fixed, predictable sizes for core fields:
- Salt: 32 bytes
- AEAD nonce: 24 bytes
- SHA-256 digests: 32 bytes
- Ed25519 public keys: 32 bytes
- Ed25519 signatures: 64 bytes
Length prefixes in the .hbc format are 4-byte big-endian integers.
6) Encryption Details (High Level)
Section titled “6) Encryption Details (High Level)”Encryption follows a deterministic pattern so that verification can be reproduced across clients:
- Derive the DEK using HKDF-SHA256 with the object salt.
- Compute the plaintext hash as SHA-256 over a domain-separated payload.
- Compute the key commitment as HMAC-SHA256 over a domain-separated payload.
- Build AAD from the canonical HeaderCore bytes with a zeroed nonce field.
- Encrypt the file using XChaCha20-Poly1305 with the DEK, AAD, and a randomly generated nonce.
The final HeaderCore stores the real AEAD nonce returned by encryption.
7) Upload
Section titled “7) Upload”The Mac app uploads the .hbc file to the API service.
Server-side steps (high-level):
- Validate the object format and signatures.
- Confirm the object belongs to the authenticated user and a registered device.
- Store the object bytes and metadata.
- Return a receipt and object ID. Public objects may be finalized into the ledger later.
Visibility Options
Section titled “Visibility Options”- Private: only the owner can access or decrypt the content.
- Public: the object can be shared via a public link and finalized into the public ledger.
- Hidden: unlisted public object (verifiable but not presented as public).
8) Receipt and Ledger
Section titled “8) Receipt and Ledger”For every accepted object, the server computes a receipt digest. For public objects, finalized ledger entries are derived from these digests.
Conceptually:
- Object digest commits to the signed header bundle and ciphertext hash.
- Receipt digest commits to the object digest and receipt timestamp.
- Block hash commits to the receipt digest and previous block hash.
This is the basis for durable, verifiable public records.
Digest formulas (simplified):
object_digest = SHA256( DS_OBJECT || sha256(header_core_bytes) || sha256(device_cert_bytes) || cipher_hash || header_signature )receipt_digest = SHA256( DS_RECEIPT || object_digest || received_at_unix_be )block_hash = SHA256( DS_BLOCK || prev_block_hash || receipt_digest || time_proof_hash )9) Verification
Section titled “9) Verification”Chronolith supports three verification layers depending on what data is available:
A) Object Authenticity (Header Verification)
Section titled “A) Object Authenticity (Header Verification)”The app verifies:
- Header format and canonical encoding
- Device certificate integrity
- Header signature validity
- Ciphertext hash match
B) Ledger Verification (Public)
Section titled “B) Ledger Verification (Public)”For public objects, the app can validate ledger integrity by recomputing:
- Object digest
- Receipt digest
- Block hash and chain continuity
C) File Match (Content Verification)
Section titled “C) File Match (Content Verification)”When the original file is available, the app recomputes:
- Salted plaintext hash
- File size
- Optional filename hash (if the user provides the filename)
If these match the header commitments, the file is confirmed to be the one that was originally uploaded.
10) Download and Decrypt
Section titled “10) Download and Decrypt”For private objects, the app downloads the .hbc file, verifies it, then decrypts locally using device-stored key material. Public objects can be shared via links and verified against the ledger.