QuarkDash - pure typescript it is a hybrid cryptographic protocol that provides post-quantum security, high performance, and attack resistance.
Have a questions? Contact me
Paper | About | Get Started | Example | Benchmark | Docs | Scheme
QuarkDash Crypto - It is a hybrid cryptographic protocol that provides post-quantum security, high performance, and attack resistance. This library can be used as shared solution for client and server. Written on pure typescript. Dependency-free.
Algorithm Scheme can be found here
🔹 Lightweight library with zero dependencies;
🔹 Powerful crypto algorithm written in Typescript;
🔹 Extremely fast (great for realtime and IoT applications);
🔹 Production ready with benchmarks;
- Asymmetric key exchange: Ring-LWE (N=256, Q=7681) / R-Ring-LWE (Q=12289) based on hardened NTT;
- Symmetric encryption: ChaCha20 (RFC 7539) or lightweight Gimli with lazy keystream generation;
- Key Derivation Function (KDF): SHAKE256 + HKDF-style re-key derivation;
- Message Authentication Code (MAC): SHAKE256 with key;
- Replay protection: timestamp + sequence number + sliding window;
- Passphrase KDF: PBKDF2-HMAC-SHA256 / Argon2id-lite;
- Transports: WebSocket / HTTP / gRPC integrations.
- Quantum stability: not broken by Shor and Grover's algorithms;
- Performance: encryption up to 2.8 GB/s, session establishment ~10 ms;
- Forward secrecy: compromising a long-term key does not reveal past sessions;
- Lazy keystream: seekable, cached, zero-copy XOR via
ChaChaKeystream/GimliKeystream; - Re-keying (Key rotation):
rekey()/applyRekey()with policy by bytes / messages / time limit; - Passphrase: Human-readable
pbkdf2/argon2idlite keys andgenerateSalt(); - Hardened Secured NTT: blinding, double-check, constant-time, polynome validation;
- Transports: native simple wrappers for
WebSocket/gRPC/HTTPtransport; - Flexibility – ChaCha20/Gimli, sync and async API, per-message nonce.
You can use the QuarkDash library as a regular library for both Backend and Frontend applications without any additional dependencies.
Installation using NPM:
npm install quarkdashOr using GitHub:
git clone https://github.com/devsdaddy/quarkdash
cd ./quarkdash/* Import modules */
import { CipherType, QuarkDash, QuarkDashUtils } from "../src";
/* Alice - client, bob - server, for example for key-exchange */
const alice = new QuarkDash({ cipher: CipherType.Gimli });
const bob = new QuarkDash({ cipher: CipherType.Gimli });
/* Generate key pair */
const alicePub = await alice.generateKeyPair();
const bobPub = await bob.generateKeyPair();
/* Initialize session at bob and jpin alice public key */
const ciphertext = (await alice.initializeSession(bobPub, true)) as Uint8Array;
await bob.initializeSession(alicePub, false);
await bob.finalizeSession(ciphertext);
/* Encrypt by alice and decrypt by bob */
const plain = QuarkDashUtils.textToBytes("Hello QuarkDash 🔒!");
const enc = await alice.encrypt(plain);
const dec = await bob.decrypt(enc);
console.log("Decrypted:", QuarkDashUtils.bytesToText(dec));import { QuarkDashChaCha, QuarkDashGimli } from "quarkdash";
const key = QuarkDashUtils.randomBytes(32);
const nonce = QuarkDashUtils.randomBytes(12);
// For example, using ChaCha20: seekable, cached, lazy
const chacha = new QuarkDashChaCha(key, nonce);
const ks = chacha.createKeystream(); // ChaChaKeystream extends LazyKeystream
const chunk = ks.getBytes(1024, 512); // custom offset without generation from scratch
const out = ks.xor(plain, 1024); // XOR with offset
ks.seek(0);
const stream = ks.blocks(0); // 64B block generator
const block0 = stream.next().value;
// Gimli is similar with 48B block
const gimli = new QuarkDashGimli(key, nonce);
const gks = gimli.createKeystream();
const enc = gks.xor(plain, 0);
// Integrate with QuarkDash with per-message nonce = metadata (12B), keystream is not resuable
const qd = new QuarkDash({
cipher: CipherType.ChaCha20,
usePerMessageNonce: true,
});const alice = new QuarkDash({
cipher: CipherType.ChaCha20,
rekey: {
policy: { afterBytes: 64 * 1024 * 1024, afterMessages: 10_000 },
autoRekey: false,
},
});
const bob = new QuarkDash({ cipher: CipherType.ChaCha20 });
// ... handshake ...
// Can be used by request
const token = await alice.rekey(); // generates salt, with local rotation and returns encrypted message
await bob.applyRekey(token); // peer applys same salt
// sync-mode variant
const tokenSync = alice.rekeySync();
bob.applyRekeySync(tokenSync);
// Local rotation without exchange (deterministic, for tests)
alice.rotateKeysLocal(salt); // or async variant with await alice.rotateKeysLocalAsync()
// Policy and stats
if (alice.needsRekey()) await alice.rekey();
console.log(alice.getRekeyStats()); // { counter, bytesEncrypted, messagesEncrypted, lastRekeyTime }
alice.setRekeyPolicy({ afterMessages: 5000 });
console.log(alice.getRekeyCounter());import { QuarkDashPassphrase, QuarkDashUtils } from "quarkdash";
// PBKDF2-HMAC-SHA256: RFC 6070 compatible (SHA256)
const salt = QuarkDashPassphrase.generateSalt(32);
const key1 = QuarkDashPassphrase.pbkdf2Sync("password", salt, 100_000, 32);
const key1a = await QuarkDashPassphrase.pbkdf2("password", salt, 100_000, 32); // uses Node crypto if available
// Argon2id-lite (memory-hard, using SHAKE256)
const key2 = QuarkDashPassphrase.argon2idSync("password", salt, 32, 3, 32); // memoryCost KB, timeCost
const { key, salt: newSalt } = await QuarkDashPassphrase.derive("my secret", {
algorithm: "argon2id",
memoryCost: 64,
});
// For QuarkDash: 64B for session+mac
const { sessionKey, macKey } = await QuarkDashPassphrase.deriveKeyForQuarkDash(
"password",
salt,
{ algorithm: "pbkdf2", iterations: 200_000 },
);import { BaseRingLWE } from "quarkdash";
const lwe = new BaseRingLWE();
lwe.setNTTProtection({
enabled: true, // enable / disable all security methods
blinding: true, // random blinding factor (a* r, b* r^{-1})
doubleCheck: true, // compute again and compare
validateInputs: true, // validate polynome length / range
});
console.log(lwe.getNTTProtection());
// Automatically apply in generateKeyPair / encapsulate / decapsulate,
// serialization is normalize coefficient ((v%Q)+Q)%Q, deserialization skip >=Qimport { QuarkDashWebSocket, QuarkDashHTTP, QuarkDashGRPC } from "quarkdash";
// WebSocket: wrapper works with any WSLike (ws / browser WebSocket)
const qdWsAlice = QuarkDashWebSocket.wrap(aliceQD, rawWs);
await qdWsAlice.send("hello ws");
await qdWsAlice.sendJSON({ type: "msg", data: 123 });
qdWsAlice.onDecrypted((plain: Uint8Array) =>
console.log(QuarkDashUtils.bytesToText(plain)),
);
// HTTP: body encryption + header x-qd-encrypted
const httpAlice = new QuarkDashHTTP(aliceQD);
const httpBob = new QuarkDashHTTP(bobQD);
const { body, headers } = await httpAlice.encryptBody({ hello: "world" });
const obj = await httpBob.decryptToJSON(body);
// as Express middleware
app.use(new QuarkDashHTTP(qd).expressMiddleware());
// as fetch wrapper
const secureFetch = new QuarkDashHTTP(qd).createFetchWrapper(fetch);
await secureFetch("https://api.example.com/data", {
method: "POST",
body: JSON.stringify(payload),
});
// gRPC: interceptor / wrapper
const grpcAlice = new QuarkDashGRPC(aliceQD);
const grpcBob = new QuarkDashGRPC(bobQD);
const enc = await grpcAlice.encryptMessage(payload);
const dec = await grpcBob.decryptMessage(enc);
const wrappedClient = grpcAlice.wrapClient(originalGrpcClient);
const serverHandler = grpcBob.serverInterceptor();| Command | Usage |
|---|---|
| npm run clean | Clean build |
| npm run build | Main build exec |
| npm run build:esm | Build esm module |
| npm run build:cjs | Build commonjs module |
| npm run build:types | Build types only |
| npm run test | Run basic tests |
| npm run bench | Run basic benchmakr |
Read more about QuarkDash library in official wiki
Below I've outlined a brief step-by-step flowchart of how the algorithm works. If you need more detailed information, please visit the Wiki.
Step-by-Step Algorithm:
- Key Pair Generation (using Ring‑LWE);
- Session Setup (using SHAKE-256 emulated KEM);
- Session Key Flow (KDF);
- Message Encryption (AEAD);
- Decryption;
Below is a brief comparison table of popular encryption algorithm variations. As we know, each algorithm serves its own purpose, so this comparison is more of a synthetic test.
| Characteristic | QuarkDash (ChaCha20) | QuarkDash (Gimli) | AES-256-GSM | ECDH/P-256 + AES | RSA-2048 + AES |
|---|---|---|---|---|---|
| Type | Hybrid | Hybrid | Symmetric | Asymmetric (KEX) | Hybrid |
| Quantum stability | ✅ Ring-LWE | ✅ Ring-LWE | ❌ No | ❌ No | ❌ No |
| Encryption speed (1mb) | ~2.5 GB/s | ~2.8 GB/s | ~1.2 GB/s | ~50 MB/s (ECIES) | ~10 MB/s |
| Decryption speed (1mb) | ~2.5 GB/s | ~2.8 GB/s | ~1.2 GB/s | ~50 MB/s | ~1 MB/s |
| Session speed | ~10-15 ms | ~10-15 ms | 0 ms (pre-shared) | ~5 ms | ~50 ms |
| Key size | ~2 KB | ~2 KB | N/A | 33 bytes | 256 bytes |
| Forward secrecy | ✅ | ✅ | ❌ | ❌ | |
| Out-of-box security | ✅ | ✅ | ❌ | ||
| The Difficulty of Quantum Hacking | 2^256 | 2^256 | 2^128 (Grover) | 0 (Shor) | 0 (Shor) |
Full comparison can be found in wiki
Below I have described performance tests in comparison with other popular encryption algorithm combinations.
Please, note. This benchmark is launched at Intel i5-12700H, 16GB RAM, Node.js 24
| Operation | QuarkDash (ChaCha20) | QuarkDash (Gimli) | AES-256-GSM | ECDH (P-256) + AES | RSA-2048 |
|---|---|---|---|---|---|
| Key generation | 0.7ms | 0.9ms | N/A | 1.2ms | 48ms |
| Session (KEM) | 2.9ms | 2.9ms | N/A | 3.4ms | 42ms |
| Encryption (1KB) | 0.003ms | 0.0028ms | 0.005ms | 0.05ms | 0.8ms |
| Decryption (1KB) | 0.003ms | 0.0028ms | 0.005ms | 0.05ms | 0.1ms |
| Encryption (1MB) | 0.42ms | 0.38ms | 0.85ms | 21ms | 102ms |
| Decryption (1MB) | 0.42ms | 0.38ms | 0.85ms | 21ms | 1080ms |
| Encryption (per-message nonce) (1KB) | 0.5ms | 1ms | - | - | - |
| Encryption (per-message nonce) (64KB) | 5.5ms | 5.32ms | - | - | - |
| Encryption (per-message nonce) (1MB) | 81ms | 67.5ms | - | - | - |
| Decryption (per-message nonce) (1KB) | 0.29ms | 0.46ms | - | - | - |
| Decryption (per-message nonce) (64KB) | 5.95ms | 4.16ms | - | - | - |
| Decryption (per-message nonce) (1MB) | 80ms | 64.1ms | - | - | - |
You can run benchmark on your machine using npm run bench
Full documentation with algorithm description, examples and theory can be found at official wiki pages
Have a questions? Contact me
QuarkDash Crypto library is distributed under the MIT license. You can use it however you like. I would appreciate any feedback and suggestions for improvement. Full license text can be found here
About | Get Started | Example | Benchmark | Docs
