Local-first cryptographic proof bundles for digital works: hashes, Merkle roots, signatures, and OpenTimestamps evidence.
  • Go 86.4%
  • Python 12.3%
  • Makefile 1.3%
Find a file
Gabriele Salati 79246b4f78 Add multi-platform release targets and certificate generator
Include Makefile release target for Linux, macOS, and Windows cross-compilation with SHA256SUMS calculation. Add script to generate formal cryptographic evidence certificates in HTML and PDF format from proof bundles.
2026-09-20 04:32:42 +02:00
cmd/proofbundle Add optional YubiKey PIV signing backend 2026-09-20 04:32:42 +02:00
docs Add optional YubiKey PIV signing backend 2026-09-20 04:32:42 +02:00
internal/proof Add optional YubiKey PIV signing backend 2026-09-20 04:32:42 +02:00
scripts Add multi-platform release targets and certificate generator 2026-09-20 04:32:42 +02:00
.gitignore Add multi-platform release targets and certificate generator 2026-09-20 04:32:42 +02:00
AGENTS.md Initial ProofBundle MVP 2026-07-07 16:53:43 +02:00
go.mod Initial ProofBundle MVP 2026-07-07 16:53:43 +02:00
Makefile Add multi-platform release targets and certificate generator 2026-09-20 04:32:42 +02:00
PROJECT_CONTEXT.md Add optional YubiKey PIV signing backend 2026-09-20 04:32:42 +02:00
README.md Add optional YubiKey PIV signing backend 2026-09-20 04:32:42 +02:00
TODO.md Add multi-platform release targets and certificate generator 2026-09-20 04:32:42 +02:00

ProofBundle

ProofBundle creates portable cryptographic proof bundles for digital works.

It is a local-first CLI: original works stay on your machine. The bundle records a canonical manifest, Merkle root, signed author/custody claim, and optional OpenTimestamps proof.

ProofBundle is not copyright registration and does not replace SIAE, courts, public registries, or legal advice. It produces technical evidence of existence, integrity, temporal priority, and a signed author claim.

Product page: Ilion Web Solutions

Build

make build

The binary is written to bin/proofbundle.

Quick Start

# Create a proof bundle for a directory.
proofbundle create ./my-work --title "Demo Song" --author "Alice"

# Verify the bundle itself.
proofbundle verify my-work.proof.zip

# Verify the original work still matches the bundle.
proofbundle verify my-work.proof.zip --work ./my-work

# Show metadata.
proofbundle info my-work.proof.zip

For deterministic offline tests without OpenTimestamps:

proofbundle create ./my-work --no-stamp

Commands

proofbundle create [options] <file|zip|directory>
proofbundle verify [--work path] [--ots] <bundle.proof.zip>
proofbundle info <bundle.proof.zip>
proofbundle diff <old.proof.zip> <new.proof.zip>
proofbundle keygen [--out path]
proofbundle ots upgrade <bundle.proof.zip>
proofbundle ots verify <bundle.proof.zip>

Input Modes

  • auto: directory as directory, normal file as file, .zip as raw zip bytes.
  • raw: prove exact bytes of a file; for zip this is zip-raw.
  • unpack: prove logical contents of a zip archive with deterministic ordering.
  • directory: prove recursive directory contents.
  • zip-raw: prove exact zip bytes.
  • zip-unpack: prove zip member contents, ignoring zip timestamps/metadata.

Examples:

proofbundle create song.zip --mode raw
proofbundle create song.zip --mode unpack
proofbundle create ./album --private-names
proofbundle create ./album --signer openpgp --signing-key ABCDEF1234567890ABCDEF1234567890ABCDEF12
proofbundle create ./album --signer yubisigner-piv-ed25519
proofbundle diff album-v1.proof.zip album-v2.proof.zip

Bundle Contents

manifest.json
merkle-tree.json
merkle-root.txt
author-claim.json
signature.ed25519
public-key.txt
signature.openpgp.asc       # when --signer openpgp is used
signer.openpgp.json         # when --signer openpgp is used
signature.yubisigner.json   # when --signer yubisigner-piv-ed25519 is used
timestamp.msg
timestamp-status.json
timestamp.ots              # only when OpenTimestamps stamping succeeds
verification-report.txt

The original work is not included.

Signing

ProofBundle supports three signing modes:

  • ed25519: default local software key, usable by anyone without extra hardware.
  • openpgp: optional detached OpenPGP signature through the external gpg command, useful for existing OpenPGP identities and optional YubiKey-backed signing keys.
  • yubisigner-piv-ed25519: optional hardware-backed signature through the external yubisigner-cli, using an Ed25519 key in YubiKey PIV slot 9C.

By default the CLI uses Ed25519 and creates or reuses:

~/.config/proofbundle/identity.ed25519.json

Generate one explicitly:

proofbundle keygen
proofbundle keygen --out ./identity.ed25519.json

Keep this private key safe. It is not stored in proof bundles.

For optional OpenPGP signing:

proofbundle create ./my-work \
  --signer openpgp \
  --signing-key ABCDEF1234567890ABCDEF1234567890ABCDEF12

Use an OpenPGP fingerprint or key ID for --signing-key; a full fingerprint is recommended. Verification uses gpg --verify against signature.openpgp.asc and author-claim.json.

For direct YubiKey PIV signing, install yubisigner-cli and use a YubiKey with firmware 5.7 or later, an Ed25519 key and certificate in slot 9C:

proofbundle create ./my-work --signer yubisigner-piv-ed25519

ProofBundle invokes yubisigner-cli sign-raw during creation. The PIN is read by that tool without echo and is never passed as a command-line argument. signature.yubisigner.json includes the public key and signature, so ordinary proofbundle verify remains offline and does not require the YubiKey or yubisigner-cli. A hardware-backed key demonstrates key custody at signing time; it does not by itself establish the signer's legal identity or ownership.

OpenTimestamps

If the ots command is installed, create attempts to stamp timestamp.msg. If ots is missing or offline, bundle creation still succeeds and records the status in timestamp-status.json.

Later:

proofbundle ots upgrade work.proof.zip
proofbundle ots verify work.proof.zip

Install the OpenTimestamps client separately according to your OS/package manager.

Development

make check

This runs gofmt, go test ./..., and go vet ./....

Use careful language:

  • It proves that this exact byte sequence or directory state existed before a verifiable timestamp.
  • It proves that the current work matches the manifest and Merkle root.
  • It proves that an Ed25519 key or OpenPGP key signed a claim about that root.

It does not prove by itself:

  • legal copyright ownership
  • originality
  • that no one else created the work earlier
  • that SIAE or legal institutions are unnecessary