mirror of
https://github.com/luxfi/pulsar.git
synced 2026-07-27 06:55:04 +00:00
pulsar: claim hygiene — nonce safe-by-construction, authenticated blame, honest GATE-C wording
Update VERSIONS.md + PROOF-CLAIMS.md so no claim overstates: - nonce single-use is now claimed ENFORCED BY DEFAULT (per-share registry on the real API), not opt-in; w1-only dedup closes cross-committee reuse. - authenticated-PartyID blame: blame gated on identity-signature validity; an attacker cannot frame/exclude an honest victim; never blame off a raw PartyID. - GATE-C: 'complete for DIRECT calls' + companion indirection lint — drop the 'never miss one' overstatement; the pair (not either half) closes the banned set. - residuals restated honestly: persistent ledger (in-process default safe now), networked transport auth, BDLOP valid-sigma-wrong-z.
This commit is contained in:
+13
-3
@@ -34,9 +34,19 @@ This is the single sentence the project stands behind. Its honest decomposition:
|
||||
release-gate to a **liveness fault, never a forge/leak**.
|
||||
- **malicious-CSCP + networked-MPC are gated residuals** — UNBUILT, fail-closed,
|
||||
tracked (Residual A). The `harden/malicious-security` branch advances this:
|
||||
nonce single-use, identifiable-abort plumbing, reachability GATE-2; the **sound
|
||||
valid-sigma wrong-`z` blame** (needs BDLOP lattice commitments) remains residual.
|
||||
See `ref/go/pkg/pulsar/VERSIONS.md`.
|
||||
**nonce single-use safe by construction** (per-share registry enforces it on the
|
||||
DEFAULT API, not opt-in; `w1`-only dedup closes cross-committee reuse),
|
||||
**authenticated-PartyID blame** (blame is gated on identity-signature validity —
|
||||
an attacker cannot frame or front-run-exclude an honest victim; no blame is ever
|
||||
emitted off a raw unauthenticated PartyID), identifiable-abort plumbing, and
|
||||
GATE-2 reachability **paired with an indirection lint** (the name call-graph is
|
||||
complete for DIRECT calls only — the lint forbids function-value/closure/
|
||||
`go:linkname` indirection of the banned primitives, so the pair is complete).
|
||||
Still residual: the **sound valid-sigma wrong-`z` blame** (needs BDLOP lattice
|
||||
commitments), a **persistent (crash-safe) nonce ledger** (the in-process default
|
||||
is safe now), and **networked transport authentication** (the partial→producer
|
||||
crypto binding is in place; authenticated delivery is consensus-owned). See
|
||||
`ref/go/pkg/pulsar/VERSIONS.md`.
|
||||
|
||||
**NEVER claim:** FIPS/NIST-certified threshold ML-DSA · fully-malicious-secure-proven
|
||||
· global-1000-validator DKG. (Any artifact asserting these is wrong — fix the
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|---|---|---|---|
|
||||
| **v0.3 — algebraic broadcast** | **REMOVED** | The `AlgebraicAggregate` path broadcast per-party `c·s2` / `c·t0` residual shares and reconstructed the leaking `MakeHint` residual at the aggregator. | Closed as **PULSAR-V13-HINT-LEAK** — broadcasting those shares leaks the long-term key. Ripped out (commit `b185533`); **no backward-compatible re-entry**. |
|
||||
| **v0.4 — BCC/CSCP no-reconstruct** | **CURRENT (production sign path)** | Boundary-Cleared Carry-elimination (BCC/CEF) + Comparison-Secure-Comparison-Protocol (CSCP). Each validator holds exactly one poly-vector Shamir share of `s1`; signing aggregates only masked `z`-partials; the hint is recovered from the **public** `w' = A·z − c·t1·2^d` and `w1`. No process forms `s1`, the seed, `sk`, `c·s2`, `c·t0`, `r0`, or full `w`. Output verifies under unmodified FIPS 204 ML-DSA (`mldsa{65,87}.Verify`). | Base `main` @ `v0.4.0` (commit `b652893`). The sole production path. |
|
||||
| **v0.4.x — `harden/malicious-security`** | **THIS BRANCH (in review, NOT merged)** | Hardens v0.4 from semi-honest/no-leak toward **malicious** security: nonce single-use / anti-replay ledger (closes the nonce-reuse key-recovery vector), identifiable-abort plumbing (duplicate-PartyID rejection, invalid-proof blame attribution, per-party commitment binding), GATE-2 hardened to call-graph reachability, CI invariant against `legacy_trusted_dealer` in the prod build. | Branch off `origin/main`; **a RED agent re-verifies before any merge.** See "Malicious-hardening status" below for implemented-vs-residual. |
|
||||
| **v0.4.x — `harden/malicious-security`** | **THIS BRANCH (in review, NOT merged)** | Hardens v0.4 from semi-honest/no-leak toward **malicious** security: nonce single-use **safe by construction** (per-share registry, default-path enforced; `w1`-only dedup closes cross-committee reuse), **authenticated-PartyID blame** (forged victim-slot partials dropped before attribution; blame gated on identity-signature validity — an attacker cannot frame/exclude an honest victim), identifiable-abort plumbing (duplicate-PartyID rejection, invalid/malformed blame, per-party commitment binding), GATE-2 reachability **+ indirection lint**, CI invariant against `legacy_trusted_dealer` in the prod build. | Branch off `origin/main`; **a RED agent re-verifies before any merge.** See "Malicious-hardening status" below for implemented-vs-residual. |
|
||||
|
||||
## Keygen / nonce-gen track (separate from the sign path)
|
||||
|
||||
@@ -28,21 +28,42 @@ The no-reconstruct property above is a **SIGN-time** property. Key and nonce
|
||||
## Malicious-hardening status (this branch — honest implemented-vs-residual)
|
||||
|
||||
**Implemented, with a passing gate:**
|
||||
- **Nonce single-use / anti-replay** (`nonce_ledger.go`) — per-signer ledger keyed on
|
||||
the nonce commitment `(committeeID ‖ w1)`; `Round2` reserves before emitting the
|
||||
secret `z`-partial; reuse (even relabeled under a new `nonceID`) is rejected
|
||||
fail-closed. GATE A (`TestRED_NonceReuse_RecoversS1`) demonstrates the
|
||||
key-recovery math is real **and** that the guard blocks obtaining the second
|
||||
partial.
|
||||
- **Duplicate-PartyID rejection** + **invalid/malformed-proof blame attribution** in
|
||||
`AggregateBCC` — a deviating partial is attributed to its `PartyID` (structured
|
||||
`AbortEvidence`), not silently dropped. GATE B covers these.
|
||||
- **Nonce single-use / anti-replay — SAFE BY CONSTRUCTION** (`nonce_ledger.go`). The
|
||||
single-use store is resolved from a **process-global registry keyed by SHARE
|
||||
IDENTITY** (`shareIdentityKey`), so EVERY signer instance over the same key-share
|
||||
shares ONE ledger by DEFAULT — there is **no opt-in and no per-instance
|
||||
empty-ledger fail-open**. The dedup key is the nonce commitment **`w1` ALONE**
|
||||
(committee-independent), so reuse is refused even when relabeled under a new
|
||||
`nonceID` AND when the same joint nonce is presented across two committees that
|
||||
share a victim. `Round2` reserves before emitting the secret `z`-partial.
|
||||
- GATE A `TestRED_NonceReuse_RecoversS1` (key-recovery math is real + injected-
|
||||
ledger guard), `TestRED_PoC_DefaultLedger_NonceReuse_Refused` (the **DEFAULT**
|
||||
API — fresh signer per message, **no** `SetNonceLedger` — refuses the second
|
||||
partial + relabel), `TestRED_LOW_CrossCommittee_SameNonce_Deduped` (same nonce
|
||||
across committees deduped).
|
||||
- **Authenticated PartyID → blame gated on signature validity** (RED MEDIUM,
|
||||
`distributed_bcc.go` / `protocol_auth.go`). Each `Partial` carries `Author +
|
||||
AuthSig` (the producer's identity-key signature over slot ‖ content);
|
||||
`AggregateBCCWithBlame` AUTHENTICATES each partial (valid signature **and**
|
||||
`Author == quorum[PartyID]`) BEFORE attribution, dropping forged/wrong-slot
|
||||
partials with **no blame against the slot's honest owner**, before the
|
||||
first-per-PartyID/duplicate logic. Blame is **never** emitted off a raw
|
||||
unauthenticated PartyID (with no verifier wired, no blame is produced at all).
|
||||
- GATE B (duplicate / invalid-proof / malformed all attributed to the SIGNING
|
||||
deviator) + `TestRED_PoC_MEDIUM_CannotFrameOrExcludeHonestVictim` (a forged
|
||||
victim-slot partial cannot blame or exclude the victim; the verifier is shown
|
||||
load-bearing).
|
||||
- **Per-party DKG/nonce commitment binding** — `AggregateBCC` populates and verifies
|
||||
the commitments the sigma proof is bound to (non-transferability).
|
||||
- **GATE-2 → reachability** (`gate2_reachability_test.go`) — stdlib AST call-graph;
|
||||
the reconstruct primitives (`KeyFromSeed`, `deriveKeyMaterial`, `bccSign`,
|
||||
`shamirReconstruct*`, `LargeCombine`) must be **unreachable** from the committee
|
||||
sign entrypoints. GATE C catches the `deriveKeyMaterial`+`bccSign` bypass.
|
||||
- **GATE-2 → reachability + indirection lint** (`gate2_reachability_test.go`) — a
|
||||
stdlib AST name call-graph proves the reconstruct primitives (`KeyFromSeed`,
|
||||
`deriveKeyMaterial`, `bccSign`, `shamirReconstruct*`, `LargeCombine`) are
|
||||
**unreachable from the committee sign entrypoints via direct calls** (GATE C
|
||||
catches a `deriveKeyMaterial`+`bccSign` bypass), **paired** with a companion lint
|
||||
that forbids taking any banned primitive as a non-call **value** or aliasing it
|
||||
via `//go:linkname`. The graph is complete for DIRECT calls; the lint closes
|
||||
function-value / closure / linkname indirection — the pair (not either half) is
|
||||
complete for the banned set.
|
||||
- **CI invariant** — the production (default-tag) build never carries
|
||||
`legacy_trusted_dealer`.
|
||||
|
||||
@@ -52,10 +73,15 @@ The no-reconstruct property above is a **SIGN-time** property. Key and nonce
|
||||
A homomorphic `A·s1_i` / `A·y_i` commitment is **rejected** because it reopens
|
||||
PULSAR-V13-W-LEAK / HINT-LEAK. Until then, a valid-sigma wrong-`z` is a
|
||||
**liveness fault (unattributed abort), never a forgery or leak**.
|
||||
- **Malicious-secure CSCP**, **networked MPC transcript**, **authenticated /
|
||||
signed protocol channels**, **leak-free NonceMPC**, **persistent nonce ledger**
|
||||
(crash-restart safety), **last-mover-bias controls**. See `BLOCKERS.md`
|
||||
Residual A and the branch report.
|
||||
- **Persistent nonce ledger (crash-restart safety).** The in-process default is
|
||||
safe NOW (registry, above); the persistent per-share ledger that survives a
|
||||
restart is the residual — install one at startup via `SetNonceLedger` (writes the
|
||||
same per-share registry slot, first-writer-wins).
|
||||
- **Networked / authenticated transport.** The partial→producer crypto binding is
|
||||
in place (above); the networked channel that authenticates message DELIVERY is
|
||||
owned by the consensus layer and remains a flagged residual.
|
||||
- **Malicious-secure CSCP**, **networked MPC transcript**, **leak-free NonceMPC**,
|
||||
**last-mover-bias controls**. See `BLOCKERS.md` Residual A and the branch report.
|
||||
|
||||
## The honest one-line scope (canonical)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user