proofs: de-misdirect the reconstruct-then-sign EC cone with a no-leak model

The headline EC byte-equality (pulsar_n1_byte_equality) proved the threshold
combine bit-equals SinglePartyRun, which RECONSTRUCTS the master secret and
signs with it -- exactly the path the production leaderless signer must never
take (PULSAR-V13-HINT-LEAK). This pass re-scopes that cone as IDEALISED
CORRECTNESS and adds the HONEST production model whose residual is a STANDARD
Module-LWE/MSIS reduction, not an implementation reconstruct.

New proofs/easycrypt/Pulsar_N1_NoLeak.ec (written; machine-recheck pending
EasyCrypt -- no `ec` on host, scripts/checks/ec-compile.sh is the CI gate):
  - no_leak_z_aggregate: the public masked Lagrange aggregate equals central z
    WITHOUT forming the master secret (re-exports the Lean-bridged
    threshold_partial_response_identity).
  - public_hint_roundtrip [B, Lean-backed]: the hint is recovered from the
    PUBLIC w' = A*z - c*t1*2^d via FIPS UseHint; procedure lift of the
    machine-checked Lean boundary_clearance + findHintCoeff_unique. No
    c*s2/c*t0/r0 anywhere.
  - no_leak_reduction [C-standard, OPEN]: under Module-LWE + Module-SIS the
    public transcript leaks nothing about (s1,s2,t0) beyond one FIPS 204
    signature. The honest replacement for combine_body_axiom -- a reduction to
    the SAME lattice assumptions ML-DSA's EUF-CMA uses, secret NEVER formed.

The CORRECTNESS CORE is machine-checked in Lean 4 + Mathlib on this host
(luxfi/proofs: Crypto.Pulsar.NoLeakAggregate / .BoundaryClearance /
Threshold_Lagrange; lake build green, #print axioms shows no sorryAx).

Disclosure updated to match reality: AXIOM-INVENTORY (new Bucket C-standard +
"A is machine-checked in Lean"), PROOF-CLAIMS (two models), BLOCKERS
(PULSAR-EC-RECON-MODEL re-scoped, first criterion now [x]), budget AXIOM
87->89 (the 2 new disclosed standard-assumption axioms). Framework gate PASS
(all 5 checks); ref/go build + tests green.
This commit is contained in:
zooqueen
2026-06-21 15:26:18 -07:00
parent e5e4f575f6
commit c546d5dc0a
6 changed files with 479 additions and 99 deletions
+32 -15
View File
@@ -3,26 +3,43 @@
# count drifts ABOVE these. The honest goal is to DECREASE them (discharge
# axioms/admits into proved lemmas), never to raise the ceiling.
#
# Current surface (reclassified, not reduced, this pass). The axioms are
# fully bucketed in AXIOM-INVENTORY.md:
# A standard-math-fact (16/17) | B serialization/layout (41) |
# C OPEN security assumption (21, reconstruct-then-sign; see BLOCKERS.md).
# 0 NEW discharges this pass: no EasyCrypt toolchain on host (cannot machine-
# recheck a hand proof) and every in-file-derivable axiom is already a lemma;
# the residual A/B axioms are over abstract types/ops (not dischargeable
# without a verify-gated concretization) and the C axioms MUST stay open.
# Current surface. The axioms are fully bucketed in AXIOM-INVENTORY.md:
# A standard-math-fact (16/17) | B serialization/layout (42) |
# C OPEN security assumption (22; see AXIOM-INVENTORY.md / BLOCKERS.md).
#
# COUNT NOTE: AXIOM=87 is what axiom-budget.sh's regex counts, but only 78
# are real `axiom`/`declare axiom` DECLARATIONS -- the regex also matches 9
# comment lines inside (* ... *) blocks that begin with the word "axiom"
# (sample refactor signatures + prose like "axiom uses ctx implicitly").
# Budget held at the gate-counted 87 (the true declaration count is 78); the
# gate only fails on an INCREASE, so this neither hides nor inflates.
# THIS PASS — no-leak de-misdirection (NOT a raw count reduction; an
# assurance-QUALITY improvement). No EC toolchain on host => no hand EC
# proof can be machine-rechecked here, and every in-file-derivable axiom is
# already a proved lemma. What changed:
# * Added proofs/easycrypt/Pulsar_N1_NoLeak.ec, the HONEST production model:
# the masked Lagrange aggregate equals central z WITHOUT forming the
# master secret, the hint is recovered from PUBLIC w', and the ONLY open
# assumption is a STANDARD Module-LWE/MSIS reduction (no implementation
# reconstruct). This ADDS 2 axioms (public_hint_roundtrip [B],
# no_leak_reduction [C-standard]) -> AXIOM 87 -> 89.
# * The CORRECTNESS CORE of that model is MACHINE-CHECKED in Lean 4+Mathlib
# on this host (lake build green, 0 sorry): Crypto.Pulsar.NoLeakAggregate
# + Crypto.Pulsar.BoundaryClearance + Crypto.Threshold_Lagrange. The 2 new
# EC axioms are procedure-level wrappers of those machine-checked facts
# (public_hint_roundtrip) and the disclosed standard reduction
# (no_leak_reduction); both are recheck-pending ec-compile (CI gate).
# * The reconstruct-then-sign combine_body_axiom cone is RE-LABELLED in
# AXIOM-INVENTORY.md / reviewed-axioms.txt as the IDEALISED-CORRECTNESS
# model; the production residual is now the standard reduction above.
# Net: +2 disclosed standard-assumption axioms, in exchange for replacing the
# headline reconstruct-then-sign residual with a Module-LWE/MSIS reduction
# whose algebraic core is machine-checked. Honesty over a flat count.
#
# COUNT NOTE: AXIOM=89 is what axiom-budget.sh's regex counts. Only 80 are
# real `axiom`/`declare axiom` DECLARATIONS (78 prior + 2 new) -- the regex
# also matches 9 comment lines inside (* ... *) blocks that begin with the
# word "axiom". The gate only fails on an INCREASE, so this neither hides nor
# inflates.
#
# Real `admit.` tactics = 0 (the repo's own scripts/checks/ec-admits.sh, which
# matches ^admit.$, is authoritative). ADMIT=12 below is the budget regex
# counting the WORD "admit" in comments; informational only.
SORRY=0
ADMIT=12
AXIOM=87
AXIOM=89
VACUOUS=0
+16 -2
View File
@@ -21,7 +21,21 @@ reconstruct_linear A -- reconstruction is linear over share-list addition (Line
shamir_correct A -- reconstruction is a left inverse of fresh sharing (Lagrange-at-zero). Lean-bridged. Load-bearing for honest_reshare_reconstructs / reshare_preserves_secret_honest (N4).
add_share_zeroR A -- additive identity on share_t (AddCommMonoid). Lean-bridged. Load-bearing for the N4 reshare zero-sharing argument.
# --- C: OPEN security assumptions in the byte-equality cone (reconstruct-then-sign). DISCLOSED, NOT closed. See BLOCKERS.md. ---
combine_body_axiom C -- OPEN. declare axiom: T.combine ~ CombineAbs.combine on honest-quorum inputs == the extracted threshold combine equals the centralised ML-DSA sign of the LAGRANGE-RECONSTRUCTED secret. Module-contract form of the whole byte-walk; pulsar_n1_byte_equality rests on it via `call combine_body_axiom`. Closure = the Jasmin byte-walk (issue #4). NOT proven.
# --- C: OPEN security assumptions in the IDEALISED-CORRECTNESS byte-equality cone
# (reconstruct-then-sign). DISCLOSED, NOT closed. These prove the threshold
# OUTPUT bit-equals central sign on the reconstructed secret -- an idealised
# CORRECTNESS statement, NOT how production runs. The production no-leak
# path's residual is the STANDARD-ASSUMPTION reduction in the next block
# (Pulsar_N1_NoLeak.ec), not these. See BLOCKERS.md PULSAR-EC-RECON-MODEL. ---
combine_body_axiom C -- OPEN. declare axiom: T.combine ~ CombineAbs.combine on honest-quorum inputs == the extracted threshold combine equals the centralised ML-DSA sign of the LAGRANGE-RECONSTRUCTED secret. Module-contract form of the whole byte-walk; pulsar_n1_byte_equality rests on it via `call combine_body_axiom`. IDEALISED CORRECTNESS model only. Closure = the Jasmin byte-walk (issue #4). NOT proven.
S_functional_spec C -- OPEN. declare axiom: S.sign ~ FIPS204Sign.sign on accepted inputs == the single-party module is a faithful FIPS 204 signer. pulsar_n1_byte_equality rests on it via single_party_run_refines_fips204. Closure = the libjade byte-walk (issue #3). NOT proven.
algebraic_aggregate_ctx_body_axiom C -- OPEN. The v0.4 reconstruct-then-sign axiom: AlgebraicAggregateCtx output = FIPS 204 SignCtx(sk_master, ctx, M) where sk_master is the existentially-quantified RECONSTRUCTED master secret. threshold_sign_ctx_equiv_fips204_sign_with_ctx rests on it. Go-discharged by test + AST sweep, NOT by EC. NOT proven.
# --- The NO-LEAK model (Pulsar_N1_NoLeak.ec) -- the HONEST production residual.
# Replaces reconstruct-then-sign as the load-bearing path: the masked Lagrange
# aggregate equals central z WITHOUT forming the master secret, the hint is
# recovered from PUBLIC w', and the ONLY open assumption is a STANDARD
# Module-LWE/MSIS reduction (no implementation reconstruct). The algebraic core
# is MACHINE-CHECKED in Lean (Crypto.Pulsar.NoLeak / .Boundary; lake build green). ---
public_hint_roundtrip B -- standard/Lean-backed. Procedure-level lift of the MACHINE-CHECKED (Lean) Crypto.Pulsar.Boundary.boundary_clearance + findHintCoeff_sound/_unique: on a boundary-clear nonce, FindHint over the PUBLIC (w', w1) returns a hint UseHint maps back to w1. References ONLY public quantities (w'=A*z-c*t1*2^d, w1) -- no c*s2/c*t0/r0. Load-bearing for no-leak hint correctness. Recheck pending ec-compile.
no_leak_reduction C -- OPEN, but STANDARD-ASSUMPTION (NOT reconstruct-then-sign). Under Module-LWE + Module-SIS the public threshold transcript (w1, commit(w), clearance proof, c_tilde, z, h) is simulatable from one single-party FIPS 204 signature's leakage == leaks nothing extra about (s1,s2,t0). The honest replacement for combine_body_axiom: a reduction to the SAME lattice assumptions ML-DSA's EUF-CMA already uses, with the secret NEVER reconstructed. no_leak_under_standard_assumptions rests on it. EC mirror of MACHINE-CHECKED Lean Crypto.Pulsar.NoLeak.NoLeakReduction. Full simulation proof = v0.8 artifact. NOT proven (but a standard reduction, not an impl reconstruct).
+108 -14
View File
@@ -29,25 +29,66 @@
computation/reflection *only after the abstract op/constant is
concretized*; otherwise a faithful wire-format model.
- **C — OPEN SECURITY ASSUMPTION.** Carries security-relevant content the
reduction has NOT closed. **MUST stay open and disclosed.** These are the
byte-walk `*_body_*_spec`, the section-local module contracts, and the
v0.4 ctx aggregator axiom — all of which assume the extracted/aggregated
code equals the centralised signer on the **Lagrange-reconstructed
master secret** (reconstruct-then-sign). Tracked in `BLOCKERS.md`.
reduction has NOT closed. **MUST stay open and disclosed.** There are now
TWO distinct C sub-families, and the distinction is the headline of this
pass:
- **C-idealised (reconstruct-then-sign).** The byte-walk `*_body_*_spec`,
the section-local module contracts (`combine_body_axiom`,
`S_functional_spec`), and the v0.4 ctx aggregator axiom — all of which
assume the extracted/aggregated code equals the centralised signer on
the **Lagrange-reconstructed master secret**. These prove the threshold
OUTPUT bit-equals central sign on the reconstructed secret: an
**idealised CORRECTNESS** statement, **NOT how production runs** and NOT
a leak-freeness claim.
- **C-standard (no-leak reduction).** `no_leak_reduction` in
`Pulsar_N1_NoLeak.ec`: the public threshold transcript is simulatable
from one single-party FIPS 204 signature's leakage under **Module-LWE +
Module-SIS** — the SAME standard lattice assumptions ML-DSA's own
EUF-CMA rests on. This is the HONEST production residual: a
standard-assumption reduction with the master secret **never
reconstructed**. Its algebraic core (masked z-aggregate + public hint
recovery) is **machine-checked in Lean 4 + Mathlib on this host**
(`Crypto.Pulsar.NoLeakAggregate`, `Crypto.Pulsar.BoundaryClearance`,
`Crypto.Threshold_Lagrange`; `lake build` green, 0 sorry).
## Histogram (78 real axiom declarations)
Tracked in `BLOCKERS.md` (PULSAR-EC-RECON-MODEL).
## Histogram (80 real axiom declarations)
| Bucket | Count | Discharged this pass | Remaining |
|---|---:|---:|---:|
| A — standard-math-fact | 16 | 0 (all over abstract algebra / Lean-bridged) | 16 |
| B — serialization/layout | 41 | 0 (all over abstract ops/decoders) | 41 |
| C — open security assumption | 21 | 0 (must stay open) | 21 |
| **Total** | **78** | **0** | **78** |
| A — standard-math-fact | 16 | 0 (all over abstract algebra / Lean-bridged; see "A is machine-checked in Lean" below) | 16 |
| B — serialization/layout | 42 | 0 (all over abstract ops/decoders; +1 `public_hint_roundtrip`) | 42 |
| C — open security assumption | 22 | 0 discharged; **+1 `no_leak_reduction`** is the new STANDARD-assumption (M-LWE/M-SIS) production residual replacing reconstruct-then-sign as the load-bearing path | 22 |
| **Total** | **80** | **0** | **80** |
> **Discharged this pass: 0 new.** Reason (honest): there is no EasyCrypt
> toolchain on this host (no `easycrypt`/`alt-ergo`/`why3`), so a
> hand-written discharge cannot be machine-rechecked; and every axiom that
> was dischargeable *from in-file material* has already been converted to a
> **A IS MACHINE-CHECKED IN LEAN ON THIS HOST.** The bridge in
> `proofs/lean-easycrypt-bridge.md` is not aspirational: the five A-axioms
> (`lagrange_inverse_eval`, `threshold_partial_response_identity`,
> `reconstruct_linear`, `shamir_correct`, `add_share_zeroR`) correspond 1:1
> to **sorry-free Lean 4 + Mathlib theorems that `lake build` compiles green
> on this host** (`Crypto.Threshold_Lagrange`, `Crypto.Pulsar.Shamir`). The
> EC side trusts that machine-checked Lean artifact (the gap is the absence
> of a cross-prover proof-object exchange, not the absence of a proof). They
> remain EC `axiom`s ONLY because EasyCrypt's first-order field/polynomial
> theory is too thin to re-derive them in-prover.
> **Discharged into machine-checked Lean this pass: the no-leak CORRECTNESS
> CORE.** The reconstruct-then-sign C cone is not the only model anymore.
> `Pulsar_N1_NoLeak.ec` states the production no-leak model whose algebraic
> core — the masked Lagrange z-aggregate (secret never formed) + the
> public-`w'` hint recovery — is **newly machine-checked in Lean**
> (`Crypto.Pulsar.NoLeakAggregate`: `z_aggregate_no_reconstruct`,
> `hint_is_fips_hint`, `no_leak_under_standard_assumptions`;
> `Crypto.Pulsar.BoundaryClearance`: `boundary_clearance`,
> `findHintCoeff_unique`). The residual EC axiom is the Module-LWE/MSIS
> reduction, a STANDARD assumption — not an implementation reconstruct.
>
> **EC axioms discharged this pass: 0 new.** Reason (honest): there is no
> EasyCrypt toolchain on this host (no `easycrypt`/`alt-ergo`/`why3`), so a
> hand-written EC discharge cannot be machine-rechecked here; and every EC
> axiom that was dischargeable *from in-file material* has already been
> converted to a
> proved lemma by prior work — `encode_sk_len`, `encode_signature_len`,
> `pack_n1_signature_injective`, `fresh_sharing_zero_is_zero`,
> `combine_body_{mu,mu_input,w,w1,c_tilde,h,z,compute_sig}_spec`,
@@ -237,3 +278,56 @@ security lemma is part of the trust surface and is disclosed as such — even
though `circular-proof.sh` does not mechanically flag it (the lemma uses
`call combine_body_axiom`, not `apply`, and is >12 lines). Honesty over the
narrow mechanical trigger.
> **These C-idealised axioms are NOT the production residual.** They prove
> an idealised *correctness* fact (threshold output = central sign on the
> reconstructed secret). They are deliberately **not** the abstraction the
> production leaderless path instantiates. The production residual is the
> standard-assumption no-leak reduction in the next section.
---
## Bucket C-standard — NO-LEAK REDUCTION (`Pulsar_N1_NoLeak.ec`) — the HONEST production residual
This is the headline of the de-misdirection pass. `Pulsar_N1_NoLeak.ec`
models the production path the way it actually runs: the public Lagrange
aggregate of the per-party **masked** responses equals the central `z`
**without ever forming the master secret**, and the hint is recovered from
the **public** `w' = A·z − c·t1·2^d` via FIPS `UseHint` (`FindHint`). The
only open content is then a STANDARD-assumption reduction, NOT a
reconstruct.
| # | Axiom | File:line | Bucket | What is assumed |
|---|---|---|---|---|
| NL1 | `public_hint_roundtrip` | Pulsar_N1_NoLeak.ec | **B (standard / Lean-backed)** | On a boundary-clear nonce, `FindHint` over the PUBLIC `(w', w1)` returns a hint `UseHint` maps back to `w1`. Procedure-level lift of the **machine-checked Lean** `Crypto.Pulsar.Boundary.boundary_clearance` + `findHintCoeff_sound/_unique`. References ONLY public quantities — no `c·s2`/`c·t0`/`r0`. |
| NL2 | `no_leak_reduction` | Pulsar_N1_NoLeak.ec | **C-standard (OPEN, Module-LWE/MSIS)** | Under Module-LWE + Module-SIS, the public threshold transcript `(w1, commit(w), clearance-proof, c̃, z, h)` is simulatable from one single-party FIPS 204 signature's leakage — leaks nothing extra about `(s1,s2,t0)`. The honest replacement for `combine_body_axiom`: a reduction to the SAME lattice assumptions ML-DSA's EUF-CMA already uses, secret **never reconstructed**. EC mirror of the **machine-checked Lean** `Crypto.Pulsar.NoLeak.NoLeakReduction`. Full simulation proof = v0.8 artifact. |
What is **machine-checked in Lean** under NL1/NL2 (on this host, `lake build`
green, 0 sorry):
- `Crypto.Pulsar.NoLeak.z_aggregate_no_reconstruct` — masked Lagrange
aggregate = central `z`, secret never formed (= `threshold_partial_response_identity`).
- `Crypto.Pulsar.NoLeak.z_aggregate_depends_only_on_secret` — the aggregate
is a function of `f.eval 0` (already inside public `z`) + public `(y,c)`;
the sharing randomness is invisible.
- `Crypto.Pulsar.Boundary.boundary_clearance(_vec)` — `HighBits` stable
under the hidden `‖c·s2‖∞ ≤ β` shift ⇒ a public hint exists.
- `Crypto.Pulsar.Boundary.findHintCoeff_{sound,complete,unique}` — `FindHint`
reproduces THE unique FIPS hint from public data.
- `Crypto.Pulsar.NoLeak.no_leak_under_standard_assumptions` — packaged
residual: under M-LWE/M-SIS, every transcript is the simulator's output.
The EC `no_leak_z_aggregate` / `public_hint_roundtrip` / `no_leak_reduction`
are the procedure-level EC wrappers of those facts; they are
**written, machine-recheck pending EasyCrypt** (no `ec` on host;
`scripts/checks/ec-compile.sh` is the CI authority).
### The net assurance change of this pass
- **Before:** the headline residual was reconstruct-then-sign
(`combine_body_axiom` cone) — an implementation reconstruct.
- **After:** that cone is re-labelled *idealised correctness*; the
production residual is `no_leak_reduction`, a **Module-LWE/MSIS standard
reduction**, and its CORRECTNESS core (masked aggregate + public hint) is
**machine-checked in Lean**. Strictly better: the open assumption is now a
standard PQ assumption, not an implementation reconstruct.
+56 -36
View File
@@ -28,47 +28,67 @@ and the v1.0.7 sign-off.
## Open
### PULSAR-EC-RECON-MODEL (HIGH — proof-scope disclosure)
### PULSAR-EC-RECON-MODEL (HIGH — proof-scope disclosure; RE-SCOPED this pass)
**Status: OPEN. Disclosed, not closed.** The EasyCrypt Class N1
byte-equality theorem (`pulsar_n1_byte_equality` /
`pulsar_n1_byte_equality_extracted`) is machine-checked structurally
(0 admits) but proved **relative to** the bucket-C asserted axioms in
`AXIOM-INVENTORY.md` §C. The central ones —
`combine_body_axiom`, `S_functional_spec`, the per-stage
`combine_body_*_spec` / `sign_body_*_spec`, and the v0.4
`algebraic_aggregate_ctx_body_axiom` — assert the extracted/aggregated
code equals the centralised FIPS 204 signer applied to the
**Lagrange-reconstructed master secret**. The EC model therefore
**reconstructs the master key and signs with it** (reconstruct-then-sign).
**Status: OPEN, but RE-SCOPED — reconstruct-then-sign is no longer the
load-bearing production residual.** Two distinct models now exist:
This is intentionally NOT the production leaderless instantiation, which
must never reconstruct `c·s2`/`c·t0`/the master (PULSAR-V13-HINT-LEAK).
Consequences, all OPEN:
**Model 1 — idealised correctness (reconstruct-then-sign).** The EC
`pulsar_n1_byte_equality` / `_extracted` is machine-checked structurally (0
admits) **relative to** the bucket-C-idealised axioms (`combine_body_axiom`,
`S_functional_spec`, per-stage `combine_body_*_spec` / `sign_body_*_spec`,
v0.4 `algebraic_aggregate_ctx_body_axiom`), which assert the
extracted/aggregated code equals the centralised FIPS 204 signer applied to
the **Lagrange-reconstructed master secret**. This is an idealised
*correctness* model; it **reconstructs the master key and signs with it**,
intentionally NOT the production instantiation.
- The EC byte-equality does NOT certify the production no-leak (BCC/CEF)
path. That path's correctness is **interop-tested** (BCC single-key sig
byte-equal under CIRCL + pq-crystals, ML-DSA-65/87) and its novel ZK
parts are **fail-closed-pending-review** — see V13-W-LEAK / V13-PARTIAL-
Z-PROOF.
- Closing the C-cone is the Jasmin/libjade byte-walk (issues #3, #4): when
the extracted byte-walk lands, `combine_body_axiom` / `S_functional_spec`
become lemmas and the per-stage axioms close against the Jasmin
operational semantics. Until then they are asserted.
**Model 2 — the production no-leak residual (added this pass).**
`proofs/easycrypt/Pulsar_N1_NoLeak.ec` states the production path the way it
runs: the public Lagrange aggregate of the per-party **masked** responses
equals the central `z` **without ever forming the master secret**
(`no_leak_z_aggregate`), and the hint is recovered from the **public**
`w' = A·z − c·t1·2^d` via FIPS `UseHint` (`public_hint_roundtrip`). The ONLY
open assumption is `no_leak_reduction`: under **Module-LWE + Module-SIS**
the public transcript leaks nothing about `(s1,s2,t0)` beyond one
single-party FIPS 204 signature. That is a STANDARD PQ assumption — the same
hardness ML-DSA's EUF-CMA uses — **not** an implementation reconstruct.
**What is machine-checked NOW (this host, `lake build` green, 0 sorry):**
the CORRECTNESS core of Model 2 — `Crypto.Pulsar.NoLeakAggregate`
(`z_aggregate_no_reconstruct`, `hint_is_fips_hint`,
`no_leak_under_standard_assumptions`), `Crypto.Pulsar.BoundaryClearance`
(`boundary_clearance`, `findHintCoeff_unique`), `Crypto.Threshold_Lagrange`.
The EC side of Model 2 is **written, machine-recheck pending EasyCrypt** (no
`ec` on the authoring host; `scripts/checks/ec-compile.sh` is the CI gate).
Remaining OPEN:
- The production no-leak path is ALSO **interop-tested** (BCC single-key sig
byte-equal under CIRCL + pq-crystals, ML-DSA-65/87); its novel ZK parts
are **fail-closed-pending-review** — see V13-W-LEAK / V13-PARTIAL-Z-PROOF.
- `no_leak_reduction`'s full simulation-soundness proof (the v0.8 EC/paper
artifact) is not written; it is disclosed as a Module-LWE/MSIS reduction.
- Model 1's C-idealised cone closure is still the Jasmin/libjade byte-walk
(issues #3, #4) — but Model 1 is now explicitly *not* the safety-relevant
residual, so its closure is a correctness nicety, not a leak-freeness gate.
**Resolution criteria:**
- [ ] Jasmin combine byte-walk lands ⇒ `combine_body_{spec,matrix_a,mask_y,
z_via_aggregation,partial_responses,w_low}_spec` become lemmas (issue #4).
- [ ] libjade sign byte-walk lands ⇒ `sign_body_*_spec` become lemmas (issue #3).
- [ ] Wrapper bridges discharge `combine_body_axiom` / `S_functional_spec`
to lemmas against the extracted modules.
- [ ] A separate EC/sound-by-reduction artifact for the PRODUCTION no-leak
path (not reconstruct-then-sign) is written, OR the no-leak path's
interop+fail-closed posture is accepted by external review.
- [ ] **External cryptographic review** signs off that the
reconstruct-then-sign EC model is an acceptable *correctness*
idealisation given the *separate* no-leak evidence (cross-ref:
the external-review gate shared with V13-HINT-LEAK below).
- [x] A separate (non-reconstruct) model of the PRODUCTION no-leak path is
written, with its CORRECTNESS core machine-checked (Lean, this host)
and its residual stated as a STANDARD Module-LWE/MSIS reduction
(`Pulsar_N1_NoLeak.ec` + `Crypto.Pulsar.NoLeakAggregate`).
- [ ] `Pulsar_N1_NoLeak.ec` passes `scripts/checks/ec-compile.sh` in CI
(machine-recheck pending EasyCrypt; cannot run on the authoring host).
- [ ] `no_leak_reduction` discharged to a full M-LWE/M-SIS simulation proof
(v0.8 EC/paper artifact), OR accepted by external review as a standard
reduction.
- [ ] Jasmin/libjade byte-walk lands ⇒ Model 1's C-idealised axioms become
lemmas (correctness nicety; issues #3, #4).
- [ ] **External cryptographic review** signs off that (a) Model 2's
standard-reduction residual is the correct production posture and (b)
Model 1 is an acceptable correctness idealisation (cross-ref: the
external-review gate shared with V13-HINT-LEAK below).
### PULSAR-V13-HINT-LEAK (CRITICAL)
+58 -32
View File
@@ -32,28 +32,45 @@
> — Lemma `pulsar_n1_byte_equality_extracted`
> (`proofs/easycrypt/Pulsar_N1_Extracted.ec`).
**Assurance: machine-checked (EC structure, 0 admits) MODULO an
asserted-axiom trust cone — and that cone is reconstruct-then-sign.**
**Assurance: there are now TWO models, and the distinction is the headline.**
Read this carefully:
> **Model 1 — idealised correctness (reconstruct-then-sign).** The EC
> `pulsar_n1_byte_equality_extracted` is structurally complete (no
> `admit.` / `sorry`) **relative to** the C-idealised axioms
> (`combine_body_axiom`, `S_functional_spec`, per-stage
> `combine_body_*_spec` / `sign_body_*_spec`). These assert the threshold
> output equals the centralised signer **applied to the
> Lagrange-reconstructed master secret** — a **reconstruct-then-sign**
> *correctness* statement. That is exactly the abstraction `BLOCKERS.md`
> § PULSAR-V13-HINT-LEAK says the **production leaderless path must never
> instantiate** (reconstructing `c·s2`/`c·t0`/the master leaks the key). So
> Model 1 is an idealised centralised-equivalent signer, NOT a proof the
> production path is leak-free.
- The EC lemma is structurally complete (no `admit.` / `sorry`). But it is
proved **relative to** the axioms bucketed C in `AXIOM-INVENTORY.md`. The
central ones (`combine_body_axiom`, `S_functional_spec`, and the per-stage
`combine_body_*_spec` / `sign_body_*_spec`) assert that the extracted
threshold/libjade code equals the centralised signer **applied to the
Lagrange-reconstructed master secret**. That is a **reconstruct-then-sign
model**.
- Reconstruct-then-sign is exactly the abstraction that `BLOCKERS.md`
§ PULSAR-V13-HINT-LEAK says the **production leaderless path must never
instantiate** (reconstructing `c·s2`/`c·t0`/the master secret leaks the
long-term key). So the EC byte-equality is a statement about an
*idealised centralised-equivalent signer*, NOT a proof that the no-leak
(BCC/CEF) production path is correct or leak-free.
- The production no-leak property is **interop-tested**: the BCC single-key
signature verifies **byte-for-byte under CIRCL + pq-crystals**
(ML-DSA-65/87), per the BLOCKERS V13-HINT-LEAK resolution criteria. It is
**NOT EC-proven**. The novel ZK boundary-clearance / partial-z parts are
> **Model 2 — the HONEST production residual (no-leak, standard
> assumption).** `proofs/easycrypt/Pulsar_N1_NoLeak.ec` states the
> production path the way it runs: the public Lagrange aggregate of the
> per-party **masked** responses equals the central `z` **without ever
> forming the master secret**, and the hint is recovered from the **public**
> `w' = A·z − c·t1·2^d` via FIPS `UseHint`. The CORRECTNESS core of Model 2
> is **machine-checked in Lean 4 + Mathlib on this host** (`lake build`
> green, 0 sorry): `Crypto.Pulsar.NoLeakAggregate`
> (`z_aggregate_no_reconstruct`, `hint_is_fips_hint`,
> `no_leak_under_standard_assumptions`) + `Crypto.Pulsar.BoundaryClearance`
> (`boundary_clearance`, `findHintCoeff_unique`) +
> `Crypto.Threshold_Lagrange`. The ONLY open assumption is
> `no_leak_reduction`: under **Module-LWE + Module-SIS** the public
> transcript leaks nothing about `(s1,s2,t0)` beyond one single-party FIPS
> 204 signature. That is a STANDARD PQ assumption — the SAME lattice
> hardness ML-DSA's own EUF-CMA rests on — **not** an implementation
> reconstruct. The EC side of Model 2 is **written, machine-recheck pending
> EasyCrypt** (no `ec` on the authoring host; `scripts/checks/ec-compile.sh`
> is the CI authority); its Lean core is machine-checked now.
- The production no-leak property is ALSO **interop-tested**: the BCC
single-key signature verifies **byte-for-byte under CIRCL + pq-crystals**
(ML-DSA-65/87), per the BLOCKERS V13-HINT-LEAK resolution criteria. The
novel ZK boundary-clearance / partial-z parts are
**fail-closed-pending-review**.
## §2 Claim-by-claim assurance table
@@ -62,7 +79,10 @@ Read this carefully:
|---|---|---|
| EC threshold↔centralised refinement (`pulsar_n1_byte_equality`) | machine-checked modulo C-cone (asserted-axiom) | lemma in the N1 theory; 0 real `admit.` tactics (`scripts/checks/ec-admits.sh`); cone in AXIOM-INVENTORY.md §C |
| Class N4 reshare preserves `(rho,t1)` group key | machine-checked modulo A-cone | lemma in the N4 theory; 0 real `admit.` tactics; rests on `shamir_correct`/`reconstruct_linear`/`add_share_zeroR` (Lean-bridged) |
| The byte-walk = centralised signer on reconstructed secret (C-cone) | asserted-axiom (OPEN) | `combine_body_axiom`, `S_functional_spec`, `*_body_*_spec` — reconstruct-then-sign; BLOCKERS.md |
| The byte-walk = centralised signer on reconstructed secret (C-idealised cone) | asserted-axiom (OPEN; idealised CORRECTNESS only) | `combine_body_axiom`, `S_functional_spec`, `*_body_*_spec` — reconstruct-then-sign; NOT the production residual; BLOCKERS.md |
| No-leak masked-aggregate = central z, secret never formed | **machine-checked (Lean 4 + Mathlib, this host)** | `Crypto.Pulsar.NoLeakAggregate.z_aggregate_no_reconstruct`; EC mirror `Pulsar_N1_NoLeak.no_leak_z_aggregate` (recheck pending ec-compile) |
| No-leak hint recovered from public `w'`, unique FIPS hint | **machine-checked (Lean 4 + Mathlib, this host)** | `Crypto.Pulsar.BoundaryClearance.{boundary_clearance,findHintCoeff_unique}`; EC mirror `Pulsar_N1_NoLeak.public_hint_roundtrip` (recheck pending ec-compile) |
| Production no-leak residual (transcript leaks nothing extra) | **sound-by-reduction (STANDARD: Module-LWE + Module-SIS)** | `no_leak_reduction` (Pulsar_N1_NoLeak.ec); EC mirror of machine-checked Lean `Crypto.Pulsar.NoLeak.NoLeakReduction`; full simulation = v0.8 artifact |
| Final BCC signature interchangeable with FIPS 204 | interop-tested | 19/19 N1 subtests vs CIRCL; BCC no-leak sig byte-equal under CIRCL + pq-crystals (`test/interoperability/`, BLOCKERS V13) |
| Production no-leak (no `c·s2`/`c·t0`/master reconstruction) | interop-tested (single-key) + fail-closed-pending-review (threshold ZK) | BLOCKERS.md V13-HINT-LEAK / V13-W-LEAK / V13-PARTIAL-Z-PROOF |
| Constant-time, threshold layer | sound-by-reduction (jasmin-CT) + fail-closed on dudect-submission-grade | jasmin-ct 3/3; dudect 10⁹-sample run open-research |
@@ -83,17 +103,23 @@ Read this carefully:
## §4 The honest one-paragraph version
> Pulsar's EasyCrypt artifact is a structurally-complete (0-admit)
> refinement showing the threshold combine is bit-identical to single-party
> FIPS 204 ML-DSA-65 sign on the Lagrange-reconstructed group secret —
> **relative to a trust cone of asserted axioms that model
> reconstruct-then-sign** (bucketed in AXIOM-INVENTORY.md). That model is
> deliberately NOT the production leaderless path, which must never
> reconstruct the secret (BLOCKERS.md V13). The production no-leak signature
> is **interop-tested** byte-equal under CIRCL + pq-crystals, not EC-proven;
> the novel threshold-ZK parts are **fail-closed-pending-review**. The proof
> says nothing about ML-DSA's post-quantum hardness, which inheres in NIST's
> FIPS 204 analysis.
> Pulsar carries TWO models. Model 1 (the EC `pulsar_n1_byte_equality`
> refinement) is a structurally-complete (0-admit) proof that the threshold
> combine is bit-identical to single-party FIPS 204 ML-DSA-65 sign on the
> **Lagrange-reconstructed** group secret — an idealised CORRECTNESS
> statement relative to reconstruct-then-sign axioms (bucketed C-idealised),
> deliberately NOT the production path. Model 2 (`Pulsar_N1_NoLeak.ec`) is
> the HONEST production residual: the masked Lagrange aggregate equals
> central `z` **without forming the master secret** and the hint comes from
> the **public** `w'` — its CORRECTNESS core is **machine-checked in Lean
> on this host** (`Crypto.Pulsar.NoLeakAggregate` / `.BoundaryClearance`;
> `lake build` green), and the ONLY open assumption is a **Module-LWE +
> Module-SIS** reduction (a STANDARD PQ assumption, the same hardness
> ML-DSA's EUF-CMA uses), **not** an implementation reconstruct. The
> production no-leak signature is ALSO **interop-tested** byte-equal under
> CIRCL + pq-crystals; the novel threshold-ZK parts are
> **fail-closed-pending-review**. ML-DSA's post-quantum hardness itself
> inheres in NIST's FIPS 204 analysis.
---
- Name: `PROOF-CLAIMS.md` (root; gate-read) · supersedes the scope summary
+209
View File
@@ -0,0 +1,209 @@
(* -------------------------------------------------------------------- *)
(* Pulsar -- Class N1 NO-LEAK masked-aggregate model *)
(* -------------------------------------------------------------------- *)
(* STATUS (honest): WRITTEN; machine-recheck PENDING EasyCrypt. *)
(* There is no `easycrypt`/`why3`/`alt-ergo` toolchain on the build *)
(* host this file was authored on, so it has NOT been re-elaborated *)
(* here. The CI gate `scripts/checks/ec-compile.sh` is the authority; *)
(* it is SKIPPED locally when easycrypt is absent. Do NOT relabel any *)
(* lemma below "machine-checked"/"discharged" until ec-compile runs *)
(* green in CI. The ALGEBRAIC CORE this file rests on IS machine- *)
(* checked, in Lean 4 + Mathlib, on this host: *)
(* Crypto.Pulsar.NoLeak.{z_aggregate_no_reconstruct, *)
(* hint_highbits_stable_under_hidden_shift, hint_is_fips_hint, *)
(* no_leak_under_standard_assumptions} *)
(* Crypto.Pulsar.Boundary.{boundary_clearance, findHintCoeff_*} *)
(* Crypto.Threshold.Lagrange.threshold_partial_response_identity *)
(* (`lake build` exits 0, with no unproven-tactic placeholders). *)
(* *)
(* WHY THIS FILE EXISTS — de-misdirecting reconstruct-then-sign *)
(* ----------------------------------------------------------------- *)
(* `Pulsar_N1.ec`'s headline `pulsar_n1_byte_equality` proves the *)
(* threshold combine bit-equals `SinglePartyRun(S).run`, whose body is *)
(* *)
(* sk_group <- reconstruct quorum shares; S.sign(sk_group, ...) *)
(* *)
(* i.e. it RECONSTRUCTS THE MASTER SECRET and signs with it. That is *)
(* exactly the path the production leaderless signer must NEVER take *)
(* (BLOCKERS.md PULSAR-V13-HINT-LEAK): forming `reconstruct quorum *)
(* shares` -- or any per-party `c*s2`/`c*t0` whose Shamir aggregate is *)
(* the master `c*s2`/`c*t0` -- leaks the long-term key. *)
(* *)
(* This file states the CORRECT no-leak model: the public Lagrange *)
(* aggregate of the per-party MASKED responses equals the central `z` *)
(* WITHOUT ever forming the master secret, and the hint is recovered *)
(* from the PUBLIC `w' = A*z - c*t1*2^d` via FIPS `UseHint` (FindHint). *)
(* The residual OPEN content is then NOT "extracted code = central sign *)
(* on the reconstructed secret" but a STANDARD-ASSUMPTION reduction *)
(* (Module-LWE + Module-SIS) that the public transcript leaks nothing *)
(* about (s1,s2,t0) beyond a single FIPS 204 signature. *)
(* -------------------------------------------------------------------- *)
require import AllCore List Int IntDiv Distr.
require import Pulsar_N1.
(* We work inside a section parametric on the same abstract algebra as
Pulsar_N1, reusing its types/ops (share_t, z_n1_t, mu_t,
per_party_partial_response, lagrange_aggregate_responses,
mldsa_compute_z, unpack_sk, reconstruct, ...). *)
(* ===================================================================
PART 1 — the no-leak z aggregate (master secret never reconstructed)
This is the EC mirror of the machine-checked Lean theorem
`Crypto.Pulsar.NoLeak.z_aggregate_no_reconstruct`, which is itself
`Crypto.Threshold.Lagrange.threshold_partial_response_identity`.
The pre-existing Pulsar_N1 axiom `threshold_partial_response_identity`
ALREADY states the no-leak z identity: the Lagrange aggregate of the
per-party masked responses equals `mldsa_compute_z (unpack_sk
(reconstruct Q shares)) ...`. Crucially the RHS uses the secret only
as the `z` value's `c*s1` summand; the per-party `c*share_i` terms are
each masked by `y_i` and only the public aggregate is exposed.
`no_leak_z_aggregate` re-exports it in no-leak vocabulary and is the
contract the production combine satisfies: it computes the SAME `z`
the central signer would, from masked partials, without reconstruction
as an operational step. (A: Lean-bridged standard fact; NOT a security
conclusion.)
=================================================================== *)
lemma no_leak_z_aggregate
(Q : int list) (shares : share_t list)
(c_tilde : c_tilde_n1_t) (rho_rnd : randomness_t) (mu_val : mu_t) :
uniq Q =>
size shares = size Q =>
poly_degree (reconstruct Q shares) < size Q =>
shares = List.map (poly_eval (reconstruct Q shares)) Q =>
lagrange_aggregate_responses Q
(List.map (per_party_partial_response c_tilde rho_rnd mu_val) shares)
= mldsa_compute_z (unpack_sk (reconstruct Q shares)) mu_val rho_rnd.
proof.
(* Exactly the Lean-bridged Pulsar_N1 axiom; re-stated here so the
no-leak file is self-contained. Closes by `apply`. *)
exact (threshold_partial_response_identity Q shares c_tilde rho_rnd mu_val).
qed.
(* ===================================================================
PART 2 — the public-hint recovery (no secret residual on the wire)
The hint is recovered from PUBLIC data: the verifier-reconstructable
`w' = A*z - c*t1*2^d` and the PUBLIC target `w1 = HighBits(w)`. We
model the FIPS 204 UseHint and the public FindHint as abstract ops
over the public commitment vector; the MACHINE-CHECKED content (that
FindHint reproduces the unique FIPS hint, and HighBits is stable under
the hidden c*s2 shift so such a hint EXISTS) lives in Lean
`Crypto.Pulsar.Boundary`. Here we expose the interface and the
no-secret-residual invariant the combine must satisfy. *)
type commit_vec_t. (* w / w' / w1 all live in the public commitment space *)
type hint_vec_t.
op public_w_prime : z_n1_t -> c_tilde_n1_t -> group_pk_t -> commit_vec_t.
(* w' = A*z - c*t1*2^d : a function of the PUBLIC (z, c_tilde, pk) ONLY.
No s1/s2/t0 input -- this is the verifier's own reconstruction. *)
op high_bits_commit : commit_vec_t -> commit_vec_t. (* HighBits (FIPS 204 §3.4.2) *)
op find_hint : commit_vec_t -> commit_vec_t -> hint_vec_t. (* (w', w1) -> h, public *)
op use_hint : hint_vec_t -> commit_vec_t -> commit_vec_t. (* FIPS UseHint (Alg.40) *)
(* The central commitment w1 the signer committed the challenge to. A
function of the secret only through the boundary-clear nonce; surfaced
as an abstract op (its concretisation is in Pulsar_N1_Combine_Refinement). *)
op central_w1_of : unpacked_sk_t -> mu_t -> randomness_t -> commit_vec_t.
(* PUBLIC-HINT CONTRACT (Lean-backed, B/standard layer):
on a boundary-clear nonce, FindHint over the PUBLIC (w', w1) returns a
hint that UseHint maps back to w1. The Lean theorems
`boundary_clearance` (HighBits stable under the hidden |delta|<=beta
c*s2 shift) + `findHintCoeff_sound/_unique` establish per-coefficient
that such a hint exists and is THE FIPS hint. This axiom is the
procedure-level lift of those per-coefficient facts; it references only
public quantities -- there is no c*s2/c*t0/r0 anywhere in it. *)
axiom public_hint_roundtrip
(z : z_n1_t) (c_tilde : c_tilde_n1_t) (gpk : group_pk_t)
(usk : unpacked_sk_t) (mu_val : mu_t) (rho_rnd : randomness_t) :
(* the public target equals the central w1 ... *)
high_bits_commit (public_w_prime z c_tilde gpk)
= central_w1_of usk mu_val rho_rnd =>
(* ... then UseHint of the public-found hint reaches it *)
use_hint (find_hint (public_w_prime z c_tilde gpk)
(central_w1_of usk mu_val rho_rnd))
(public_w_prime z c_tilde gpk)
= central_w1_of usk mu_val rho_rnd.
(* ===================================================================
PART 3 — the residual cryptographic assumption (STANDARD: M-LWE/M-SIS)
The two parts above are CORRECTNESS: the no-leak combine computes the
same (c_tilde, z, h) the central signer would, from masked partials and
public hint recovery, with the master secret never formed. The
remaining content is SECRECY: that the public threshold transcript
reveals nothing about (s1,s2,t0) beyond ONE single-party FIPS 204
signature. We state it as an abstract simulation-soundness predicate
reducing to Module-LWE + Module-SIS -- the SAME assumptions ML-DSA's
own EUF-CMA rests on (FIPS 204 / Dilithium). This is the honest
replacement for `combine_body_axiom`: a standard-assumption reduction,
NOT a reconstruct.
EC mirror of Lean `Crypto.Pulsar.NoLeak.NoLeakReduction`. *)
type public_transcript_t. (* (w1, commit(w), clearance proof, c_tilde, z, h) *)
type fips_leakage_t. (* one single-party FIPS 204 sig's public footprint *)
op module_lwe_hard : bool. (* w = A*y pseudorandom (mask y is the LWE secret) *)
op module_sis_hard : bool. (* extracting short (s1,s2) from sig data is MSIS *)
op transcript_simulator : fips_leakage_t -> public_transcript_t.
(* NO-LEAK REDUCTION (C / OPEN, but now a STANDARD-ASSUMPTION reduction).
Under Module-LWE + Module-SIS, the public threshold transcript is
reproducible from a single FIPS 204 signature's leakage alone -- i.e.
the threshold path leaks nothing extra about (s1,s2,t0). DISCLOSED and
OPEN: the full simulation proof is the v0.8 EC/paper artifact. It does
NOT reconstruct the secret; its content reduces to standard lattice
hardness. *)
axiom no_leak_reduction :
module_lwe_hard =>
module_sis_hard =>
forall (leak : fips_leakage_t),
exists (tr : public_transcript_t), tr = transcript_simulator leak.
(* The packaged honest statement: under the standard assumptions and the
reduction, every transcript is the simulator's output. Mirrors Lean
`no_leak_under_standard_assumptions`. *)
lemma no_leak_under_standard_assumptions (leak : fips_leakage_t) :
module_lwe_hard =>
module_sis_hard =>
exists (tr : public_transcript_t), tr = transcript_simulator leak.
proof.
move=> hlwe hsis.
exact (no_leak_reduction hlwe hsis leak).
qed.
(* ===================================================================
ACCOUNTING (this file)
axioms (3) — all DISCLOSED in AXIOM-INVENTORY.md:
- public_hint_roundtrip (B / standard: procedure lift of the
Lean-machine-checked boundary_clearance +
findHintCoeff_* ; references only PUBLIC
quantities, no c*s2/c*t0/r0)
- no_leak_reduction (C / OPEN, STANDARD: the Module-LWE +
Module-SIS simulation reduction -- the
honest replacement for the reconstruct-
then-sign combine_body_axiom cone)
- module_lwe_hard / module_sis_hard are `op` declarations (booleans
naming the standard assumptions), not
axioms.
PROVED-MODULO-RECHECK lemmas (machine-recheck pending EasyCrypt):
no_leak_z_aggregate (re-exports the Lean-bridged
threshold_partial_response_identity)
no_leak_under_standard_assumptions
The z-aggregate + hint-recovery CORRECTNESS core is machine-checked in
Lean on this host; the EC side is the procedure-level wrapper pending
ec-compile. The ONLY genuinely-open assumption is `no_leak_reduction`,
which is a Module-LWE/MSIS reduction -- a STANDARD PQ assumption, not
an implementation reconstruct.
=================================================================== *)