Following on from the attack on known plaintext for a T52ab Sturgeon cipher machine, this post describes an attack with unknown plaintext. The known plaintext attack relied on a brute-force application of all possible XOR wheel settings to the plaintext. This created a representation of the state halfway through encryption (prior to the permutation). Since this intermediate five-bit state was only subject to a permutation by the rest of the key, the number of set bits in the intermediate state will match the number of set bits in the ciphertext, character by character. With about 20 characters, this generates a unique result and therefore solves the XOR part of the key. An attack without known plaintext cannot use the same method as the machine applies the XOR to the plaintext. The ciphertext cannot be treated with the XOR as it would have to be permuted first, and the permutation is unknown.
However if we look at a candidate XOR stream and find a place where the 5-bit XOR applied to a character has either no bits set or all bits set, then the bit permutation is irrelevant in terms of deciding how the XOR will act as the XOR is the same for each bit. This does not quite return us to the same state as the known plaintext attack – in the known plaintext attack we could check that the number of bits matched between an XOR’d-plaintext and a ciphertext character. But here we do not have plaintext characters. All we can do is statistical – rely on the fact that plaintext contains a bias in the expected number of set bits. Fortunately it does. T52 relies on the standard teleprinter alphabet which tends to favour a low number of set bits for common letters.
The disadvantage of relying on XOR characters that have either none or all bits set is that these occur at only about 1/16th of the points in the keystream. We can improve matters by observing that a similar effect occurs when the CT itself has all or no bits set. Again this occurs 1/16th of the time on average, although some will clash with the known cases, so a suitable case occurs in about 12% of the message characters. Despite this, the test is quite powerful and works for typical T52 message lengths (1000-2000 characters). However we can improve.
If we know, say, that there is one bit set in the XOR and one bit set in the ciphertext, there are then only two possible situations. If the two bits align after the unknown permutation (p=0.2), this will result in zero bits set in the plaintext. Conversely if they do not align (p=0.8), there will be two bits set in the plaintext. Without knowing which of these two cases is right, we can use the probabilities to aggregate a likelihood estimate. Similar situations, with different probabilities, exist for each combination of the number of bits set in the ciphertext and XOR characters. The all-or-none-set case is simply a special case, albeit the most powerful one.
The algorithm, as might be expected, does need significantly more characters than the known plaintext solution (hundreds as opposed to just twenty). Somewhat counterintuitively, it operates faster than the known plaintext algorithm (12s-30s per partition on a P106-100 for 1000 character text, partitions vary in size). This is mostly because not knowing the internal permutation does not get ‘double counted’ against not knowing the ordering of the XOR wheels. In the known plaintext case, we must apply the right XOR and so must not just use the right partition of XOR wheels, we must use the right order. This involves permuting the choice of five wheels (i.e. a factor of 120). This permutation is distinct from the permutation the machine does internally. For the unknown plaintext case, the algorithm is such that while these are different permutations, their net effect is of one permutation. It might also be argued that the unknown plaintext algorithm does less : it can determine the right XOR wheels and their position, but only as a set of wheels, it does not determine their ordering.
Taken together the fasted solution to a likely message (1000+ characters of which a short preamble could be guessed) would be to determine the wheel partition using the Unknown plaintext algorithm and then the ordering using the known plaintext algorithm.
Cuda implementation. In this implementation, the keystream for the specified set of XOR wheels is generated in a first step. However unlike the known plaintext case where the full keystream was stored, all that is required here is the number of set bits at each position in the stream. This fits in under 0.7GB, reasonable with current GPU memories. The second step involves calculating from every startpoint in the stream, the log likelihood score of those XORs, given each position in the ciphertext. While the correct key is not guaranteed to have the highest score, it is likely to be a high scoring result – and this likelihood obviously increases with ciphertext length. Other high-scoring keys are likely to be similar to the true key (which is why a hill-climbing attack may be preferable to this brute force attack).
The CUDA kernels are short and simple and the code for this attack is available on GitHub.