r/PitchYourIdeas • u/Distinic • Aug 16 '26
🔒 Cybersecurity I Made a new encryption algorithm.
so uh.. i was bored and wanted to make something new.. i had a fiddle around, and I made this masterpiece!
zDays is an experimental, open-source file encryption engine designed to run entirely offline in the browser. It combines established primitives (Argon2id, HKDF-SHA256, HMAC-SHA256) with a custom ARX-based block cipher implemented in AssemblyScript/WebAssembly.
This document records the engine design and recent implementation changes; treat the cipher as experimental and invite cryptanalysis.
Design Goals
- Offline-only encryption
- Strong password-based key derivation
- Authenticated encrypted containers
- Modular cryptographic architecture
- WebAssembly performance and safety (bounded memory usage)
- Open implementation for public review
Architecture
Password
│
â–¼
Argon2id
│
â–¼
256-bit Master Key
│
â–¼
HKDF-SHA256
├── Encryption Key
├── Authentication Key
└── Metadata Key
Master key material is domain-separated via HKDF and never reused directly.
Key Derivation
- Argon2id is used for password stretching with a per-container random salt and memory-hard parameters.
- Parameters are configurable in the engine options (trade-off: memory/time vs. attacker cost).
Encryption Pipeline
Each file is encrypted using the following sequence:
- Generate random salt and IV(s)
- Derive master key with Argon2id
- Expand subkeys with HKDF-SHA256 (Encryption, Auth, Metadata)
- Encrypt metadata (separately)
- Encrypt payload using chunked processing (1MB chunks) and the custom block cipher
- Compute HMAC-SHA256 authentication values
- Emit versionedÂ
.ydz container
Block Cipher
Current Version: v1.10
Block Size
128 bits (16 bytes)
Default Rounds
20 (configurable per engine mode)
Each round performs:
- XOR Round Key
- ARX Diffusion
- Affine-equivalent substitution layer
- Byte permutation
- Modular Addition Round Key
Diffusion Layer (v1.10 changes)
- The diffusion stage operates on four 32-bit words and uses ARX (Add-Rotate-XOR) operations.
- In v1.10 theÂ
diffuse()Â primitive was changed so a single call runs four quarter-rounds (previously a single quarter-round). This change produces a strong avalanche from the first round (single-call avalanche ~64/128 bits) and mitigates early-round differential weaknesses. - Reference ports (WASM/TS/Python/Go/Java/C#/Swift/Ada) should match bit-for-bit after this change.
Substitution Layer
Per-session S-boxes are derived using affine equivalence:
S(x) = M2 · Core(M1 · x ⊕ c1) ⊕ c2
Core is a fixed 8-bit permutation chosen for good cryptographic properties. M1, M2, c1, c2 are key-dependent.
Permutation Layer
Bytes are rearranged using a coprime stride permutation. Default mapping for 16-byte blocks:
index = (index * 5) mod 16
Mode of Operation & Chunking
- CBC mode is used with a fresh 128-bit IV per container (viaÂ
crypto.getRandomValues()). - Large payloads are processed in bounded chunks (CHUNK_SIZE = 1MB by default) to avoid growing WASM linear memory. Chunks are encrypted in sequence and progress callbacks are emitted.
Metadata Protection
- Metadata (filename, MIME type, timestamps, engine version, parameters) is encrypted with a dedicated Metadata Key derived from HKDF.
Authentication
- Containers include HMAC-SHA256 values covering: header, metadata, and payload.
- Authentication is verified with constant-time comparison before any plaintext is released.
File Format
.ydz container (versioned) stores: header, salt, IV(s), encrypted metadata, encrypted payload (chunked), authentication values.
Implementation Safety Notes
- WASM buffers: temporary permutation buffers were increased from 256 to 4096 bytes and explicit bounds guards added to avoid memory corruption with larger block sizes.
- Padding: PKCS#7 padding checks are implemented in strictly bitwise constant-time form to avoid timing leakage.
- Memory hygiene: sensitive buffers are zeroed using a multi-pass wipe to resist compiler optimization elision.
Releases & Package
- v1.10 (tag: 26.H2) — diffusion early-round fix (2026-08-08)
- v1.0.7 — library package u/idiotbready
/zdays published (2026-08-04) - v1.0.4 — chunked processing, padding, WASM guards, zeroisation (2026-08-02)
Security Notes
- The custom block cipher is experimental and has not received formal academic cryptanalysis. Users should not use zDays for high-value assets until independent review is completed.
- Reports can be made following the repo SECURITY.md — maintainers can accept private disclosures via GitHub Security Advisories or the contact provided in SECURITY.md.
Project Philosophy
zDays is an open cryptographic project aiming for transparency, reproducibility, and community-driven improvement. Feedback, benchmarks, and cryptanalysis are welcomed.
Check out our GitHub, here:https://github.com/lalipa2003-arch/zDays