mirror of
https://github.com/luxfi/threshold.git
synced 2026-10-30 15:15:53 +00:00
Closes a HIGH-severity production-routing risk identified in the
pulsar/corona audit (2026-05-31).
The file protocols/lss/adapters/corona.go was a paper-grade
demonstrator that named itself "Corona" — colliding with the real
luxfi/corona Ring-LWE primitive. Anyone invoking the LSS factory with
`lss.NewLSS(lss.Corona, ...)` got the toy adapter, not the production
primitive. The toy adapter has:
- A textbook-LWE "DKG" that sums each party's s_i into a combined
master secret at the aggregator. NO Lagrange threshold sharing.
The threshold parameter is decorative.
- Q = 12289 (< 2^14) — far below any meaningful LWE security bound.
- A Box-Muller-from-uniform-mod-Q Gaussian sampler using
floating-point math on secret-dependent inputs. NOT constant-time.
Side-channel leakage is GUARANTEED.
- No matching verifier.
This commit:
- adapters/corona.go +build researchpreview
- adapters/corona_test.go +build researchpreview
- adapters/corona_external_test.go new gated external-test file
- factory_corona_prod.go new — production refuses with a routing
error pointing at
luxfi/threshold/protocols/corona →
luxfi/corona
- factory_corona_research.go new — research-preview returns the toy
Tests and benchmarks in adapters_test.go and full_coverage_test.go
that referenced NewCoronaAdapter / GetRecommendedParams have moved to
corona_external_test.go (gated). Production `go test ./protocols/lss/
adapters/...` passes; research `go test -tags researchpreview` also
passes.
Production users that need PQ threshold signing must route through
luxfi/threshold/protocols/corona (which wraps luxfi/corona): real
Ring-LWE with Pedersen-DKG, canonical wire codec (corona@42838bd), and
dudect-validated CT hot paths.
(cherry picked from commit eedafda56b8e277c483d9c96e67ba40a49052246)
76 lines
2.0 KiB
Go
76 lines
2.0 KiB
Go
// SPDX-License-Identifier: BSD-3-Clause
|
|
//go:build researchpreview
|
|
// +build researchpreview
|
|
|
|
// Tests for the LSS-side toy Corona adapter. Build with
|
|
// -tags=researchpreview only. The adapter itself ships under the same
|
|
// gate; production builds must NOT compile this file. See the
|
|
// disclosure block at the top of corona.go for the full trust-model
|
|
// statement.
|
|
package adapters
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/luxfi/threshold/pkg/party"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestCoronaAdapter tests the research-preview LSS Corona adapter
|
|
// surface for shape only — it does NOT assert any cryptographic
|
|
// soundness. The adapter is paper-grade, not production. See
|
|
// corona.go header.
|
|
func TestCoronaAdapter(t *testing.T) {
|
|
t.Run("SecurityLevels", func(t *testing.T) {
|
|
levels := []int{128, 192, 256}
|
|
|
|
for _, level := range levels {
|
|
adapter := NewCoronaAdapter(level, 5)
|
|
require.NotNil(t, adapter)
|
|
|
|
config := &UnifiedConfig{
|
|
SignatureScheme: SignatureCorona,
|
|
Threshold: 3,
|
|
PartyIDs: []party.ID{"alice", "bob", "charlie", "dave", "eve"},
|
|
CoronaConfig: &CoronaExtensions{
|
|
SecurityLevel: level,
|
|
},
|
|
}
|
|
|
|
err := adapter.ValidateConfig(config)
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
|
|
t.Run("PreprocessingGeneration", func(t *testing.T) {
|
|
adapter := NewCoronaAdapter(128, 5)
|
|
|
|
parties := []party.ID{"alice", "bob", "charlie", "dave", "eve"}
|
|
// GeneratePreprocessing would be called here if it existed
|
|
_ = adapter
|
|
_ = parties
|
|
|
|
// Verify adapter was created successfully
|
|
assert.NotNil(t, adapter)
|
|
assert.Len(t, parties, 5)
|
|
})
|
|
|
|
t.Run("SignatureSize", func(t *testing.T) {
|
|
testCases := []struct {
|
|
securityLevel int
|
|
expectedSize int
|
|
}{
|
|
{128, 13400},
|
|
{192, 28600},
|
|
{256, 53200},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
_ = NewCoronaAdapter(tc.securityLevel, 5)
|
|
params := GetRecommendedParams(tc.securityLevel, 5)
|
|
assert.Equal(t, tc.expectedSize, params.SignatureSize)
|
|
}
|
|
})
|
|
}
|