Skip to content

Releases: Ymsniper/NoEyes

v0.5.0 — Forward Secrecy, PyNaCl, Ratchet

28 Mar 17:47

Choose a tag to compare

What's new

Cryptography

  • Migrated from Fernet/HKDF to PyNaCl XSalsa20-Poly1305 + BLAKE2b
  • Sender Keys ratchet (/ratchet start) — per-message unique keys, forward secrecy
  • Full mesh fix: initiator now distributes all chain keys to all peers
  • Ratchet invite triggers full restart instead of forwarding live chains
  • X25519 pairwise DH, Ed25519 identity signing, ChaCha20-Poly1305 file transfer

Architecture

  • Refactored into smaller modules: client_ratchet, client_dh, client_send, client_recv, client_commands, client_tofu, server_handlers, server_rooms

New features

  • /ratchet start — group forward secrecy, all clients confirm
  • /ratchet invite — re-add a user with full ratchet restart
  • /proceed — vote to continue after peer migration
  • Ratchet activation animation (CRT red with gear art + SFX)
  • Ratchet deactivation animation (cyan reverse)
  • --generate-access-key and --generate-chat-key CLI flags
  • Termux: SODIUM_INSTALL=system for fast PyNaCl install

Changes

  • /nick removed (no server-side identity validation)
  • /clear now actually clears messages
  • /join and /leave warn before breaking ratchet session
  • Solo ratchet auto-exit when all peers disconnect

modular rewrite (core/, network/, ui/), signed manifest, firewall module, improved TUI, fixed Windows support

09 Mar 06:00

Choose a tag to compare

modular rewrite (core/, network/, ui/), signed manifest, firewall module, improved TUI, fixed Windows support

File Transfer Fixes

06 Mar 21:07

Choose a tag to compare

FILE: CHANGELOG.md

Changelog

[v0.3.1] — File Transfer Fixes

Bug Fixes

File transfer not working (receiver side)

  • Receiver was displaying raw JSON instead of processing file transfer frames.
    _handle_privmsg read subtype from the unencrypted header, but the sender
    puts it inside the encrypted body as tag. Fixed: receiver now checks
    body.get("tag") after decryption as fallback.
  • Receiver got filename=unknown, size=0 because _handle_file_start was
    reading fields from the outer Fernet body dict instead of the inner JSON
    string in body["text"]. Fixed: inner JSON is now unwrapped before dispatch.

File transfer silently dropped mid-transfer

  • Server's privmsg rate limiter (25/15min per pair) was counting binary chunk
    frames, causing all chunks beyond the limit to be silently dropped.
    Fixed: file_chunk_bin frames are now exempt from the per-pair rate limiter.

UI freezing during file send

  • _send_file was called directly from the input thread, blocking all input
    and output for the entire transfer duration.
    Fixed: file sends now run in a background daemon thread.

Progress display corruption

  • Bare print(..., end="\r") calls bypassed the TUI lock, producing garbled
    backwards progress numbers racing with animation redraws.
    Fixed: progress uses utils.print_msg through the output lock.

Double file read on send

  • SHA-256 hash for the Ed25519 signature was computed in a second full file
    read after all chunks were sent. Fixed: hash is computed inline while
    reading chunks, eliminating the redundant disk I/O.

Slower transfers after chunk size change

  • Chunk size was incorrectly reduced to 512KB, turning a 1-frame transfer
    into 11 frames. Each frame adds bore tunnel relay latency.
    Reverted to 32MB chunks — 1 frame for files under 32MB.

TCP latency

  • Added TCP_NODELAY on the client socket to disable Nagle's algorithm and
    prevent artificial send delays on the tunnel.

v0.3.0 — Security Hardening + Notification System

05 Mar 15:38

Choose a tag to compare

FILE: CHANGELOG.md

Changelog

[2.0.0] — Blind-Forwarder E2E Encryption Upgrade

Summary

This release makes NoEyes a true end-to-end encrypted chat system. The server
is now a blind forwarder — it routes messages by reading only the plaintext
header JSON and forwards the encrypted payload bytes verbatim, never decrypting
them.

Breaking changes

  • The wire protocol header format changes from a simple newline-delimited
    encrypted blob to the framed format:
    [4-byte header_len BE] [4-byte payload_len BE] [header JSON] [payload bytes]
    Clients older than this release are not compatible and must be updated.

New features

Server

  • Zero decryption: all calls to Fernet.decrypt, fernet.decrypt, and
    any private-key primitives have been removed from server.py.
  • Pubkey announcement store: when a client announces its Ed25519 verify
    key (pubkey_announce header), the server stores only the hex string in
    memory and rebroadcasts it to room members so they can populate their TOFU
    stores. The server never holds private keys.
  • DH routing: dh_init and dh_resp frames are forwarded point-to-point
    to the to header field recipient without inspection of the payload.

Client / Crypto

  • Ed25519 identity (~/.noeyes/identity.key): auto-generated on first
    run. Every private message payload is signed with the sender's Ed25519
    signing key. Recipients verify the signature against their TOFU store.
  • X25519 DH handshake: sending /msg user text when no pairwise key
    exists triggers a DH handshake. The DH public keys are carried inside
    group-Fernet-encrypted payloads so the server cannot read them. Once the
    handshake completes the original message is re-sent automatically.
  • Pairwise Fernet: derived from the X25519 shared secret via SHA-256.
    All /msg payloads are encrypted with this key.
  • TOFU store (~/.noeyes/tofu_pubkeys.json): first-seen pubkeys are
    trusted and persisted; subsequent appearances are verified; mismatches
    produce a loud security warning.
  • --gen-key: new CLI flag to generate a Fernet key file and exit.

Utilities

  • identity.py — new module: load_tofu, save_tofu, trust_or_verify,
    export_tofu, import_tofu.
  • encryption.py — extended with: generate_identity, load_identity,
    save_identity, sign_message, verify_signature, dh_generate_keypair,
    dh_derive_shared_fernet.