Files

274 lines
6.2 KiB
Go

package main
import (
"errors"
"fmt"
"sync"
"github.com/luxfi/threshold/internal/test"
"github.com/luxfi/threshold/pkg/ecdsa"
"github.com/luxfi/threshold/pkg/math/curve"
"github.com/luxfi/threshold/pkg/party"
"github.com/luxfi/threshold/pkg/pool"
"github.com/luxfi/threshold/pkg/protocol"
"github.com/luxfi/threshold/pkg/taproot"
"github.com/luxfi/threshold/protocols/cmp"
"github.com/luxfi/threshold/protocols/example"
"github.com/luxfi/threshold/protocols/frost"
)
func XOR(id party.ID, ids party.IDSlice, n *test.Network) error {
h, err := protocol.NewMultiHandler(example.StartXOR(id, ids), nil)
if err != nil {
return err
}
test.HandlerLoop(id, h, n)
_, err = h.Result()
if err != nil {
return err
}
return nil
}
func CMPKeygen(id party.ID, ids party.IDSlice, threshold int, n *test.Network, pl *pool.Pool) (*cmp.Config, error) {
h, err := protocol.NewMultiHandler(cmp.Keygen(curve.Secp256k1{}, id, ids, threshold, pl), nil)
if err != nil {
return nil, err
}
test.HandlerLoop(id, h, n)
r, err := h.Result()
if err != nil {
return nil, err
}
return r.(*cmp.Config), nil
}
func CMPRefresh(c *cmp.Config, n *test.Network, pl *pool.Pool) (*cmp.Config, error) {
hRefresh, err := protocol.NewMultiHandler(cmp.Refresh(c, pl), nil)
if err != nil {
return nil, err
}
test.HandlerLoop(c.ID, hRefresh, n)
r, err := hRefresh.Result()
if err != nil {
return nil, err
}
return r.(*cmp.Config), nil
}
func CMPSign(c *cmp.Config, m []byte, signers party.IDSlice, n *test.Network, pl *pool.Pool) error {
h, err := protocol.NewMultiHandler(cmp.Sign(c, signers, m, pl), nil)
if err != nil {
return err
}
test.HandlerLoop(c.ID, h, n)
signResult, err := h.Result()
if err != nil {
return err
}
signature := signResult.(*ecdsa.Signature)
if !signature.Verify(c.PublicPoint(), m) {
return errors.New("failed to verify cmp signature")
}
return nil
}
func CMPPreSign(c *cmp.Config, signers party.IDSlice, n *test.Network, pl *pool.Pool) (*ecdsa.PreSignature, error) {
h, err := protocol.NewMultiHandler(cmp.Presign(c, signers, pl), nil)
if err != nil {
return nil, err
}
test.HandlerLoop(c.ID, h, n)
signResult, err := h.Result()
if err != nil {
return nil, err
}
preSignature := signResult.(*ecdsa.PreSignature)
if err = preSignature.Validate(); err != nil {
return nil, errors.New("failed to verify cmp presignature")
}
return preSignature, nil
}
func CMPPreSignOnline(c *cmp.Config, preSignature *ecdsa.PreSignature, m []byte, n *test.Network, pl *pool.Pool) error {
h, err := protocol.NewMultiHandler(cmp.PresignOnline(c, preSignature, m, pl), nil)
if err != nil {
return err
}
test.HandlerLoop(c.ID, h, n)
signResult, err := h.Result()
if err != nil {
return err
}
signature := signResult.(*ecdsa.Signature)
if !signature.Verify(c.PublicPoint(), m) {
return errors.New("failed to verify cmp signature")
}
return nil
}
func FrostKeygen(id party.ID, ids party.IDSlice, threshold int, n *test.Network) (*frost.Config, error) {
h, err := protocol.NewMultiHandler(frost.Keygen(curve.Secp256k1{}, id, ids, threshold), nil)
if err != nil {
return nil, err
}
test.HandlerLoop(id, h, n)
r, err := h.Result()
if err != nil {
return nil, err
}
return r.(*frost.Config), nil
}
func FrostSign(c *frost.Config, id party.ID, m []byte, signers party.IDSlice, n *test.Network) error {
h, err := protocol.NewMultiHandler(frost.Sign(c, signers, m), nil)
if err != nil {
return err
}
test.HandlerLoop(id, h, n)
r, err := h.Result()
if err != nil {
return err
}
signature := r.(frost.Signature)
if !signature.Verify(c.PublicKey, m) {
return errors.New("failed to verify frost signature")
}
return nil
}
func FrostKeygenTaproot(id party.ID, ids party.IDSlice, threshold int, n *test.Network) (*frost.TaprootConfig, error) {
h, err := protocol.NewMultiHandler(frost.KeygenTaproot(id, ids, threshold), nil)
if err != nil {
return nil, err
}
test.HandlerLoop(id, h, n)
r, err := h.Result()
if err != nil {
return nil, err
}
return r.(*frost.TaprootConfig), nil
}
func FrostSignTaproot(c *frost.TaprootConfig, id party.ID, m []byte, signers party.IDSlice, n *test.Network) error {
h, err := protocol.NewMultiHandler(frost.SignTaproot(c, signers, m), nil)
if err != nil {
return err
}
test.HandlerLoop(id, h, n)
r, err := h.Result()
if err != nil {
return err
}
signature := r.(taproot.Signature)
if !c.PublicKey.Verify(signature, m) {
return errors.New("failed to verify frost signature")
}
return nil
}
func All(id party.ID, ids party.IDSlice, threshold int, message []byte, n *test.Network, wg *sync.WaitGroup, pl *pool.Pool) error {
defer wg.Done()
// XOR
err := XOR(id, ids, n)
if err != nil {
return err
}
// CMP KEYGEN
keygenConfig, err := CMPKeygen(id, ids, threshold, n, pl)
if err != nil {
return err
}
// CMP REFRESH
refreshConfig, err := CMPRefresh(keygenConfig, n, pl)
if err != nil {
return err
}
// FROST KEYGEN
frostResult, err := FrostKeygen(id, ids, threshold, n)
if err != nil {
return err
}
// FROST KEYGEN TAPROOT
frostResultTaproot, err := FrostKeygenTaproot(id, ids, threshold, n)
if err != nil {
return err
}
signers := ids[:threshold+1]
if !signers.Contains(id) {
// Non-signers can exit early
return nil
}
// CMP SIGN
err = CMPSign(refreshConfig, message, signers, n, pl)
if err != nil {
return err
}
// CMP PRESIGN
preSignature, err := CMPPreSign(refreshConfig, signers, n, pl)
if err != nil {
return err
}
// CMP PRESIGN ONLINE
err = CMPPreSignOnline(refreshConfig, preSignature, message, n, pl)
if err != nil {
return err
}
// FROST SIGN
err = FrostSign(frostResult, id, message, signers, n)
if err != nil {
return err
}
// FROST SIGN TAPROOT
err = FrostSignTaproot(frostResultTaproot, id, message, signers, n)
if err != nil {
return err
}
return nil
}
func main() {
ids := party.IDSlice{"a", "b", "c", "d", "e", "f"}
threshold := 4
messageToSign := []byte("hello")
net := test.NewNetwork(ids)
var wg sync.WaitGroup
for _, id := range ids {
wg.Add(1)
go func(id party.ID) {
pl := pool.NewPool(0)
defer pl.TearDown()
if err := All(id, ids, threshold, messageToSign, net, &wg, pl); err != nil {
fmt.Println(err)
}
}(id)
}
wg.Wait()
}