3 ms·
decrypted[i] = encrypted[i] ^ key[pos_a] ^ key[pos_b]; key[pos_c] = (key[pos_c] << 31) | (key[pos_c] >> 1); key[pos_a] ^= key[pos_c] ^ i ^ decrypted[i];
by Strilanc 13y ago
decrypted[i] = encrypted[i] ^ key[pos_a] ^ key[pos_b];
key[pos_c] = (key[pos_c] << 31) | (key[pos_c] >> 1);
key[pos_a] ^= key[pos_c] ^ i ^ decrypted[i];
Expanding decrypted:
key[pos_a] ^= key[pos_c] ^ i ^ encrypted[i] ^ key[pos_a] ^ key[pos_b];
You just xored key[pos_a] into itself so we can eliminate it:
key[pos_a] = key[pos_c] ^ i ^ encrypted[i] ^ key[pos_b];
I'm pretty sure you just threw away one word's worth of entropy.
- a1k0n 13y agoexcept pos_c might be equal to pos_a or pos_b, and key[pos_c] just got rotated. It's not quite equivalent, I tried it.
- fhars 13y agoDuring the encryption phase the argument by Strilanc doesn't hold (as in that case decrypted[i] is given as the input and does not contain any key admixture), and it is exactly the case where pos_c equals pos_a that is problematic, as in that case the statement key[pos_a] ^= key[pos_c] ^ i ^ decrypted[i]; overwites key[pos_a] with the value i ^ plaintext[i] that doesn't depend on any part of the key at all.
- Strilanc 13y agoYou're right, if pos_c = pos_a, the rotation does prevent the cancellation. But throwing away a word of entropy most of the time is still very serious, and ending up with a different cancellation in the remaining cases is not really promising.