func (b *Machine) GenActOne() ([ActOneSize]byte, error) {
	var (
		err    error
		actOne [ActOneSize]byte
	)
	b.localEphemeral, err = b.ephemeralGen()
	if err != nil {
		return actOne, err
	}
	e := b.localEphemeral.PubKey().SerializeCompressed()
	b.mixHash(e)
	authPayload := b.EncryptAndHash([]byte{})
	actOne[0] = HandshakeVersion
	copy(actOne[1:34], e)
	copy(actOne[34:], authPayload)
	return actOne, nil
}
GenActOne generates the initial packet (act one) to be sent from initiator
to responder. During act one the initiator generates an ephemeral key and
hashes it into the handshake digest. Future payloads are encrypted with a key
derived from this result.
-> e
package cxnoise
import (
	"crypto/cipher"
	"crypto/sha256"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"math"
	"time"
	"golang.org/x/crypto/chacha20poly1305"
	"golang.org/x/crypto/hkdf"
	"github.com/mit-dci/lit/crypto/koblitz"
)
const (
	protocolName = "Noise_XX_secp256k1_ChaChaPoly_SHA256"
	macSize = 16
	lengthHeaderSize = 2
	keyRotationInterval = 1000
	handshakeReadTimeout = time.Second * 5  
)
func ecdh(pub *koblitz.PublicKey, priv *koblitz.PrivateKey) []byte {
	s := &koblitz.PublicKey{}
	x, y := koblitz.S256().ScalarMult(pub.X, pub.Y, priv.D.Bytes())
	s.X = x
	s.Y = y
	h := sha256.Sum256(s.SerializeCompressed())
	return h[:]
}
type cipherState struct {
	nonce uint64
	secretKey [32]byte
	salt [32]byte
	cipher cipher.AEAD
}
func (c *cipherState) Encrypt(associatedData, cipherText, plainText []byte) []byte {
	defer func() {
		c.nonce++
		if c.nonce == keyRotationInterval {
			c.rotateKey()
		}
	}()
	var nonce [12]byte
	binary.LittleEndian.PutUint64(nonce[4:], c.nonce)
	return c.cipher.Seal(cipherText, nonce[:], plainText, associatedData)
}
func (c *cipherState) Decrypt(associatedData, plainText, cipherText []byte) ([]byte, error) {
	defer func() {
		c.nonce++
		if c.nonce == keyRotationInterval {
			c.rotateKey()
		}
	}()
	var nonce [12]byte
	binary.LittleEndian.PutUint64(nonce[4:], c.nonce)
	return c.cipher.Open(plainText, nonce[:], cipherText, associatedData)
}
func (c *cipherState) InitializeKey(key [32]byte) {
	c.secretKey = key
	c.nonce = 0
	c.cipher, _ = chacha20poly1305.New(c.secretKey[:])
}
func (c *cipherState) InitializeKeyWithSalt(salt, key [32]byte) {
	c.salt = salt
	c.InitializeKey(key)
}
func (c *cipherState) rotateKey() {
	var (
		info    []byte
		nextKey [32]byte
	)
	oldKey := c.secretKey
	h := hkdf.New(sha256.New, oldKey[:], c.salt[:], info)
	h.Read(c.salt[:])
	h.Read(nextKey[:])
	c.InitializeKey(nextKey)
}
type symmetricState struct {
	cipherState
	chainingKey [32]byte
	tempKey [32]byte
	handshakeDigest [32]byte
}
func (s *symmetricState) mixKey(input []byte) {
	var info []byte
	secret := input
	salt := s.chainingKey
	h := hkdf.New(sha256.New, secret, salt[:], info)
	h.Read(s.chainingKey[:])
	h.Read(s.tempKey[:])
	s.InitializeKey(s.tempKey)
}
func (s *symmetricState) mixHash(data []byte) {
	h := sha256.New()
	h.Write(s.handshakeDigest[:])
	h.Write(data)
	copy(s.handshakeDigest[:], h.Sum(nil))
}
func (s *symmetricState) EncryptAndHash(plaintext []byte) []byte {
	ciphertext := s.Encrypt(s.handshakeDigest[:], nil, plaintext)
	s.mixHash(ciphertext)
	return ciphertext
}
func (s *symmetricState) DecryptAndHash(ciphertext []byte) ([]byte, error) {
	plaintext, err := s.Decrypt(s.handshakeDigest[:], nil, ciphertext)
	if err != nil {
		return nil, err
	}
	s.mixHash(ciphertext)
	return plaintext, nil
}
func (s *symmetricState) InitializeSymmetric(protocolName []byte) {
	var empty [32]byte
	s.handshakeDigest = sha256.Sum256(protocolName)
	s.chainingKey = s.handshakeDigest
	s.InitializeKey(empty)  
}
type handshakeState struct {
	symmetricState
	initiator bool
	localStatic    *koblitz.PrivateKey
	localEphemeral *koblitz.PrivateKey
	remoteStatic    *koblitz.PublicKey
	remoteEphemeral *koblitz.PublicKey
}
func newHandshakeState(initiator bool, prologue []byte,
	localStatic *koblitz.PrivateKey) handshakeState {
	h := handshakeState{
		initiator:   initiator,
		localStatic: localStatic,
	}
	h.InitializeSymmetric([]byte(protocolName))
	h.mixHash(prologue)
	return h
}
func EphemeralGenerator(gen func() (*koblitz.PrivateKey, error)) func(*Machine) {
	return func(m *Machine) {
		m.ephemeralGen = gen
	}
}
type Machine struct {
	sendCipher cipherState
	recvCipher cipherState
	ephemeralGen func() (*koblitz.PrivateKey, error)
	handshakeState
	nextCipherHeader [lengthHeaderSize + macSize]byte
	nextCipherText [math.MaxUint16 + macSize]byte
}
func NewNoiseMachine(initiator bool, prologue []byte, localStatic *koblitz.PrivateKey,
	options ...func(*Machine)) *Machine {
	handshake := newHandshakeState(initiator, prologue, localStatic)
	m := &Machine{handshakeState: handshake}
	m.ephemeralGen = func() (*koblitz.PrivateKey, error) {
		return koblitz.NewPrivateKey(koblitz.S256())
	}
	for _, option := range options {
		option(m)
	}
	return m
}
const (
	HandshakeVersion = byte(1)  
	ActOneSize = 50
	ActTwoSize = 83
	ActThreeSize = 66
)