func (rs *RS) Commit(ses *Session) []byte {
	scratch := make([]byte, 4)
	h := blake256.New()
	h.Write(msgCommit)
	h.Write(ses.sid)
	binary.LittleEndian.PutUint32(scratch, uint32(ses.run))
	h.Write(scratch)
	for i := range rs.ECDH {
		h.Write(rs.ECDH[i][:])
	}
	for i := range rs.SR {
		h.Write(rs.SR[i].Bytes())
	}
	for i := range rs.M {
		h.Write(rs.M[i])
	}
	return h.Sum(nil)
}
Commit commits to the contents of the reveal secrets message.
package messages
import (
	"bytes"
	"encoding"
	"encoding/binary"
	"io"
	"math/big"
	"strconv"
	"decred.org/cspp/dcnet"
	"decred.org/cspp/x25519"
	"github.com/decred/dcrd/crypto/blake256"
	"golang.org/x/crypto/ed25519"
)
type ServerError int
const (
	ErrAbortedSession ServerError = iota + 1
	ErrInvalidUnmixed
)
func (e ServerError) Error() string {
	switch e {
	case 0:
		return "no error"
	case ErrAbortedSession:
		return "server aborted mix session"
	case ErrInvalidUnmixed:
		return "submitted unmixed data is invalid"
	default:
		return "unknown server error code " + strconv.Itoa(int(e))
	}
}
var (
	msgPR      = []byte("PR")
	msgSidH    = []byte("sidH")
	msgSidHPre = []byte("sidHPre")
	msgCommit  = []byte("COMMIT")
)
func putInt(scratch []byte, v int) []byte {
	binary.BigEndian.PutUint64(scratch, uint64(v))
	return scratch
}
func writeSignedByteSlice(w io.Writer, scratch []byte, data []byte) {
	w.Write(putInt(scratch, len(data)))
	w.Write(data)
}
type Signed interface {
	VerifySignature(pub ed25519.PublicKey) bool
}
type Session struct {
	sid     []byte
	vk      []ed25519.PublicKey
	run     int
	sidH    []byte
	sidHPre []byte
}
func NewSession(sid []byte, run int, vk []ed25519.PublicKey) *Session {
	runBytes := putInt(make([]byte, 8), run)
	h := blake256.New()
	h.Write(msgSidH)
	h.Write(sid)
	for _, k := range vk {
		if l := len(k); l != ed25519.PublicKeySize {
			panic("messages: bad ed25519 public key length: " + strconv.Itoa(l))
		}
		h.Write(k)
	}
	h.Write(runBytes)
	sidH := h.Sum(nil)
	h.Reset()
	h.Write(msgSidHPre)
	h.Write(sid)
	h.Write(runBytes)
	sidHPre := h.Sum(nil)
	return &Session{
		sid:     sid,
		vk:      vk,
		run:     run,
		sidH:    sidH,
		sidHPre: sidHPre,
	}
}
type BinaryRepresentable interface {
	encoding.BinaryMarshaler
	encoding.BinaryUnmarshaler
}
type PR struct {
	Identity       ed25519.PublicKey  
	PairCommitment []byte             
	Unmixed        []byte             
	MessageCount   int                
	Signature      []byte
}
func PairRequest(pk ed25519.PublicKey, sk ed25519.PrivateKey, commitment, unmixed []byte, mixes int) *PR {
	pr := &PR{
		Identity:       pk,
		PairCommitment: commitment,
		Unmixed:        unmixed,
		MessageCount:   mixes,
	}
	buf := new(bytes.Buffer)
	pr.WriteSigned(buf)
	pr.Signature = ed25519.Sign(sk, buf.Bytes())
	return pr
}
func (pr *PR) WriteSigned(w io.Writer) {
	scratch := make([]byte, 8)
	w.Write(msgPR)
	writeSignedByteSlice(w, scratch, pr.Identity)
	writeSignedByteSlice(w, scratch, pr.PairCommitment)
	writeSignedByteSlice(w, scratch, pr.Unmixed)
	w.Write(putInt(scratch, pr.MessageCount))
}
func (pr *PR) VerifySignature(pub ed25519.PublicKey) bool {
	if len(pr.Signature) != ed25519.SignatureSize {
		return false
	}
	buf := new(bytes.Buffer)
	pr.WriteSigned(buf)
	return ed25519.Verify(pub, buf.Bytes(), pr.Signature)
}
type BR struct {
	Vk            []ed25519.PublicKey
	MessageCounts []int
	Sid           []byte
	Err           ServerError
}
func BeginRun(vk []ed25519.PublicKey, mixes []int, sid []byte) *BR {
	return &BR{
		Vk:            vk,
		MessageCounts: mixes,
		Sid:           sid,
	}
}
func (br *BR) ServerError() error {
	if br.Err == 0 {
		return nil
	}
	return br.Err
}
type KE struct {
	Run        int               
	ECDH       []*x25519.Public  
	Commitment []byte            
}
func KeyExchange(ecdh []*x25519.Public, commitment []byte, ses *Session) *KE {
	return &KE{
		Run:        ses.run,
		ECDH:       ecdh,
		Commitment: commitment,
	}
}
type KEs struct {
	KEs []*KE
	BR   
	Err ServerError
}
func (kes *KEs) ServerError() error {
	if kes.Err == 0 {
		return nil
	}
	return kes.Err
}
type SR struct {
	Run   int
	DCMix [][]*big.Int
}
func SlotReserve(dcmix [][]*big.Int, s *Session) *SR {
	return &SR{
		Run:   s.run,
		DCMix: dcmix,
	}
}
type RM struct {
	Run           int
	Roots         []*big.Int
	RevealSecrets bool
	BR             
	Err           ServerError
}
func (rm *RM) ServerError() error {
	if rm.Err == 0 {
		return nil
	}
	return rm.Err
}
func RecoveredMessages(roots []*big.Int, s *Session) *RM {
	return &RM{
		Run:   s.run,
		Roots: roots,
	}
}
type DC struct {
	Run           int
	DCNet         []*dcnet.Vec
	RevealSecrets bool
}
func DCNet(dcs []*dcnet.Vec, s *Session) *DC {
	return &DC{
		Run:   s.run,
		DCNet: dcs,
	}
}
type CM struct {
	Mix           BinaryRepresentable
	RevealSecrets bool
	BR             
	Err           ServerError
}
func (cm *CM) ServerError() error {
	if cm.Err == 0 {
		return nil
	}
	return cm.Err
}
func ConfirmMix(mix BinaryRepresentable) *CM {
	return &CM{Mix: mix}
}
type RS struct {
	ECDH []*x25519.Scalar
	SR   []*big.Int
	M    [][]byte
}
func RevealSecrets(ecdh []*x25519.KX, sr []*big.Int, m [][]byte) *RS {
	rs := &RS{
		ECDH: make([]*x25519.Scalar, len(ecdh)),
		SR:   sr,
		M:    m,
	}
	for i := range ecdh {
		rs.ECDH[i] = &ecdh[i].Scalar
	}
	return rs
}