Skip to content

Anes1032/proof-bundle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

proof-bundle

Trustless, offline verification of signed agreements. Take a piece of content, have two people sign it with WebAuthn passkeys (ES256), freeze it into a deterministic manifest, and anchor that manifest's hash to Bitcoin via OpenTimestamps. The result is a single JSON proof bundle that anyone can verify offline — no server, no trust in the issuer required.

Extracted from the provy contract-signing app as a reusable, product-agnostic core.

Why it's trustworthy under a compromised server

Only two things in a bundle are unforgeable even if the issuing server is fully compromised:

  • The ES256 assertions — signed by authenticator-held private keys the server never sees.
  • The Bitcoin anchor — a public, permissionless clock.

Everything else (audit hash-chain, HMAC timestamps) is recomputable by whoever holds it, so it counts as operational logging, not evidence. See SPEC.md.

Layout

crates/core   # proof-bundle-core — the Rust library (WASM-friendly, no server deps)
crates/cli    # proof-bundle — the `verify` / `audit` command-line tool
ots/          # Node helpers for the OpenTimestamps steps (the OTS lib is Node-only)

The cryptographic verification (content hash, manifest/final_hash, ES256 assertions, distinct signers) is pure Rust. Only the OpenTimestamps Bitcoin-anchor check is delegated to Node, because the OpenTimestamps library does not run outside Node.

Verify a bundle

# full check, including the OpenTimestamps anchor (needs Node + `npm i` in ots/)
cargo run -p proof-bundle-cli -- verify bundle.json

# crypto-only, skip the OTS/Node step
cargo run -p proof-bundle-cli -- verify bundle.json --no-ots

For the OTS step:

cd ots && npm install
node ots/ots-verify.mjs bundle.json

Anchor a bundle to Bitcoin

# stamp final_hash to the OTS calendars (status: pending)
node ots/ots-stamp.mjs --bundle bundle.json      # prints {finalHash, proof, status}

# hours later, upgrade the proof once it's in a Bitcoin block
node ots/ots-upgrade.mjs --bundle bundle.json     # prints {..., status: "bitcoin"}

These helpers are storage-agnostic: they take a hash or bundle in and print the proof out. Wiring the proof back into your datastore is up to you.

Use the library

use proof_bundle_core::{bundle, manifest};

// Build a manifest + final_hash from your own signatures:
let (manifest_str, final_hash) = manifest::build(id, content_hash, &parties, &sig_refs);

// Verify a bundle offline (crypto layers only):
let b: bundle::Bundle = serde_json::from_str(&json)?;
let report = bundle::verify(&b);
assert!(report.ok());

Test

cargo test

The vector tests synthesize a real two-signer bundle with genuine ES256 assertions, confirm it verifies, then apply each tampering case (modified content, forged signature, wrong final_hash, single signer, mutated audit row) and confirm verification breaks.

License

Dual-licensed under either of Apache-2.0 or MIT, at your option.

About

No description, website, or topics provided.

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors