# NymDrop

A modern, Nym-native anonymous submission system — a SecureDrop alternative that
uses the [Nym mixnet](https://nymtech.net/) as its transport instead of Tor.

The source uses an ordinary browser. There is nothing to install, no onion
service to reach, and no client-side configuration. Anonymity protection lives in
the design, not in an obligation on the source to install anything.

## Design

- **Transport:** Nym mixnet only — no Tor. Cover traffic, padding and mixnet
  unlinkability protect the server side.
- **Client-side encryption:** submissions are encrypted in the browser with
  X25519 + HKDF-SHA-256 + AES-GCM-256 (WebCrypto). The server never sees
  plaintext.
- **No-log server:** no IP, no timestamps, no metadata persisted. A blind relay
  forwards ciphertext through the mixnet and keeps nothing on disk.
- **No third parties:** no CDN, no Cloudflare, no NIST curves, no tracking
  JavaScript.

See [`ARCHITECTURE.md`](ARCHITECTURE.md) for the full threat model and component
breakdown.

## Components

| Binary | Role |
|---|---|
| `nymdrop` | Public-facing HTTP server + blind relay. Embeds a `nym-client`, accepts encrypted submissions on `POST /submit`, forwards them through the mixnet to the reader's Nym address. |
| `nymdrop-reader` | Operator-side inbox. Runs a `nym-client`, receives messages from the mixnet, decrypts them with the operator's X25519 private key, and writes submissions to disk. Headless/CLI by default; `--gui` launches a graphical inbox instead. `--data-dir` makes a run fully self-contained (key, inbox, and the embedded nym-client's own state all live under that directory) for portable, no-install-trace use, e.g. from a USB stick. |
| `nymdrop-source` | Optional SOCKS5-based source helper. |

## Build

The `nym-client` binary is required at build time (embedded via `go:embed`) but
is **not** committed to keep the repository small. Fetch it first:

```sh
./scripts/fetch-nym-binaries.sh   # downloads nym-client v1.1.76 (linux/amd64)

go build ./cmd/nymdrop/
go build ./cmd/nymdrop-reader/
```

## Run

```sh
# 1. Start the reader (prints its Nym inbox address and the public key to deploy)
./nymdrop-reader --id nymdrop-inbox --ws-port 1977

# ...or with a graphical inbox instead of the terminal:
./nymdrop-reader --gui

# ...or fully self-contained (e.g. running from a USB stick, nothing touches
# the host's real home directory):
./nymdrop-reader --gui --data-dir /path/to/usb/nymdrop-data

# 2. Start the server, pointing it at the reader's Nym address
./nymdrop --journalist "<NYM_ADDRESS_FROM_READER>" --static ./static --listen 127.0.0.1:8080
```

Deploy the reader's public key into `static/crypto.js` so the browser encrypts to
the right key. Put the server behind TLS in production.

## Platform support

The submission page (`static/`) is a plain web form: any browser on any OS works
today, nothing to install.

`nymdrop` and `nymdrop-reader` themselves are **Linux/amd64 only** for now. This
is not a choice we made — it is a limit of the upstream `nym-client` binary they
embed: Nym's official releases ship a single Linux build only, no Windows or
macOS binary. Building `nym-client` for another OS would mean compiling the
whole Rust client from source, which Nym's own documentation calls
"experimental" and "not recommended" outside Linux, with no platform-specific
build instructions provided. Cross-platform reader builds are tracked as a TODO,
not attempted yet.

## Status

End-to-end verified: browser/client → HTTP server → Nym mixnet → reader →
decrypted submission on disk. A prebuilt `nymdrop-reader` (linux/amd64) is
available under [Releases](https://git.virebent.art/virebent/nymdrop/releases)
(fetch via the Forgejo API/token or an SSH tunnel to the host — the public
`git.virebent.art` domain serves cgit for browsing only, not release downloads).

## License

[AGPL-3.0](LICENSE).
