ceremonyclient/node/execution/ceremony/application/ceremony_application_finalizing.go
2023-09-24 21:43:35 -05:00

263 lines
6.0 KiB
Go

package application
import (
"bytes"
"fmt"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
func (a *CeremonyApplication) applyTranscriptShare(
share *protobufs.CeremonyTranscriptShare,
) error {
if len(share.AdditiveG1Powers) != len(a.LatestTranscript.G1Powers)-1 {
return errors.Wrap(errors.New("invalid g1s"), "apply transcript share")
}
if len(share.AdditiveG2Powers) != len(a.LatestTranscript.G2Powers)-1 {
return errors.Wrap(errors.New("invalid g2s"), "apply transcript share")
}
if share.AdditiveG1_256Witness == nil ||
share.AdditiveG1_256Witness.KeyValue == nil {
return errors.Wrap(
errors.New("invalid g1 witness"),
"apply transcript share",
)
}
if _, err := curves.BLS48581G1().Point.FromAffineCompressed(
share.AdditiveG1_256Witness.KeyValue,
); err != nil {
return errors.Wrap(
errors.Wrap(err, "invalid g1 witness"),
"apply transcript share",
)
}
if share.AdditiveG2_256Witness == nil ||
share.AdditiveG2_256Witness.KeyValue == nil {
return errors.Wrap(
errors.New("invalid g2 witness"),
"apply transcript share",
)
}
for _, s := range a.TranscriptShares {
if bytes.Equal(
s.AdditiveG1Powers[0].KeyValue,
share.AdditiveG1Powers[0].KeyValue,
) {
return nil
}
}
matchFound := false
for _, c := range a.FinalCommits {
if bytes.Equal(
share.ProverSignature.PublicKey.KeyValue,
c.ProverSignature.PublicKey.KeyValue,
) {
matchFound = true
break
}
}
if !matchFound {
return errors.Wrap(
errors.New(
fmt.Sprintf(
"no corresponding commit in commit set (size %d)",
len(a.FinalCommits),
),
),
"apply transcript share",
)
}
if err := share.VerifySignature(); err != nil {
return errors.Wrap(err, "apply transcript share")
}
eg := errgroup.Group{}
eg.SetLimit(100)
for i, g1 := range a.LatestTranscript.G1Powers {
i := i
g1 := g1
eg.Go(func() error {
if _, err := curves.BLS48581G1().Point.FromAffineCompressed(
g1.KeyValue,
); err != nil {
return errors.Wrap(
errors.Wrap(err, fmt.Sprintf("invalid g1 at position %d", i)),
"apply transcript share",
)
}
return nil
})
}
for i, g2 := range a.LatestTranscript.G2Powers {
i := i
g2 := g2
eg.Go(func() error {
if _, err := curves.BLS48581G2().Point.FromAffineCompressed(
g2.KeyValue,
); err != nil {
return errors.Wrap(
errors.Wrap(err, fmt.Sprintf("invalid g2 at position %d", i)),
"apply transcript share",
)
}
return nil
})
}
if err := eg.Wait(); err != nil {
return err
}
exists := false
for _, s := range a.TranscriptShares {
exists = bytes.Equal(
s.ProverSignature.Signature,
share.ProverSignature.Signature,
)
if exists {
break
}
}
if !exists {
a.TranscriptShares = append(a.TranscriptShares, share)
}
return nil
}
func (a *CeremonyApplication) finalizeTranscript() error {
a.UpdatedTranscript = &protobufs.CeremonyTranscript{
G1Powers: make(
[]*protobufs.BLS48581G1PublicKey,
len(a.LatestTranscript.G1Powers),
),
G2Powers: make(
[]*protobufs.BLS48581G2PublicKey,
len(a.LatestTranscript.G2Powers),
),
RunningG1_256Witnesses: a.LatestTranscript.RunningG1_256Witnesses,
RunningG2_256Powers: a.LatestTranscript.RunningG2_256Powers,
}
a.UpdatedTranscript.G1Powers[0] = a.LatestTranscript.G1Powers[0]
a.UpdatedTranscript.G2Powers[0] = a.LatestTranscript.G2Powers[0]
for i := range a.UpdatedTranscript.G1Powers[1:] {
g1, err := curves.BLS48581G1().Point.FromAffineCompressed(
a.TranscriptShares[0].AdditiveG1Powers[i].KeyValue,
)
if err != nil {
return errors.Wrap(err, "finalize transcript")
}
if len(a.TranscriptShares) > 1 {
for _, share := range a.TranscriptShares[1:] {
ag1, err := curves.BLS48581G1().Point.FromAffineCompressed(
share.AdditiveG1Powers[i].KeyValue,
)
if err != nil {
return errors.Wrap(err, "finalize transcript")
}
g1 = g1.Add(ag1)
}
}
if !g1.IsOnCurve() || g1.IsIdentity() {
return errors.Wrap(
errors.New("invalid g1 power"),
"finalize transcript",
)
}
a.UpdatedTranscript.G1Powers[i+1] = &protobufs.BLS48581G1PublicKey{
KeyValue: g1.ToAffineCompressed(),
}
}
for i := range a.UpdatedTranscript.G2Powers[1:] {
g2, err := curves.BLS48581G2().Point.FromAffineCompressed(
a.TranscriptShares[0].AdditiveG2Powers[i].KeyValue,
)
if err != nil {
return errors.Wrap(err, "finalize transcript")
}
if len(a.TranscriptShares) > 1 {
for _, share := range a.TranscriptShares[1:] {
ag2, err := curves.BLS48581G2().Point.FromAffineCompressed(
share.AdditiveG2Powers[i].KeyValue,
)
if err != nil {
return errors.Wrap(err, "finalize transcript")
}
g2 = g2.Add(ag2)
}
}
if !g2.IsOnCurve() || g2.IsIdentity() {
return errors.Wrap(
errors.New("invalid g2 power"),
"finalize transcript",
)
}
a.UpdatedTranscript.G2Powers[i+1] = &protobufs.BLS48581G2PublicKey{
KeyValue: g2.ToAffineCompressed(),
}
}
g1Witness, err := curves.BLS48581G1().Point.FromAffineCompressed(
a.TranscriptShares[0].AdditiveG1_256Witness.KeyValue,
)
if err != nil {
return errors.Wrap(err, "finalize transcript")
}
if len(a.TranscriptShares) > 1 {
for _, share := range a.TranscriptShares[1:] {
ag1, err := curves.BLS48581G1().Point.FromAffineCompressed(
share.AdditiveG1_256Witness.KeyValue,
)
if err != nil {
return errors.Wrap(err, "finalize transcript")
}
g1Witness = g1Witness.Add(ag1)
}
}
if !g1Witness.IsOnCurve() || g1Witness.IsIdentity() {
return errors.Wrap(
errors.New("invalid witness"),
"finalize transcript",
)
}
a.UpdatedTranscript.RunningG1_256Witnesses = append(
a.UpdatedTranscript.RunningG1_256Witnesses,
&protobufs.BLS48581G1PublicKey{
KeyValue: g1Witness.ToAffineCompressed(),
},
)
a.UpdatedTranscript.RunningG2_256Powers = append(
a.UpdatedTranscript.RunningG2_256Powers,
a.UpdatedTranscript.G2Powers[len(a.UpdatedTranscript.G2Powers)-1],
)
return nil
}