Files
zeekay d58a1e0f6b quasar: wire Polaris cert profile composing pulsar + corona + magnetar
Audit found: the QuasarCert struct previously declared a Pulsar field
that was never serialized, and had no Magnetar slot at all — the cert
wire codec only carried BLS + Corona + MLDSARollup (three legs). The
papers/lux-quasar-composition profile registry §04 names three
profiles:

  Pulsar   — BLS ‖ Puls ‖ ZK            (minimum PQ posture)
  Aurora   — BLS ‖ Puls ‖ Cor ‖ ZK      (intra-lattice diversity)
  Polaris  — BLS ‖ Puls ‖ Cor ‖ Mag ‖ ZK (cross-family maximum)

The pre-change cert could not represent Polaris on the wire, and the
Pulsar field was structurally aspirational. This change makes the
"double lattice + hash-based" PQ defense-in-depth real:

* QuasarCert gains a Magnetar []byte slot and serializes all five
  legs (BLS + Corona + Pulsar + Magnetar + MLDSARollup) under a new
  scheme byte 0x05 (forward-only — no back-compat per "forward
  perfection" rule).

* polaris.go adds ComposePolaris(PolarisLegs) — pure-function cert
  composer that consumes already-completed signing outputs from each
  of the four primitives and emits one QuasarCert. Corona and Pulsar
  serialize via the canonical CORS / PULS wire codecs (luxfi/corona
  v0.7.6 and luxfi/pulsar v1.0.23). Magnetar serializes via
  EncodeMagnetarAggregate (Mode + N + signers + pubkeys + sigs,
  parallel-slices form matching magnetar.ValidatorAggregateCert).

* VerifyWithRealKeysPolaris extends VerifyWithRealKeys with two new
  legs: the Pulsar leg routes through pulsar.VerifyBytes (stateless
  PULG/PULS verifier) and the Magnetar leg routes through
  magnetar.VerifyAggregateCert with quorum = every-signer-verifies.

* corona_gob.go switched from a local ring-poly length-prefix encoding
  to the canonical CORS Signature.MarshalBinary wire codec, so the
  cert's Corona slot carries exactly what the corona/threshold v0.7.6
  verifier expects.

* go.mod adds direct requires for luxfi/magnetar v0.5.2 and
  luxfi/pulsar v1.0.23, and bumps luxfi/corona v0.7.5 → v0.7.6 to
  pick up the CORS wire codec.

Gate test TestQuasarCert_ComposesAllThreeSchemes constructs a real
(3, 2) Pulsar DKG + threshold-sign ceremony, a real Corona
trusted-dealer threshold sign, and three real Magnetar per-validator
standalone SLH-DSA signatures. It composes them into a QuasarCert,
round-trips through the 5-leg wire codec, verifies under
VerifyWithRealKeysPolaris, and tamper-checks each PQ leg. PASS in
~75s.

Production status today:
  Pulsar profile = wired (Pulsar field now serializes)
  Aurora profile = wired (Corona slot already carried CORS bytes;
                          now under the canonical v0.7.6 wire codec)
  Polaris profile = wired (this change)
2026-06-01 12:31:14 -07:00

43 lines
1.3 KiB
Go

// Copyright (C) 2025-2026, Lux Industries Inc. All rights reserved.
package quasar
import (
coronaThreshold "github.com/luxfi/threshold/protocols/corona"
)
// coronaGobEncode serializes a Corona threshold signature via the
// canonical CORS wire codec exposed by corona/threshold.Signature.
// The legacy name is preserved for caller compatibility; the encoder
// is now the v0.7.6 wire codec (4-byte magic "CORS" + 2-byte version
// + length-prefixed ring polynomial bytes). The receiver verifies
// with coronaThreshold.Verify after decoding through coronaGobDecode.
//
// Returns nil on encoder error; callers treat nil as "no signature
// available" and the round driver falls back to the next-lower
// witness level.
func coronaGobEncode(sig *coronaThreshold.Signature) []byte {
if sig == nil {
return nil
}
out, err := sig.MarshalBinary()
if err != nil {
return nil
}
return out
}
// coronaGobDecode is the inverse of coronaGobEncode. Strict
// trailing-bytes policy is enforced by the underlying CORS wire
// codec.
func coronaGobDecode(data []byte) (*coronaThreshold.Signature, error) {
if len(data) == 0 {
return nil, ErrCertCorrupt
}
out := &coronaThreshold.Signature{}
if err := out.UnmarshalBinary(data); err != nil {
return nil, ErrCertCorrupt
}
return out, nil
}