Pure Python AES-256-CTR file encryption — no dependencies, no compromises.
A minimal, transparent AES-256 implementation that passes all 17 NIST SP 800-22 statistical randomness tests. Written entirely in Python with zero external dependencies — no compiled extensions, no OpenSSL bindings, no DLLs.
Many encryption tools advertise "AES-256" but make implementation compromises that weaken the output quality. AES-256-Pure uses the textbook AES-256 algorithm in CTR mode with no shortcuts:
- S-Box generated from GF(2^8) multiplicative inverse + affine transform
- 14 rounds of SubBytes, ShiftRows, MixColumns, AddRoundKey
- CTR mode — no padding, output = input size
- PBKDF2-HMAC-SHA256 key derivation with 600,000 iterations
- Random salt and nonce per encryption (16 bytes each from
os.urandom)
Tested with 10 MB of all-zero bytes — the strictest possible input:
[PASS] 01 Monobit Frequency p = 0.367832
[PASS] 02 Block Frequency p = 0.865593
[PASS] 03 Runs Test p = 0.955665
[PASS] 04 Longest Run of Ones p = 0.563015
[PASS] 05 Cumulative Sums (fwd) p = 0.438856
[PASS] 06 Cumulative Sums (bwd) p = 0.364426
[PASS] 07 Approximate Entropy p = 0.020961
[PASS] 08 Serial Test (1) p = 0.837442
[PASS] 08 Serial Test (2) p = 0.835648
[PASS] 09 Maurer Universal p = 0.395534
[PASS] 10 DFT/Spectral p = 0.029317
[PASS] 11 Binary Matrix Rank p = 0.782477
[PASS] 12 Non-Overlapping Tmpl p = 0.826376
[PASS] 13 Linear Complexity p = 0.385012
[PASS] 14 Chi-Squared Byte p = 0.879788
[PASS] 16 Serial Correlation r = -0.000791
[PASS] 17 Shannon Entropy 7.999984 bits/byte
=== SUMMARY: 17/17 tests passed ===
python src/aes256_gui.py
Requires only Python 3.6+ with tkinter (included in standard Python installs).
from src.aes256_core import encrypt_file, decrypt_file
# Encrypt
encrypt_file("document.pdf", "document.pdf.aes", "my-password")
# Decrypt
decrypt_file("document.pdf.aes", "document.pdf", "my-password")Offset Size Content
0 16 Salt (random, unique per encryption)
16 16 Nonce / initial counter (random)
32 N Ciphertext (XOR of plaintext with AES-256-CTR keystream)
- Output file is exactly 32 bytes larger than input
- No metadata, no file names, no timestamps stored
- Salt and nonce are not secret — they ensure each encryption produces unique ciphertext
| Property | Value |
|---|---|
| Algorithm | AES-256 (FIPS 197) |
| Mode | CTR (NIST SP 800-38A) |
| Key length | 256 bits |
| Key derivation | PBKDF2-HMAC-SHA256 |
| KDF iterations | 600,000 |
| Salt | 16 bytes (random per file) |
| Nonce | 16 bytes (random per file) |
| NIST SP 800-22 | 17/17 PASS |
This is a pure Python implementation — it prioritizes transparency and auditability over speed. Typical throughput is ~50-100 KB/s. For large files (>10 MB), consider using the command line version which shows progress.
This is an educational and reference implementation. Pure Python table lookups are not constant-time — they are vulnerable to timing side-channel attacks that can leak key material. For production encryption of sensitive data, use a hardened library like cryptography (OpenSSL-backed) or pycryptodome.
AES-256-Pure is ideal for:
- Learning how AES works internally
- Comparing cipher output quality (NIST tests) against other implementations
- Environments where no compiled extensions are available
| Project | Description |
|---|---|
| Turbine V5.2 | Self-developed stream cipher — 17/17 NIST tests, custom S-Box (0x11D) |
| py-nist-sp800-22 | NIST SP 800-22 statistical test suite used to validate both ciphers |
| encryption-tools | S-Box generator, bias analysis, and cryptographic testing tools |
MIT