# lafsession Go package: mutually authenticated AEAD session for opaque binary payloads (LAF envelopes) over a caller-provided transport. ## Algorithms | Role | Algorithm | |------|-----------| | Identity | Ed25519 | | Ephemeral ECDH | X25519 | | KDF | HKDF-SHA256 | | Record AEAD | ChaCha20-Poly1305 | | Anti-replay | sliding bit window (default 1024) | Protocol version `1`, suite `X25519 + ChaCha20-Poly1305`. ## Handshake ``` ClientHello → ServerHello → ClientFinished → ServerFinished ``` Transcript binds both ephemeral and identity public keys. HKDF info includes protocol label, version, suite, and transcript hash. Keys are derived at ClientFinished; ServerFinished is identity confirmation only. ## Record ``` type (1) || seq (8 BE) || ChaCha20-Poly1305(ciphertext ‖ tag) ``` Nonce = `0x00000000 ‖ seq`. AAD = `type ‖ seq`. Payload is opaque. ## Server ```go id, err := lafsession.GenerateIdentity() s, err := lafsession.New(lafsession.Config{ Identity: id, Role: lafsession.RoleServer, AcceptPeer: func(pub []byte) bool { return pinned[lafsession.FingerprintOf(pub)] }, }) serverHello, err := s.HandleHandshake(clientHello) _, err = s.HandleHandshake(clientFinished) sf, err := s.SendFinished() frame, err := s.Seal(lafBytes) // frame valid until next Seal/Close laf, err := s.Open(frame) // laf valid until next Open // zero-alloc when caller owns buffers: // frame, err = s.SealTo(dst[:0], lafBytes) // laf, err = s.OpenTo(out[:0], frame) closeFrame, err := s.Close() ``` ## Client ```go c, err := lafsession.New(lafsession.Config{ Identity: clientID, Role: lafsession.RoleClient, AcceptPeer: func(pub []byte) bool { return lafsession.FingerprintOf(pub) == expectedServerFP }, }) ch, err := c.StartHandshake() cf, err := c.HandleHandshake(serverHello) _, err = c.HandleHandshake(serverFinished) frame, err := c.Seal(lafBytes) laf, err := c.Open(frame) ``` ## Errors `ErrNotEstablished`, `ErrAlreadyEstablished`, `ErrIdentityRejected`, `ErrBadVersion`, `ErrBadCipher`, `ErrBadSignature`, `ErrBadTag`, `ErrReplay`, `ErrHandshakeState`, `ErrShortMessage`, `ErrClosed`. ## Module ```text wkgit.wk19.lol/wkgit/lafsession ``` Replace the module path in `go.mod` when publishing under your own import path.