Inspiration

A question that wouldn't let me sleep: how do you protect a secret when the guardians themselves might be compromised? The 1995 Herzberg et al. paper on proactive cryptography sparked the idea — refresh shares periodically so yesterday's compromise becomes today's noise. The Star Wars aesthetic crystallized the threat model: five Jedi guarding a holocron, one possibly fallen, but the Council renews its bonds every cycle.

What it does

A (3,5) (3,5)-threshold proactive secret sharing system in C++20. Five nodes hold shares of a master secret. Every epoch, each node generates a zero-constant refresh polynomial and distributes contributions to peers. Feldman commitments over Ristretto255 make every contribution verifiable. The master secret s s never moves — only the shares do. Byzantine nodes are detected via signed complaints and received-set broadcasts. A 4-of-5 commit certificate gates every epoch transition. A write-ahead log survives crashes.

How we built it

Eight days, one layer per day. Day 1: GMP-backed finite-field arithmetic over Ristretto255's scalar field, verified against a SymPy oracle. Day 2: Shamir dealer and reconstruction with an exhaustive 10-subset test. Day 3: proactive refresh engine and Feldman commitments — the 20-epoch secret invariance test. Day 4: Ed25519-signed messages, a 9-state epoch FSM, and a WAL. Day 5: Byzantine fault handling with complaint and commit-certificate protocols. Day 6: 15 adversarial scenarios emitting structured JSON, plus an 11-operation benchmark suite. Day 7: four LaTeX documents with a four-way claim classification. Day 8: unified CLI, demo script, and full verification pipeline.

Challenges we ran into

A double-call bug in cluster.cpp regenerated refresh polynomials mid-protocol, silently breaking the secret invariant — caught only because the 20-epoch test failed. Feldman verification required two math layers (field arithmetic for shares, group arithmetic for commitments) that initially lived in separate modules and didn't talk. The epoch FSM grew to nine states with subtle transition rules; in-memory state wasn't enough, so the WAL became mandatory. And the hardest part: writing honest documentation that marks Byzantine fault tolerance as [Tested] rather than [Proven], because we didn't write formal safety proofs.

Accomplishments that we're proud of

The core correctness property — that the master secret is preserved unchanged at every epoch — holds across 20 consecutive refreshes in unit tests and 5 epochs in the end-to-end demo, verified across all 10 possible 3-of-5 reconstruction subsets. Every one of 15 adversarial scenarios — collusion, mobile adversary, malicious contribution, replay, tamper, withholding, false complaint, rollback, restart, interrupted refresh, corrupted share, malformed group element, invalid signature, inconsistent evaluations, threshold boundary — produces the expected outcome. The four-way claim classification (Proven / Inherited / Tested / Unproven) is applied consistently across every security assertion.

What we learned

You cannot fake the math — a single wrong modulus breaks 30% of tests. Proactive refresh is beautiful: the zero-constant property makes the invariant fall out of induction in one line. Byzantine fault tolerance is harder than the papers suggest, especially withholding detection on private channels. Secure zeroization is necessary but not sufficient against physical attacks. And honest limitations are more valuable than false claims — a prototype that knows what it doesn't do is more useful than a demo that pretends to do everything.

What's next for GHOSTQUORUM

Distributed key generation to retire the trusted dealer. Real network I/O replacing the in-process cluster. Formal BFT proofs in TLA+. Pedersen commitments for information-theoretic coefficient hiding. Per-epoch signing-key rotation for forward secrecy. Constant-time field arithmetic to harden against timing side channels. A pybind11 bridge for Python-native integration. And a live five-node deployment across real machines to watch the holocron pulse in the wild.

Built With

  • math
Share this project:

Updates

Submission history