introduced digraph reversal in case of same row/column

This commit is contained in:
Luxferre
2025-02-24 11:29:07 +02:00
parent 5eb44b10d6
commit 2fd14fc10c
2 changed files with 27 additions and 17 deletions
+18 -9
View File
@@ -147,14 +147,16 @@ For each plaintext character P1, do the following:
3. If P1 and P2 are not on the same row and not on the same column, find the
opposite corners of the imaginary rectangle on the grid. The ciphertext
character C1 will be on the same row as P1, and the ciphertext character C2
will be on the same row as P2.
will be on the same row as P2. The resulting digraph will be `C1C2`.
4. If P1 and P2 are on the same row, C1 and C2 will be to the immediate right
of P1 and P2 respectively. If a character is in the rightmost column, the
resulting character will be on the first one of the same row.
resulting character will be on the first one of the same row. Lastly, you
need to swap the ciphertext characters (`P1P2` => `C2C1`).
5. If P1 and P2 are on the same column, C1 and C2 will be to the immediate down
of P1 and P2 respectively. If a character is in the bottommost row, the
resulting character will be on the first one of the same column.
6. Write down C1 and C2 as the ciphertext digraph.
resulting character will be on the first one of the same column. Then you
need to swap the ciphertext characters (`P1P2` => `C2C1`).
6. Write down the resulting ciphertext digraph.
After all plaintext characters are processed, add PL random characters in front
of the ciphertext, where PL = KL mod 10 + 1, where KL is the initial key phrase
@@ -171,10 +173,10 @@ Then, for each ciphertext digraph C1C2, do the following:
2. If C1 and C2 are not on the same row and not on the same column, find the
opposite corners of the imaginary rectangle on the grid. The plaintext
character P1 will be on the same row as C1.
3. If C1 and C2 are on the same row, P1 will be to the immediate left of C1.
If C1 is in the leftmost column, P1 will be on the last one of the same row.
4. If C1 and C2 are on the same column, P1 will be to the immediate up of C1.
If C1 is in the topmost row, P1 will be on the last one of the same column.
3. If C1 and C2 are on the same row, P1 will be to the immediate left of C2.
If C2 is in the leftmost column, P1 will be on the last one of the same row.
4. If C1 and C2 are on the same column, P1 will be to the immediate up of C2.
If C2 is in the topmost row, P1 will be on the last one of the same column.
5. Write down P1 as the next plaintext character.
Design rationale
@@ -195,6 +197,12 @@ InterPlay-36 improves over the classic Playfair in several ways:
2. Adds a plaintext interleaving step into the encryption phase (see below).
3. Allows to preserve whitespace in the plaintext while making sure the end
ciphertext will never start with whitespace.
4. By reversing the ciphertext digraph in case of the "same row/column" rules,
it eliminates the possibility of homophonic analysis by just discarding
every odd ciphertext character (after removing the prefix). Even letters
still have a statistical bias (25/36 against 10/36) but there's no way to
tell for sure which letter in particular ciphertext digraph is significant
and which one is a decoy.
The interleaving step is important to break several negative properties of the
Playfair algorithm that make its cryptanalysis easier, like its susceptibility
@@ -206,7 +214,8 @@ that no digraph contains a repeated letter, without complicating the logic.
InterPlay-36 was designed to be used "as is", however one can easily combine it
with other popular encryption methods such as transposition ciphers (using the
key grid, a transposed key grid and/or the keyphrase length as the key sources).
key grid, a transposed key grid and/or the keyphrase length as the key sources)
or a keyed fractionation scheme like Bifid, using the same keyed grid.
In any case, it is advised to apply InterPlay-36 first in the chain when you are
encrypting the messages, and last when decrypting. The reference implementation
of InterPlay-36 in HTML5/JS also contains a flag to apply a DCT (double columnar
+9 -8
View File
@@ -83,8 +83,9 @@ def ipfencrypt(msg:str, key:str):
elif y1 == y2: # same row: get the coords to the right
x1 = (x1 + 1) % pfsize
x2 = (x2 + 1) % pfsize
enc.append(getgridchar(kg, x1, y1))
# swap the ciphertext character
enc.append(getgridchar(kg, x2, y2))
enc.append(getgridchar(kg, x1, y1))
# generate a random prefix
preflen = (len(key) % 10) + 1
prefix = ''
@@ -112,14 +113,14 @@ def ipfdecrypt(enc:str, key:str):
msg.append(getgridchar(kg, x2, y1))
else:
if x1 == x2: # same column: get the coords above
y1 -= 1
if y1 < 0:
y1 += pfsize
y2 -= 1
if y2 < 0:
y2 += pfsize
elif y1 == y2: # same row: get the coords to the left
x1 -= 1
if x1 < 0:
x1 += pfsize
msg.append(getgridchar(kg, x1, y1))
x2 -= 1
if x2 < 0:
x2 += pfsize
msg.append(getgridchar(kg, x2, y2))
# finalize the decrypted message
return ''.join(msg).strip()