Nellix/sonic-chat

Offline authenticated text chat carried entirely by audible sound — no Wi-Fi, Bluetooth, account, or server.

4

stars

3

commits

Rust

primary language

Sep 1, 2026

updated

acoustic-modem
android
audio
audio-processing
cryptography
digital-signal-processing
flutter
linux
macos
modem
noise-protocol
offline-first
peer-to-peer
privacy
rust
signal-processing

README

SonicChat

Offline, authenticated text chat carried entirely by audible sound.

Status: alpha CI Flutter License: Apache-2.0 Rust Flutter UI

SonicChat lets nearby devices exchange text through their ordinary speakers and microphones. Sending needs no Wi-Fi, Bluetooth, cellular connection, account, cloud service, or external server. The modem is custom Rust code; SonicChat does not use ggwave at runtime.

[!WARNING] SonicChat is an experimental alpha. Its modem is audible and half-duplex, messages are slow compared with Internet chat, and compatibility depends on the room and hardware. Do not rely on it for emergencies or safety-critical communication.

Why it is interesting

  • Actually offline: application traffic never needs a network permission or server.
  • One app, shared core: an adaptive Flutter UI targets Android, macOS, and Linux while the same Rust engine also powers a native daemon and terminal client.
  • Security with honest labels: Noise XX pairing, a six-digit SAS, Ed25519 sender authentication, XChaCha20-Poly1305 encryption, replay rejection, and encrypted local history.
  • Direct and group chat: authenticated ACK/retry, delivery state, signed public messages, encrypted direct messages, and owner-managed group epochs.
  • Built for investigation: deterministic channel simulation, reproducible benchmarks, protocol fixtures, property tests, fuzz harnesses, and a layered DSP/protocol/crypto architecture.

Sound is a broadcast medium. Public / authenticated messages can be decoded or recorded by any compatible listener; addressing is not privacy. Encrypted messages hide content from passive listeners, but not traffic timing, jamming, or compromise of an endpoint. Read the security model and threat model before sensitive use.

Project status

The source is published as 0.1.0-alpha.1.

TargetCompositionCurrent evidence
AndroidFlutter UI + Rust enginePhysically validated with one Android/macOS device pair
macOSFlutter UI + Rust engine; native daemon/CLIPhysically validated with one Android/macOS device pair
Ubuntu/LinuxFlutter UI; native daemon/CLIImplemented and covered by portable/virtual tests; the physical Linux matrix remains open
WindowsPortable Rust core onlyProduct integration is planned
iOS/iPadOSArchitecture onlyProduct integration is planned

The physical Android/macOS session completed bidirectional discovery, Noise pairing with matching SAS, an encrypted direct message with authenticated ACK, group creation/key distribution, and an encrypted group message acknowledged by both members. This is proof of interoperability for that device pair—not a range or reliability claim. See test status and the hardening record.

Quick start: Flutter app

Prerequisites

  • Flutter stable with the target platform enabled
  • Rust stable 1.85 or newer
  • macOS: Xcode, CocoaPods, and a free Apple Personal Team for local signing
  • Android: Android Studio/SDK 36, NDK 27.0.12077973, and a USB-debuggable Android 6.0+ device

Clone and prepare the shared app:

git clone https://github.com/Nellix/sonic-chat.git
cd sonic-chat/apps/sonic_chat
flutter doctor -v
flutter pub get

Run on macOS:

flutter run -d macos

Run on a connected Android device:

flutter devices
flutter run -d <device-id>

The first macOS build may require selecting Runner → Signing & Capabilities → Team in macos/Runner.xcworkspace. The complete Flutter user guide covers prerequisites, Linux, Android APKs, signing, permissions, and troubleshooting.

First acoustic chat

  1. Put both foreground devices in the same quiet room, one to two metres apart. Disconnect Bluetooth audio and headphones; use a moderate speaker volume.
  2. Open Nearby. Run discovery in one direction at a time until both current labels are visible.
  3. Select Pair on either device. Wait for the fragmented handshake, compare all six SAS digits, and select Codes match on both devices.
  4. Open the contact under Chats, keep Encrypted selected, and send a short message. Do not speak over a burst; wait for the authenticated delivery result.
  5. Pair every member directly before selecting Create group.

The safe default Reliable profile uses small repeated acoustic packets. Robust and Fast are experimental opt-ins for paths already proven with Reliable. SonicChat never changes either device's system volume.

Native daemon and terminal client

The native composition is useful on Linux and macOS:

cargo run -p sonic-daemon --release -- \
  --name 'My computer' --allow-unprotected-key-file --no-stdin

In a second terminal:

cargo run -p sonic-cli --release -- status
cargo run -p sonic-cli --release -- discovery start
cargo run -p sonic-cli --release -- nearby
cargo run -p sonic-cli --release -- help

Only the daemon owns audio and security state. The explicit long option accepts that this development composition protects its random storage key using private file permissions rather than an OS keyring. See the native terminal guide.

Build, test, and simulate

The main quality gate targets stable Rust:

cargo fmt --all -- --check
cargo test --workspace --all-targets --locked
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo build --workspace --release --locked

Flutter checks:

cd apps/sonic_chat
flutter analyze
flutter test

Generate and decode a deterministic acoustic sample:

cargo run -p sonic-simulator --release --bin sonic-sim -- \
  encode robust 'hello' /tmp/hello.wav
cargo run -p sonic-simulator --release --bin sonic-sim -- \
  decode /tmp/hello.wav

sonic-bench --full emits per-seed CSV. These are digital channel measurements, not physical distance evidence. The longer full-engine virtual pairing and group commands are documented in the test plan.

Architecture

flowchart LR
    UI["Flutter UI or terminal client"] --> Engine["Shared Rust chat engine"]
    Engine --> Protocol["Protocol + crypto + storage"]
    Engine --> Transport["Half-duplex transport + ACK/retry"]
    Transport --> Modem["DSP + custom acoustic modem"]
    Modem --> Audio["Microphone / speaker adapter"]

The boundaries, trust model, on-disk state, and crate responsibilities are in ARCHITECTURE.md.

Documentation

Read thisFor
Flutter user guidemacOS, Android, Linux, first chat, groups, troubleshooting
Native terminal guidedaemon/CLI setup and audio diagnostics
Architecturecomponents, trust boundaries, data flow
Acoustic modemwaveforms, synchronization, FEC, profiles
Protocolversioned binary wire format
Discovery and groupslifecycle and security semantics
Security and threat modelguarantees, residual risk, disclosure
Benchmarking and test planreproducible evidence and open validation
Roadmaprelease criteria and contribution opportunities

Contributing

This project especially welcomes reproducible room measurements, Android/Linux audio compatibility reports, DSP improvements backed by fixtures, accessibility work, documentation, and security review. Start with CONTRIBUTING.md, use the issue forms, and read the Code of Conduct. Please use GitHub's private security reporting flow for vulnerabilities rather than a public issue.

If SonicChat is useful or intriguing, a GitHub star, a tested device report, a short demo video, or a well-scoped contribution all help the project become discoverable.

License

Licensed under the Apache License 2.0.

Contributors

Nellix

3 commits

Nellix/sonic-chat

Offline authenticated text chat carried entirely by audible sound — no Wi-Fi, Bluetooth, account, or server.

4

stars

3

commits

Rust

primary language

Sep 1, 2026

updated

acoustic-modem
android
audio
audio-processing
cryptography
digital-signal-processing
flutter
linux
macos
modem
noise-protocol
offline-first
peer-to-peer
privacy
rust
signal-processing

README

SonicChat

Offline, authenticated text chat carried entirely by audible sound.

Status: alpha CI Flutter License: Apache-2.0 Rust Flutter UI

SonicChat lets nearby devices exchange text through their ordinary speakers and microphones. Sending needs no Wi-Fi, Bluetooth, cellular connection, account, cloud service, or external server. The modem is custom Rust code; SonicChat does not use ggwave at runtime.

[!WARNING] SonicChat is an experimental alpha. Its modem is audible and half-duplex, messages are slow compared with Internet chat, and compatibility depends on the room and hardware. Do not rely on it for emergencies or safety-critical communication.

Why it is interesting

  • Actually offline: application traffic never needs a network permission or server.
  • One app, shared core: an adaptive Flutter UI targets Android, macOS, and Linux while the same Rust engine also powers a native daemon and terminal client.
  • Security with honest labels: Noise XX pairing, a six-digit SAS, Ed25519 sender authentication, XChaCha20-Poly1305 encryption, replay rejection, and encrypted local history.
  • Direct and group chat: authenticated ACK/retry, delivery state, signed public messages, encrypted direct messages, and owner-managed group epochs.
  • Built for investigation: deterministic channel simulation, reproducible benchmarks, protocol fixtures, property tests, fuzz harnesses, and a layered DSP/protocol/crypto architecture.

Sound is a broadcast medium. Public / authenticated messages can be decoded or recorded by any compatible listener; addressing is not privacy. Encrypted messages hide content from passive listeners, but not traffic timing, jamming, or compromise of an endpoint. Read the security model and threat model before sensitive use.

Project status

The source is published as 0.1.0-alpha.1.

TargetCompositionCurrent evidence
AndroidFlutter UI + Rust enginePhysically validated with one Android/macOS device pair
macOSFlutter UI + Rust engine; native daemon/CLIPhysically validated with one Android/macOS device pair
Ubuntu/LinuxFlutter UI; native daemon/CLIImplemented and covered by portable/virtual tests; the physical Linux matrix remains open
WindowsPortable Rust core onlyProduct integration is planned
iOS/iPadOSArchitecture onlyProduct integration is planned

The physical Android/macOS session completed bidirectional discovery, Noise pairing with matching SAS, an encrypted direct message with authenticated ACK, group creation/key distribution, and an encrypted group message acknowledged by both members. This is proof of interoperability for that device pair—not a range or reliability claim. See test status and the hardening record.

Quick start: Flutter app

Prerequisites

  • Flutter stable with the target platform enabled
  • Rust stable 1.85 or newer
  • macOS: Xcode, CocoaPods, and a free Apple Personal Team for local signing
  • Android: Android Studio/SDK 36, NDK 27.0.12077973, and a USB-debuggable Android 6.0+ device

Clone and prepare the shared app:

git clone https://github.com/Nellix/sonic-chat.git
cd sonic-chat/apps/sonic_chat
flutter doctor -v
flutter pub get

Run on macOS:

flutter run -d macos

Run on a connected Android device:

flutter devices
flutter run -d <device-id>

The first macOS build may require selecting Runner → Signing & Capabilities → Team in macos/Runner.xcworkspace. The complete Flutter user guide covers prerequisites, Linux, Android APKs, signing, permissions, and troubleshooting.

First acoustic chat

  1. Put both foreground devices in the same quiet room, one to two metres apart. Disconnect Bluetooth audio and headphones; use a moderate speaker volume.
  2. Open Nearby. Run discovery in one direction at a time until both current labels are visible.
  3. Select Pair on either device. Wait for the fragmented handshake, compare all six SAS digits, and select Codes match on both devices.
  4. Open the contact under Chats, keep Encrypted selected, and send a short message. Do not speak over a burst; wait for the authenticated delivery result.
  5. Pair every member directly before selecting Create group.

The safe default Reliable profile uses small repeated acoustic packets. Robust and Fast are experimental opt-ins for paths already proven with Reliable. SonicChat never changes either device's system volume.

Native daemon and terminal client

The native composition is useful on Linux and macOS:

cargo run -p sonic-daemon --release -- \
  --name 'My computer' --allow-unprotected-key-file --no-stdin

In a second terminal:

cargo run -p sonic-cli --release -- status
cargo run -p sonic-cli --release -- discovery start
cargo run -p sonic-cli --release -- nearby
cargo run -p sonic-cli --release -- help

Only the daemon owns audio and security state. The explicit long option accepts that this development composition protects its random storage key using private file permissions rather than an OS keyring. See the native terminal guide.

Build, test, and simulate

The main quality gate targets stable Rust:

cargo fmt --all -- --check
cargo test --workspace --all-targets --locked
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo build --workspace --release --locked

Flutter checks:

cd apps/sonic_chat
flutter analyze
flutter test

Generate and decode a deterministic acoustic sample:

cargo run -p sonic-simulator --release --bin sonic-sim -- \
  encode robust 'hello' /tmp/hello.wav
cargo run -p sonic-simulator --release --bin sonic-sim -- \
  decode /tmp/hello.wav

sonic-bench --full emits per-seed CSV. These are digital channel measurements, not physical distance evidence. The longer full-engine virtual pairing and group commands are documented in the test plan.

Architecture

flowchart LR
    UI["Flutter UI or terminal client"] --> Engine["Shared Rust chat engine"]
    Engine --> Protocol["Protocol + crypto + storage"]
    Engine --> Transport["Half-duplex transport + ACK/retry"]
    Transport --> Modem["DSP + custom acoustic modem"]
    Modem --> Audio["Microphone / speaker adapter"]

The boundaries, trust model, on-disk state, and crate responsibilities are in ARCHITECTURE.md.

Documentation

Read thisFor
Flutter user guidemacOS, Android, Linux, first chat, groups, troubleshooting
Native terminal guidedaemon/CLI setup and audio diagnostics
Architecturecomponents, trust boundaries, data flow
Acoustic modemwaveforms, synchronization, FEC, profiles
Protocolversioned binary wire format
Discovery and groupslifecycle and security semantics
Security and threat modelguarantees, residual risk, disclosure
Benchmarking and test planreproducible evidence and open validation
Roadmaprelease criteria and contribution opportunities

Contributing

This project especially welcomes reproducible room measurements, Android/Linux audio compatibility reports, DSP improvements backed by fixtures, accessibility work, documentation, and security review. Start with CONTRIBUTING.md, use the issue forms, and read the Code of Conduct. Please use GitHub's private security reporting flow for vulnerabilities rather than a public issue.

If SonicChat is useful or intriguing, a GitHub star, a tested device report, a short demo video, or a well-scoped contribution all help the project become discoverable.

License

Licensed under the Apache License 2.0.

Contributors

Nellix

3 commits

Languages

Rust

74.7%

Dart

22.1%

CMake

1.3%