deadrop 0.2.0

Zero-knowledge encrypted dead drop. One binary. One command. Gone.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
<p align="center">
  <img src="assets/deadrop-logo.png" width="220" alt="deadrop logo" />
</p>

<h1 align="center">deadrop</h1>

<p align="center">
  <b>Zero‑knowledge file drops that self‑destruct.</b><br/>
  One command. One link. Gone. Like it never happened. 🫠
</p>

<p align="center">
  <a href="https://crates.io/crates/deadrop"><img src="https://img.shields.io/crates/v/deadrop.svg?style=flat-square&color=00ff88" alt="crates.io" /></a>
  <a href="https://github.com/Karmanya03/Deadrop/releases"><img src="https://img.shields.io/github/v/release/Karmanya03/Deadrop?style=flat-square&color=00ff88" alt="release" /></a>
  <a href="https://github.com/Karmanya03/Deadrop/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-00ff88?style=flat-square" alt="license" /></a>
  <img src="https://img.shields.io/badge/encryption-XChaCha20--Poly1305-00ff88?style=flat-square" alt="encryption" />
  <img src="https://img.shields.io/badge/written_in-Rust_πŸ¦€-00ff88?style=flat-square" alt="rust" />
</p>

<p align="center">
  <img src="https://img.shields.io/badge/server_knows-nothing_🀷-ff4444?style=flat-square" alt="zero knowledge" />
  <img src="https://img.shields.io/badge/after_download-πŸ’₯_self_destructs-ff4444?style=flat-square" alt="self destruct" />
  <img src="https://img.shields.io/badge/dependencies-just_the_binary-blueviolet?style=flat-square" alt="single binary" />
  <img src="https://img.shields.io/badge/tor-πŸ§…_hidden_service-blueviolet?style=flat-square" alt="tor" />
</p>

---

## What is this?

Remember in spy movies when someone leaves a briefcase under a park bench, and someone else picks it up later? That's a **dead drop**.

This is that, but for files. And the briefcase is encrypted with military-grade cryptography. And the park bench self-destructs after pickup. And nobody β€” not even the bench β€” knows what's inside. And now the bench can hide on the dark web. πŸ§…

```
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚   You   β”‚                                          β”‚  Friend β”‚
    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜                                          β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
         β”‚                                                    β”‚
         β”‚  ded ./secret-plans.pdf                            β”‚
         β”‚  ━━━━━━━━━━━━━━━━━━━━━━━                           β”‚
         β”‚                                                    β”‚
    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
    β”‚                  πŸ”’ Your Machine                        β”‚β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚β”‚
    β”‚  β”‚ Encrypt  │───►│  Ciphertext  │───►│ HTTP Server  β”‚  β”‚β”‚
    β”‚  β”‚ (Rust)   β”‚    β”‚  (on disk)   β”‚    β”‚ (Axum)       β”‚  β”‚β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚β”‚
    β”‚       πŸ”‘ Key goes in URL #fragment          β”‚          β”‚β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
         β”‚                                        β”‚           β”‚
         β”‚  πŸ“² Sends link via Signal / QR scan    β”‚           β”‚
         β”‚ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─►│           β”‚
         β”‚                                        β”‚           β”‚
         β”‚                                  β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”   β”‚
         β”‚                                  β”‚  Opens URL   β”‚β—„β”€β”€β”˜
         β”‚                                  β”‚  in browser  β”‚
         β”‚                                  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                                        β”‚
         β”‚                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                          β”‚  πŸ“¦ Browser fetches blob  β”‚
         β”‚                          β”‚  πŸ”‘ Extracts #key         β”‚
         β”‚                          β”‚  ⚑ WASM decrypts locally  β”‚
         β”‚                          β”‚  πŸ’Ύ File downloads         β”‚
         β”‚                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                                        β”‚
    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
    β”‚  πŸ’₯ Self-destruct triggered       β”‚         β”‚
    β”‚  πŸ”₯ Drop marked as burned         β”‚         β”‚
    β”‚  πŸ›‘ Server shuts down             β”‚         β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
         β”‚                                        β”‚
         β–Ό                                        β–Ό
    What file? There was no file.           Got it. Thanks. πŸ‘
```

## Features

### Core β€” the stuff that makes your IT department nervous

| Feature | Description |
|---|---|
| πŸ” **End‑to‑end encrypted** | XChaCha20‑Poly1305. The server never sees the key. Like a blind courier. |
| πŸ”— **Key in URL fragment** | The `#key` part never hits server logs, proxies, or HTTP headers. It's a ghost. |
| πŸ’₯ **Self‑destruct** | Expire by time, by download count, or both. This message will self‑destruct in... |
| πŸ“± **Works on phones** | Receiver only needs a browser. No app. No account. No soul‑selling signup. |
| πŸ“ **Send folders** | Directories auto‑pack to `.tar.gz`. Your entire `homework/` folder, encrypted. πŸ“š |
| πŸ“¦ **Multi‑file drops** | `ded file1.txt file2.pdf photos/` β€” bundles everything into one encrypted drop. |
| πŸ“‹ **Stdin / clipboard** | `echo "secret" \| ded -` β€” pipe anything. Your terminal is the dead drop. |
| ♾️ **Unlimited file size** | Streams from disk β€” your 50GB file won't eat your RAM for breakfast. |
| πŸ”‘ **Password protection** | Argon2id key derivation (64MB memory‑hard, GPU‑resistant). Receiver gets a password prompt in-browser β€” key is derived client-side. The server never sees the password OR the key. Fort Knox mode. 🏰 |
| πŸ“² **QR code** | Because typing URLs is for people who still use fax machines. |
| πŸ“₯ **Receive mode** | `ded receive` β€” phone‑to‑PC uploads. Your phone becomes the dead drop. |
| πŸ§… **Tor hidden service** | `--tor` β€” generates a `.onion` address. The dark web called, it wants its files. |
| πŸ“¦ **Single binary** | No runtime, no Docker, no config files. Just one executable. Like a katana. πŸ—‘οΈ |

### Security Hardening β€” because paranoia is a feature

| Feature | Description |
|---|---|
| πŸ‘» **Fragment auto‑clear** | `#key` is stripped from the URL bar and history the instant the page loads. Poof. |
| πŸ”’ **IP pinning** | Download is locked to the first IP that connects β€” everyone else gets a 403 slap. |
| πŸ›‘ **Security headers** | CSP, `X-Frame-Options: DENY`, `no-referrer`, `no-cache`. The whole paranoia buffet. |
| ⏱ **Rate limiting** | 2 req/sec per IP with burst of 5 β€” stops brute‑force nerds in their tracks. |
| 🎯 **16‑char drop IDs** | ~2⁢⁴ possible IDs β€” you'll win the lottery before guessing one. |
| πŸ• **Constant‑time 404s** | Random delay on not-found β€” prevents timing‑based detective work. |
| πŸ”₯ **Burn page** | Late visitors see "πŸ”₯ This drop was already downloaded and destroyed." Savage. |
| ⏰ **Auto‑expire page** | Tab stays open past expiry? Key nuked from JS memory. The UI self‑destructs. |
| 🧠 **Memory locking** | `mlock()` on Unix prevents the key from being swapped to disk. It lives in RAM or dies. |
| πŸ—‘ **Zero‑write deletion** | Encrypted temp files get overwritten with zeros before `rm`. CSI can't touch this. |
| 🧹 **Key zeroization** | Key wiped from RAM (via `zeroize`) on drop, both server and browser. Clean exit. |

## Installation

### πŸš€ One-line install (Linux/macOS)

```bash
curl -fsSL https://raw.githubusercontent.com/Karmanya03/Deadrop/main/install.sh | bash
```

> Detects your OS & architecture automatically, downloads the right binary, and adds it to your PATH. Magic.

### Download a binary

Grab the latest release for your platform from [**Releases**](https://github.com/Karmanya03/Deadrop/releases).

| Platform | Binary | Architecture |
|---|---|---|
| **Windows** | [`ded-windows-x86_64.exe`]https://github.com/Karmanya03/Deadrop/releases/latest/download/ded-windows-x86_64.exe | x86_64 |
| **Linux** | [`ded-linux-x86_64`]https://github.com/Karmanya03/Deadrop/releases/latest/download/ded-linux-x86_64 | x86_64 (musl, static) |
| **Linux** | [`ded-linux-aarch64`]https://github.com/Karmanya03/Deadrop/releases/latest/download/ded-linux-aarch64 | ARM64 (Raspberry Pi, etc.) |
| **macOS** | [`ded-macos-x86_64`]https://github.com/Karmanya03/Deadrop/releases/latest/download/ded-macos-x86_64 | Intel |
| **macOS** | [`ded-macos-aarch64`]https://github.com/Karmanya03/Deadrop/releases/latest/download/ded-macos-aarch64 | Apple Silicon (M1/M2/M3/M4) |

**Quick install (Linux/macOS):**

```bash
# Linux x86_64
curl -L https://github.com/Karmanya03/Deadrop/releases/latest/download/ded-linux-x86_64 -o ded && chmod +x ded && sudo mv ded /usr/local/bin/

# macOS Apple Silicon
curl -L https://github.com/Karmanya03/Deadrop/releases/latest/download/ded-macos-aarch64 -o ded && chmod +x ded && sudo mv ded /usr/local/bin/
```

### Via cargo

```bash
cargo install deadrop
```

### Build from source (for the trust‑no‑one crowd)

```bash
git clone https://github.com/Karmanya03/Deadrop.git
cd Deadrop
cargo build --release
# Binary at: target/release/ded
```

### πŸ”„ Update

```bash
# Linux/macOS β€” same as install, overwrites the old binary
curl -fsSL https://raw.githubusercontent.com/Karmanya03/Deadrop/main/install.sh | bash

# Via cargo
cargo install deadrop --force
```

### πŸ—‘ Uninstall

```bash
# If installed via script
rm -f ~/.local/bin/ded && echo "deadrop removed ☠"

# If installed to /usr/local/bin/
sudo rm -f /usr/local/bin/ded && echo "deadrop removed ☠"

# If installed via cargo
cargo uninstall deadrop
```

## Usage

### The basics β€” impress your friends in 3 seconds

```bash
# Send a file β€” that's it, that's the whole tool
ded secret.pdf

# Send a folder β€” auto-archives to .tar.gz
ded ./tax-returns-2025/

# Send multiple files β€” bundles into one drop
ded passwords.csv nudes.zip plans.pdf

# Pipe from stdin β€” your clipboard is a dead drop
echo "the password is swordfish" | ded -
cat ~/.ssh/id_rsa | ded -
```

### Receive mode β€” your phone becomes the dead drop

```bash
# Open upload page on your LAN β€” scan QR from phone
ded receive

# Save to a specific folder
ded receive -o ~/Downloads/

# Custom port, no QR
ded receive -p 9090 --no-qr
```

Scan the QR from your phone β†’ pick a file β†’ encrypted in-browser β†’ sent to your PC β†’ decrypted β†’ saved. One upload, then πŸ’₯ server self-destructs.

### Password mode β€” true zero‑knowledge πŸ”‘

```bash
# Share a file with a password
ded secret.pdf --pw "correct-horse-battery-staple"
```

**How it works:**
1. Server encrypts the file with a key derived from your password via **Argon2id** (64MB, 3 iterations)
2. The URL contains the **salt** (not the key) β€” so the link alone can't decrypt anything
3. Receiver opens the link β†’ sees a πŸ”‘ password prompt β†’ enters the password
4. Browser derives the same key via **Argon2id in WASM** (same params, runs client-side)
5. File decrypts locally. Server never sees the password or the key. Ever.

> πŸ’‘ **Pro tip:** Send the link over Slack, tell them the password on a phone call. Two channels = maximum paranoia.

### The spicy options 🌢️

```bash
# Self-destruct after 1 download, expire in 10 minutes
ded evidence.zip -n 1 -e 10m

# 30-second self-destruct. Blink and it's gone.
ded confession.txt -e 30s

# Go full Mission Impossible
ded plans.pdf -n 1 -e 30s --pw "this-message-will-self-destruct"

# Go full dark web spy πŸ•΅οΈ
ded whistleblower-docs.pdf --tor

# Receive via Tor β€” your phone uploads through the shadow realm
ded receive --tor -o ~/secrets/
```

### What you see

```
     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
     β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—
     β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•
     β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•
     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘
     β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β• β•šβ•β•  β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•
          ⚑ zero-knowledge encrypted file sharing ⚑

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  URL  http://192.168.1.42:8080/d/a3f9c1b2#xK9m  β”‚
  β”‚                                                   β”‚
  β”‚  β”œβ”€ File       secret.pdf                         β”‚
  β”‚  β”œβ”€ Size       4.2 MB                             β”‚
  β”‚  β”œβ”€ Expires    10m                                β”‚
  β”‚  β”œβ”€ Downloads  1                                  β”‚
  β”‚  β”œβ”€ πŸ”‘ Password  yes (Argon2id)                   β”‚
  β”‚  └─ Crypto     XChaCha20-Poly1305                 β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  πŸ§… Tor: http://abc...xyz.onion/d/a3f9c1b2#pw:...   ← (with --tor)

  β–ˆβ–€β–€β–€β–€β–€β–ˆ β–€β–€β–€β–ˆβ–„β–ˆ β–ˆβ–€β–€β–€β–€β–€β–ˆ     <- QR code appears here
  β–ˆ β–ˆβ–ˆβ–ˆ β–ˆ β–ˆβ–€β–ˆ β–€β–„  β–ˆ β–ˆβ–ˆβ–ˆ β–ˆ        scan with phone πŸ“±
  ...
```

### What the receiver sees (password-protected drop)

```
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  DEADROP  encrypted dead drop            β”‚
  β”‚                                          β”‚
  β”‚  πŸ“„ File       secret.pdf                β”‚
  β”‚  πŸ“¦ Size       4.2 MB                    β”‚
  β”‚  ⏰ Expires    59m                       β”‚
  β”‚  πŸ” Encryption XChaCha20-Poly1305        β”‚
  β”‚                                          β”‚
  β”‚  πŸ”‘ This drop requires a password        β”‚
  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
  β”‚  β”‚ Enter password...               β–ˆβ”‚    β”‚
  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
  β”‚                                          β”‚
  β”‚  [ πŸ”“ Unlock & Download ]               β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

After entering the correct password, Argon2id runs in WASM (~2-5 seconds on the derivation), then the file decrypts and downloads. Wrong password? Decryption fails gracefully β€” try again.

## πŸš€ Demo Commands β€” Try Every Feature

> **Run one at a time** β€” each starts a server. Ctrl+C to stop, then run the next.

| # | Feature | Command | What happens |
|---|---|---|---|
| 1 | πŸ“„ **Single file** | `ded secret.pdf` | Encrypts β†’ serves link β†’ browser decrypts β†’ πŸ’₯ |
| 2 | πŸ“ **Folder** | `ded ./my-folder/` | Archives β†’ encrypts β†’ serves `.tar.gz` |
| 3 | πŸ“¦ **Multi-file** | `ded file1.txt file2.pdf pics/` | Bundles all β†’ one encrypted archive |
| 4 | πŸ“‹ **Stdin pipe** | `echo "swordfish" \| ded -` | Reads stdin β†’ drops as `clipboard.txt` |
| 5 | ⏱ **Custom expiry** | `ded file.txt -e 5m` | Auto-expires after 5 minutes |
| 6 | πŸ”’ **Download limit** | `ded file.txt -n 3` | Self-destructs after 3 downloads |
| 7 | 🚫 **No QR** | `ded file.txt --no-qr` | URL only, no QR code (you hate fun) |
| 8 | πŸ”‘ **Password** | `ded file.txt --pw "hunter2"` | Receiver gets password prompt. Argon2id in-browser. |
| 9 | 🌐 **Custom port** | `ded file.txt -p 9090` | Listens on port 9090 |
| 10 | 🀯 **Full paranoia** | `ded file.txt -n 1 -e 30s --pw "yolo"` | 1 download, 30s, password. Gone. |
| 11 | πŸ“₯ **Receive mode** | `ded receive -o ~/Downloads/` | Upload page β†’ phone sends file to PC |
| 12 | πŸ“₯πŸ”§ **Receive custom** | `ded receive -p 9999 --no-qr` | Custom port receive, no QR |
| 13 | πŸ§… **Tor send** | `ded secret.pdf --tor` | Generates `.onion` URL. Dark web drop. |
| 14 | πŸ§…πŸ“₯ **Tor receive** | `ded receive --tor -o ~/secrets/` | Tor receive. Max stealth. |
| 15 | πŸ”’ **IP pinning test** | `ded file.txt -n 2` | Download on PC β†’ try on phone β†’ 403 blocked |
| 16 | ⏰ **Auto-expiry test** | `ded file.txt -e 30s` | Wait 30s β†’ open URL β†’ "Drop not found" |

## ⚑ Flags Cheat Sheet

### `ded [send]` β€” Send mode (the default)

> `send` is optional β€” `ded file.txt` and `ded send file.txt` are identical.

| Flag | Short | Default | What it does | Vibe |
|---|---|---|---|---|
| `<PATH>...` | β€” | β€” | File(s), folder(s), or `-` for stdin | 🎯 The stuff you're dropping |
| `--port` | `-p` | `8080` | Port to listen on | πŸšͺ Pick your door |
| `--expire` | `-e` | `1h` | Auto‑expire duration (`30s`, `10m`, `1h`, `7d`) | ⏰ The countdown timer |
| `--downloads` | `-n` | `1` | Max downloads before self‑destruct (0 = ∞) | πŸ’£ How many pickups |
| `--pw` | β€” | None | Password-protect drop (Argon2id, 64MB memory‑hard). Receiver gets a password prompt in-browser. | 🏰 Fort Knox mode |
| `--bind` | `-b` | `0.0.0.0` | Bind address | 🌐 Which interface |
| `--no-qr` | β€” | `false` | Suppress QR code | 😐 You hate fun |
| `--tor` | β€” | `false` | Enable Tor hidden service | πŸ§… Dark web activated |

### `ded receive` β€” Receive mode

| Flag | Short | Default | What it does | Vibe |
|---|---|---|---|---|
| `--port` | `-p` | `8080` | Port to listen on | πŸšͺ Pick your door |
| `--output` | `-o` | `.` | Save received files here | πŸ“‚ Where the loot goes |
| `--bind` | `-b` | `0.0.0.0` | Bind address | 🌐 Which interface |
| `--no-qr` | β€” | `false` | Suppress QR code | 😐 Still no fun |
| `--tor` | β€” | `false` | Enable Tor hidden service | πŸ§… Receive from the shadow realm |

## How It Works

### Send flow

```
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Sender  β”‚          β”‚   Server (your PC) β”‚          β”‚ Receiver β”‚
  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
        β”‚                         β”‚                           β”‚
        β”‚  1. Generate random     β”‚                           β”‚
        β”‚     256-bit key         β”‚                           β”‚
        β”‚     (or derive from pw) β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  2. Encrypt file        β”‚                           β”‚
        β”‚     XChaCha20-Poly1305  β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  3. Store ciphertext ──►│                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  4. Key β†’ URL #fragment β”‚                           β”‚
        β”‚     (or salt if --pw)   β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  5. Share link ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─►│
        β”‚     (Signal, QR, etc.)  β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         │◄── 6. Open link ──────────│
        β”‚                         β”‚                           β”‚
        β”‚                         │─── 7. Serve encrypted ──►│
        β”‚                         β”‚       blob (HTTP)         β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         β”‚    8. Browser extracts    β”‚
        β”‚                         β”‚       #key (or prompts    β”‚
        β”‚                         β”‚        for password)      β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         β”‚    9. WASM decrypts       β”‚
        β”‚                         β”‚       locally in browser  β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         β”‚   10. File downloads      β”‚
        β”‚                         β”‚       to device           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
        β”‚  β”‚  πŸ’₯ Self-destruct β”‚ πŸ”₯ Burned β”‚ πŸ›‘ Off β”‚        β”‚
        β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
        β–Ό                                                     β–Ό
```

### Password flow (zero-knowledge)

```
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Sender  β”‚          β”‚   Server (your PC) β”‚          β”‚ Receiver β”‚
  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
        β”‚                         β”‚                           β”‚
        β”‚  ded file --pw "pass"   β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  1. Argon2id(pass,salt) β”‚                           β”‚
        β”‚     β†’ 256-bit key       β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  2. Encrypt with key    β”‚                           β”‚
        β”‚  3. URL = #pw:<salt>    β”‚                           β”‚
        β”‚     (NOT the key!)      β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  5. Share link ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─►│
        β”‚  6. Tell password  ─ ─ ─│─ ─ ─ ─ (phone call) ─ ─►│
        β”‚                         β”‚                           β”‚
        β”‚                         │◄── 7. Open link ──────────│
        β”‚                         β”‚                           β”‚
        β”‚                         β”‚    8. Browser shows πŸ”‘    β”‚
        β”‚                         β”‚       password prompt     β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         β”‚    9. Receiver types pw   β”‚
        β”‚                         β”‚   10. WASM: Argon2id      β”‚
        β”‚                         β”‚       (pw,salt) β†’ key     β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         │◄──11. Fetch blob ─────────│
        β”‚                         │──►12. Return ciphertext──►│
        β”‚                         β”‚                           β”‚
        β”‚                         β”‚   13. WASM decrypts       β”‚
        β”‚                         β”‚   14. File downloads      β”‚
        β”‚                         β”‚                           β”‚
        β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
        β”‚    β”‚  Server never saw: password or key  β”‚         β”‚
        β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
        β–Ό                                                     β–Ό
```

### Receive flow

```
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Receiver β”‚          β”‚   Server (your PC) β”‚          β”‚  Phone   β”‚
  β”‚   (PC)   β”‚          β”‚                    β”‚          β”‚ (sender) β”‚
  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
        β”‚                         β”‚                           β”‚
        β”‚  ded receive            β”‚                           β”‚
        β”‚  ━━━━━━━━━━━━           β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  1. Generate key ──────►│                           β”‚
        β”‚  2. Key β†’ QR code       β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         │◄── 3. Scan QR, open ─────│
        β”‚                         β”‚       upload page         β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         β”‚    4. Pick file           β”‚
        β”‚                         β”‚    5. WASM encrypts       β”‚
        β”‚                         β”‚       in-browser          β”‚
        β”‚                         β”‚                           β”‚
        β”‚                         │◄── 6. Upload ciphertext ─│
        β”‚                         β”‚                           β”‚
        β”‚  7. Server decrypts  ◄──│                           β”‚
        β”‚  8. Saves to disk       β”‚                           β”‚
        β”‚                         β”‚                           β”‚
        β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚
        β”‚  β”‚  βœ… Saved β”‚ πŸ’₯ Self-destruct β”‚ πŸ›‘ Off β”‚          β”‚
        β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚
        β–Ό                                                     β–Ό
```

**The critical insight**: the `#fragment` in a URL is **never sent to the server**. Not in HTTP requests, not in logs, not in referrer headers. The server literally cannot learn the key even if it wanted to. It's like trying to read a letter through a sealed envelope. While blindfolded. In the dark.

### Tor flow πŸ§…

```
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Sender  │────►│  ded --tor  │────►│  Tor Network  │────►│ Receiver β”‚
  β”‚          β”‚     β”‚             β”‚     β”‚  (.onion)     β”‚     β”‚ (Tor     β”‚
  β”‚          β”‚     β”‚  Generates  β”‚     β”‚               β”‚     β”‚  Browser)β”‚
  β”‚          β”‚     β”‚  .onion URL β”‚     β”‚  3 relays     β”‚     β”‚          β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                               β”‚
                                        No IP. No trace.       β”‚
                                        Just encrypted bytes.  β”‚
                                                               β–Ό
                                                          File decrypts
                                                          in browser πŸ”“
```

## Security Architecture

### Defense in Depth

```
  ╔══════════════════════════════════════════════════════════════════╗
  β•‘  Layer 7 β”‚ Self-destruct    One download β†’ burn β†’ server off    β•‘
  ╠══════════β•ͺ══════════════════════════════════════════════════════╣
  β•‘  Layer 6 β”‚ Browser          Fragment auto-clear + auto-expire   β•‘
  ╠══════════β•ͺ══════════════════════════════════════════════════════╣
  β•‘  Layer 5 β”‚ Anti-forensics   mlock() + zeroize + zero-write     β•‘
  ╠══════════β•ͺ══════════════════════════════════════════════════════╣
  β•‘  Layer 4 β”‚ Access control   IP pinning + rate limit + 64-bit IDβ•‘
  ╠══════════β•ͺ══════════════════════════════════════════════════════╣
  β•‘  Layer 3 β”‚ Network          HTTP + security headers             β•‘
  ╠══════════β•ͺ══════════════════════════════════════════════════════╣
  β•‘  Layer 2 β”‚ Zero-knowledge   Key in URL #fragment only          β•‘
  ╠══════════β•ͺ══════════════════════════════════════════════════════╣
  β•‘  Layer 1 β”‚ Encryption       XChaCha20-Poly1305 (256-bit, AEAD) β•‘
  ╠══════════β•ͺ══════════════════════════════════════════════════════╣
  β•‘  Layer 0 β”‚ Anonymity        Tor hidden service (.onion) πŸ§…     β•‘
  β•šβ•β•β•β•β•β•β•β•β•β•β•§β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
```

### Threat Model

#### βœ… Protected against

| Threat | How |
|---|---|
| Server operator learning file contents | Zero‑knowledge β€” key never reaches server |
| Man‑in‑the‑middle reading the key | Key lives in `#fragment`, never transmitted over HTTP |
| Someone intercepting the URL (with `--pw`) | URL contains salt, not key. They still need the password. |
| Network eavesdropping | Encryption at application layer (XChaCha20-Poly1305) |
| Server logs leaking the key | Fragments aren't logged by any HTTP server or proxy |
| Brute force on encryption | XChaCha20-Poly1305 with 256‑bit keys. See you in 10²⁰ years. |
| GPU attacks on passwords | Argon2id with 64MB memory cost. Your 4090 weeps. |
| Drop ID enumeration | 16‑char IDs (~2⁢⁴) + rate limiting + constant‑time 404s |
| URL bar shoulder surfing | Fragment stripped from URL bar on page load |
| Browser history forensics | `history.replaceState()` removes the `#key` |
| Key persisting in RAM | `zeroize` on Rust side, `key = null` on JS side |
| Key swapped to disk (Unix) | `mlock()` pins key memory pages |
| Encrypted file recovery | Zero‑overwrite before deletion |
| Clickjacking / iframe embedding | `X-Frame-Options: DENY` + `frame-ancestors 'none'` |
| XSS injection | Content Security Policy β€” scripts only from `'self'` |
| Stale tab leaking key | Auto‑expire nukes key from memory when drop expires |
| IP tracking | `--tor` hides both sender and receiver behind .onion |
| Late visitor confusion | Burn page β€” "already downloaded and destroyed" |

#### ❌ NOT protected against

- Someone who has the full URL with the `#key` (for non-password drops, that IS the key β€” guard it)
- Malware on sender/receiver device (keyloggers, screen capture)
- Your friend screenshotting the file and posting it on Twitter
- Rubber hose cryptanalysis (look it up, it's not pretty πŸ”¨)
- Time travelers
- Your mom looking over your shoulder
- The NSA (just kidding... unless? πŸ‘€)

## Technical Details

| Component | Choice | Why |
|---|---|---|
| Encryption | XChaCha20‑Poly1305 | 256‑bit, extended nonce, AEAD. Used by WireGuard, Cloudflare |
| KDF | Argon2id | Memory‑hard, GPU‑resistant. 64MB cost, 3 iterations. Winner of Password Hashing Competition |
| Browser KDF | Argon2id (WASM) | Same Rust `argon2` crate compiled to WASM β€” identical params, runs client-side |
| Chunk size | 64KB | Balances streaming performance vs. auth tag overhead |
| Server | Axum (Rust) | Async, zero-copy, no garbage collector. Blazingly fastβ„’ |
| Rate limiter | tower_governor | Token bucket per IP β€” stops brute force |
| Browser crypto | WebAssembly | Same Rust code compiled to WASM, near-native speed |
| Nonce derivation | base XOR chunk_index | Per-chunk unique nonces without storing them |
| Binary embedding | rust-embed | HTML, CSS, JS, WASM all baked into the single binary |
| Memory safety | mlock + zeroize | Key never hits swap, wiped from RAM on drop |
| Anonymity | Tor hidden service | `.onion` address via local `tor` daemon |
| Archive | tar + flate2 | Folder/multi-file bundling with gzip compression |

## Memory Usage

| File Size | Server RAM | Browser RAM | Notes |
|---|---|---|---|
| 1 MB | ~5 MB | ~5 MB | Smol file, smol memory |
| 100 MB | ~5 MB | ~200 MB | Still chill |
| 1 GB | ~5 MB | ~2 GB | Desktop territory |
| 10 GB | ~5 MB | Desktop only | Streaming mode. Server doesn't care. |

The server uses constant memory regardless of file size. It streams encrypted chunks from disk. Your 50GB Linux ISO is treated the same as a 1KB text file (memory-wise).

## FAQ

**Q: Is this legal?**
A: It's a file sharing tool with encryption. Like Signal, or HTTPS, or putting a letter in an envelope. What you put inside is your business.

**Q: Can I use this at work?**
A: Your IT department will either promote you or fire you. No in-between.

**Q: Why not just use Google Drive?**
A: Google Drive knows your files. Deadrop doesn't. That's the whole point. Also Google Drive doesn't self-destruct. Boring.

**Q: What happens if I lose the URL?**
A: The file is gone. That's... the feature. It's a dead drop, not Google Photos.

**Q: Can the server see my files?**
A: No. The encryption key is in the URL fragment which never reaches the server. The server holds meaningless encrypted bytes. It's like asking if your mailbox can read your letters.

**Q: What about password-protected drops?**
A: Even better. The URL only has the salt β€” the server never sees the password or the key. The receiver's browser derives the key locally via Argon2id in WASM. True zero-knowledge. The server is literally clueless.

**Q: What if someone intercepts my password drop URL?**
A: Without the password, the URL is useless. It only contains a random salt. They'd need to brute-force Argon2id (64MB memory Γ— 3 iterations per guess). Good luck with that.

**Q: What if someone else tries the link?**
A: They can't. IP pinning locks the download to the first device. Second IP gets 403'd into oblivion.

**Q: What if I visit a dead link?**
A: Already downloaded β†’ "πŸ”₯ This drop was already downloaded and destroyed." Expired β†’ "Drop not found." Either way, it's gone. Like your ex's texts.

**Q: Why does `--tor` take so long?**
A: Tor needs ~30-60 seconds to generate a `.onion` address and establish circuits through 3 relays. Patience. Good anonymity takes time.

**Q: Can I send multiple files?**
A: Yes! `ded file1.txt file2.pdf folder/` bundles everything into one encrypted `.tar.gz` archive automatically.

**Q: Can I pipe from stdin?**
A: `echo "the password is swordfish" | ded -` β€” works like a charm. Serves it as `clipboard.txt`.

**Q: Why Rust?**
A: Because we wanted the binary to be fast, safe, and have zero runtime dependencies. Also because we enjoy fighting the borrow checker at 3 AM. It builds character.

## Contributing

PRs welcome. Here's the roadmap:

- [x] ~~End-to-end encryption (XChaCha20-Poly1305)~~
- [x] ~~QR code generation~~
- [x] ~~Self-destruct by time & download count~~
- [x] ~~IP pinning~~
- [x] ~~Folder support (.tar.gz)~~
- [x] ~~`ded receive` mode (phone β†’ PC)~~
- [x] ~~Multi-file drops~~
- [x] ~~Stdin / clipboard mode~~
- [x] ~~Tor hidden service~~
- [x] ~~Password protection (Argon2id)~~
- [x] ~~In-browser password prompt with client-side Argon2id~~
- [ ] Receiver‑side streaming decryption for huge files on mobile
- [ ] Web UI drag-and-drop improvements
- [ ] Resume interrupted downloads
- [ ] Multi-recipient drops (different keys per recipient)

## Star History

If you've read this far, you're legally obligated to star the repo. It's in the fine print.

⭐ **[Star this repo](https://github.com/Karmanya03/Deadrop)** β€” it makes the self-destruct mechanism work better. (Not really, but it makes us happy.)

## License

MIT β€” do whatever you want. Just don't blame us if your dead drop gets intercepted by actual spies. Or if your friend screenshots the file. Or if time travelers get involved.

---

<p align="center">
  <sub>Built with πŸ¦€ and an unreasonable amount of paranoia.</sub><br/>
  <sub>Remember: just because you're paranoid doesn't mean they're not after your files.</sub>
</p>