Files
zeekay 75be0e607e round: rename Helper to Base — name the value, not the laziness
round.Helper was the canonical anti-pattern: a bare-noun
qualifier-name that told you nothing about what the type does. The
type is the embeddable Session implementation that protocol round
structs anchor on — its VALUE is "the base every round builds on".
Rename it to that.

  type Helper struct { ... }   → type Base struct { ... }
  func (h *Helper) ...         → func (h *Base) ...
  func NewSession(...) (*Helper, error) → (*Base, error)
  Output { *Helper }           → Output { *Base }
  Abort  { *Helper }           → Abort  { *Base }
  round.Helper                 → round.Base   (18 files)
  Helper: helper               → Base: helper (struct literal init)
  r.Helper.X / r.Helper        → r.Base.X / r.Base (field access)

internal/round/helper.go    → base.go
internal/round/helper_test.go → base_test.go

Forward-only — no type alias, no deprecation. The Go FAQ pointer-
receiver consistency landed in the prior commit (f7b1365) so the
method set is already aligned; this commit only renames the type.

Build + vet clean; round / CMP keygen smoke / FROST keygen all
PASS unchanged.
2026-06-01 00:26:33 -07:00

107 lines
3.1 KiB
Go

package keygen
import (
"crypto/rand"
"github.com/luxfi/threshold/internal/ot"
"github.com/luxfi/threshold/internal/params"
"github.com/luxfi/threshold/internal/round"
"github.com/luxfi/threshold/pkg/hash"
"github.com/luxfi/threshold/pkg/math/curve"
"github.com/luxfi/threshold/pkg/math/sample"
zksch "github.com/luxfi/threshold/pkg/zk/sch"
)
// message1S is the message the Sender provides in response to the first round.
type message1S struct {
// PublicShare is our secret share times the group generator.
PublicShare curve.Point
// ChainKey is our contribution to the chain key.
ChainKey []byte
// RefreshScalar is our contribution to refreshing the shares.
RefreshScalar curve.Scalar
// Proof is the proof of knowledge for the discrete logarithm of PublicShare.
Proof *zksch.Proof
// OtMsg is the forwarded message for the underlying OT setup.
OtMsg *ot.CorreOTSetupSendRound1Message
}
func (message1S) RoundNumber() round.Number { return 2 }
// round1S corresponds to the second round from the Sender's perspective.
type round1S struct {
*round.Base
// refresh indicates if we're refreshing, instead of generating a new key.
refresh bool
// public is an existing public key, when refreshing
public curve.Point
// Our generated secret share
secretShare curve.Scalar
// Our secret share * G
publicShare curve.Point
sender *ot.CorreOTSetupSender
// The commitment sent to us by the receiver.
receiverCommit hash.Commitment
// The chain key commitment sent to us by the receiver.
chainKeyCommit hash.Commitment
// The refresh commitment sent to us by the receiver
refreshCommit hash.Commitment
otMsg *ot.CorreOTSetupSendRound1Message
}
func (r *round1S) VerifyMessage(msg round.Message) error {
body, ok := msg.Content.(*message1R)
if !ok || body == nil {
return round.ErrInvalidContent
}
if err := body.Commit.Validate(); err != nil {
return err
}
if err := body.ChainKeyCommit.Validate(); err != nil {
return err
}
if err := body.RefreshCommit.Validate(); err != nil {
return err
}
if body.OtMsg == nil {
return round.ErrNilFields
}
return nil
}
func (r *round1S) StoreMessage(msg round.Message) (err error) {
body := msg.Content.(*message1R)
r.otMsg, err = r.sender.Round1(body.OtMsg)
if err != nil {
return err
}
r.receiverCommit = body.Commit
r.chainKeyCommit = body.ChainKeyCommit
r.refreshCommit = body.RefreshCommit
return nil
}
func (r *round1S) Finalize(out chan<- *round.Message) (round.Session, error) {
proof := zksch.NewProof(r.Hash(), r.publicShare, r.secretShare, nil)
chainKey := make([]byte, params.SecBytes)
_, _ = rand.Read(chainKey)
refreshScalar := sample.Scalar(rand.Reader, r.Group())
if err := r.SendMessage(out, &message1S{r.publicShare, chainKey, refreshScalar, proof, r.otMsg}, ""); err != nil {
return r, err
}
return &round2S{
round1S: r,
chainKey: chainKey,
refreshScalar: refreshScalar,
}, nil
}
func (r *round1S) MessageContent() round.Content {
return &message1R{OtMsg: ot.EmptyCorreOTSetupReceiveRound1Message(r.Group())}
}
func (*round1S) Number() round.Number { return 1 }