mirror of
https://github.com/luxfi/threshold.git
synced 2026-10-30 15:15:53 +00:00
SharedLSSConfigs builds a genuine Shamir sharing: each config's ECDSA is f(id), every party's Public holds f(j)·G, and those interpolate to f(0)·G, which is what PublicPoint expects and what a signature verifies against. The existing CreateMockLSSConfigs holds zero scalars and identity points, so a protocol run over it proves nothing about signing — which is how whole packages of round code stayed at zero coverage behind tests that looked like they exercised it. Signing now runs on it. Resharing does not complete when driven the same way, and the note records what was measured and where to start: round 1 finalizes in isolation, round 2 sends a share to itself that Message.IsFor refuses by construction, and round 3 adds its own contribution separately anyway.
130 lines
3.7 KiB
Go
130 lines
3.7 KiB
Go
package test
|
|
|
|
import (
|
|
"io"
|
|
|
|
"github.com/luxfi/threshold/pkg/math/curve"
|
|
"github.com/luxfi/threshold/pkg/math/polynomial"
|
|
"github.com/luxfi/threshold/pkg/math/sample"
|
|
"github.com/luxfi/threshold/pkg/party"
|
|
"github.com/luxfi/threshold/protocols/lss/config"
|
|
)
|
|
|
|
// CreateMockLSSConfigs creates mock LSS configs for testing
|
|
func CreateMockLSSConfigs(partyIDs []party.ID, threshold int) []*config.Config {
|
|
configs := make([]*config.Config, len(partyIDs))
|
|
group := curve.Secp256k1{}
|
|
|
|
for i, id := range partyIDs {
|
|
configs[i] = &config.Config{
|
|
ID: id,
|
|
Threshold: threshold,
|
|
Group: group,
|
|
ECDSA: group.NewScalar(),
|
|
ChainKey: []byte("mock-chain-key"),
|
|
RID: []byte("mock-rid"),
|
|
Public: make(map[party.ID]*config.Public),
|
|
}
|
|
|
|
// Add public keys for all parties
|
|
for _, pid := range partyIDs {
|
|
configs[i].Public[pid] = &config.Public{
|
|
ECDSA: group.NewPoint(),
|
|
}
|
|
}
|
|
}
|
|
|
|
return configs
|
|
}
|
|
|
|
// CreateMockFROSTConfigs creates mock FROST configs for testing
|
|
func CreateMockFROSTConfigs(partyIDs []party.ID, threshold int) []interface{} {
|
|
configs := make([]interface{}, len(partyIDs))
|
|
group := curve.Secp256k1{}
|
|
|
|
for i, id := range partyIDs {
|
|
// Create a mock config that satisfies FROST requirements
|
|
configs[i] = struct {
|
|
ID party.ID
|
|
Threshold int
|
|
Group curve.Curve
|
|
PublicKey curve.Point
|
|
SecretShare curve.Scalar
|
|
PublicShares map[party.ID]curve.Point
|
|
}{
|
|
ID: id,
|
|
Threshold: threshold,
|
|
Group: group,
|
|
PublicKey: group.NewPoint(),
|
|
SecretShare: group.NewScalar(),
|
|
PublicShares: make(map[party.ID]curve.Point),
|
|
}
|
|
}
|
|
|
|
return configs
|
|
}
|
|
|
|
// CreateMockCMPConfigs creates mock CMP configs for testing
|
|
func CreateMockCMPConfigs(partyIDs []party.ID, threshold int) []interface{} {
|
|
configs := make([]interface{}, len(partyIDs))
|
|
group := curve.Secp256k1{}
|
|
|
|
for i, id := range partyIDs {
|
|
// Create a mock config that satisfies CMP requirements
|
|
configs[i] = struct {
|
|
ID party.ID
|
|
Threshold int
|
|
Group curve.Curve
|
|
PublicKey curve.Point
|
|
Share curve.Scalar
|
|
Nonce []byte
|
|
}{
|
|
ID: id,
|
|
Threshold: threshold,
|
|
Group: group,
|
|
PublicKey: group.NewPoint(),
|
|
Share: group.NewScalar(),
|
|
Nonce: []byte("mock-nonce"),
|
|
}
|
|
}
|
|
|
|
return configs
|
|
}
|
|
|
|
// SharedLSSConfigs builds a REAL Shamir sharing of one key over ids: each
|
|
// config's ECDSA is f(id), every party's Public holds f(j)·G, and those
|
|
// interpolate back to f(0)·G, which is what PublicPoint expects and what a
|
|
// signature verifies against. It returns the group public key alongside.
|
|
//
|
|
// CreateMockLSSConfigs above cannot stand in for this. Its shares are the zero
|
|
// scalar and its public points are the identity, so a protocol run over it
|
|
// proves nothing about signing — which is how a whole package of round code
|
|
// stayed at zero coverage behind tests that looked like they exercised it.
|
|
func SharedLSSConfigs(ids []party.ID, degree int, rand io.Reader) (map[party.ID]*config.Config, curve.Point) {
|
|
group := curve.Secp256k1{}
|
|
secret := sample.Scalar(rand, group)
|
|
poly := polynomial.NewPolynomial(group, degree, secret)
|
|
|
|
public := make(map[party.ID]*config.Public, len(ids))
|
|
shares := make(map[party.ID]curve.Scalar, len(ids))
|
|
for _, id := range ids {
|
|
s := poly.Evaluate(id.Scalar(group))
|
|
shares[id] = s
|
|
public[id] = &config.Public{ECDSA: s.ActOnBase()}
|
|
}
|
|
|
|
configs := make(map[party.ID]*config.Config, len(ids))
|
|
for _, id := range ids {
|
|
configs[id] = &config.Config{
|
|
ID: id,
|
|
Group: group,
|
|
Threshold: degree + 1,
|
|
ECDSA: shares[id],
|
|
Public: public,
|
|
ChainKey: []byte("chain-key"),
|
|
RID: []byte("rid"),
|
|
}
|
|
}
|
|
return configs, secret.ActOnBase()
|
|
}
|