package mpc import ( "github.com/onsonr/sonr/crypto/core/curves" "github.com/onsonr/sonr/crypto/core/protocol" "github.com/onsonr/sonr/crypto/tecdsa/dklsv1" ) // GenEnclave generates a new MPC keyshare func GenEnclave(nonce []byte) (Enclave, error) { curve := curves.K256() valKs := dklsv1.NewAliceDkg(curve, protocol.Version1) userKs := dklsv1.NewBobDkg(curve, protocol.Version1) aErr, bErr := RunProtocol(userKs, valKs) if err := checkIteratedErrors(aErr, bErr); err != nil { return nil, err } valRes, err := valKs.Result(protocol.Version1) if err != nil { return nil, err } userRes, err := userKs.Result(protocol.Version1) if err != nil { return nil, err } return newEnclave(valRes, userRes, nonce) } // ExecuteSigning runs the MPC signing protocol func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) ([]byte, error) { aErr, bErr := RunProtocol(signFuncVal, signFuncUser) if err := checkIteratedErrors(aErr, bErr); err != nil { return nil, err } out, err := signFuncUser.Result(protocol.Version1) if err != nil { return nil, err } s, err := dklsv1.DecodeSignature(out) if err != nil { return nil, err } sig, err := serializeSignature(s) if err != nil { return nil, err } return sig, nil } // ExecuteRefresh runs the MPC refresh protocol func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc, nonce []byte) (Enclave, error) { aErr, bErr := RunProtocol(refreshFuncVal, refreshFuncUser) if err := checkIteratedErrors(aErr, bErr); err != nil { return nil, err } valRefreshResult, err := refreshFuncVal.Result(protocol.Version1) if err != nil { return nil, err } userRefreshResult, err := refreshFuncUser.Result(protocol.Version1) if err != nil { return nil, err } return newEnclave(valRefreshResult, userRefreshResult, nonce) } // For DKG bob starts first. For refresh and sign, Alice starts first. func RunProtocol(firstParty protocol.Iterator, secondParty protocol.Iterator) (error, error) { var ( message *protocol.Message aErr error bErr error ) for aErr != protocol.ErrProtocolFinished || bErr != protocol.ErrProtocolFinished { // Crank each protocol forward one iteration message, bErr = firstParty.Next(message) if bErr != nil && bErr != protocol.ErrProtocolFinished { return nil, bErr } message, aErr = secondParty.Next(message) if aErr != nil && aErr != protocol.ErrProtocolFinished { return aErr, nil } } return aErr, bErr }