func MergeMultisigTransactions(stxsBytes ...[]byte) (txid string, stxBytes []byte, err error) {
	if len(stxsBytes) < 2 {
		err = errMsigMergeLessThanTwo
		return
	}
	var sig types.MultisigSig
	var refAddr *types.Address
	var refTx types.Transaction
	var refAuthAddr types.Address
	for _, partStxBytes := range stxsBytes {
		partStx := types.SignedTxn{}
		err = msgpack.Decode(partStxBytes, &partStx)
		if err != nil {
			return
		}
		partMa, innerErr := MultisigAccountFromSig(partStx.Msig)
		if innerErr != nil {
			err = innerErr
			return
		}
		partAddr, innerErr := partMa.Address()
		if innerErr != nil {
			err = innerErr
			return
		}
		if refAddr == nil {
			refAddr = &partAddr
			sig.Version = partStx.Msig.Version
			sig.Threshold = partStx.Msig.Threshold
			sig.Subsigs = make([]types.MultisigSubsig, len(partStx.Msig.Subsigs))
			for i := 0; i < len(sig.Subsigs); i++ {
				c := make([]byte, len(partStx.Msig.Subsigs[i].Key))
				copy(c, partStx.Msig.Subsigs[i].Key)
				sig.Subsigs[i].Key = c
			}
			refTx = partStx.Txn
			refAuthAddr = partStx.AuthAddr
		}
		if partAddr != *refAddr {
			err = errMsigMergeKeysMismatch
			return
		}
		if partStx.AuthAddr != refAuthAddr {
			err = errMsigMergeAuthAddrMismatch
			return
		}
		zeroSig := types.Signature{}
		for i := 0; i < len(sig.Subsigs); i++ {
			mSubsig := partStx.Msig.Subsigs[i]
			if mSubsig.Sig != zeroSig {
				if sig.Subsigs[i].Sig == zeroSig {
					sig.Subsigs[i].Sig = mSubsig.Sig
				} else if sig.Subsigs[i].Sig != mSubsig.Sig {
					err = errMsigMergeInvalidDups
					return
				}
			}
		}
	}
	stx := types.SignedTxn{
		Msig:     sig,
		Txn:      refTx,
		AuthAddr: refAuthAddr,
	}
	stxBytes = msgpack.Encode(stx)
	txid = txIDFromTransaction(refTx)
	return
}
MergeMultisigTransactions merges the given (partially) signed multisig transactions, and
returns an encoded signed multisig transaction with the component signatures.
package crypto
import (
	"bytes"
	"crypto/rand"
	"crypto/sha512"
	"encoding/base32"
	"encoding/binary"
	"fmt"
	"golang.org/x/crypto/ed25519"
	"github.com/algorand/go-algorand-sdk/encoding/msgpack"
	"github.com/algorand/go-algorand-sdk/logic"
	"github.com/algorand/go-algorand-sdk/types"
)
var txidPrefix = []byte("TX")
var tgidPrefix = []byte("TG")
var bidPrefix = []byte("aB")
var bytesPrefix = []byte("MX")
var programPrefix = []byte("Program")
var programDataPrefix = []byte("ProgData")
var appIDPrefix = []byte("appID")
func RandomBytes(s []byte) {
	_, err := rand.Read(s)
	if err != nil {
		panic(err)
	}
}
func GenerateAddressFromSK(sk []byte) (types.Address, error) {
	edsk := ed25519.PrivateKey(sk)
	var a types.Address
	pk := edsk.Public()
	n := copy(a[:], []byte(pk.(ed25519.PublicKey)))
	if n != ed25519.PublicKeySize {
		return [32]byte{}, fmt.Errorf("generated public key has the wrong size, expected %d, got %d", ed25519.PublicKeySize, n)
	}
	return a, nil
}
func SignTransaction(sk ed25519.PrivateKey, tx types.Transaction) (txid string, stxBytes []byte, err error) {
	s, txid, err := rawSignTransaction(sk, tx)
	if err != nil {
		return
	}
	stx := types.SignedTxn{
		Sig: s,
		Txn: tx,
	}
	a, err := GenerateAddressFromSK(sk)
	if err != nil {
		return
	}
	if stx.Txn.Sender != a {
		stx.AuthAddr = a
	}
	stxBytes = msgpack.Encode(stx)
	return
}
func rawTransactionBytesToSign(tx types.Transaction) []byte {
	encodedTx := msgpack.Encode(tx)
	msgParts := [][]byte{txidPrefix, encodedTx}
	return bytes.Join(msgParts, nil)
}
func txIDFromRawTxnBytesToSign(toBeSigned []byte) (txid string) {
	txidBytes := sha512.Sum512_256(toBeSigned)
	txid = base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(txidBytes[:])
	return
}
func txIDFromTransaction(tx types.Transaction) (txid string) {
	txidBytes := TransactionID(tx)
	txid = base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(txidBytes[:])
	return
}
func TransactionID(tx types.Transaction) (txid []byte) {
	toBeSigned := rawTransactionBytesToSign(tx)
	txid32 := sha512.Sum512_256(toBeSigned)
	txid = txid32[:]
	return
}
func TransactionIDString(tx types.Transaction) (txid string) {
	txid = base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(TransactionID(tx))
	return
}
func rawSignTransaction(sk ed25519.PrivateKey, tx types.Transaction) (s types.Signature, txid string, err error) {
	toBeSigned := rawTransactionBytesToSign(tx)
	signature := ed25519.Sign(sk, toBeSigned)
	n := copy(s[:], signature)
	if n != len(s) {
		err = errInvalidSignatureReturned
		return
	}
	txid = txIDFromRawTxnBytesToSign(toBeSigned)
	return
}
func SignBytes(sk ed25519.PrivateKey, bytesToSign []byte) (signature []byte, err error) {
	toBeSigned := bytes.Join([][]byte{bytesPrefix, bytesToSign}, nil)
	signature = ed25519.Sign(sk, toBeSigned)
	return
}
func VerifyBytes(pk ed25519.PublicKey, message, signature []byte) bool {
	msgParts := [][]byte{bytesPrefix, message}
	toBeVerified := bytes.Join(msgParts, nil)
	return ed25519.Verify(pk, toBeVerified, signature)
}
func SignBid(sk ed25519.PrivateKey, bid types.Bid) (signedBid []byte, err error) {
	encodedBid := msgpack.Encode(bid)
	msgParts := [][]byte{bidPrefix, encodedBid}
	toBeSigned := bytes.Join(msgParts, nil)
	sig := ed25519.Sign(sk, toBeSigned)
	var s types.Signature
	n := copy(s[:], sig)
	if n != len(s) {
		err = errInvalidSignatureReturned
		return
	}
	sb := types.SignedBid{
		Bid: bid,
		Sig: s,
	}
	nf := types.NoteField{
		Type:      types.NoteBid,
		SignedBid: sb,
	}
	signedBid = msgpack.Encode(nf)
	return
}
type signer func() (signature types.Signature, err error)
func multisigSingle(sk ed25519.PrivateKey, ma MultisigAccount, customSigner signer) (msig types.MultisigSig, myIndex int, err error) {
	myIndex = len(ma.Pks)
	myPublicKey := sk.Public().(ed25519.PublicKey)
	for i := 0; i < len(ma.Pks); i++ {
		if bytes.Equal(myPublicKey, ma.Pks[i]) {
			myIndex = i
		}
	}
	if myIndex == len(ma.Pks) {
		err = errMsigInvalidSecretKey
		return
	}
	msig.Version = ma.Version
	msig.Threshold = ma.Threshold
	msig.Subsigs = make([]types.MultisigSubsig, len(ma.Pks))
	for i := 0; i < len(ma.Pks); i++ {
		c := make([]byte, len(ma.Pks[i]))
		copy(c, ma.Pks[i])
		msig.Subsigs[i].Key = c
	}
	rawSig, err := customSigner()
	if err != nil {
		return
	}
	msig.Subsigs[myIndex].Sig = rawSig
	return
}
func SignMultisigTransaction(sk ed25519.PrivateKey, ma MultisigAccount, tx types.Transaction) (txid string, stxBytes []byte, err error) {
	err = ma.Validate()
	if err != nil {
		return
	}
	customSigner := func() (rawSig types.Signature, err error) {
		rawSig, txid, err = rawSignTransaction(sk, tx)
		return rawSig, err
	}
	sig, _, err := multisigSingle(sk, ma, customSigner)
	if err != nil {
		return
	}
	stx := types.SignedTxn{
		Msig: sig,
		Txn:  tx,
	}
	maAddress, err := ma.Address()
	if err != nil {
		return
	}
	if stx.Txn.Sender != maAddress {
		stx.AuthAddr = maAddress
	}
	stxBytes = msgpack.Encode(stx)
	return
}