crypto

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package crypto implements the Noise IK handshake pattern used by WireGuard.

Pattern: Noise_IK_25519_ChaChaPoly_BLAKE2s

Message layout:

-> e, es, s, ss   (initiator sends message 1: 32+32+16+16 = 96 bytes + payload)
<- e, ee, se      (responder sends message 2: 32+16 = 48 bytes + payload)

Index

Constants

View Source
const (
	// NoiseProtocolName is used to initialise the hash/chaining key.
	NoiseProtocolName = "Noise_IK_25519_ChaChaPoly_BLAKE2s"
	// NoisePrologue is the karadul-specific prologue.
	NoisePrologue = "karadul-v1"
)
View Source
const (
	// WindowSize is the number of packets tracked in the sliding window.
	// Must be a multiple of 64.
	WindowSize = 2048
)

Variables

This section is empty.

Functions

func Counter64

func Counter64(n uint64) []byte

Counter64 encodes n as little-endian 8 bytes.

func DecryptAEAD

func DecryptAEAD(key [32]byte, nonce uint64, ciphertext, aad []byte) ([]byte, error)

DecryptAEAD decrypts and authenticates ciphertext (including 16-byte tag).

func DecryptZeroNonce

func DecryptZeroNonce(key [32]byte, ciphertext, aad []byte) ([]byte, error)

DecryptZeroNonce decrypts with a zero nonce.

func EncryptAEAD

func EncryptAEAD(key [32]byte, nonce uint64, plaintext, aad []byte) ([]byte, error)

EncryptAEAD encrypts plaintext with ChaCha20-Poly1305. nonce is a 64-bit counter encoded as little-endian in the 12-byte nonce (bytes 4–11). aad is additional authenticated data (may be nil). Returns ciphertext || 16-byte auth tag.

func EncryptZeroNonce

func EncryptZeroNonce(key [32]byte, plaintext, aad []byte) ([]byte, error)

EncryptZeroNonce encrypts with a zero nonce (used during Noise handshake).

func HKDF

func HKDF(secret, salt, info []byte) [32]byte

HKDF derives a 32-byte key from secret, salt and info using BLAKE2s as PRF. This is a simplified Extract+Expand without the counter-based iteration required by full HKDF — suitable for single 32-byte output.

func HMAC

func HMAC(key, data []byte) [32]byte

HMAC computes BLAKE2s-keyed MAC: BLAKE2s(key, data). key must be 1–32 bytes.

func Hash

func Hash(data []byte) [32]byte

Hash computes a BLAKE2s-256 hash of data.

func HashMany

func HashMany(inputs ...[]byte) [32]byte

HashMany computes BLAKE2s-256 over the concatenation of all inputs.

func MixHash

func MixHash(h [32]byte, data []byte) [32]byte

MixHash mixes data into the handshake hash state.

func MixKey

func MixKey(ck [32]byte, input []byte) ([32]byte, [32]byte)

MixKey mixes input into the chaining key using HKDF-style extract/expand. Returns (new chaining key, new temp key).

func SaveKeyPair

func SaveKeyPair(kp KeyPair, dir string) error

SaveKeyPair writes private and public keys to files under dir. Private key is in <dir>/private.key, public in <dir>/public.key.

func Split

func Split(ck [32]byte) (k1, k2 [32]byte)

Split derives two 32-byte transport keys from the chaining key.

Types

type HandshakeState

type HandshakeState struct {
	// contains filtered or unexported fields
}

HandshakeState holds the state of an in-progress Noise IK handshake.

func InitiatorHandshake

func InitiatorHandshake(localStatic KeyPair, remoteStatic Key) (*HandshakeState, error)

InitiatorHandshake creates a HandshakeState for the initiator role. localStatic is our long-term key pair; remoteStatic is the peer's public key.

func ResponderHandshake

func ResponderHandshake(localStatic KeyPair) (*HandshakeState, error)

ResponderHandshake creates a HandshakeState for the responder role.

func (*HandshakeState) ReadMessage1

func (hs *HandshakeState) ReadMessage1(msg []byte) error

ReadMessage1 processes the initiator's first handshake message on the responder.

func (*HandshakeState) ReadMessage2

func (hs *HandshakeState) ReadMessage2(msg []byte) error

ReadMessage2 processes the responder's reply on the initiator.

func (*HandshakeState) RemoteStaticKey

func (hs *HandshakeState) RemoteStaticKey() Key

RemoteStaticKey returns the authenticated remote static public key. Valid only after ReadMessage1 (responder) or after completing the handshake.

func (*HandshakeState) TransportKeys

func (hs *HandshakeState) TransportKeys() (send, recv [32]byte, err error)

TransportKeys derives the final send/recv symmetric keys. Call only after a complete handshake (nMsg == 2).

func (*HandshakeState) WriteMessage1

func (hs *HandshakeState) WriteMessage1() ([]byte, error)

WriteMessage1 produces the initiator's first handshake message. Returns the 96-byte message.

func (*HandshakeState) WriteMessage2

func (hs *HandshakeState) WriteMessage2() ([]byte, error)

WriteMessage2 produces the responder's reply message.

type Key

type Key [32]byte

Key is a 32-byte Curve25519 key.

func ECDH

func ECDH(priv, pub Key) (Key, error)

ECDH performs a Diffie-Hellman exchange: returns shared secret.

func KeyFromBase64

func KeyFromBase64(s string) (Key, error)

KeyFromBase64 parses a base64-encoded key.

func KeyFromHex

func KeyFromHex(s string) (Key, error)

KeyFromHex parses a hex-encoded key.

func PublicFromPrivate

func PublicFromPrivate(priv Key) (Key, error)

PublicFromPrivate derives the public key from a private key.

func (Key) Hex

func (k Key) Hex() string

Hex returns the key as a lowercase hex string.

func (Key) IsZero

func (k Key) IsZero() bool

IsZero reports whether the key is all zeros.

func (Key) String

func (k Key) String() string

String returns the key as a base64-encoded string.

type KeyPair

type KeyPair struct {
	Private Key
	Public  Key
}

KeyPair holds a Curve25519 private/public key pair.

func GenerateKeyPair

func GenerateKeyPair() (KeyPair, error)

GenerateKeyPair creates a new random Curve25519 key pair.

func LoadKeyPair

func LoadKeyPair(dir string) (KeyPair, error)

LoadKeyPair reads key files from dir.

type ReplayWindow

type ReplayWindow struct {
	// contains filtered or unexported fields
}

ReplayWindow is a thread-safe sliding window replay filter. It tracks which counter values have been seen and rejects duplicates or packets that fall behind the window floor.

func (*ReplayWindow) Advance

func (w *ReplayWindow) Advance(counter uint64)

Advance marks counter as seen and advances the window if necessary. Should be called only after the packet has been authenticated.

func (*ReplayWindow) Check

func (w *ReplayWindow) Check(counter uint64) bool

Check returns true if counter is acceptable (not a replay, not too old). It does NOT advance the window; call Advance after authenticating the packet.

func (*ReplayWindow) Reset

func (w *ReplayWindow) Reset()

Reset clears the window and resets the floor counter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL