func (p *Exponent) WriteTo(w io.Writer) (int64, error) {
	data, err := p.MarshalBinary()
	if err != nil {
		return 0, err
	}
	total, err := w.Write(data)
	return int64(total), err
}
WriteTo implements io.WriterTo and should be used within the hash.Hash function.
package polynomial
import (
	"encoding/binary"
	"errors"
	"io"
	"github.com/cronokirby/safenum"
	"github.com/fxamacker/cbor/v2"
	"github.com/taurusgroup/multi-party-sig/pkg/math/curve"
)
type rawExponentData struct {
	IsConstant   bool
	Coefficients []curve.Point
}
type Exponent struct {
	group curve.Curve
	IsConstant bool
	coefficients []curve.Point
}
func NewPolynomialExponent(polynomial *Polynomial) *Exponent {
	p := &Exponent{
		group:        polynomial.group,
		IsConstant:   polynomial.coefficients[0].IsZero(),
		coefficients: make([]curve.Point, 0, len(polynomial.coefficients)),
	}
	for i, c := range polynomial.coefficients {
		if p.IsConstant && i == 0 {
			continue
		}
		p.coefficients = append(p.coefficients, c.ActOnBase())
	}
	return p
}
func (p *Exponent) Evaluate(x curve.Scalar) curve.Point {
	result := p.group.NewPoint()
	for i := len(p.coefficients) - 1; i >= 0; i-- {
		result = x.Act(result).Add(p.coefficients[i])
	}
	if p.IsConstant {
		result = x.Act(result)
	}
	return result
}
func (p *Exponent) evaluateClassic(x curve.Scalar) curve.Point {
	var tmp curve.Point
	xPower := p.group.NewScalar().SetNat(new(safenum.Nat).SetUint64(1))
	result := p.group.NewPoint()
	if p.IsConstant {
		xPower.Mul(x)
	}
	for i := 0; i < len(p.coefficients); i++ {
		tmp = xPower.Act(p.coefficients[i])
		result = result.Add(tmp)
		xPower.Mul(x)
	}
	return result
}
func (p *Exponent) Degree() int {
	if p.IsConstant {
		return len(p.coefficients)
	}
	return len(p.coefficients) - 1
}
func (p *Exponent) add(q *Exponent) error {
	if len(p.coefficients) != len(q.coefficients) {
		return errors.New("q is not the same length as p")
	}
	if p.IsConstant != q.IsConstant {
		return errors.New("p and q differ in 'IsConstant'")
	}
	for i := 0; i < len(p.coefficients); i++ {
		p.coefficients[i] = p.coefficients[i].Add(q.coefficients[i])
	}
	return nil
}
func Sum(polynomials []*Exponent) (*Exponent, error) {
	var err error
	summed := polynomials[0].copy()
	for j := 1; j < len(polynomials); j++ {
		err = summed.add(polynomials[j])
		if err != nil {
			return nil, err
		}
	}
	return summed, nil
}
func (p *Exponent) copy() *Exponent {
	q := &Exponent{
		group:        p.group,
		IsConstant:   p.IsConstant,
		coefficients: make([]curve.Point, 0, len(p.coefficients)),
	}
	for i := 0; i < len(p.coefficients); i++ {
		q.coefficients = append(q.coefficients, p.coefficients[i])
	}
	return q
}
func (p *Exponent) Equal(other Exponent) bool {
	if p.IsConstant != other.IsConstant {
		return false
	}
	if len(p.coefficients) != len(other.coefficients) {
		return false
	}
	for i := 0; i < len(p.coefficients); i++ {
		if !p.coefficients[i].Equal(other.coefficients[i]) {
			return false
		}
	}
	return true
}
func (p *Exponent) Constant() curve.Point {
	c := p.group.NewPoint()
	if p.IsConstant {
		return c
	}
	return p.coefficients[0]
}