# terminalphone encrypted, anonymous walkie-talkie over tor. single bash script (~3k lines), no servers, no accounts. your .onion address is your identity. ## what it does two parties share a secret, connect via tor hidden services, and talk using push-to-talk voice (opus-encoded, aes-encrypted). also supports encrypted text chat mid-call. ## audio pipeline ``` mic → raw pcm (8khz mono) → opus encode (16kbps) → aes encrypt → base64 → socat → tor tor → socat → base64 decode → aes decrypt → opus decode → speaker ``` record-then-send model (not streaming) - irregular transmission patterns make traffic analysis harder. ## wire protocol text-based, line-delimited over socat/tor: - `ID:` - caller id exchange - `CIPHER:` - cipher negotiation - `PTT_START` / `PTT_STOP` - recording state - `AUDIO:` - encrypted audio payload - `MSG:` - encrypted text message - `HANGUP` / `PING` - control signals optional HMAC-SHA256 signing with nonce replay protection (both sides must match). ## project structure ``` terminalphone.sh the whole thing. single script README.md usage docs CHANGELOG version history LICENSE MIT CLI.png screenshot ``` runtime data lives in `.terminalphone/` (auto-created): - `tor_data/` - tor hidden service keys - `audio/` - temp audio files (cleaned on exit) - `pids/` - process id tracking - `run/` - named pipes, flags, cipher state - `shared_secret` - encrypted pre-shared key - `torrc` - generated tor config - `config` - user settings ## dependencies core: `tor`, `opus-tools`, `sox`, `socat`, `openssl`, `arecord`/`aplay` optional: `snowflake-client`, `qrencode`, `jq` (termux vol-ptt) platforms: linux (deb/fed/arch), android (termux + termux:api from f-droid) ## running it ```bash bash terminalphone.sh # interactive menu bash terminalphone.sh listen # listen mode bash terminalphone.sh call ADDR # call a .onion address bash terminalphone.sh install # install deps bash terminalphone.sh test # audio loopback test bash terminalphone.sh status # show status ``` in-call: SPACE=ptt, T=text msg, S=settings, Q=hangup ## key code areas the script is organized roughly as: - **config** (~line 1-150): load_config/save_config, defaults - **deps/install** (~150-400): install_deps, check_dep, platform detection - **tor management** (~400-700): setup_tor, start/stop/restart, get_onion, rotate_onion - **encryption** (~700-900): encrypt_file/decrypt_file, PBKDF2 key derivation, fd passing - **protocol** (~900-1050): proto_send/proto_verify, HMAC auth, nonce tracking - **audio** (~1050-1400): audio_record, start_recording, stop_and_send, audio_play, voice effects - **call flow** (~1400-1900): listen_for_call, call_remote, in_call_session, cleanup_call - **settings menus** (~1900-2600): cipher (21 options), opus quality, snowflake, voice effects, tor, security - **auto-listen** (~2600-2750): background listener management - **main menu** (~2750-3079): interactive menu loop, cli arg parsing ## config options stored in `.terminalphone/config`: - `LISTEN_PORT` (7777), `TOR_SOCKS_PORT` (9050) - `OPUS_BITRATE` (16kbps), `CIPHER` (aes-256-cbc) - `SNOWFLAKE_ENABLED`, `AUTO_LISTEN`, `PTT_KEY` - `SHOW_CIRCUIT`, `EXCLUDE_NODES`, `HMAC_AUTH` - `VOICE_EFFECT` (none/deep/high/robot/echo/whisper/custom) ## security model - e2e encryption with 21 cipher options (aes, chacha20, camellia, aria) - secrets passed via file descriptors (not visible in process table) - tor hidden service per instance (no ip exposure) - passphrase-protected secrets at rest (aes-256-cbc + 100k pbkdf2) - opaque temp filenames (random hex, generic .tmp extension) - country exclusion for tor circuits (five/nine/fourteen eyes presets) ## hacking notes - it's all bash - no build step, no transpilation - named pipes (fifos) are the ipc mechanism between socat and the call session - `uid()` generates random hex from /dev/urandom - platform branching happens via `is_termux()` checks throughout - cleanup_call() is critical - handles pipe/process/file cleanup on disconnect - the settings system uses a simple key=value flat file - no test framework exists yet - testing is manual via loopback (option 5) ## style - bash with `#!/usr/bin/env bash` - functions use snake_case - log_info/log_warn/log_error/log_debug for output - match existing formatting and comment style