func (r *round3) Finalize(chan<- *round.Message) (round.Session, error) {
	z := r.Group().NewScalar()
	for _, z_l := range r.z {
		z.Add(z_l)
	}
	if r.taproot {
		sig := taproot.Signature(make([]byte, 0, taproot.SignatureLen))
		sig = append(sig, r.R.(*curve.Secp256k1Point).XBytes()...)
		zBytes, err := z.MarshalBinary()
		if err != nil {
			return r, err
		}
		sig = append(sig, zBytes[:]...)
		taprootPub := taproot.PublicKey(r.Y.(*curve.Secp256k1Point).XBytes())
		if !taprootPub.Verify(sig, r.M) {
			return r.AbortRound(fmt.Errorf("generated signature failed to verify")), nil
		}
		return r.ResultRound(sig), nil
	} else {
		sig := Signature{
			R: r.R,
			z: z,
		}
		if !sig.Verify(r.Y, r.M) {
			return r.AbortRound(fmt.Errorf("generated signature failed to verify")), nil
		}
		return r.ResultRound(sig), nil
	}
}
Finalize implements round.Round.
package sign
import (
	"fmt"
	"github.com/taurusgroup/multi-party-sig/internal/round"
	"github.com/taurusgroup/multi-party-sig/pkg/math/curve"
	"github.com/taurusgroup/multi-party-sig/pkg/party"
	"github.com/taurusgroup/multi-party-sig/pkg/taproot"
)
type round3 struct {
	*round2
	R curve.Point
	RShares map[party.ID]curve.Point
	c curve.Scalar
	z map[party.ID]curve.Scalar
	Lambda map[party.ID]curve.Scalar
}
type broadcast3 struct {
	round.NormalBroadcastContent
	Z_i curve.Scalar
}
func (r *round3) StoreBroadcastMessage(msg round.Message) error {
	from := msg.From
	body, ok := msg.Content.(*broadcast3)
	if !ok || body == nil {
		return round.ErrInvalidContent
	}
	if body.Z_i == nil {
		return round.ErrNilFields
	}
	expected := r.c.Act(r.Lambda[from].Act(r.YShares[from])).Add(r.RShares[from])
	actual := body.Z_i.ActOnBase()
	if !actual.Equal(expected) {
		return fmt.Errorf("failed to verify response from %v", from)
	}
	r.z[from] = body.Z_i
	return nil
}
func (round3) VerifyMessage(round.Message) error { return nil }
func (round3) StoreMessage(round.Message) error { return nil }