- Go 99.5%
- Makefile 0.5%
| .proofbundle/2026-07-09/9564d3c | ||
| cmd/proofbundle | ||
| docs | ||
| internal/proof | ||
| .gitignore | ||
| AGENTS.md | ||
| go.mod | ||
| Makefile | ||
| PROJECT_CONTEXT.md | ||
| README.md | ||
| TODO.md | ||
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.
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,.zipas raw zip bytes.raw: prove exact bytes of a file; for zip this iszip-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 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
timestamp.msg
timestamp-status.json
timestamp.ots # only when OpenTimestamps stamping succeeds
verification-report.txt
The original work is not included.
Signing
ProofBundle supports two signing modes:
ed25519: default local software key, usable by anyone without extra hardware.openpgp: optional detached OpenPGP signature through the externalgpgcommand, useful for existing OpenPGP identities and optional YubiKey-backed signing keys.
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.
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.
Repository provenance
Public Git snapshots of this repository are attested with ProofBundle itself.
ProofBundle binds a Git archive to a deterministic manifest, Merkle root, signed authorship/custody claim, and OpenTimestamps proof. For this project, the public author claim is signed with the OpenPGP Ed25519 key:
Gabriele Salati <gabriel1@gabrielesalati.eu>
08BBBF34E279618861E2897D03E8E3F46FBDC8AA
This is technical evidence of integrity, timestamping, and signed claim of authorship/custody; it is not copyright registration.
Published attestation:
- Commit:
9564d3c - Merkle root:
17c826018d65bb03eb4017c07d7b2627f474270b61a93c566ee28983158f6acb - Proof files:
.proofbundle/2026-07-09/9564d3c/
Development
make check
This runs gofmt, go test ./..., and go vet ./....
Legal Positioning
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