An academic research project exploring targeted modifications to the RC4 stream cipher — improving its statistical properties through Double KSA, Drop-N, and a Modified PRGA with a third state variable.
RC4 (Rivest Cipher 4) is a classic symmetric stream cipher widely used in SSL/TLS, WEP, and WPA. Despite its simplicity and speed, several statistical weaknesses have been documented over the years — most notably the initial-byte bias exploited in the FMS attack that broke WEP.
This project applies three targeted modifications to RC4 and measures their effect using rigorous statistical analysis:
| Modification | Addresses |
|---|---|
| Double KSA | Weak state diffusion between similar keys |
| Drop-N (512 bytes) | Statistical bias in initial keystream bytes |
| Modified PRGA | Predictability in the output function |
| SHA-256 IV Derivation | Key-reuse vulnerability |
⚠️ Academic use only. This implementation is for research and learning. For production systems, use ChaCha20-Poly1305 or AES-256-GCM.
enhanced-rc4/
│
├── rc4_modified_en.py # Main implementation + statistical analysis
├── README.md # This file
The standard KSA makes a single pass over the 256-byte state array S. The enhanced version adds a second independent pass with a different index pattern:
# Pass 1 — standard KSA
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
# Pass 2 — secondary shuffle (different pattern)
j = 0
for i in range(256):
j = (j + S[i] + key[(i * 3 + 7) % len(key)] + i) % 256
S[i], S[j] = S[j], S[i]The + i term ensures the second pass produces a structurally different shuffle, increasing avalanche: a single-bit key change now alters significantly more positions in S.
The first ~256 bytes of RC4's keystream carry a statistical bias inherited from KSA — this is the root cause of the FMS/WEP attack. The fix: generate and discard the first 512 bytes before encrypting real data.
# Discard first 512 bytes — never used for encryption
for _ in range(512):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = (k + S[(i + j) % 256]) % 256N = 512 is chosen to cover the biased region with a safety margin, with negligible performance cost.
The standard PRGA uses two indices (i, j). The modified version introduces a third variable k that evolves based on cross-term coupling:
i = (i + 1) % 256
j = (j + S[i]) % 256
k = (k + S[(i + j) % 256]) % 256 # new
S[i], S[j] = S[j], S[i]
output_byte = S[(S[i] + S[j] + S[k]) % 256] # uses all threeThis non-linear feedback makes it harder to reconstruct the internal state from observed keystream bytes.
Rather than naïvely concatenating an IV with the key (WEP's fatal mistake), a fresh session key is derived per message using SHA-256:
iv = os.urandom(16) # 16 random bytes, unique per message
session_key = hashlib.sha256(key + iv).digest() # 256-bit derived keyThe IV is prepended to the ciphertext in plaintext — it requires no secrecy, only uniqueness.
Requirements: Python 3.8+ — no external dependencies.
# Clone the repo
git clone https://github.com/your-username/enhanced-rc4.git
cd enhanced-rc4
# Run the full statistical comparison
python rc4_modified_en.pyBasic usage in your own code:
from rc4_modified_en import rc4_modified, rc4_modified_decrypt
key = b"your-secret-key"
plaintext = b"Hello, World!"
# Encrypt
ciphertext = rc4_modified(key, plaintext) # returns IV + ciphertext
# Decrypt
recovered = rc4_modified_decrypt(key, ciphertext)
assert recovered == plaintext # always TrueMeasured on 50,000 bytes of random plaintext (Python 3.12):
| Metric | Original RC4 | Enhanced RC4 | Ideal | Notes |
|---|---|---|---|---|
| Shannon Entropy | 7.9963 bits | 7.9967 bits | 8.0 bits | Higher = better |
| Chi-Square χ² | 246.99 | 227.47 | 255.0 | Closer to 255 = better |
| Autocorrelation | −0.000074 | 0.003506 | 0.0 | Closer to 0 = better |
| Initial-byte bias | 2.2355 | 2.1417 | 0.0 | Lower = better |
| Encryption time | 10.29 ms | 12.63 ms | — | +22.7% overhead |
Key finding: The Drop-N modification reduces initial-byte bias by ~4–7%, directly addressing the statistical pattern exploited by the FMS attack on WEP.
The script includes a built-in sanity check and full statistical suite:
============================================================
Enhanced RC4 -- Statistical Comparison
Modifications: Double KSA + Drop-512 + Modified PRGA
============================================================
Initial test: PASSED
[1/4] Computing Shannon entropy ...
[2/4] Running chi-square test ...
[3/4] Computing autocorrelation ...
[4/4] Analysing initial-byte bias ...
Decryption verification: PASSED
Statistical Comparison Results
[Entropy] higher is better | max = 8.0 bits/byte
Original RC4 : 7.996337
Enhanced RC4 : 7.996233
[Initial-Byte Bias] lower is better
Original RC4 : 2.2355
Enhanced RC4 : 2.1417
Improvement : 4.20%
- Fluhrer, S., Mantin, I., & Shamir, A. (2001). Weaknesses in the Key Scheduling Algorithm of RC4. SAC 2001, LNCS 2259.
- Mantin, I., & Shamir, A. (2001). A Practical Attack on Broadcast RC4. FSE 2001.
- AlFardan, N., et al. (2013). On the Security of RC4 in TLS. USENIX Security.
- Klein, A. (2008). Attacks on the RC4 Stream Cipher. Designs, Codes and Cryptography, 48(3).
- Katz, J., & Lindell, Y. (2020). Introduction to Modern Cryptography, 3rd ed. CRC Press.
- RFC 8439 — ChaCha20 and Poly1305 for IETF Protocols. IETF, 2018.
This project is released for academic and educational purposes only.
Part of an academic research project in Information Security & Cryptography.