wuka bb1e3cf140 33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00
33
2026-09-23 16:09:17 +02:00

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

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

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

github.com/example/lafsession

Replace the module path in go.mod when publishing under your own import path.

Description
No description provided
Readme 58 KiB
Languages
Go 100%