daku 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,274 +1,370 @@
1
1
  # DAKU
2
2
 
3
- > **Anonymous authentication. Zero personal data.**
3
+ > **Anonymous authentication & encryption. Zero personal data. One library.**
4
4
 
5
- **DAKU** (pronounced _DAA KU_) means "bandits" in Punjabi. Historically, bandits operated anonymously, often using masks to hide their identity. This library adopts that privacy-first ethos—anonymous cryptographic authentication without personal data.
5
+ **DAKU** (Punjabi for "bandits") is a minimal cryptographic toolkit for building passwordless, privacy-first applications. No emails, no passwords, no databases of credentials to breach.
6
+
7
+ ```bash
8
+ npm install daku
9
+ ```
6
10
 
7
11
  ---
8
12
 
9
13
  ## Why DAKU?
10
14
 
11
- **Stop storing passwords. Stop managing email verifications. Stop worrying about data breaches.**
12
-
13
- DAKU is a simpler approach to user authentication that keeps both you and your users anonymous. No databases of usernames, no password hashes to secure, no personal information to leak.
15
+ | Traditional Auth | DAKU |
16
+ |------------------|------|
17
+ | Store emails & passwords | Just verify signatures |
18
+ | Hash passwords, manage resets | No passwords exist |
19
+ | GDPR compliance headaches | No PII collected |
20
+ | Database = honeypot for hackers | Nothing sensitive to steal |
21
+ | OAuth complexity | 3 functions to authenticate |
14
22
 
15
23
  ```javascript
16
- // Traditional auth: Store emails, hash passwords, manage resets...
17
- // DAKU: Just verify cryptographic signatures ✨
18
- const publicKey = await verifyAuth(token);
19
- ```
20
-
21
- ### The Problem with Traditional Auth
22
-
23
- Every traditional authentication system carries risk:
24
-
25
- - **Passwords**: Users reuse them, forget them, get them stolen
26
- - **Email/Phone**: Requires collecting personal data (GDPR, privacy laws)
27
- - **Databases**: Honeypots for hackers; one breach exposes everything
28
- - **Identity**: Your users leave traces everywhere they sign up
24
+ import { generateKeyPair, createAuth, verifyAuth } from "daku";
29
25
 
30
- ### The DAKU Way
26
+ // User creates identity (client-side, once)
27
+ const { privateKey, publicKey } = generateKeyPair();
31
28
 
32
- Users authenticate with cryptographic keypairs—like Bitcoin wallets, but for your app:
29
+ // User logs in (client-side)
30
+ const token = await createAuth(privateKey);
33
31
 
34
- - **No signup forms**: Generate a keypair, start using your app
35
- - **No passwords**: Users never create or remember passwords
36
- - **No PII collection**: No emails, phones, or personal data
37
- - **Built-in spam protection**: Proof-of-work prevents abuse
38
- - **You stay clean**: Nothing sensitive to store, nothing to breach
32
+ // Server verifies (server-side)
33
+ const userId = await verifyAuth(token); // Returns publicKey or null
34
+ ```
39
35
 
40
- > DAKU uses **secp256k1** signatures (same as Bitcoin/Ethereum) with **proof-of-work** spam protection. Auth tokens expire in 1 minute. Users control their private keys, you just verify signatures.
36
+ **That's it.** No signup forms, no email verification, no password resets.
41
37
 
42
38
  ---
43
39
 
44
- ## Installation
40
+ ## What DAKU Offers
45
41
 
46
- ```bash
47
- npm install daku
42
+ ### 🔑 Identity
43
+ ```javascript
44
+ generateKeyPair() // Create new keypair identity
45
+ getPublicKey(privateKey) // Derive public key from private
46
+ getUsername(publicKey) // Human-readable name like "oceanrunning4523"
48
47
  ```
49
48
 
50
- ## Quick Start
51
-
49
+ ### 🎫 Authentication
52
50
  ```javascript
53
- import { generateKeyPair, createAuth, verifyAuth } from "daku";
54
-
55
- // 1. User generates keypair (client-side)
56
- const { privateKey, publicKey } = generateKeyPair();
51
+ createAuth(privateKey, pow?) // Create login token (with spam protection)
52
+ verifyAuth(token, pow?) // Verify token, returns publicKey or null
53
+ ```
57
54
 
58
- // 2. Create auth token (client-side)
59
- const token = await createAuth(privateKey);
55
+ ### ✍️ Signatures
56
+ ```javascript
57
+ sign(message, privateKey, pow?) // Sign any data
58
+ verify(message, sig, publicKey, pow?) // Verify signature
59
+ sha256(message) // SHA-256 hash
60
+ ```
60
61
 
61
- // 3. Verify auth (server-side)
62
- const publicKey = await verifyAuth(token);
63
- // Authenticated! publicKey is the unique user ID
62
+ ### 🔐 E2E Encryption
63
+ ```javascript
64
+ deriveSharedSecret(myPrivate, theirPublic) // ECDH key agreement
65
+ encrypt(plaintext, key) // AES-256-GCM encrypt
66
+ decrypt(ciphertext, key) // AES-256-GCM decrypt
64
67
  ```
65
68
 
66
69
  ---
67
70
 
68
- ## Core Functions
71
+ ## 20+ Use Cases
72
+
73
+ | # | Use Case |
74
+ |---|----------|
75
+ | 1 | **Anonymous chat apps** — Users communicate without revealing identity or phone numbers |
76
+ | 2 | **Passwordless API authentication** — Clients sign requests instead of using API keys |
77
+ | 3 | **End-to-end encrypted messaging** — Private conversations only sender and receiver can read |
78
+ | 4 | **Anonymous feedback systems** — Collect honest feedback without identifying who submitted it |
79
+ | 5 | **Whistleblower platforms** — Secure, anonymous submission of sensitive information to journalists |
80
+ | 6 | **Decentralized identity** — Users own their identity, no central authority controls access |
81
+ | 7 | **IoT device authentication** — Devices authenticate without passwords or certificate authorities |
82
+ | 8 | **Wallet-based login** — Same keys work with Bitcoin/Ethereum ecosystems (secp256k1) |
83
+ | 9 | **Document signing** — Cryptographically sign contracts, agreements, or any digital document |
84
+ | 10 | **Anonymous voting systems** — Verify votes are legitimate without revealing who voted |
85
+ | 11 | **Encrypted file sharing** — Share files that only intended recipients can decrypt |
86
+ | 12 | **Private note-taking apps** — Notes encrypted locally, unreadable even if server breached |
87
+ | 13 | **Spam-resistant forms** — Proof-of-work prevents bots from mass-submitting without CAPTCHAs |
88
+ | 14 | **Multiplayer game authentication** — Players authenticate without creating accounts or emails |
89
+ | 15 | **Anonymous support tickets** — Users get help without revealing personal information |
90
+ | 16 | **Secure configuration sharing** — Share secrets between team members with E2E encryption |
91
+ | 17 | **Timestamped proof of existence** — Sign documents to prove they existed at specific time |
92
+ | 18 | **Private health apps** — Health data stays encrypted, only user can access it |
93
+ | 19 | **Anonymous marketplace** — Buy/sell without linking transactions to real identity |
94
+ | 20 | **Encrypted backups** — Backup data that only you can restore, even on untrusted storage |
95
+ | 21 | **CLI tool authentication** — Command-line tools authenticate without browser OAuth flows |
96
+ | 22 | **Peer-to-peer apps** — Direct encrypted communication between users without servers |
97
+ | 23 | **Private analytics** — Collect anonymous usage data without tracking individuals |
98
+ | 24 | **Secure team collaboration** — Group encryption for team channels and shared documents |
69
99
 
70
- ### `generateKeyPair()`
100
+ ---
71
101
 
72
- **Create a new identity**
102
+ ## How It Works
73
103
 
74
- ```javascript
75
- const { privateKey, publicKey } = generateKeyPair();
104
+ ### Authentication Flow
105
+ ```
106
+ ┌─────────────────────────────────────────────────────────────┐
107
+ │ CLIENT │
108
+ │ │
109
+ │ 1. First visit: generateKeyPair() → save privateKey │
110
+ │ 2. Login: createAuth(privateKey) → token │
111
+ │ 3. Send token to server │
112
+ └─────────────────────────────────────────────────────────────┘
113
+
114
+
115
+ ┌─────────────────────────────────────────────────────────────┐
116
+ │ SERVER │
117
+ │ │
118
+ │ 1. verifyAuth(token) → publicKey (user ID) │
119
+ │ 2. publicKey is the unique, permanent user identifier │
120
+ │ 3. No passwords, no emails, no database of credentials │
121
+ └─────────────────────────────────────────────────────────────┘
76
122
  ```
77
123
 
78
- Generates a secp256k1 keypair. The **privateKey** stays with the user (never share it), the **publicKey** identifies them to your service.
124
+ ### E2E Encryption Flow
125
+ ```
126
+ Alice Bob
127
+ │ │
128
+ │ 1. deriveSharedSecret(alice.priv, bob.pub) │
129
+ │ ═══════════════════════════════════ │
130
+ │ (Both derive SAME secret) │
131
+ │ ═══════════════════════════════════ │
132
+ │ 2. deriveSharedSecret(bob.priv, alice.pub) │
133
+ │ │
134
+ │ 3. encrypt("Hello", secret) ──────────────►│
135
+ │ ◄──────────────│ 4. decrypt(cipher, secret)
136
+ │ │
137
+ └─────────────────────────────────────────────┘
138
+ Only Alice & Bob can read messages
139
+ ```
79
140
 
80
- - Returns: `{ privateKey: string, publicKey: string }`
81
- - Use case: First-time users, account creation
141
+ ### Group Encryption
142
+ ```javascript
143
+ import { deriveSharedSecret, encrypt, decrypt } from "daku";
144
+ import crypto from "node:crypto";
82
145
 
83
- ---
146
+ // Admin creates group key (just random 32 bytes)
147
+ const groupKey = crypto.randomBytes(32).toString("hex");
84
148
 
85
- ### `getPublicKey(privateKey)`
149
+ // Distribute to each member securely
150
+ for (const member of members) {
151
+ const secret = deriveSharedSecret(admin.privateKey, member.publicKey);
152
+ const encryptedKey = await encrypt(groupKey, secret);
153
+ // Send encryptedKey to member
154
+ }
86
155
 
87
- **Derive the public identity**
156
+ // Member decrypts their copy
157
+ const memberSecret = deriveSharedSecret(member.privateKey, admin.publicKey);
158
+ const groupKey = await decrypt(encryptedKey, memberSecret);
88
159
 
89
- ```javascript
90
- const publicKey = getPublicKey(privateKey);
160
+ // Everyone encrypts/decrypts with the shared group key
161
+ const message = await encrypt("Hello group!", groupKey);
91
162
  ```
92
163
 
93
- Extract the public key from a private key. Useful when users return with their saved privateKey.
164
+ ---
94
165
 
95
- - Returns: `publicKey` string
96
- - Deterministic: Same privateKey always produces same publicKey
166
+ ## Security
167
+
168
+ | Feature | Implementation |
169
+ |---------|----------------|
170
+ | **Signatures** | secp256k1 ECDSA (same as Bitcoin/Ethereum) |
171
+ | **Encryption** | AES-256-GCM with random 96-bit IV |
172
+ | **Key Exchange** | ECDH (Elliptic Curve Diffie-Hellman) |
173
+ | **Hashing** | SHA-256 |
174
+ | **Spam Protection** | Proof-of-work (configurable difficulty) |
175
+ | **Token Expiry** | Auth tokens valid for 1 minute only |
176
+
177
+ ### What DAKU Protects Against
178
+ - ✅ Password breaches (no passwords exist)
179
+ - ✅ Credential stuffing (nothing to stuff)
180
+ - ✅ Phishing (no credentials to phish)
181
+ - ✅ Database leaks (no PII stored)
182
+ - ✅ Replay attacks (1-minute token expiry)
183
+ - ✅ Spam/bots (proof-of-work)
184
+ - ✅ Man-in-the-middle (E2E encryption)
185
+
186
+ ### User Responsibilities
187
+ - 🔑 Users must securely store their private key
188
+ - 🔑 Lost private key = lost identity (no recovery)
189
+ - 🔑 Compromised private key = compromised identity
97
190
 
98
191
  ---
99
192
 
100
- ### `getUsername(publicKey)`
193
+ ## Examples
101
194
 
102
- **Make public keys human-readable**
195
+ ### Express.js Middleware
196
+ ```javascript
197
+ import { verifyAuth, getUsername } from "daku";
103
198
 
199
+ async function authMiddleware(req, res, next) {
200
+ const token = req.headers.authorization?.replace("Bearer ", "");
201
+
202
+ const publicKey = await verifyAuth(token);
203
+ if (!publicKey) {
204
+ return res.status(401).json({ error: "Unauthorized" });
205
+ }
206
+
207
+ req.userId = publicKey;
208
+ req.username = getUsername(publicKey);
209
+ next();
210
+ }
211
+ ```
212
+
213
+ ### React Login
104
214
  ```javascript
105
- const username = await getUsername(publicKey);
106
- // → "happy-ocean-flows-1234"
215
+ import { generateKeyPair, createAuth } from "daku";
216
+
217
+ function useAuth() {
218
+ const login = async () => {
219
+ let privateKey = localStorage.getItem("privateKey");
220
+
221
+ if (!privateKey) {
222
+ const keys = generateKeyPair();
223
+ privateKey = keys.privateKey;
224
+ localStorage.setItem("privateKey", privateKey);
225
+ }
226
+
227
+ const token = await createAuth(privateKey);
228
+ return fetch("/api/login", {
229
+ headers: { Authorization: `Bearer ${token}` }
230
+ });
231
+ };
232
+
233
+ return { login };
234
+ }
107
235
  ```
108
236
 
109
- Public keys are long hex strings. `getUsername()` converts them into memorable usernames for your UI.
237
+ ### Encrypted Chat
238
+ ```javascript
239
+ import { deriveSharedSecret, encrypt, decrypt } from "daku";
110
240
 
111
- - Returns: Human-readable username string
112
- - Deterministic: Same publicKey always → same username
113
- - Format: `adjective-noun-verb-number`
241
+ // Both users derive the same shared secret
242
+ const secret = deriveSharedSecret(myPrivateKey, theirPublicKey);
114
243
 
115
- > [!IMPORTANT]
116
- > **Never ask users to create usernames.** DAKU keeps users anonymous. Display the generated username in your UI, but always identify users by their **publicKey** in your database.
244
+ // Send encrypted message
245
+ const encrypted = await encrypt("Hello!", secret);
246
+ ws.send(encrypted);
117
247
 
118
- ---
248
+ // Receive and decrypt
249
+ ws.onmessage = async (e) => {
250
+ const message = await decrypt(e.data, secret);
251
+ console.log(message);
252
+ };
253
+ ```
119
254
 
120
- ### `createAuth(privateKey, pow?)`
255
+ ---
121
256
 
122
- **Generate authentication token**
257
+ ## API Reference
123
258
 
259
+ ### `generateKeyPair()`
260
+ Creates a new secp256k1 keypair.
124
261
  ```javascript
125
- const token = await createAuth(privateKey, 2); // pow = difficulty
262
+ const { privateKey, publicKey } = generateKeyPair();
263
+ // privateKey: 64-char hex (keep secret!)
264
+ // publicKey: 66-char hex (share freely)
126
265
  ```
127
266
 
128
- Creates a signed auth token with timestamp, nonce, signature, and proof-of-work. Send this to your server for verification.
267
+ ### `getPublicKey(privateKey)`
268
+ Derives public key from private key.
269
+ ```javascript
270
+ const publicKey = getPublicKey(privateKey);
271
+ ```
129
272
 
130
- - Returns: Base64-encoded auth token
131
- - Default POW: 2 (adjust for spam protection)
132
- - Includes: timestamp, nonce, signature, proof-of-work
273
+ ### `getUsername(publicKey)`
274
+ Generates a deterministic human-readable username.
275
+ ```javascript
276
+ const name = getUsername(publicKey); // "oceanrunning4523"
277
+ ```
133
278
 
134
- ---
279
+ ### `createAuth(privateKey, pow?)`
280
+ Creates a signed authentication token. Default POW difficulty is 2.
281
+ ```javascript
282
+ const token = await createAuth(privateKey);
283
+ const token = await createAuth(privateKey, 3); // Higher difficulty
284
+ ```
135
285
 
136
286
  ### `verifyAuth(token, pow?)`
137
-
138
- **Verify authentication token**
139
-
287
+ Verifies an auth token. Returns `publicKey` on success, `null` on failure.
140
288
  ```javascript
141
- const publicKey = await verifyAuth(token, 2);
289
+ const publicKey = await verifyAuth(token);
142
290
  if (publicKey) {
143
- // ✅ Valid! User authenticated
144
- console.log(`User ${publicKey} logged in`);
145
- } else {
146
- // ❌ Invalid or expired
291
+ // Authenticated! publicKey is the user ID
147
292
  }
148
293
  ```
149
294
 
150
- Verifies the signature, proof-of-work, and timestamp (must be < 1 minute old). Returns the user's publicKey on success.
151
-
152
- - Returns: `publicKey` string or `null`
153
- - Checks: Signature validity, POW correctness, timestamp freshness
154
- - Token lifetime: 1 minute
155
-
156
- ---
157
-
158
295
  ### `sign(message, privateKey, pow?)`
159
-
160
- **Sign any message**
161
-
296
+ Signs a message with proof-of-work.
162
297
  ```javascript
163
- const { signature, pow } = await sign("hello world", privateKey, 2);
298
+ const sig = await sign("Hello", privateKey);
299
+ // { signature: "...", pow: 123 }
164
300
  ```
165
301
 
166
- Create a cryptographic signature for any message with proof-of-work. Lower-level function used by `createAuth()`.
167
-
168
- - Returns: `{ signature: string, pow: number }`
169
- - Use case: Custom message signing beyond authentication
170
-
171
- ---
172
-
173
302
  ### `verify(message, signatureData, publicKey, pow?)`
174
-
175
- **Verify any signature**
176
-
303
+ Verifies a signature.
177
304
  ```javascript
178
- const isValid = await verify("hello world", { signature, pow }, publicKey, 2);
305
+ const isValid = await verify("Hello", sig, publicKey);
179
306
  ```
180
307
 
181
- Verify a message signature and proof-of-work. Lower-level function used by `verifyAuth()`.
182
-
183
- - Returns: `boolean`
184
- - Checks: Signature + POW validity
185
-
186
- ---
187
-
188
- ## Express.js Middleware
189
-
308
+ ### `sha256(message)`
309
+ SHA-256 hash.
190
310
  ```javascript
191
- import express from "express";
192
- import { verifyAuth, getUsername } from "daku";
193
-
194
- const app = express();
195
-
196
- // Middleware: Verify DAKU auth
197
- const daku =
198
- (powDifficulty = 2) =>
199
- async (req, res, next) => {
200
- const token = req.headers["daku"];
201
- const publicKey = await verifyAuth(token, powDifficulty);
202
-
203
- if (!publicKey) {
204
- return res.status(401).json({ error: "Unauthorized" });
205
- }
311
+ const hash = await sha256("Hello"); // Uint8Array(32)
312
+ ```
206
313
 
207
- req.userId = publicKey; // Attach user ID
208
- next();
209
- };
314
+ ### `deriveSharedSecret(myPrivateKey, theirPublicKey)`
315
+ ECDH key agreement. Both parties derive the same secret.
316
+ ```javascript
317
+ const secret = deriveSharedSecret(alice.privateKey, bob.publicKey);
318
+ // Same as: deriveSharedSecret(bob.privateKey, alice.publicKey)
319
+ ```
210
320
 
211
- // Protected route
212
- app.post("/api/profile", daku(), async (req, res) => {
213
- const username = await getUsername(req.userId);
214
- res.json({
215
- message: `Welcome, ${username}!`,
216
- userId: req.userId,
217
- });
218
- });
321
+ ### `encrypt(plaintext, key)`
322
+ AES-256-GCM encryption.
323
+ ```javascript
324
+ const ciphertext = await encrypt("Secret message", sharedSecret);
325
+ ```
219
326
 
220
- app.listen(3000);
327
+ ### `decrypt(ciphertext, key)`
328
+ AES-256-GCM decryption. Returns `null` on failure.
329
+ ```javascript
330
+ const plaintext = await decrypt(ciphertext, sharedSecret);
221
331
  ```
222
332
 
223
333
  ---
224
334
 
225
- ## Key Benefits
226
-
227
- | Traditional Auth | DAKU |
228
- | ----------------------------------- | -------------------------------------- |
229
- | Manage passwords, hashes, resets | No passwords—just verify signatures |
230
- | Store emails/phones (PII) | Zero personal data collected |
231
- | User databases = security liability | Only store public keys (not sensitive) |
232
- | Slow authentication flows | Instant cryptographic verification |
233
- | GDPR compliance overhead | No PII = simpler compliance |
234
- | Spam = manual moderation/CAPTCHAs | Built-in proof-of-work protection |
335
+ ## Comparison
235
336
 
236
- ---
337
+ | Feature | DAKU | Passport.js | Auth0 | Firebase Auth |
338
+ |---------|------|-------------|-------|---------------|
339
+ | No passwords | ✅ | ❌ | ❌ | ❌ |
340
+ | No email required | ✅ | ❌ | ❌ | ❌ |
341
+ | No database needed | ✅ | ❌ | ❌ | ❌ |
342
+ | E2E encryption | ✅ | ❌ | ❌ | ❌ |
343
+ | Self-hosted | ✅ | ✅ | ❌ | ❌ |
344
+ | Zero dependencies* | ✅ | ❌ | ❌ | ❌ |
345
+ | Works offline | ✅ | ❌ | ❌ | ❌ |
346
+ | Bundle size | ~50KB | ~200KB | SDK required | SDK required |
237
347
 
238
- ## Features
239
-
240
- - **🕵️ Anonymous**: No email, no phone, no personal data
241
- - **🔐 Secure**: secp256k1 signatures (Bitcoin/Ethereum-grade)
242
- - **🛡️ Spam-proof**: Configurable proof-of-work difficulty
243
- - **⚡ Lightweight**: Minimal dependencies, works everywhere
244
- - **🌐 Universal**: Node.js + Browser compatible
245
- - **⏱️ Short-lived tokens**: 1-minute expiration (anti-replay)
246
- - **🌍 Cross-project identity**: Reuse one keypair across apps
348
+ *Only 2 peer dependencies: `@noble/secp256k1` and `@noble/hashes`
247
349
 
248
350
  ---
249
351
 
250
- ## Global Identity
251
-
252
- Users can reuse **one private key** across multiple services. Same privateKey → same publicKey → same identity everywhere.
352
+ ## Installation
253
353
 
254
- ```javascript
255
- // User's keypair works on yourapp.com AND anotherapp.com
256
- const publicKey = getPublicKey(samePrivateKey);
257
- // → Same publicKey = consistent cross-platform identity
354
+ ```bash
355
+ npm install daku
258
356
  ```
259
357
 
260
- > [!WARNING]
261
- > Reusing keypairs links user identity across services. This enables seamless cross-app experiences but reduces anonymity between services. For per-app isolation, derive or generate separate keys.
358
+ **Requirements:** Node.js 16+ or modern browser
262
359
 
263
360
  ---
264
361
 
265
- ## Security Notes
362
+ ## License
266
363
 
267
- - **Private keys**: Users must store them securely (localStorage, hardware wallets). Lost keys = lost access.
268
- - **Token lifetime**: Hardcoded to 1 minute; prevent replay attacks.
269
- - **POW difficulty**: Default = 2 leading zeros. Increase for high-traffic endpoints (trade-off: slower auth).
270
- - **No server secrets**: DAKU has no shared secrets—everything is public-key cryptography.
364
+ ISC © [besoeasy](https://github.com/besoeasy)
271
365
 
272
366
  ---
273
367
 
274
- **DAKU: The authentication system that doesn't know anything about your users. By design.**
368
+ <p align="center">
369
+ <b>Leave no trace. Just authenticate.</b>
370
+ </p>