mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
quasar: kill all remaining Ringtail identifiers; rename test/bench helpers
Final identifier sweep. After this commit zero 'Ringtail' / 'RINGTAIL'
references remain in any Go file in the consensus repo. Surface
changes (compound-identifier camelCase):
bench:
pqModesRingtailCounts → pqModesCoronaCounts
ringtailMaxRetries → coronaMaxRetries
ringtailFixture → coronaFixture
newRingtailFixture → newCoronaFixture
BenchmarkPQModes_BLSPlusRingtail → BenchmarkPQModes_BLSPlusCorona
protocol/quasar:
RingtailSignature → CoronaSignature
RingtailRound1Data → CoronaRound1Data
RingtailRound1State→ CoronaRound1State
RingtailBits → CoronaBits
RingtailProof → CoronaProof
RingtailAggregated → CoronaAggregated
verifyRingtailThreshold → verifyCoronaThreshold
ringtailCount/Bits/ShareMap → coronaCount/Bits/ShareMap
TestQuantumFinalityWithRingtail → TestQuantumFinalityWithCorona
TestGenerateCert_RefusesPartialTriple_WithSigner_NoRingtail
→ TestGenerateCert_RefusesPartialTriple_WithSigner_NoCorona
TestQuasarCert_Verify_RejectsMissingRingtail
→ TestQuasarCert_Verify_RejectsMissingCorona
TestVerkleWitness_VerifyRingtailThreshold
→ TestVerkleWitness_VerifyCoronaThreshold
TestVerkleWitness_FullVerification_RingtailThresholdNotMet
→ TestVerkleWitness_FullVerification_CoronaThresholdNotMet
TestRingtailCertSize_BinaryVsGob → TestCoronaCertSize_BinaryVsGob
TestNoRingtailDirectImport → TestNoCoronaDirectImport
file rename: ringtail_death_test.go → corona_death_test.go
TestQuasar_ValidatorSetSync_BLSAndRingtail
→ TestQuasar_ValidatorSetSync_BLSAndCorona
engine/pq:
CompleteRingtailRound2 → CompleteCoronaRound2
GetRingtailGroupKey → GetCoronaGroupKey
TestGetRingtailGroupKey → TestGetCoronaGroupKey
ringtailShare/Signer/Group → coronaShare/Signer/Group
pkg/wire:
SigRingtail → SigCorona
TestQuantumPolicyRingtailOnlyRTNotRequired
→ TestQuantumPolicyCoronaOnlyRTNotRequired
ringtailHash → coronaHash
Parallel Ring+Module Double-Lattice PQ posture stands: QuasarCert
carries both Corona (Ring-LWE) and Pulsar (Module-LWE) bytes,
checkable independently. Pure-PQ profile drops BLS entirely.
Tests green: quasar 42s, engine/pq 2s, bench 1s, wire 2s, config 1s.
This commit is contained in:
@@ -45,17 +45,17 @@ import (
|
||||
// per-validator linear paths (notably ML-DSA-65 = 3309 B per validator).
|
||||
var pqModesValidatorCounts = []int{4, 21, 64, 100}
|
||||
|
||||
// pqModesRingtailCounts is the validator-set sizes used for Corona-bearing
|
||||
// pqModesCoronaCounts is the validator-set sizes used for Corona-bearing
|
||||
// modes. n=4 is excluded because the Ring-LWE rejection sampler is known
|
||||
// flaky at that group size (see consensus CLAUDE.md). n=100 is excluded
|
||||
// because a single full 2-round Corona signing pass takes 5+ minutes
|
||||
// at that group size; the bench instead measures n in {21, 64} which is
|
||||
// where the shape of the cost curve is informative.
|
||||
var pqModesRingtailCounts = []int{21, 64}
|
||||
var pqModesCoronaCounts = []int{21, 64}
|
||||
|
||||
// ringtailMaxRetries bounds how many times we re-run Round1/Round2/Finalize
|
||||
// coronaMaxRetries bounds how many times we re-run Round1/Round2/Finalize
|
||||
// when verify fails (Corona rejection-sampling is nondeterministic).
|
||||
const ringtailMaxRetries = 4
|
||||
const coronaMaxRetries = 4
|
||||
|
||||
// modeMetrics is the per-mode per-n result row aggregated by the suite.
|
||||
type modeMetrics struct {
|
||||
@@ -302,11 +302,11 @@ func BenchmarkPQModes_BLSPlusMLDSA(b *testing.B) {
|
||||
// Mode 3: BLS + Corona (lattice threshold, O(1) cert in N)
|
||||
// =============================================================================
|
||||
|
||||
// ringtailFixture holds a fully-keyed Corona group plus a parallel BLS
|
||||
// coronaFixture holds a fully-keyed Corona group plus a parallel BLS
|
||||
// keyset. We re-use the dual_threshold_test.go flow: GenerateDualKeys
|
||||
// gives us BLS-threshold + Corona-threshold shares for a (t, n) group,
|
||||
// and we drive Round1 / Round2 / Finalize to produce a real signature.
|
||||
type ringtailFixture struct {
|
||||
type coronaFixture struct {
|
||||
cfg *quasar.SignerConfig
|
||||
signer *quasar.Signer
|
||||
rtSigners []*coronaThreshold.Signer
|
||||
@@ -317,7 +317,7 @@ type ringtailFixture struct {
|
||||
n int
|
||||
}
|
||||
|
||||
func newRingtailFixture(t, n int) (*ringtailFixture, error) {
|
||||
func newCoronaFixture(t, n int) (*coronaFixture, error) {
|
||||
cfg, err := quasar.GenerateDualKeys(t, n)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateDualKeys(%d,%d): %w", t, n, err)
|
||||
@@ -338,7 +338,7 @@ func newRingtailFixture(t, n int) (*ringtailFixture, error) {
|
||||
rtIDs[i] = i
|
||||
}
|
||||
|
||||
return &ringtailFixture{
|
||||
return &coronaFixture{
|
||||
cfg: cfg,
|
||||
signer: s,
|
||||
rtSigners: rtSigners,
|
||||
@@ -359,11 +359,11 @@ type signResult struct {
|
||||
}
|
||||
|
||||
// signWithRetry re-runs signOnce until the produced Corona signature
|
||||
// verifies, up to ringtailMaxRetries attempts. Returns (result, attempts,
|
||||
// verifies, up to coronaMaxRetries attempts. Returns (result, attempts,
|
||||
// error). Used because Corona rejection sampling is nondeterministic.
|
||||
func (f *ringtailFixture) signWithRetry(msg []byte, prfKey []byte, groupKey *coronaThreshold.GroupKey) (*signResult, int, error) {
|
||||
func (f *coronaFixture) signWithRetry(msg []byte, prfKey []byte, groupKey *coronaThreshold.GroupKey) (*signResult, int, error) {
|
||||
var lastErr error
|
||||
for i := 0; i < ringtailMaxRetries; i++ {
|
||||
for i := 0; i < coronaMaxRetries; i++ {
|
||||
res, err := f.signOnce(msg, i+1, prfKey)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
@@ -374,12 +374,12 @@ func (f *ringtailFixture) signWithRetry(msg []byte, prfKey []byte, groupKey *cor
|
||||
}
|
||||
lastErr = fmt.Errorf("Corona verify failed on attempt %d", i+1)
|
||||
}
|
||||
return nil, ringtailMaxRetries, lastErr
|
||||
return nil, coronaMaxRetries, lastErr
|
||||
}
|
||||
|
||||
// signOnce runs the Corona 2-round flow once and returns the resulting
|
||||
// signature alongside the BLS aggregate over the same message.
|
||||
func (f *ringtailFixture) signOnce(msg []byte, sessionID int, prfKey []byte) (*signResult, error) {
|
||||
func (f *coronaFixture) signOnce(msg []byte, sessionID int, prfKey []byte) (*signResult, error) {
|
||||
round1 := make(map[int]*coronaThreshold.Round1Data, f.n)
|
||||
for _, s := range f.rtSigners {
|
||||
d := s.Round1(sessionID, prfKey, f.rtSignerIDs)
|
||||
@@ -409,8 +409,8 @@ func (f *ringtailFixture) signOnce(msg []byte, sessionID int, prfKey []byte) (*s
|
||||
return &signResult{rtSig: rtSig, rtBytes: rtBytes, blsAgg: blsAgg, blsAggPK: blsAggPK}, nil
|
||||
}
|
||||
|
||||
func BenchmarkPQModes_BLSPlusRingtail(b *testing.B) {
|
||||
for _, n := range pqModesRingtailCounts {
|
||||
func BenchmarkPQModes_BLSPlusCorona(b *testing.B) {
|
||||
for _, n := range pqModesCoronaCounts {
|
||||
n := n
|
||||
b.Run(fmt.Sprintf("n%d", n), func(b *testing.B) {
|
||||
t := (2*n + 2) / 3 // ~2/3 threshold (BFT)
|
||||
@@ -420,7 +420,7 @@ func BenchmarkPQModes_BLSPlusRingtail(b *testing.B) {
|
||||
if t >= n {
|
||||
t = n - 1
|
||||
}
|
||||
fix, err := newRingtailFixture(t, n)
|
||||
fix, err := newCoronaFixture(t, n)
|
||||
if err != nil {
|
||||
b.Skipf("Corona fixture for n=%d failed: %v", n, err)
|
||||
return
|
||||
@@ -539,7 +539,7 @@ func BenchmarkPQModes_BLSPlusGroth16(b *testing.B) {
|
||||
// =============================================================================
|
||||
|
||||
func BenchmarkPQModes_TripleQuantum(b *testing.B) {
|
||||
for _, n := range pqModesRingtailCounts {
|
||||
for _, n := range pqModesCoronaCounts {
|
||||
n := n
|
||||
b.Run(fmt.Sprintf("n%d", n), func(b *testing.B) {
|
||||
t := (2*n + 2) / 3
|
||||
@@ -549,7 +549,7 @@ func BenchmarkPQModes_TripleQuantum(b *testing.B) {
|
||||
if t >= n {
|
||||
t = n - 1
|
||||
}
|
||||
fix, err := newRingtailFixture(t, n)
|
||||
fix, err := newCoronaFixture(t, n)
|
||||
if err != nil {
|
||||
b.Skipf("Corona fixture for n=%d failed: %v", n, err)
|
||||
return
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ func (p Parameters) PostQuantum() bool {
|
||||
// true -> PQModeTripleQuantum // strongest available
|
||||
// false -> PQModeBLSOnly // classical fast path
|
||||
//
|
||||
// For middle-ground modes (BLSPlusMLDSA, BLSPlusRingtail, BLSPlusGroth16),
|
||||
// For middle-ground modes (BLSPlusMLDSA, BLSPlusCorona, BLSPlusGroth16),
|
||||
// call WithPQMode directly with the desired constant.
|
||||
func (p Parameters) WithPostQuantum(on bool) Parameters {
|
||||
p.PQMode = PQModeFromBool(on)
|
||||
|
||||
+22
-22
@@ -23,9 +23,9 @@ type CertificateGenerator struct {
|
||||
blsPublicKey *bls.PublicKey
|
||||
|
||||
// Corona threshold signing
|
||||
ringtailShare *threshold.KeyShare
|
||||
ringtailSigner *threshold.Signer
|
||||
ringtailGroup *threshold.GroupKey
|
||||
coronaShare *threshold.KeyShare
|
||||
coronaSigner *threshold.Signer
|
||||
coronaGroup *threshold.GroupKey
|
||||
|
||||
// ML-DSA-65 identity key (FIPS 204).
|
||||
mldsaSecret *mldsa.PrivateKey
|
||||
@@ -54,9 +54,9 @@ func NewCertificateGenerator(blsKey, pqKey []byte) *CertificateGenerator {
|
||||
// The pqKey seeds the random generation
|
||||
shares, groupKey, err := threshold.GenerateKeys(2, 3, nil)
|
||||
if err == nil && len(shares) > 0 {
|
||||
cg.ringtailShare = shares[0]
|
||||
cg.ringtailGroup = groupKey
|
||||
cg.ringtailSigner = threshold.NewSigner(shares[0])
|
||||
cg.coronaShare = shares[0]
|
||||
cg.coronaGroup = groupKey
|
||||
cg.coronaSigner = threshold.NewSigner(shares[0])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,9 +78,9 @@ func (cg *CertificateGenerator) InitializeThreshold(share *threshold.KeyShare) {
|
||||
cg.mu.Lock()
|
||||
defer cg.mu.Unlock()
|
||||
|
||||
cg.ringtailShare = share
|
||||
cg.ringtailGroup = share.GroupKey
|
||||
cg.ringtailSigner = threshold.NewSigner(share)
|
||||
cg.coronaShare = share
|
||||
cg.coronaGroup = share.GroupKey
|
||||
cg.coronaSigner = threshold.NewSigner(share)
|
||||
}
|
||||
|
||||
// GenerateBLSSignature generates a real BLS signature for a block.
|
||||
@@ -171,16 +171,16 @@ func (cg *CertificateGenerator) GeneratePQCertificate(blockID ids.ID, sessionID
|
||||
cg.mu.RLock()
|
||||
defer cg.mu.RUnlock()
|
||||
|
||||
if cg.ringtailSigner == nil {
|
||||
if cg.coronaSigner == nil {
|
||||
return nil, fmt.Errorf("Corona signer not initialized")
|
||||
}
|
||||
|
||||
round1 := cg.ringtailSigner.Round1(sessionID, prfKey, signers)
|
||||
round1 := cg.coronaSigner.Round1(sessionID, prfKey, signers)
|
||||
return round1, nil
|
||||
}
|
||||
|
||||
// CompleteRingtailRound2 performs round 2 of Corona signing.
|
||||
func (cg *CertificateGenerator) CompleteRingtailRound2(
|
||||
// CompleteCoronaRound2 performs round 2 of Corona signing.
|
||||
func (cg *CertificateGenerator) CompleteCoronaRound2(
|
||||
sessionID int,
|
||||
message string,
|
||||
prfKey []byte,
|
||||
@@ -190,23 +190,23 @@ func (cg *CertificateGenerator) CompleteRingtailRound2(
|
||||
cg.mu.RLock()
|
||||
defer cg.mu.RUnlock()
|
||||
|
||||
if cg.ringtailSigner == nil {
|
||||
if cg.coronaSigner == nil {
|
||||
return nil, fmt.Errorf("Corona signer not initialized")
|
||||
}
|
||||
|
||||
return cg.ringtailSigner.Round2(sessionID, message, prfKey, signers, round1Data)
|
||||
return cg.coronaSigner.Round2(sessionID, message, prfKey, signers, round1Data)
|
||||
}
|
||||
|
||||
// FinalizeRingtailSignature aggregates round 2 data into final signature.
|
||||
func (cg *CertificateGenerator) FinalizeRingtailSignature(round2Data map[int]*threshold.Round2Data) (*threshold.Signature, error) {
|
||||
// FinalizeCoronaSignature aggregates round 2 data into final signature.
|
||||
func (cg *CertificateGenerator) FinalizeCoronaSignature(round2Data map[int]*threshold.Round2Data) (*threshold.Signature, error) {
|
||||
cg.mu.RLock()
|
||||
defer cg.mu.RUnlock()
|
||||
|
||||
if cg.ringtailSigner == nil {
|
||||
if cg.coronaSigner == nil {
|
||||
return nil, fmt.Errorf("Corona signer not initialized")
|
||||
}
|
||||
|
||||
return cg.ringtailSigner.Finalize(round2Data)
|
||||
return cg.coronaSigner.Finalize(round2Data)
|
||||
}
|
||||
|
||||
// GetBLSPublicKey returns the BLS public key bytes.
|
||||
@@ -220,11 +220,11 @@ func (cg *CertificateGenerator) GetBLSPublicKey() []byte {
|
||||
return bls.PublicKeyToCompressedBytes(cg.blsPublicKey)
|
||||
}
|
||||
|
||||
// GetRingtailGroupKey returns the Corona group public key.
|
||||
func (cg *CertificateGenerator) GetRingtailGroupKey() *threshold.GroupKey {
|
||||
// GetCoronaGroupKey returns the Corona group public key.
|
||||
func (cg *CertificateGenerator) GetCoronaGroupKey() *threshold.GroupKey {
|
||||
cg.mu.RLock()
|
||||
defer cg.mu.RUnlock()
|
||||
return cg.ringtailGroup
|
||||
return cg.coronaGroup
|
||||
}
|
||||
|
||||
// VerifyBLSAggregate verifies a BLS aggregate signature against public keys.
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestNewCertificateGenerator(t *testing.T) {
|
||||
// Keys are now internal - verify they were initialized by checking derived values
|
||||
require.NotNil(t, cg.blsSecretKey)
|
||||
require.NotNil(t, cg.blsPublicKey)
|
||||
require.NotNil(t, cg.ringtailGroup)
|
||||
require.NotNil(t, cg.coronaGroup)
|
||||
}
|
||||
|
||||
func TestNewCertificateGenerator_ShortKeys(t *testing.T) {
|
||||
@@ -37,7 +37,7 @@ func TestNewCertificateGenerator_ShortKeys(t *testing.T) {
|
||||
|
||||
require.NotNil(t, cg)
|
||||
require.Nil(t, cg.blsSecretKey) // Too short to initialize
|
||||
require.Nil(t, cg.ringtailGroup)
|
||||
require.Nil(t, cg.coronaGroup)
|
||||
}
|
||||
|
||||
func TestGenerateBLSSignature(t *testing.T) {
|
||||
@@ -255,19 +255,19 @@ func TestGetBLSPublicKey_NoKey(t *testing.T) {
|
||||
require.Nil(t, pubKey)
|
||||
}
|
||||
|
||||
func TestGetRingtailGroupKey(t *testing.T) {
|
||||
func TestGetCoronaGroupKey(t *testing.T) {
|
||||
blsKey, pqKey := GenerateTestKeys()
|
||||
cg := NewCertificateGenerator(blsKey, pqKey)
|
||||
|
||||
groupKey := cg.GetRingtailGroupKey()
|
||||
groupKey := cg.GetCoronaGroupKey()
|
||||
|
||||
require.NotNil(t, groupKey)
|
||||
}
|
||||
|
||||
func TestGetRingtailGroupKey_NoKey(t *testing.T) {
|
||||
func TestGetCoronaGroupKey_NoKey(t *testing.T) {
|
||||
cg := NewCertificateGenerator(nil, nil)
|
||||
|
||||
groupKey := cg.GetRingtailGroupKey()
|
||||
groupKey := cg.GetCoronaGroupKey()
|
||||
|
||||
require.Nil(t, groupKey)
|
||||
}
|
||||
@@ -377,12 +377,12 @@ func TestInitializeThreshold(t *testing.T) {
|
||||
cg := NewCertificateGenerator(blsKey, pqKey)
|
||||
|
||||
// Get the existing share
|
||||
existingGroup := cg.GetRingtailGroupKey()
|
||||
existingGroup := cg.GetCoronaGroupKey()
|
||||
require.NotNil(t, existingGroup)
|
||||
|
||||
// The internal share should exist after construction
|
||||
require.NotNil(t, cg.ringtailShare)
|
||||
require.NotNil(t, cg.ringtailSigner)
|
||||
require.NotNil(t, cg.coronaShare)
|
||||
require.NotNil(t, cg.coronaSigner)
|
||||
}
|
||||
|
||||
func BenchmarkGenerateBLSSignature(b *testing.B) {
|
||||
|
||||
@@ -128,7 +128,7 @@ const (
|
||||
SigNone byte = 0x00
|
||||
SigEd25519 byte = 0x01
|
||||
SigBLS byte = 0x02
|
||||
SigRingtail byte = 0x03
|
||||
SigCorona byte = 0x03
|
||||
SigQuasar byte = 0x04 // BLS + Corona (Quasar protocol)
|
||||
)
|
||||
|
||||
|
||||
@@ -128,9 +128,9 @@ func TestCertificate_TranscriptHash_BindsHashSuiteID(t *testing.T) {
|
||||
corona := NewCertificateWithSuite(candidateID, 100, PolicyPQ, HashSuiteBLAKE3Legacy, []byte("p"))
|
||||
|
||||
pulsarHash := pulsar.TranscriptHash()
|
||||
ringtailHash := corona.TranscriptHash()
|
||||
coronaHash := corona.TranscriptHash()
|
||||
|
||||
if pulsarHash == ringtailHash {
|
||||
if pulsarHash == coronaHash {
|
||||
t.Fatalf("transcript hash collides across HashSuiteID: Pulsar(SHA3-NIST) and Corona(BLAKE3-legacy) share PolicyPQ; F1 fix requires HashSuiteID to break the digest")
|
||||
}
|
||||
|
||||
|
||||
@@ -534,7 +534,7 @@ func (p *QuantumPolicy) OnVote(ctx context.Context, vote *Vote) error {
|
||||
p.blsVotes[vote.CandidateID] = make(map[VoterID][]byte)
|
||||
}
|
||||
p.blsVotes[vote.CandidateID][vote.VoterID] = vote.Signature[1:] // Skip scheme byte
|
||||
case SigRingtail:
|
||||
case SigCorona:
|
||||
// Only allowed if requireRT is false
|
||||
if p.pqVotes[vote.CandidateID] == nil {
|
||||
p.pqVotes[vote.CandidateID] = make(map[VoterID][]byte)
|
||||
@@ -585,8 +585,8 @@ func sigSchemeToString(scheme byte) string {
|
||||
return "SigEd25519"
|
||||
case SigBLS:
|
||||
return "SigBLS"
|
||||
case SigRingtail:
|
||||
return "SigRingtail"
|
||||
case SigCorona:
|
||||
return "SigCorona"
|
||||
case SigQuasar:
|
||||
return "SigQuasar"
|
||||
default:
|
||||
|
||||
@@ -662,14 +662,14 @@ func TestQuantumPolicyUnknownSchemeRTNotRequired(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuantumPolicyRingtailOnlyRTNotRequired(t *testing.T) {
|
||||
func TestQuantumPolicyCoronaOnlyRTNotRequired(t *testing.T) {
|
||||
policy := NewQuantumPolicyWithOptions(1, false)
|
||||
ctx := context.Background()
|
||||
c := NewCandidate([]byte("d"), []byte("p"), EmptyCandidateID, 1)
|
||||
policy.OnCandidate(ctx, c)
|
||||
|
||||
vote := NewVote(c.ID, DeriveVoterID("a", []byte("v")), 0, true)
|
||||
vote.Signature = []byte{SigRingtail, 4, 5, 6}
|
||||
vote.Signature = []byte{SigCorona, 4, 5, 6}
|
||||
err := policy.OnVote(ctx, vote)
|
||||
if err != nil {
|
||||
t.Errorf("RT-only vote should be accepted when RT not required: %v", err)
|
||||
@@ -686,7 +686,7 @@ func TestSigSchemeToString(t *testing.T) {
|
||||
{SigNone, "SigNone"},
|
||||
{SigEd25519, "SigEd25519"},
|
||||
{SigBLS, "SigBLS"},
|
||||
{SigRingtail, "SigRingtail"},
|
||||
{SigCorona, "SigCorona"},
|
||||
{SigQuasar, "SigQuasar"},
|
||||
{0xFF, "Unknown"},
|
||||
}
|
||||
|
||||
@@ -426,7 +426,7 @@ func TestQuantumPolicyRTEnforcement(t *testing.T) {
|
||||
|
||||
// Test 2: Corona-only vote should also be rejected
|
||||
rtVote := NewVote(candidate.ID, voter1, 0, true)
|
||||
rtVote.Signature = []byte{SigRingtail, 4, 5, 6} // Corona only
|
||||
rtVote.Signature = []byte{SigCorona, 4, 5, 6} // Corona only
|
||||
|
||||
err = policy.OnVote(ctx, rtVote)
|
||||
if err == nil {
|
||||
|
||||
@@ -10,12 +10,12 @@ import (
|
||||
coronaThreshold "github.com/luxfi/corona/threshold"
|
||||
)
|
||||
|
||||
// TestRingtailCertSize_BinaryVsGob measures the on-wire Pulsar/Corona
|
||||
// TestCoronaCertSize_BinaryVsGob measures the on-wire Pulsar/Corona
|
||||
// signature size produced by the native binary encoder vs the legacy gob
|
||||
// encoder, for the production parameter set (M=8, N=7, LogN=8 -> ring
|
||||
// degree 256, Q=0x1000000004A01 48-bit prime). Reports per-cert and
|
||||
// 10K-cert storage so we can see the gob -> native delta.
|
||||
func TestRingtailCertSize_BinaryVsGob(t *testing.T) {
|
||||
func TestCoronaCertSize_BinaryVsGob(t *testing.T) {
|
||||
cfg, err := GenerateDualKeys(2, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateDualKeys: %v", err)
|
||||
|
||||
@@ -1052,7 +1052,7 @@ func TestWitnessProof_Size(t *testing.T) {
|
||||
Path: make([]byte, 16),
|
||||
OpeningProof: make([]byte, 32),
|
||||
BLSAggregate: make([]byte, 96),
|
||||
RingtailBits: make([]byte, 4),
|
||||
CoronaBits: make([]byte, 4),
|
||||
ValidatorSet: make([]byte, 32),
|
||||
BlockHeight: 100,
|
||||
StateRoot: make([]byte, 32),
|
||||
@@ -1093,7 +1093,7 @@ func TestWitnessProof_Compress(t *testing.T) {
|
||||
w := &WitnessProof{
|
||||
Commitment: make([]byte, 32),
|
||||
OpeningProof: make([]byte, 32),
|
||||
RingtailBits: []byte{0xFF, 0x0F, 0x00, 0x01},
|
||||
CoronaBits: []byte{0xFF, 0x0F, 0x00, 0x01},
|
||||
BlockHeight: 0x12345678,
|
||||
Timestamp: 0xFEDCBA98,
|
||||
}
|
||||
@@ -1195,7 +1195,7 @@ func TestVerkleWitness_CheckPQFinality(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
witness := &WitnessProof{RingtailBits: tt.bits}
|
||||
witness := &WitnessProof{CoronaBits: tt.bits}
|
||||
got := w.checkPQFinality(witness)
|
||||
if got != tt.want {
|
||||
t.Errorf("checkPQFinality() = %v, want %v", got, tt.want)
|
||||
@@ -1204,7 +1204,7 @@ func TestVerkleWitness_CheckPQFinality(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerkleWitness_VerifyRingtailThreshold(t *testing.T) {
|
||||
func TestVerkleWitness_VerifyCoronaThreshold(t *testing.T) {
|
||||
w := NewVerkleWitness(2)
|
||||
|
||||
tests := []struct {
|
||||
@@ -1217,9 +1217,9 @@ func TestVerkleWitness_VerifyRingtailThreshold(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
got := w.verifyRingtailThreshold(tt.bits)
|
||||
got := w.verifyCoronaThreshold(tt.bits)
|
||||
if got != tt.want {
|
||||
t.Errorf("verifyRingtailThreshold(%v) = %v, want %v", tt.bits, got, tt.want)
|
||||
t.Errorf("verifyCoronaThreshold(%v) = %v, want %v", tt.bits, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1307,14 +1307,14 @@ func TestVerkleWitness_CreateWitness(t *testing.T) {
|
||||
t.Error("expected non-empty opening proof")
|
||||
}
|
||||
|
||||
if len(witness.RingtailBits) == 0 {
|
||||
if len(witness.CoronaBits) == 0 {
|
||||
t.Error("expected non-empty corona bits")
|
||||
}
|
||||
|
||||
// Check corona bits match signers
|
||||
expectedBits := compressToBitfield(signers)
|
||||
for i := range expectedBits {
|
||||
if witness.RingtailBits[i] != expectedBits[i] {
|
||||
if witness.CoronaBits[i] != expectedBits[i] {
|
||||
t.Error("corona bits mismatch")
|
||||
}
|
||||
}
|
||||
@@ -1346,7 +1346,7 @@ func TestVerkleWitness_VerifyStateTransition(t *testing.T) {
|
||||
Commitment: commitmentBytes[:],
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
RingtailBits: []byte{0x01}, // 1 signer meets threshold of 1
|
||||
CoronaBits: []byte{0x01}, // 1 signer meets threshold of 1
|
||||
BlockHeight: 100,
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
@@ -1364,7 +1364,7 @@ func TestVerkleWitness_VerifyStateTransition_InvalidCommitment(t *testing.T) {
|
||||
Commitment: []byte{1, 2, 3}, // Invalid commitment bytes
|
||||
Path: []byte{4, 5, 6},
|
||||
OpeningProof: []byte{7, 8, 9},
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
}
|
||||
|
||||
err := w.VerifyStateTransition(witness)
|
||||
@@ -1393,7 +1393,7 @@ func TestVerkleWitness_BatchVerify(t *testing.T) {
|
||||
Commitment: commitmentBytes[:],
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
}
|
||||
@@ -1421,7 +1421,7 @@ func TestVerkleWitness_BatchVerify_WithInvalid(t *testing.T) {
|
||||
Commitment: commitmentBytes[:],
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
|
||||
@@ -1430,7 +1430,7 @@ func TestVerkleWitness_BatchVerify_WithInvalid(t *testing.T) {
|
||||
Commitment: []byte{1, 2, 3}, // Invalid
|
||||
Path: []byte{4, 5, 6},
|
||||
OpeningProof: []byte{7, 8, 9},
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
}
|
||||
|
||||
witnesses := []*WitnessProof{validWitness, invalidWitness}
|
||||
@@ -1471,7 +1471,7 @@ func TestVerkleWitness_FullVerification(t *testing.T) {
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
BLSAggregate: blsSigBytes,
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
ValidatorSet: []byte{5, 6, 7, 8},
|
||||
BlockHeight: 100,
|
||||
StateRoot: stateRoot,
|
||||
@@ -1507,7 +1507,7 @@ func TestVerkleWitness_FullVerification_InsufficientThreshold(t *testing.T) {
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
BLSAggregate: blsSig, // Valid-length signature
|
||||
RingtailBits: []byte{0x01}, // Only 1 signer, need 5
|
||||
CoronaBits: []byte{0x01}, // Only 1 signer, need 5
|
||||
ValidatorSet: []byte{5, 6, 7, 8},
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
@@ -2355,7 +2355,7 @@ func TestVerkleWitness_VerifyVerkleCommitment_InvalidOpeningProof(t *testing.T)
|
||||
Commitment: commitmentBytes[:],
|
||||
Path: path,
|
||||
OpeningProof: []byte{1, 2, 3, 4, 5}, // Wrong proof
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
|
||||
@@ -2656,7 +2656,7 @@ func TestSigner_VerifyAggregatedSignature_BLSSignatureTamperedFail(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerkleWitness_FullVerification_RingtailThresholdNotMet(t *testing.T) {
|
||||
func TestVerkleWitness_FullVerification_CoronaThresholdNotMet(t *testing.T) {
|
||||
w := NewVerkleWitness(10) // High threshold
|
||||
w.assumePQFinal = false // Force full verification path
|
||||
|
||||
@@ -2684,7 +2684,7 @@ func TestVerkleWitness_FullVerification_RingtailThresholdNotMet(t *testing.T) {
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
BLSAggregate: blsSig, // Valid-length signature
|
||||
RingtailBits: []byte{0x01}, // Only 1 signer, need 10
|
||||
CoronaBits: []byte{0x01}, // Only 1 signer, need 10
|
||||
ValidatorSet: []byte{5, 6, 7, 8},
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
@@ -2866,7 +2866,7 @@ func TestVerkleWitness_VerifyStateTransition_FastPath(t *testing.T) {
|
||||
Commitment: commitmentBytes[:],
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
RingtailBits: []byte{0x01}, // 1 signer meets threshold
|
||||
CoronaBits: []byte{0x01}, // 1 signer meets threshold
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
|
||||
@@ -2898,7 +2898,7 @@ func TestVerkleWitness_VerifyStateTransition_SlowPath(t *testing.T) {
|
||||
Path: path,
|
||||
OpeningProof: openingProof,
|
||||
BLSAggregate: blsSigBytes,
|
||||
RingtailBits: []byte{0x01}, // 1 signer meets threshold
|
||||
CoronaBits: []byte{0x01}, // 1 signer meets threshold
|
||||
ValidatorSet: []byte{5, 6, 7, 8},
|
||||
StateRoot: stateRoot,
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ type QuantumBlock struct {
|
||||
SourceBlocks []*Block
|
||||
QuantumHash string
|
||||
BLSSignature []byte
|
||||
RingtailProof []byte // ML-DSA signature
|
||||
CoronaProof []byte // ML-DSA signature
|
||||
Timestamp time.Time
|
||||
CreatedAt time.Time // When this block entered the pending set
|
||||
ValidatorSigs map[string]*QuasarSig
|
||||
@@ -870,12 +870,12 @@ func (q *Quasar) VerifyQuasarSig(message []byte, sig *QuasarSig) bool {
|
||||
}
|
||||
|
||||
// CoronaRound1 executes Round 1 of the Corona threshold signing protocol.
|
||||
func (q *Quasar) CoronaRound1(validatorID string, sessionID int, prfKey []byte) (*RingtailRound1Data, error) {
|
||||
func (q *Quasar) CoronaRound1(validatorID string, sessionID int, prfKey []byte) (*CoronaRound1Data, error) {
|
||||
data, err := q.signer.CoronaRound1(validatorID, sessionID, prfKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RingtailRound1Data{PartyID: data.PartyID}, nil
|
||||
return &CoronaRound1Data{PartyID: data.PartyID}, nil
|
||||
}
|
||||
|
||||
// Internal helpers
|
||||
|
||||
@@ -95,7 +95,7 @@ func TestQuasar(t *testing.T) {
|
||||
processed, proofs, height)
|
||||
}
|
||||
|
||||
func TestQuantumFinalityWithRingtail(t *testing.T) {
|
||||
func TestQuantumFinalityWithCorona(t *testing.T) {
|
||||
// Test that Corona and BLS signatures work in parallel
|
||||
qa, err := NewQuasar(2)
|
||||
if err != nil {
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestNoRingtailDirectImport — fails if any non-test .go file in this
|
||||
// TestNoCoronaDirectImport — fails if any non-test .go file in this
|
||||
// package imports `github.com/luxfi/nasua/...` or invokes
|
||||
// corona.GenerateKeys (matched as a selector expression
|
||||
// `corona.GenerateKeys(...)` regardless of the package alias).
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
// Test files (*_test.go) are scanned too — the corona kernel is
|
||||
// equally forbidden from package tests so the cutover doesn't slip
|
||||
// back through a "just for the test" import.
|
||||
func TestNoRingtailDirectImport(t *testing.T) {
|
||||
func TestNoCoronaDirectImport(t *testing.T) {
|
||||
pkgDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("os.Getwd: %v", err)
|
||||
@@ -57,7 +57,7 @@ func TestNoRingtailDirectImport(t *testing.T) {
|
||||
// literals as part of the death-test guard — the regex /
|
||||
// fixture below would match itself otherwise.
|
||||
base := filepath.Base(f)
|
||||
if base == "ringtail_death_test.go" {
|
||||
if base == "corona_death_test.go" {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func TestNoRingtailDirectImport(t *testing.T) {
|
||||
// dot-imported alias, which we reject below by name.
|
||||
for _, f := range matches {
|
||||
base := filepath.Base(f)
|
||||
if base == "ringtail_death_test.go" {
|
||||
if base == "corona_death_test.go" {
|
||||
continue
|
||||
}
|
||||
src, err := os.ReadFile(f)
|
||||
@@ -522,7 +522,7 @@ func TestQuasar_UpdateValidatorSet(t *testing.T) {
|
||||
t.Log("Updated validator set: v2->inactive, added v3, v4")
|
||||
}
|
||||
|
||||
func TestQuasar_ValidatorSetSync_BLSAndRingtail(t *testing.T) {
|
||||
func TestQuasar_ValidatorSetSync_BLSAndCorona(t *testing.T) {
|
||||
q, err := NewQuasar(2)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
+14
-14
@@ -111,8 +111,8 @@ type SignerConfig struct {
|
||||
CoronaGroupKey *coronaThreshold.GroupKey
|
||||
}
|
||||
|
||||
// RingtailRound1State holds Round 1 data for all parties in a signing session.
|
||||
type RingtailRound1State struct {
|
||||
// CoronaRound1State holds Round 1 data for all parties in a signing session.
|
||||
type CoronaRound1State struct {
|
||||
SessionID int
|
||||
PRFKey []byte
|
||||
SignerIDs []int
|
||||
@@ -225,12 +225,12 @@ func GenerateDualKeys(t, n int) (*SignerConfig, error) {
|
||||
|
||||
// Convert to maps keyed by validator ID
|
||||
blsShareMap := make(map[string]threshold.KeyShare)
|
||||
ringtailShareMap := make(map[string]*coronaThreshold.KeyShare)
|
||||
coronaShareMap := make(map[string]*coronaThreshold.KeyShare)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
id := fmt.Sprintf("v%d", i)
|
||||
blsShareMap[id] = blsShares[i]
|
||||
ringtailShareMap[id] = coronaShares[i]
|
||||
coronaShareMap[id] = coronaShares[i]
|
||||
}
|
||||
|
||||
return &SignerConfig{
|
||||
@@ -238,7 +238,7 @@ func GenerateDualKeys(t, n int) (*SignerConfig, error) {
|
||||
TotalParties: n,
|
||||
BLSKeyShares: blsShareMap,
|
||||
BLSGroupKey: blsGroupKey,
|
||||
CoronaShares: ringtailShareMap,
|
||||
CoronaShares: coronaShareMap,
|
||||
CoronaGroupKey: coronaGroupKey,
|
||||
}, nil
|
||||
}
|
||||
@@ -301,8 +301,8 @@ func (s *signer) CoronaFinalize(validatorID string, round2Data map[int]*coronaTh
|
||||
return signer.Finalize(round2Data)
|
||||
}
|
||||
|
||||
// VerifyRingtailSignature verifies a Corona threshold signature.
|
||||
func (s *signer) VerifyRingtailSignature(message string, sig *coronaThreshold.Signature) bool {
|
||||
// VerifyCoronaSignature verifies a Corona threshold signature.
|
||||
func (s *signer) VerifyCoronaSignature(message string, sig *coronaThreshold.Signature) bool {
|
||||
if s.coronaGroupKey == nil || sig == nil {
|
||||
return false
|
||||
}
|
||||
@@ -319,10 +319,10 @@ func (s *signer) VerifyRingtailSignature(message string, sig *coronaThreshold.Si
|
||||
func (s *signer) DualSignRound1(ctx context.Context, validatorID string, message []byte, sessionID int, prfKey []byte) (*QuasarSig, *coronaThreshold.Round1Data, error) {
|
||||
s.mu.RLock()
|
||||
blsSigner, hasBLS := s.blsSigners[validatorID]
|
||||
_, hasRingtail := s.coronaSigners[validatorID]
|
||||
_, hasCorona := s.coronaSigners[validatorID]
|
||||
s.mu.RUnlock()
|
||||
|
||||
if !hasBLS || !hasRingtail {
|
||||
if !hasBLS || !hasCorona {
|
||||
return nil, nil, errors.New("validator not configured for dual signing")
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ func (s *signer) DualSignRound2(validatorID string, sessionID int, message strin
|
||||
func (s *signer) TripleSignRound1(ctx context.Context, validatorID string, message []byte, sessionID int, prfKey []byte) (*QuasarSig, *coronaThreshold.Round1Data, error) {
|
||||
s.mu.RLock()
|
||||
blsSigner, hasBLS := s.blsSigners[validatorID]
|
||||
_, hasRingtail := s.coronaSigners[validatorID]
|
||||
_, hasCorona := s.coronaSigners[validatorID]
|
||||
mldsaSK, hasMLDSA := s.mldsaKeys[validatorID]
|
||||
s.mu.RUnlock()
|
||||
|
||||
@@ -409,7 +409,7 @@ func (s *signer) TripleSignRound1(ctx context.Context, validatorID string, messa
|
||||
}
|
||||
|
||||
paths := 1 // BLS always
|
||||
if hasRingtail {
|
||||
if hasCorona {
|
||||
paths++
|
||||
}
|
||||
if hasMLDSA {
|
||||
@@ -424,7 +424,7 @@ func (s *signer) TripleSignRound1(ctx context.Context, validatorID string, messa
|
||||
}()
|
||||
|
||||
// Path 2: Corona Round 1 (PQ lattice threshold)
|
||||
if hasRingtail {
|
||||
if hasCorona {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
round1Data, rtErr = s.CoronaRound1(validatorID, sessionID, prfKey)
|
||||
@@ -598,7 +598,7 @@ func (s *signer) VerifyQuasarSig(message []byte, sig *QuasarSig) bool {
|
||||
|
||||
// VerifyQuasarSigWithContext verifies a signature.
|
||||
// Verifies all present paths: BLS (always), ML-DSA (when sig.MLDSA is non-empty).
|
||||
// Corona threshold verification is handled separately via VerifyRingtailSignature.
|
||||
// Corona threshold verification is handled separately via VerifyCoronaSignature.
|
||||
func (s *signer) VerifyQuasarSigWithContext(ctx context.Context, message []byte, sig *QuasarSig) bool {
|
||||
if ctx.Err() != nil {
|
||||
return false
|
||||
@@ -787,7 +787,7 @@ type QuasarSig struct {
|
||||
// AggregatedSignature contains aggregated signatures.
|
||||
type AggregatedSignature struct {
|
||||
BLSAggregated []byte
|
||||
RingtailAggregated []byte
|
||||
CoronaAggregated []byte
|
||||
ValidatorIDs []string
|
||||
SignerCount int
|
||||
IsThreshold bool
|
||||
|
||||
@@ -38,12 +38,12 @@ func TestGenerateCert_RefusesPartialTriple(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestGenerateCert_RefusesPartialTriple_WithSigner_NoRingtail proves
|
||||
// TestGenerateCert_RefusesPartialTriple_WithSigner_NoCorona proves
|
||||
// the realCert fallback path is also closed: a signer can produce a
|
||||
// BLS+MLDSA cert (Corona empty because aggregation is at the
|
||||
// BundleSigner layer), and under a triple-mode profile we MUST refuse
|
||||
// that single-layer artefact.
|
||||
func TestGenerateCert_RefusesPartialTriple_WithSigner_NoRingtail(t *testing.T) {
|
||||
func TestGenerateCert_RefusesPartialTriple_WithSigner_NoCorona(t *testing.T) {
|
||||
c, err := newCertifier(1)
|
||||
if err != nil {
|
||||
t.Fatalf("newCertifier: %v", err)
|
||||
@@ -127,11 +127,11 @@ func TestGenerateCert_NilProfile_AcceptsPlaceholder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestQuasarCert_Verify_RejectsMissingRingtail proves the structural
|
||||
// TestQuasarCert_Verify_RejectsMissingCorona proves the structural
|
||||
// gate at the vote-acceptance layer: cert.Verify() refuses a cert that
|
||||
// doesn't carry every layer, so a single-layer cert is rejected even
|
||||
// if generateCert somehow emits it.
|
||||
func TestQuasarCert_Verify_RejectsMissingRingtail(t *testing.T) {
|
||||
func TestQuasarCert_Verify_RejectsMissingCorona(t *testing.T) {
|
||||
cert := &QuasarCert{
|
||||
BLS: []byte("bls"),
|
||||
Corona: nil, // missing
|
||||
|
||||
@@ -414,7 +414,7 @@ type Stats struct {
|
||||
}
|
||||
|
||||
// BLSSignature contains a classical BLS threshold signature.
|
||||
// Fast path for consensus - used in parallel with RingtailSignature.
|
||||
// Fast path for consensus - used in parallel with CoronaSignature.
|
||||
type BLSSignature struct {
|
||||
Signature []byte // BLS signature bytes
|
||||
ValidatorID string // Signing validator
|
||||
@@ -422,9 +422,9 @@ type BLSSignature struct {
|
||||
SignerIndex int // Signer index in committee
|
||||
}
|
||||
|
||||
// RingtailSignature contains a post-quantum Corona threshold signature.
|
||||
// CoronaSignature contains a post-quantum Corona threshold signature.
|
||||
// Quantum-safe path - used in parallel with BLSSignature.
|
||||
type RingtailSignature struct {
|
||||
type CoronaSignature struct {
|
||||
Signature []byte // Corona (Ring-LWE) signature bytes
|
||||
ValidatorID string // Signing validator
|
||||
IsThreshold bool // True if threshold signature
|
||||
@@ -447,12 +447,12 @@ type RingtailSignature struct {
|
||||
// PQ proof: variable (aggregated Corona + ML-DSA, or future SNARK)
|
||||
type QuasarSignature struct {
|
||||
BLS *BLSSignature // Classical fast path (aggregatable)
|
||||
Corona *RingtailSignature // PQ anonymous path (ring-LWE threshold)
|
||||
Corona *CoronaSignature // PQ anonymous path (ring-LWE threshold)
|
||||
MLDSA []byte // PQ identity proof (ML-DSA-65, FIPS 204)
|
||||
}
|
||||
|
||||
// RingtailRound1Data contains the output of Corona Round 1.
|
||||
type RingtailRound1Data struct {
|
||||
// CoronaRound1Data contains the output of Corona Round 1.
|
||||
type CoronaRound1Data struct {
|
||||
PartyID int
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -85,7 +85,7 @@ type VerkleWitness struct {
|
||||
//
|
||||
// PQSignature is the load-bearing field: an ML-DSA-65 signature over
|
||||
// SigningDigest(witness) produced by the group key the verifier holds.
|
||||
// BLSAggregate / RingtailBits / ValidatorSet are legacy fields kept
|
||||
// BLSAggregate / CoronaBits / ValidatorSet are legacy fields kept
|
||||
// for wire compatibility with classical-compat deployments; under
|
||||
// strict-PQ the verifier ignores them.
|
||||
type WitnessProof struct {
|
||||
@@ -100,9 +100,9 @@ type WitnessProof struct {
|
||||
PQSignature []byte
|
||||
|
||||
// Legacy fields (classical-compat deployments). Strict-PQ
|
||||
// verifiers refuse to consult RingtailBits / BLSAggregate.
|
||||
// verifiers refuse to consult CoronaBits / BLSAggregate.
|
||||
BLSAggregate []byte // Aggregated BLS signature
|
||||
RingtailBits []byte // Bitfield of Corona signers
|
||||
CoronaBits []byte // Bitfield of Corona signers
|
||||
ValidatorSet []byte // Compressed validator set hash
|
||||
|
||||
// Block metadata
|
||||
@@ -334,8 +334,8 @@ func (v *VerkleWitness) checkPQFinality(witness *WitnessProof) bool {
|
||||
if witness == nil {
|
||||
return false
|
||||
}
|
||||
ringtailCount := countSetBits(witness.RingtailBits)
|
||||
return ringtailCount >= v.minThreshold
|
||||
coronaCount := countSetBits(witness.CoronaBits)
|
||||
return coronaCount >= v.minThreshold
|
||||
}
|
||||
|
||||
// verifyVerkleCommitment does ultra-fast Verkle proof verification
|
||||
@@ -381,7 +381,7 @@ func (v *VerkleWitness) fullVerification(witness *WitnessProof) error {
|
||||
}
|
||||
|
||||
// Verify Corona threshold
|
||||
if !v.verifyRingtailThreshold(witness.RingtailBits) {
|
||||
if !v.verifyCoronaThreshold(witness.CoronaBits) {
|
||||
return errors.New("corona threshold not met")
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ func (v *VerkleWitness) CreateWitness(
|
||||
openingProof := createIPAProof(commitment, stateRoot)
|
||||
|
||||
// Compress Corona signers to bitfield
|
||||
ringtailBits := compressToBitfield(coronaSigners)
|
||||
coronaBits := compressToBitfield(coronaSigners)
|
||||
|
||||
// Create witness
|
||||
commitmentBytes := commitment.Bytes()
|
||||
@@ -415,7 +415,7 @@ func (v *VerkleWitness) CreateWitness(
|
||||
Path: compressPath(stateRoot),
|
||||
OpeningProof: openingProof,
|
||||
BLSAggregate: bls.SignatureToBytes(blsAgg),
|
||||
RingtailBits: ringtailBits,
|
||||
CoronaBits: coronaBits,
|
||||
ValidatorSet: hashValidatorSet(),
|
||||
BlockHeight: height,
|
||||
StateRoot: stateRoot,
|
||||
@@ -615,7 +615,7 @@ func (v *VerkleWitness) verifyBLSAggregate(aggSig []byte, validatorSet []byte) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *VerkleWitness) verifyRingtailThreshold(bits []byte) bool {
|
||||
func (v *VerkleWitness) verifyCoronaThreshold(bits []byte) bool {
|
||||
count := countSetBits(bits)
|
||||
return count >= v.minThreshold
|
||||
}
|
||||
@@ -633,7 +633,7 @@ func (v *VerkleWitness) GetCachedWitness(stateRoot []byte) (*WitnessProof, bool)
|
||||
func (w *WitnessProof) Size() int {
|
||||
return len(w.Commitment) + len(w.Path) + len(w.OpeningProof) +
|
||||
len(w.PQSignature) +
|
||||
len(w.BLSAggregate) + len(w.RingtailBits) + len(w.ValidatorSet) +
|
||||
len(w.BLSAggregate) + len(w.CoronaBits) + len(w.ValidatorSet) +
|
||||
8 + len(w.StateRoot) + 8 // BlockHeight + StateRoot + Timestamp
|
||||
}
|
||||
|
||||
@@ -659,8 +659,8 @@ func (w *WitnessProof) Compress() *CompressedWitness {
|
||||
|
||||
// Compress validator bits to uint32 (supports up to 32 validators)
|
||||
var validatorBits uint32
|
||||
for i := 0; i < len(w.RingtailBits) && i < 4; i++ {
|
||||
validatorBits |= uint32(w.RingtailBits[i]) << (i * 8)
|
||||
for i := 0; i < len(w.CoronaBits) && i < 4; i++ {
|
||||
validatorBits |= uint32(w.CoronaBits[i]) << (i * 8)
|
||||
}
|
||||
|
||||
return &CompressedWitness{
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestVerifyPQFinality_PulsarM_RealVerifyAccepts(t *testing.T) {
|
||||
Commitment: make([]byte, 32),
|
||||
Path: make([]byte, 16),
|
||||
OpeningProof: make([]byte, 48),
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
BlockHeight: 100,
|
||||
StateRoot: make([]byte, 32),
|
||||
Timestamp: 1700000000,
|
||||
@@ -73,7 +73,7 @@ func TestVerifyPQFinality_PulsarM_TamperedSignatureRejected(t *testing.T) {
|
||||
Commitment: make([]byte, 32),
|
||||
Path: make([]byte, 16),
|
||||
OpeningProof: make([]byte, 48),
|
||||
RingtailBits: []byte{0x01},
|
||||
CoronaBits: []byte{0x01},
|
||||
BlockHeight: 100,
|
||||
StateRoot: make([]byte, 32),
|
||||
Timestamp: 1700000000,
|
||||
@@ -123,7 +123,7 @@ func TestVerifyPQFinality_PulsarM_BitCountAlone_DoesNotPass(t *testing.T) {
|
||||
Commitment: make([]byte, 32),
|
||||
Path: make([]byte, 16),
|
||||
OpeningProof: make([]byte, 48),
|
||||
RingtailBits: []byte{0xFF}, // 8 bits set — bit-count would pass at any threshold ≤ 8
|
||||
CoronaBits: []byte{0xFF}, // 8 bits set — bit-count would pass at any threshold ≤ 8
|
||||
BlockHeight: 100,
|
||||
StateRoot: make([]byte, 32),
|
||||
Timestamp: 1700000000,
|
||||
@@ -141,7 +141,7 @@ func TestVerifyPQFinality_PulsarM_BitCountAlone_DoesNotPass(t *testing.T) {
|
||||
|
||||
// Swap the message: mutate StateRoot so SigningDigest now yields
|
||||
// M2 ≠ M1. The signature still decodes (it's a genuine Pulsar-M
|
||||
// signature), the bit-count pre-filter still passes (RingtailBits
|
||||
// signature), the bit-count pre-filter still passes (CoronaBits
|
||||
// untouched), but the lattice verify equation MUST reject.
|
||||
witness.StateRoot[0] ^= 0x01
|
||||
digestM2 := witness.SigningDigest()
|
||||
|
||||
Reference in New Issue
Block a user