kiko is a C++20 croc-like file transfer tool: rendezvous relay, mnemonic pairing codes, PAKE end-to-end encryption (libsodium CPace / Ristretto255 + XChaCha20-Poly1305), zstd stream compression, resumable multi-file transfers, multiplexed relay connections, IPv6-first dual-stack networking, NAT-aware adaptive TCP punching with relay fallback, and CLI or FTXUI front-ends.
Download prebuilt binaries from Releases, or install the latest release. Current packages cover Linux x64, Linux ARM64, macOS ARM64, macOS x64, and Windows x64. Android / Termux prebuilt packages are not published yet; the shell installer detects Termux and prints source-build steps instead of installing an incompatible Linux binary.
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/suir1/kiko/main/scripts/install.sh | shWindows PowerShell:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
irm https://raw.githubusercontent.com/suir1/kiko/main/scripts/install.ps1 | iexIf raw.githubusercontent.com is blocked by your network, download the Windows zip from
Releases and unzip kiko.exe into a directory on PATH.
The installer writes to ~/.local/bin/kiko on macOS/Linux and ~/bin/kiko.exe on Windows. Set
KIKO_INSTALL_DIR to choose another directory, or KIKO_VERSION=v0.1.8-alpha to install a specific release.
Use KIKO_INSTALL_DRY_RUN=1 to print the release asset URL without downloading it.
Set KIKO_ADD_TO_PATH=1 to add the install directory to your user PATH (~/.zshrc, ~/.bashrc,
~/.profile, or Windows User PATH). On macOS/Linux you can also use KIKO_ADD_TO_PATH=prompt for
an interactive prompt when running the script from a terminal.
curl -fsSL https://raw.githubusercontent.com/suir1/kiko/main/scripts/install.sh | KIKO_ADD_TO_PATH=1 sh$env:KIKO_ADD_TO_PATH = "1"
irm https://raw.githubusercontent.com/suir1/kiko/main/scripts/install.ps1 | iexTermux source build:
pkg update
pkg install -y git clang cmake ninja pkg-config libsodium zstd
git clone https://github.com/suir1/kiko.git
cd kiko
cmake --preset system-deps
cmake --build build --target kiko
mkdir -p "$PREFIX/bin"
cp build/kiko "$PREFIX/bin/kiko"
chmod +x "$PREFIX/bin/kiko"Or let the shell installer do the clone/build/install step:
curl -fsSL https://raw.githubusercontent.com/suir1/kiko/main/scripts/install.sh | KIKO_BUILD_FROM_SOURCE=1 shOn Termux, KIKO_BUILD_FROM_SOURCE=1 runs pkg update and installs build dependencies with pkg install -y by default. Set
KIKO_INSTALL_DEPS=0 to skip that step, or KIKO_SOURCE_REF=main to build a branch/ref instead of the latest release tag.
For a custom or future Android release asset, set KIKO_ASSET=android-arm64 when running scripts/install.sh.
macOS binaries are not signed yet. If Gatekeeper blocks the downloaded binary, open System Settings →
Privacy & Security and allow kiko, or remove the quarantine flag:
xattr -d com.apple.quarantine ~/.local/bin/kikoQuick check:
kiko --version
kiko doctor
kiko send ./file-or-folder
kiko recv <code> --out ./downloads- Short pairing codes – auto-generated 6-character codes (e.g.
x7k9m2). Pass any custom code with--code(short alphanumeric, or croc-style4827-stone-iris-lake-rubywith-splitting room label and PAKE secret). - Terminal QR code – when sending from a TTY, a QR code for the pairing code is printed (disable with
--no-qrcode). - IPv6 + IPv4 dual stack –
AF_UNSPECresolve, dual-stack listeners (::), IPv6-first dial with IPv4 fallback. Bracketed endpoints:[::1]:9000. - Resume – preflights the file manifest, writes to
<name>.kikopart, renames on success, and reports the resume offset when continuing. Re-run the same send/recv pair to continue; SHA-256 verifies the whole file. imohash fingerprints skip files you already have. - Conflict policy – receivers can
overwrite,skip, orrenameexisting files with--on-conflict. - Parallel connections – relay/direct mux uses
--connections N(default 4), dynamic chunk scheduling, and per-stream XChaCha20-Poly1305 subkeys. - LAN discovery – UDP multicast finds local relays; sender embeds a croc-style LAN relay (
--no-localto disable). Receiver races LAN and external relays in parallel (--local,--no-local). - Relay health check – JSON
ping/pongon each relay connection before rendezvous registration. - LAN upgrade – after the relay pipe is up, the receiver can probe sender LAN addresses before E2E PAKE.
.gitignoresupport – directory sends respect.gitignorerules (--no-gitignoreto disable).- File metadata – executable bits are preserved, and
--symlinks preservecan send safe relative symlinks as links. - Proxy –
--proxy http://host:portorsocks5://host:portfor relay connections. - NAT awareness – LAN candidates first, then reflexive addresses; adaptive punch timing before relay fallback.
- Connectivity planning – STUN NAT probe (
--udp-probe), rule-basedRoutePlan, VPN-filtered LAN candidates, relay outbound path probing, and~/.config/kiko/profile.jsonsuccess memory. - Doctor –
kiko doctor [--udp-probe] [--json] [--ai-explain]probes relay reachability and suggests a transfer path. - AI assist (BYOK, opt-in) – OpenAI-compatible route advice and human-readable doctor explanations via env-configured API key.
Default codes are a single short string used for both relay rendezvous and PAKE. If the code contains -, the part before the first - is a public rendezvous label and the remainder is the PAKE secret (croc-style). The relay only sees SHA256("kiko-room:" + label). Peers run CPace-style PAKE over Ristretto255, mutual key confirmation, then XChaCha20-Poly1305 with HKDF-derived per-direction subkeys. The relay is a blind forwarder and cannot decrypt traffic.
Primary build uses vcpkg manifest mode (dependencies in vcpkg.json).
# Bootstrap local vcpkg (first time)
git clone https://github.com/microsoft/vcpkg.git .vcpkg
./.vcpkg/bootstrap-vcpkg.sh
cmake --preset local-vcpkg
cmake --build build
ctest --preset local-vcpkgPresets (see CMakePresets.json):
| Preset | Use |
|---|---|
local-vcpkg |
.vcpkg/ checkout in the repo |
default |
$VCPKG_ROOT environment variable |
system-deps |
Homebrew/pkg-config fallback + FetchContent |
On macOS you may need build tools for vcpkg ports: brew install pkg-config autoconf automake libtool.
Interactive TUI:
./build/kiko tuiRun a relay (LAN-announced via multicast):
./build/kiko relay --listen [::]:9000
./build/kiko relay --listen [::]:9000 --pass my-secret --room-ttl 10800Run a public/server relay without the full CLI/TUI frontend:
./build/kiko-relayd --listen 0.0.0.0:9000
./build/kiko-relayd --listen 0.0.0.0:9000 --pass my-secret --room-ttl 10800Clients use --relay-pass or KIKO_RELAY_PASS when the relay requires a password.
kiko uses 106.53.170.243:9000 as the built-in public relay when KIKO_RELAY is unset.
Saved settings in ~/.config/kiko/config.json (override with KIKO_CONFIG_PATH) are used when env vars are unset.
kiko tui updates that file automatically; CLI uses --remember on send / recv after a successful transfer.
Override it for private/self-hosted relays:
export KIKO_RELAY=relay.example.com:9000
export KIKO_RELAY_PASS=my-secretBuild with a compile-time default relay (when KIKO_RELAY is unset):
cmake -DKIKO_DEFAULT_RELAY=relay.example.com:9000 --preset local-vcpkgSend:
./build/kiko send ./file.bin
./build/kiko send ./my-folder --relay [::1]:9000 --connections 8
./build/kiko send ./repo --proxy socks5://127.0.0.1:1080
./build/kiko send ./repo --symlinks preserve
./build/kiko send ./file.bin --debug-routeReceive:
./build/kiko recv <code> --out ./downloads
./build/kiko recv <code> --out ./downloads --on-conflict renameNetwork diagnostics:
./build/kiko doctor
./build/kiko doctor --udp-probe --json
./build/kiko doctor --ai-explain # requires OPENAI_API_KEY or KIKO_AI_API_KEYdoctor reports local LAN IPs, VPN/TUN IPs, the route/interface used for the relay target, and STUN mapped
addresses when --udp-probe is enabled. This helps spot cases where a relay IP is being captured by a TUN
interface instead of going out through the physical LAN/Wi-Fi route.
When VPN/TUN interfaces are detected and no proxy or manual bind is set, send, recv, and doctor probe both
the default relay path and a likely physical interface path, then use the reachable path with lower relay RTT.
The doctor --json output includes outbound_path, outbound_reason, and outbound_probes for this decision.
It also includes relay_reachable, recommendation, direct_probe, and route_result_hint; the hint separates
the rendezvous relay from whether file data is expected to require relay forwarding.
To test a physical-interface route while VPN/TUN is active:
./build/kiko doctor --avoid-vpn
./build/kiko doctor --bind-interface en0--avoid-vpn picks a likely physical interface automatically. --bind-interface <name> forces outbound TCP
sockets onto a named interface where the platform supports it (macOS uses IP_BOUND_IF / IPV6_BOUND_IF;
Linux tries SO_BINDTODEVICE, which may require privileges). These options apply to relay probing, relay
rendezvous, relay mux connections, and active direct TCP dials. If the scoped physical route exists but relay
ping still fails, the physical network or relay port may be blocked; use a VPN DIRECT rule or a reachable relay
port.
Use send --debug-route or recv --debug-route to print a short doctor-style route summary before transfer,
including relay reachability, outbound interface choice, direct probe budget, route hint, and recommendation.
Optional AI configuration (BYOK):
export OPENAI_API_KEY=sk-...
export KIKO_AI_BASE_URL=https://api.openai.com/v1 # or http://localhost:11434/v1 for local
export KIKO_AI_MODEL=gpt-4o-miniFlags: --relay-pass, --remember, --auto-connections, --debug-route, --no-direct, --no-lan, --no-local, --local, --ip, --udp-probe, --ai-route, --ai-route-plan-only, --no-gitignore, --symlinks, --on-conflict, --no-qrcode, --proxy, --bind-interface, --avoid-vpn, --tui.
--ip overrides the relay target (port from --relay) and the addresses advertised to the peer for direct/punch paths. When set, LAN relay discovery is skipped.
ctest --preset local-vcpkg --output-on-failureRoute smoke checks:
# Relay data path: default, deterministic, same as CI smoke.
python3 scripts/relay_transfer_smoke.py ./build/kiko
# Same-machine direct path: useful before testing two real devices.
python3 scripts/relay_transfer_smoke.py ./build/kiko \
--allow-direct --allow-lan --allow-local \
--expect-data-path direct
# Public relay / IPv6 direct expectation: use on hosts that both advertise global IPv6.
python3 scripts/relay_transfer_smoke.py ./build/kiko \
--relay 106.53.170.243:9000 \
--allow-direct --allow-lan --allow-local \
--expect-data-path direct \
--expect-candidate ipv6_global \
--expect-family ipv6 \
--expect-scope globalDocker network labs:
scripts/netlab_matrix.sh
scripts/netlab_double_nat.shnetlab_matrix.sh currently verifies fake-VPN outbound physical fallback in doctor, manual
--avoid-vpn/--bind-interface overrides, fake-VPN relay transfer over the physical outbound path,
sender-only and receiver-only fake-VPN relay transfers, delayed/limited relay transfer with tc netem,
same-LAN direct TCP, same-LAN isolated relay fallback, one-side-NAT direct TCP, and Docker double-NAT
fast relay fallback after direct probing. The first Docker run builds the kiko-netlab:local image;
later runs reuse the cache.
The Docker labs are also available as optional CTest targets:
cmake -S . -B build -DKIKO_ENABLE_NETLAB_TESTS=ON
ctest --test-dir build -L netlab --output-on-failureKIKO_ENABLE_NETLAB_TESTS defaults to OFF so normal ctest runs do not require Docker or privileged networking.
The Docker Netlab GitHub workflow runs the same matrix manually and once per week.
handshake– PAKE session key agreement and rejection of wrong codestransfer– multi-file directory round-trip, manifest preflight, resume from partialprogress–ProgressReporterevent sequencemux– parallel relay connections and resumeadaptive– NAT classification and punch planningconnectivity– RoutePlan rule generationai– AI route plan validation and merge
CI Fast runs automatically on pushes and pull requests with Ubuntu x64, macOS ARM, and Windows. Use it for normal development feedback.
CI Full is manual (workflow_dispatch) and runs the full platform matrix: Ubuntu x64/ARM, macOS ARM/Intel, and Windows. It also keeps the optional public relay doctor + send/recv smoke test when KIKO_RELAY_SMOKE is set. Run it before releases or large networking/relay changes.
Tags matching v* trigger the release workflow. It builds and tests Linux, macOS, and Windows packages, then
uploads the packaged binaries to the matching GitHub Release.
git tag v0.1.8-alpha
git push origin v0.1.8-alpha| Layer | Choice |
|---|---|
| Crypto | libsodium (Ristretto255 PAKE, XChaCha20-Poly1305, SHA-256/HKDF) |
| Network | Standalone Asio + C++20 coroutines (relay) / sync I/O (transfer) |
| Compression | zstd |
| CLI | CLI11 + nlohmann-json control messages |
| UI | FTXUI (optional --tui) |
| QR | Nayuki qrcodegen (vcpkg) |