Releases: Ymsniper/NoEyes
Releases · Ymsniper/NoEyes
v0.5.0 — Forward Secrecy, PyNaCl, Ratchet
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-keyand--generate-chat-keyCLI flags- Termux: SODIUM_INSTALL=system for fast PyNaCl install
Changes
/nickremoved (no server-side identity validation)/clearnow actually clears messages/joinand/leavewarn 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
modular rewrite (core/, network/, ui/), signed manifest, firewall module, improved TUI, fixed Windows support
File Transfer Fixes
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_privmsgreadsubtypefrom the unencrypted header, but the sender
puts it inside the encrypted body astag. Fixed: receiver now checks
body.get("tag")after decryption as fallback. - Receiver got
filename=unknown, size=0because_handle_file_startwas
reading fields from the outer Fernet body dict instead of the inner JSON
string inbody["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_binframes are now exempt from the per-pair rate limiter.
UI freezing during file send
_send_filewas 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 usesutils.print_msgthrough 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_NODELAYon the client socket to disable Nagle's algorithm and
prevent artificial send delays on the tunnel.
v0.3.0 — Security Hardening + Notification System
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 fromserver.py. - Pubkey announcement store: when a client announces its Ed25519 verify
key (pubkey_announceheader), 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_initanddh_respframes are forwarded point-to-point
to thetoheader 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 textwhen 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/msgpayloads 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.