Security Model

Security is a primary design goal in Hayate. It establishes a multi-layer trust topology at the application layer over transport-layer encrypted QUIC connections.

Here is a breakdown of the cryptographic primitives and mechanisms used to ensure data privacy, authenticity, and integrity.


Cryptographic Primitives

Hayate relies on industry-standard, high-performance cryptography:

  • Key Agreement: Diffie-Hellman key exchange via X25519 (x25519-dalek crate).
  • Key Derivation: HKDF-SHA256 (hkdf crate) for deriving the final symmetric key.
  • Symmetric Encryption: Authenticated Encryption with Associated Data (AEAD) using AES-256-GCM (hardware-accelerated where available) or ChaCha20-Poly1305 (ring and chacha20poly1305 crates).
  • Integrity Hashing: Stream checksums computed using BLAKE3, Rapidhash, or SHA-256.

1. Ephemeral Key Exchange (X25519 + HKDF)

Every Hayate transfer establishes a unique session key:

  1. Both sides generate a fresh, random ephemeral X25519 keypair.
  2. Public keys are exchanged over the QUIC channel.
  3. A shared secret is computed via Diffie-Hellman.
  4. HKDF-SHA256 expands the shared secret into a 32-byte AEAD key:
    • Pairing Mode — the code phrase acts as the HKDF salt, so only peers who know the exact phrase can derive the same key.
    • Direct Mode — a fixed salt (hayate-v2-default-salt) is used; no passphrase needed but no phrase-based authentication.

Forward secrecy is guaranteed: ephemeral key material is discarded after each transfer, so past sessions cannot be retroactively decrypted.


2. Frame-Based AEAD Encryption

The payload stream is divided into independent chunks of exactly 1,048,576 bytes (1MB). Each chunk is encrypted separately to avoid buffering the entire file in memory before processing:

+--------------------------------------------------------+
|                      Ciphertext                        |
|                                                        |
|  [ 12-byte Nonce ] [ Encrypted Payload ] [ 16-byte Tag ] |
+--------------------------------------------------------+
  1. A random 12-byte initialization vector (nonce) is generated for each frame using the OS cryptographically secure pseudorandom number generator (CSPRNG).
  2. The frame payload (raw data or compressed Zstd data) is encrypted in-place using the negotiated AEAD cipher (AES-GCM or ChaCha20).
  3. A 16-byte authentication tag is generated and appended to the frame.
  4. The frame is prefixed with a 4-byte network byte-order length before being written to the QUIC stream.

This prevents Replay Attacks and Message Tampering because any modified byte inside a frame will fail the AEAD authentication check on the receiver and immediately close the connection.


3. Metadata Confidentiality

All metadata (including the filename, total transfer size, transfer type, and global integrity checksum algorithm) is encrypted before being sent:

  • The sender encrypts the metadata block using the negotiated session key and sends it to the receiver.
  • The receiver decrypts and validates the metadata block.
  • The receiver displays the filename and transfer details to the user and prompts for acceptance.

This ensures that an eavesdropper on the local network cannot discover what file is being sent, its size, or its hash.


4. Path Traversal & Extraction Safety

When transferring directories, Hayate packages files into a streamed tar archive. Extracting tar archives on a local filesystem carries risk if the archive is malicious. Hayate implements strict extraction sanitization:

  • Parent Directory Traversal: Any file path containing .. segments is rejected.
  • Absolute Paths: Absolute paths (e.g. /etc/passwd or C:\Windows\...) are converted to relative paths or rejected.
  • Symlinks & Hardlinks: Symbolic and hard links are completely ignored during extraction to prevent arbitrary file writes and symlink redirection attacks.