Recognizing and decrypting custom cipher with known plaintext and ciphertext I've been trying to reconstruct an encryption algorithm that produces a known ciphertext from a know plaintext. I have done some analysis:


the algorithm operates on single bytes
a plain text can be of any length and len(ptext) == len(ctext)
for a same letter plaintext the ciphertext repeats after 20B


Example (bytes are hex; ASCII(A) == 0x41):

P: 4141414141414141414141414141414141414141 414141...
C: cbcd7f01128216acb2495fa2625aa245d9d30366 cbcd7f...



a minor change in input reflects in minor change of output


Example (ASCII(B) = 0x42; the diffrence is probably +-3 max):

P1: 414141414141...
P2: 424242424242...
C1: cd7f01128216...
C2: ce7c02118115...



xor of ciphertexts from single letter plaintexts is obviosly corelated


Example (Cx = ciphertext of same letter 'x' plaintext)

Ca: cd7f01128216...
Cb: ce7c02118115...
Cc: cf7d03108014...
Cd: c87a04178713...

Ca ^ Cb: 3 3 3 3 3...
Ca ^ Cc: 2 2 2 2 2...
Ca ^ Cd: 5 5 5 5 5...
Cb ^ Cc: 1 1 1 1 1...
Cb ^ Cd: 6 6 6 6 6...
Cc ^ Cd: 7 7 7 7 7...


Do you recognize this cipher? How could I proceed with my analysis/reconstruct the algorithm?

Another complication is that ciphertexts seems to be sort of "rotated" with every new message, see what I mean.

Example (P1 and P2 are sent separately; '!' is used only to visualize it better):

P1: P2
P2: 4141414141414141414141414141414141414141 414141...
C1: !!!cbcd7f01128216acb2495fa2625aa245d9d30366 cbcd7f...
C2: 0366!!!cbcd7f01128216acb2495fa2625aa245d9d3 0366cb...


I am a beginner, any help is appreciated.
I figured it out.

keys = [k1, k2, ... , k20]
def encrypt(offset, message):
    ctext = []
    for i in len(message):
        ctext[i] = keys[(offset + i) % len(keys)] ^ message[i]


The "rotation" is caused by the "offset" parameter. The keys are stored in a rotation buffer and xored with plaintext bytes. The keys can be obtained by xoring a plaintext with a ciphertext.