mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
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)
43 lines
1.3 KiB
Go
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
|
|
}
|