mirror of
https://github.com/luxfi/threshold.git
synced 2026-07-27 04:01:59 +00:00
274 lines
6.2 KiB
Go
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()
|
|
}
|