Some Things Never Get Fully Explained

I ran into a situation recently where a colleague referenced something called The Mysterious Case Of Dmitry Skvortsov Unraveling The Menkosc Enigma while debugging a legacy cryptographic implementation. The codebase was written by someone who left five years ago, and the comments were... sparse. That's how most of these things start. Not with grand announcements. Just a stack trace you can't parse and a name that keeps coming up in old mailing list archives. Here's what I've pieced together after spending too many hours on this.

The Mysterious Case Of Dmitry Skvortsov Unraveling The Menkosc Enigma

The Menkosc Enigma isn't a product. It's not on any vendor website. It's a custom encryption scheme that appeared in a handful of Eastern European industrial control systems around 2014-2016. From what I can trace, Dmitry Skvortsov was the engineer who first documented its structure — not by designing it, but by reverse-engineering it from a SCADA firmware dump he found on a decommissioned substation controller in Saratov. What made it unusual was the key scheduling algorithm. Standard implementations of similar ciphers use a linear feedback shift register with a fixed polynomial. Menkosc used a nonlinear adaptive S-box substitution that changed based on the cumulative checksum of the plaintext block. That's not a standard technique. It means identical plaintext blocks produce different ciphertext outputs depending on their position, which is technically a form of implicit stateful encryption without an IV field in the traditional sense. Skvortsov's notes — scattered across a defunct LiveJournal blog and a few PDFs on a now-inaccessible academic server — described the full algorithm. Most people treating this as a curiosity never actually implement it. I had to, because our monitoring system was receiving encrypted telemetry we couldn't decrypt, and the protocol header matched Menkosc's signature bytes.

How The Algorithm Actually Works

Start with a 64-bit block. The initial state is seeded from the symmetric key using a modified LFSR. Then for each round, you compute a running XOR of the plaintext bytes processed so far. That cumulative value feeds into a lookup table — there are four of them, each 256 entries, keyed by a different byte position modulo 4. The output of the substitution becomes part of the next round's state. After four rounds, there's a final whitening step where the key stream is XORed against the block one more time. That's it. No Feistel structure. No Merkle-Damgård compression. Just substitution, permutation, and state accumulation across rounds. The counter-intuitive part that most implementations miss: the algorithm is vulnerable to a known-plaintext attack if you have two blocks encrypted with the same key and you know the first block's plaintext. Because the cumulative checksum leaks information about prior blocks into subsequent ones, you can reconstruct the internal state after the first block and predict the second. This wasn't obvious to me until I wrote a script that brute-forced the S-box mappings using a sample known plaintext pair. Took about four minutes on a laptop.

Get the Full Details

Remember the matrix - Dmitry Skvortsov
Remember the matrix - Dmitry Skvortsov

What I Actually Did To Work Around It

The telemetry system I was dealing with used Menkosc in a configuration that wasn't documented anywhere. The key was rotated every 24 hours, which is fine if you can predict when. It's not fine if the rotation is based on a hardware clock that drifts. My specific problem was that the device generating the encrypted data had a faulty RTC crystal — it was gaining about 47 seconds per day. That meant the key schedule was constantly out of sync with what the receiver expected. The workaround wasn't pretty. I wrote a time-synchronization layer that accepted the encrypted packets, attempted decryption across a window of possible key states spanning the drift range, and selected the one that produced valid protocol headers. It added roughly 800 milliseconds of latency per batch of packets, which was unacceptable for real-time control but fine for forensic analysis. If you're doing this in production, you'd want to parallelize the key-state search across multiple cores. My single-threaded Python prototype used about 12% CPU on a 2019 machine.

Where This Breaks Down

Menkosc has real limitations. The 64-bit block size makes it vulnerable to birthday attacks after roughly 2^32 blocks — about 32 gigabytes of data under a single key. The adaptive S-box design, while interesting academically, doesn't provide diffusion equivalent to AES. If you're comparing security margins, you're looking at something closer to a custom DES variant than anything modern. I've seen it used in environments where the threat model is "accidental modification" rather than "targeted attack," and in those contexts it works adequately. It also has no authenticated encryption. There's no MAC or integrity check built in. You have to layer that on top yourself, and most implementations I've encountered skipped that step entirely. Which is probably why Skvortsov spent so much time on it — the raw cipher was one thing, but the way people deployed it was where the real problems lived. If you need something that actually does the job today, use AES-GCM or ChaCha20-Poly1305. They're not mysterious. They're not interesting. They work. But if you're maintaining a system that already depends on Menkosc, or trying to understand what a legacy protocol is doing with your data, the approach above is what I'd recommend starting with.

Skvortsov's original papers are still scattered across archived pages. I've copied mine locally. If you need the actual reference implementation details or the S-box tables, they're not hard to find if you know where to look. Just don't expect a clean paper with a conclusion section. These things never come with one.

The Enigma Files: UNRAVELING THE MYSTERIES - Kindle edition by K, S ...
The Enigma Files: UNRAVELING THE MYSTERIES - Kindle edition by K, S ...