A custom stream cipher engine and file security toolkit written in Free Pascal / Lazarus.
Hazar is a self-contained encryption suite built around an original key-scheduling algorithm. It provides file encryption, file decryption with password verification, an in-memory stream cipher interface, and cryptographic secure file deletion — all in pure Pascal with no external dependencies.
| Unit | Purpose |
|---|---|
hazar.pas |
Core algorithm — key scheduling and keystream generation |
hazarcipher.pas |
In-memory stream cipher wrapper (THazarCipher) |
hazario.pas |
File encryption and decryption |
hazardel.pas |
Secure file deletion |
hazardemo.pas |
Command-line tool (uses all of the above) |
THazarEncryption is an original key-scheduling algorithm inspired by the design philosophy of RC4 but with a distinct construction.
Initialisation
- An S-Box is seeded with
I xor KeyLengthfor each indexI. GenerateBoxis applied to the S-Box, mixing it using the key via bitwise rotation, full-array addition, XOR chaining, and index-driven swaps.- The scrambled S-Box is copied to an M-Box, then
GenerateBoxis applied again — producing two independently derived permutation tables.
Keystream generation (GenerateKey)
Each call produces a fresh 256-byte keystream block using a cross-lookup between the S-Box, M-Box, and the current key state:
FTKey[ MBox[(I+1) mod N] ] := SBox[ MBox[ Key[I] xor Key[(I+1) mod N] ] ]
The key is then updated to the new table, advancing the cipher state. This means every call produces a different block — the cipher never repeats unless re-initialised with the same seed.
Compile-time width selection
| Define | Integer type | Block size | Address space |
|---|---|---|---|
{$define hazar8} |
Byte |
256 bytes | 8-bit (default) |
{$define hazar16} |
Word |
65536 words | 16-bit |
Switch modes by changing the define at the top of hazar.pas.
┌──────────────────────────────────────────────────────┐
│ 256 bytes — Password verification block │
│ (keystream block #1 stored verbatim; │
│ XOR with same keystream → all zeros │
│ confirms correct password) │
├──────────────────────────────────────────────────────┤
│ 8 bytes — Original file size (Int64, LE) │
│ XOR'd with first 8 bytes of block #2 │
├──────────────────────────────────────────────────────┤
│ N×256 bytes — Encrypted payload │
│ Each block XOR'd with block #3, #4, … │
│ Last block zero-padded to 256 bytes; │
│ truncated to original size on decrypt │
└──────────────────────────────────────────────────────┘
hazardemo e <input_file> <output_file> <password>
hazardemo d <input_file> <output_file> <password>
Returns an error immediately if the password is wrong — the output file is never created in that case.
hazardemo s <file> # 1 wipe round (default)
hazardemo s <file> <rounds> # N wipe rounds
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Bad arguments |
| 2 | Encryption failed (path / permissions) |
| 3 | Decryption failed (wrong password or corrupt file) |
| 4 | Secure deletion failed (file in use or access denied) |
SecureDelete overwrites every byte of the file before deleting it.
Each wipe round consists of two passes:
- Pass 1 — the file is overwritten with keystream bytes generated by
THazarEncryption, seeded from the current wall-clock time in whole seconds. - Pass 2 — the exact same keystream is reproduced and every byte is bitwise-inverted (
NOT) before writing, guaranteeing that each bit has been driven both HIGH and LOW within the round.
After all rounds the file is truncated to zero, renamed to a random hex filename (to obscure the original name in directory metadata), and then deleted.
For encrypting data buffers directly rather than files:
uses hazar, hazarcipher;
var
Cipher : THazarCipher;
Key : THazarData;
KLen : THazarInteger;
Data : array of Byte;
begin
// populate Key, KLen, Data ...
Cipher := THazarCipher.Create(Key, KLen);
try
Cipher.Encrypt(Data, Length(Data)); // in-place, any length
finally
Cipher.Free;
end;
// Decrypt: create a fresh instance with the same key and call Decrypt.
// XOR is its own inverse — Encrypt and Decrypt are identical internally.
end;Important: each
THazarCipherinstance must be used for one message only. Re-using the same key and instance state for two different messages is a two-time-pad vulnerability. Always create a fresh instance per message, or incorporate a unique nonce into the key.
Open the project in Lazarus or compile directly with FPC:
fpc hazardemo.pas
No external libraries or packages are required. All units are self-contained.
Tested with: Free Pascal Compiler (FPC) 3.x / Lazarus 3.x
hazar.pas — Core algorithm
hazarcipher.pas — Stream cipher wrapper
hazario.pas — File encrypt / decrypt
hazardel.pas — Secure file deletion
hazardemo.pas — Command-line entry point
This project is released as open source. See LICENSE for details.