func MakeCert(epoch uint64, signature []byte) []byte {
	buf := new(bytes.Buffer)
	if err := binary.Write(buf, binary.BigEndian, epoch); err != nil {
		panic(err)
	}
	if err := binary.Write(buf, binary.BigEndian, signature); err != nil {
		panic(err)
	}
	return buf.Bytes()
}
MakeCert composes a USIG certificate which is 64-bit big-endian
encoded epoch value followed by serialized USIG signature.
package sgx
import (
	"bytes"
	"crypto"
	"crypto/sha256"
	"crypto/x509"
	"encoding/binary"
	"fmt"
	"github.com/hyperledger-labs/minbft/usig"
)
type USIG struct {
	*USIGEnclave
}
var _ usig.USIG = new(USIG)
func New(enclaveFile string, sealedKey []byte) (*USIG, error) {
	enclave, err := NewUSIGEnclave(enclaveFile, sealedKey)
	if err != nil {
		return nil, fmt.Errorf("failed to create USIG enclave: %v", err)
	}
	return &USIG{enclave}, nil
}
func (u *USIG) CreateUI(message []byte) (*usig.UI, error) {
	counter, signature, err := u.USIGEnclave.CreateUI(messageDigest(message))
	if err != nil {
		return nil, err
	}
	return &usig.UI{
		Counter: counter,
		Cert:    MakeCert(u.epoch, signature),
	}, nil
}
func (u *USIG) VerifyUI(message []byte, ui *usig.UI, usigID []byte) error {
	return VerifyUI(message, ui, usigID)
}
func (u *USIG) ID() []byte {
	id, err := MakeID(u.Epoch(), u.PublicKey())
	if err != nil {
		panic(err)
	}
	return id
}
func VerifyUI(message []byte, ui *usig.UI, usigID []byte) error {
	epoch, pubKey, err := ParseID(usigID)
	if err != nil {
		return fmt.Errorf("failed to parse USIG ID: %s", err)
	}
	uiEpoch, signature, err := ParseCert(ui.Cert)
	if err != nil {
		return fmt.Errorf("failed to parse UI cert: %s", err)
	}
	if uiEpoch != epoch {
		return fmt.Errorf("epoch value mismatch")
	}
	return VerifySignature(pubKey, messageDigest(message), epoch, ui.Counter, signature)
}
func messageDigest(message []byte) Digest {
	return sha256.Sum256(message)
}
func MakeID(epoch uint64, publicKey interface{}) ([]byte, error) {
	publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		return nil, fmt.Errorf("failed to serialize public key: %s", err)
	}
	buf := new(bytes.Buffer)
	if err := binary.Write(buf, binary.BigEndian, epoch); err != nil {
		panic(err)
	}
	if err := binary.Write(buf, binary.BigEndian, publicKeyBytes); err != nil {
		panic(err)
	}
	return buf.Bytes(), nil
}
func ParseID(usigID []byte) (epoch uint64, pubKey crypto.PublicKey, err error) {
	buf := bytes.NewBuffer(usigID)
	err = binary.Read(buf, binary.BigEndian, &epoch)
	if err != nil {
		return uint64(0), nil, fmt.Errorf("failed to extract epoch from USIG ID: %s", err)
	}
	pubKey, err = x509.ParsePKIXPublicKey(buf.Bytes())
	if err != nil {
		return uint64(0), nil, fmt.Errorf("failed to parse public key: %s", err)
	}
	return epoch, pubKey, err
}