Files

63 lines
1.9 KiB
Go

package keygen
import (
"crypto/rand"
"fmt"
"github.com/luxfi/threshold/internal/round"
"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/pkg/pool"
"github.com/luxfi/threshold/pkg/protocol"
"github.com/luxfi/threshold/protocols/cmp/config"
)
const Rounds round.Number = 5
func Start(info round.Info, pl *pool.Pool, c *config.Config) protocol.StartFunc {
return func(sessionID []byte) (_ round.Session, err error) {
var helper *round.Base
if c == nil {
helper, err = round.NewSession(info, sessionID, pl)
} else {
helper, err = round.NewSession(info, sessionID, pl, c)
}
if err != nil {
return nil, fmt.Errorf("keygen: %w", err)
}
group := helper.Group()
// Create a stable KeyID for cross-phase commitments
// We don't include the public key in the KeyID for keygen since it's not known yet
// This ensures all parties compute the same KeyID independently
keyID := protocol.NewKeyID(info.ProtocolID, group, nil, info.PartyIDs, info.Threshold, 0)
if c != nil {
PublicSharesECDSA := make(map[party.ID]curve.Point, len(c.Public))
for id, public := range c.Public {
PublicSharesECDSA[id] = public.ECDSA
}
return &round1{
Base: helper,
PreviousSecretECDSA: c.ECDSA,
PreviousPublicSharesECDSA: PublicSharesECDSA,
PreviousChainKey: c.ChainKey,
VSSSecret: polynomial.NewPolynomial(group, helper.Threshold(), group.NewScalar()), // fᵢ(X) deg(fᵢ) = t, fᵢ(0) = 0
keyID: keyID,
}, nil
}
// sample fᵢ(X) deg(fᵢ) = t, fᵢ(0) = secretᵢ
VSSConstant := sample.Scalar(rand.Reader, group)
VSSSecret := polynomial.NewPolynomial(group, helper.Threshold(), VSSConstant)
return &round1{
Base: helper,
VSSSecret: VSSSecret,
keyID: keyID,
}, nil
}
}