Files
warp/pulsar/resolver_distinctness_test.go
zeekay 443aa53f81 feat(warp)!: typed finality-evidence model (Beam/Pulsar/Corona/P3Q) + Corona relabel
Decomplect the PQ finality lanes into a typed, impossible-to-confuse model where
KIND chooses the verifier and SUITE only chooses parameterization (fail-closed on
mismatch). Kills the prior conflation where the corona-backed lattice lane was
mislabeled "Pulse/Pulsar-SHA3".

Four strict evidence kinds — each its own verifier + suite + key registry:
  beam-bls                BLS12-381 aggregate (fast classical)
  pulsar-threshold-mldsa  threshold ML-DSA, verified as a STANDARD FIPS-204
                          ML-DSA signature under a group public key; the TALUS
                          dealerless machinery is entirely offline (VerifyPulsar
                          imports only mldsa65 — enforced by an import-hygiene test)
  corona-ringtail         Ringtail/Module-LWE lattice threshold (the corona kernel)
  p3q-mldsa-rollup        succinct rollup of independent ML-DSA-65 sigs; strict
                          ONLY when its proof system is PQ (classical SNARK gated)
Plus the raw mldsa-cert-set as a NON-strict availability/audit artifact.

Subject-agnostic verifiers take (subject, evidence, keyEra): one dispatch serves
the warp cross-chain digest D and the consensus finality subject
  M = keccak256("QUASAR_FINALITY_V1" || chainID || height || round || blockID ||
      stateRoot || signerSetID || keyEraID || generation || pChainHeight || policyID)
folding generation + pChainHeight + policyID so a signature binds its era, its
validator snapshot, and its tier (tier-downgrade replay fails closed).

Policy tiers (BLS_FAST / HYBRID_PQ_CHECKPOINT / STRICT_QUASAR / RECOVERY) select
which lanes are required — orthogonal to verification and to keys. PulsarKeyEra
and CoronaKeyEra are symmetric but DISTINCT registry types; P3Q/cert-set resolve a
per-validator SignerSetAuthority — no resolver can alias another's key material.
Offline signers (pulsard, coronad, P3Q prover) are interfaces only, never imported
by the verify path.

Wire unchanged: D, the Message c14n, messageDST, the ZAP magic and kind bytes are
byte-identical (forge Go<->Solidity equality holds; golden envelope SHA unchanged).
The corona lane DST is renamed pulseDST->coronaDST (no deployed corona sigs;
envelope KAT regenerated).

22 tests green: non-confusable dispatch, suite/kind fail-closed, Pulsar import
hygiene, subject-identity across lanes, policyID downgrade, key-era distinctness,
P3Q-classical-root strict gate.
2026-06-27 13:47:13 -07:00

78 lines
3.1 KiB
Go

// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// resolver_distinctness_test.go — proves the THREE per-lane key registries are
// structurally DISTINCT types, so no implementation can ever serve two roles
// and Pulsar ↔ Corona ↔ P3Q key material can never be aliased. This lives in
// package pulsar because it is the only place that can see all three at once:
// warp.PulsarKeyEraResolver (one threshold ML-DSA group key),
// pulsar.CoronaGroupKeyResolver (one threshold lattice group key), and
// warp.SignerSetAuthority (independent per-validator keys for P3Q / cert-set).
package pulsar
import (
"testing"
corona "github.com/luxfi/corona/threshold"
"github.com/luxfi/ids"
"github.com/luxfi/warp"
"github.com/stretchr/testify/require"
)
// Each fake implements EXACTLY ONE of the three resolver interfaces.
type onlyPulsarEra struct{}
func (onlyPulsarEra) ResolvePulsarKeyEra(ids.ID, uint64, uint64) (warp.PulsarKeyEra, error) {
return warp.PulsarKeyEra{}, nil
}
type onlyCoronaResolver struct{}
func (onlyCoronaResolver) ResolveGroupKey([32]byte, uint64, uint64) (*corona.GroupKey, string, error) {
return nil, "", nil
}
type onlySignerSet struct{}
func (onlySignerSet) ResolveSignerSet(ids.ID, uint64) ([]warp.ValidatorMLDSAKey, uint64, error) {
return nil, 0, nil
}
// TestPulsarAndCoronaUseDistinctKeyResolvers proves an implementation of one
// lane's key registry can NEVER satisfy another lane's registry interface.
func TestPulsarAndCoronaUseDistinctKeyResolvers(t *testing.T) {
var pulsarEra any = onlyPulsarEra{}
var coronaRes any = onlyCoronaResolver{}
var signerSet any = onlySignerSet{}
// Each satisfies its OWN interface.
_, ok := pulsarEra.(warp.PulsarKeyEraResolver)
require.True(t, ok, "Pulsar fake must implement PulsarKeyEraResolver")
_, ok = coronaRes.(CoronaGroupKeyResolver)
require.True(t, ok, "Corona fake must implement CoronaGroupKeyResolver")
_, ok = signerSet.(warp.SignerSetAuthority)
require.True(t, ok, "SignerSet fake must implement SignerSetAuthority")
// A Pulsar key-era resolver is NEITHER a Corona resolver NOR a signer-set
// authority — the registries cannot be confused.
_, ok = pulsarEra.(CoronaGroupKeyResolver)
require.False(t, ok, "Pulsar resolver must not alias the Corona resolver")
_, ok = pulsarEra.(warp.SignerSetAuthority)
require.False(t, ok, "Pulsar resolver must not alias the signer-set authority")
// A Corona resolver is NEITHER a Pulsar key-era resolver NOR a signer-set
// authority.
_, ok = coronaRes.(warp.PulsarKeyEraResolver)
require.False(t, ok, "Corona resolver must not alias the Pulsar resolver")
_, ok = coronaRes.(warp.SignerSetAuthority)
require.False(t, ok, "Corona resolver must not alias the signer-set authority")
// A signer-set authority (P3Q / cert-set) is NEITHER threshold resolver.
_, ok = signerSet.(warp.PulsarKeyEraResolver)
require.False(t, ok, "signer-set authority must not alias the Pulsar resolver")
_, ok = signerSet.(CoronaGroupKeyResolver)
require.False(t, ok, "signer-set authority must not alias the Corona resolver")
}