mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
Followup to the QuasarCert field rename (commit 4c9af053). This sweeps
the remaining Ringtail identifiers and prose out of the consensus repo
entirely:
- Identifiers (Go code):
ringtailThreshold → coronaThreshold (import alias)
ringtailGroupKey → coronaGroupKey
ringtailSigners → coronaSigners
ringtailShares → coronaShares
ringtailGobEncode → coronaGobEncode
ringtailGobDecode → coronaGobDecode
decodeRingtailSig → decodeCoronaSig
EncodeRingtailSig → EncodeCoronaSig
RingtailRound1{,Data,State} → CoronaRound1{,Data,State}
RingtailGroupKey/Pub/Shares → Corona*
- File rename:
protocol/quasar/ringtail_gob.go → corona_gob.go
- PQMode constants:
PQModeRingtail → PQModeNasua
SigSchemeRingtailAcademic → SigSchemeNasua
"ringtail" / "ringtail-academic" string forms → "nasua"
- Prose & comments throughout the repo: "Ringtail" → "Corona" when
naming the production Ring-LWE library, "Nasua" when naming the
historical academic upstream (luxfi/nasua, formerly luxfi/ringtail).
Canonical Pulsar family taxonomy after this rename:
Nasua — academic R-LWE 2-round threshold sig (Boschini et al,
ePrint 2024/1113); trusted-dealer DKG; kept as historical
reference fork only. NOT for an open public chain.
Corona — production Ring-LWE threshold ML-DSA (Pedersen DKG over R_q
+ proactive resharing); `github.com/luxfi/corona`. The
Ring-LWE leg of QuasarCert.
Pulsar — production Module-LWE threshold ML-DSA (FIPS 204
byte-equal); `github.com/luxfi/pulsar`. The Module-LWE
leg of QuasarCert. Pure-PQ pair = Corona + Pulsar.
Wire-format unchanged. Tests: 28/28 packages green (-short suite,
quasar 29s, integration 58s, no regressions).
181 lines
4.8 KiB
Go
181 lines
4.8 KiB
Go
// Copyright (C) 2025, Lux Industries Inc All rights reserved.
|
|
// Async quantum bundle production - runs Corona signing without blocking BLS.
|
|
//
|
|
// Architecture (parallel execution):
|
|
// BLS Layer: [B1]--[B2]--[B3]--[B4]--[B5]--[B6]--[B7]--[B8]--[B9]--...
|
|
// | 500ms finality per block |
|
|
// |_____________________________________|
|
|
// |
|
|
// Quantum Layer: [QB1: Merkle(B1-B6)]--------[QB2: Merkle(B7-B12)]
|
|
// | 3-second interval, async Corona signing
|
|
//
|
|
// NTT Corona benchmarks (IEEE S&P 2025):
|
|
// - 0.6s online signing phase (2-round protocol)
|
|
// - 2.5s total including offline prep across 5 continents
|
|
// - Our 3-second interval provides comfortable margin
|
|
|
|
package quasar
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// AsyncBundleSigner wraps BundleSigner with async signing capabilities.
|
|
// BLS block production continues uninterrupted during Corona signing.
|
|
type AsyncBundleSigner struct {
|
|
signer *BundleSigner
|
|
|
|
// Async signing state
|
|
signingInProgress bool
|
|
signedBundles chan *QuantumBundle
|
|
|
|
mu sync.Mutex
|
|
}
|
|
|
|
// NewAsyncBundleSigner creates an async bundle signer.
|
|
func NewAsyncBundleSigner(em *EpochManager) *AsyncBundleSigner {
|
|
return &AsyncBundleSigner{
|
|
signer: NewBundleSigner(em),
|
|
signedBundles: make(chan *QuantumBundle, 10),
|
|
}
|
|
}
|
|
|
|
// AddBLSBlock adds a finalized BLS block hash to the pending bundle.
|
|
func (abs *AsyncBundleSigner) AddBLSBlock(height uint64, hash [32]byte) {
|
|
abs.signer.AddBLSBlock(height, hash)
|
|
}
|
|
|
|
// PendingCount returns the number of pending BLS blocks.
|
|
func (abs *AsyncBundleSigner) PendingCount() int {
|
|
return abs.signer.PendingCount()
|
|
}
|
|
|
|
// CreateBundle bundles pending BLS blocks.
|
|
func (abs *AsyncBundleSigner) CreateBundle() *QuantumBundle {
|
|
return abs.signer.CreateBundle()
|
|
}
|
|
|
|
// SignBundle signs a bundle synchronously.
|
|
func (abs *AsyncBundleSigner) SignBundle(
|
|
bundle *QuantumBundle,
|
|
sessionID int,
|
|
prfKey []byte,
|
|
validators []string,
|
|
) error {
|
|
return abs.signer.SignBundle(bundle, sessionID, prfKey, validators)
|
|
}
|
|
|
|
// SignBundleAsync signs a bundle asynchronously.
|
|
// BLS block production continues uninterrupted during signing.
|
|
func (abs *AsyncBundleSigner) SignBundleAsync(
|
|
bundle *QuantumBundle,
|
|
sessionID int,
|
|
prfKey []byte,
|
|
validators []string,
|
|
) {
|
|
go func() {
|
|
abs.mu.Lock()
|
|
abs.signingInProgress = true
|
|
abs.mu.Unlock()
|
|
|
|
defer func() {
|
|
abs.mu.Lock()
|
|
abs.signingInProgress = false
|
|
abs.mu.Unlock()
|
|
}()
|
|
|
|
err := abs.signer.SignBundle(bundle, sessionID, prfKey, validators)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
abs.signedBundles <- bundle
|
|
}()
|
|
}
|
|
|
|
// SignedBundles returns the channel of signed bundles.
|
|
func (abs *AsyncBundleSigner) SignedBundles() <-chan *QuantumBundle {
|
|
return abs.signedBundles
|
|
}
|
|
|
|
// IsSigningInProgress returns true if async signing is in progress.
|
|
func (abs *AsyncBundleSigner) IsSigningInProgress() bool {
|
|
abs.mu.Lock()
|
|
defer abs.mu.Unlock()
|
|
return abs.signingInProgress
|
|
}
|
|
|
|
// VerifyBundle verifies a bundle's signature.
|
|
func (abs *AsyncBundleSigner) VerifyBundle(bundle *QuantumBundle) bool {
|
|
return abs.signer.VerifyBundle(bundle)
|
|
}
|
|
|
|
// LastBundle returns the most recent bundle.
|
|
func (abs *AsyncBundleSigner) LastBundle() *QuantumBundle {
|
|
return abs.signer.LastBundle()
|
|
}
|
|
|
|
// ============================================================================
|
|
// BundleRunner - Automated quantum bundle production
|
|
// ============================================================================
|
|
|
|
// BundleRunner runs the quantum bundle production loop.
|
|
// It creates bundles every 3 seconds and signs them asynchronously.
|
|
type BundleRunner struct {
|
|
signer *AsyncBundleSigner
|
|
validators []string
|
|
prfKey []byte
|
|
sessionID int
|
|
|
|
stopCh chan struct{}
|
|
doneCh chan struct{}
|
|
}
|
|
|
|
// NewBundleRunner creates a new bundle runner.
|
|
func NewBundleRunner(signer *AsyncBundleSigner, validators []string, prfKey []byte) *BundleRunner {
|
|
return &BundleRunner{
|
|
signer: signer,
|
|
validators: validators,
|
|
prfKey: prfKey,
|
|
stopCh: make(chan struct{}),
|
|
doneCh: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
// Start begins the bundle production loop.
|
|
// Bundles are created every 3 seconds, signed asynchronously.
|
|
func (br *BundleRunner) Start() {
|
|
go br.run()
|
|
}
|
|
|
|
// Stop stops the bundle production loop.
|
|
func (br *BundleRunner) Stop() {
|
|
close(br.stopCh)
|
|
<-br.doneCh
|
|
}
|
|
|
|
func (br *BundleRunner) run() {
|
|
defer close(br.doneCh)
|
|
|
|
ticker := time.NewTicker(QuantumCheckpointInterval)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-br.stopCh:
|
|
return
|
|
case <-ticker.C:
|
|
// Create bundle from pending BLS blocks
|
|
bundle := br.signer.CreateBundle()
|
|
if bundle == nil {
|
|
continue // No pending blocks
|
|
}
|
|
|
|
// Sign asynchronously (doesn't block BLS production)
|
|
br.sessionID++
|
|
br.signer.SignBundleAsync(bundle, br.sessionID, br.prfKey, br.validators)
|
|
}
|
|
}
|
|
}
|