Substitution cipher model¶
We implement the encryption model using simple substitution (monoalphabetic cipher).
Problem description¶
Substitution ciphers are another basic building block of modern encryption systems. Its various variants were used both in antiquity (Caesar's cipher, simple substitution cipher) and inside the realisations of the most modern algorithms, as the next stage of encryption.
The cipher we are implementing is called a simple substitution cipher, and its operation boils down to creating an encryption table that assumes a single letter of the ciphertext for each letter of the plaintext. We will use only 33 characters - the uppercase part of the Cyrillic alphabet characters (including the letter
Ё
).
We will encrypt messages character by character, replacing each character with its corresponding ciphertext character by means of a substitution table.
The alphabet of the original message consists of 33 characters:
print( collect(1:33) )
The cipher alphabet must contain all these characters, but in a pseudo-random order:
target_order = shuffle( Xoshiro(1), 1:33 );
print( target_order )
To use this table in reverse, we will need to apply sorting:
print( sortperm( target_order ) )
Note that when we invoke the command shuffle
we initialise the random number generator each time with some number 1
. This allows us to get the same pseudo-random sort order of values from time to time (the same for the encryption block and the decryption block).
Such a model performs encryption and decryption of the message.
Transposition blocks¶
The operation models Перестановки
and Обратной перестановки
are created with the help of blocks LookupTableND
, for convenience provided with a mask with controls.
The front side of the permutation block reflects two things:
- the number
Seed
, with which we initialise the random number generator - whether the permutation is forward or backward
The parameters of the permutation block are set in the settings of its mask.
Starting the model¶
Let's run the model by means of programme control:
# Загрузим модель, если она еще не открыта на холсте
if "substitution_cipher_model" ∉ getfield.(engee.get_all_models(), :name)
engee.load( "$(@__DIR__)/substitution_cipher_model.engee");
end
model_data = engee.run( "substitution_cipher_model" );
source_message = collect(model_data["Сообщение"]).value
cipher_text = Int.(collect(model_data["Шифротекст"]).value)
received_message = Int.(collect(model_data["Расшифровка"]).value)
println( "Отправленное сообщение: ", source_message )
println( "Зашифрованное сообщение: ", cipher_text )
println( "Полученное сообщение: ", received_message )
alphabet_dict = Dict( zip( 1:33, "абвгдеёжзиёклмнопрстуфхцчшщъыьэюя" ))
print( "Расшифрованное сообщение: ", join( [alphabet_dict[d] for d in received_message], "" ) )
Since in this demonstration the message is passed round in a circle, we have obtained 11 letters, which may be more or less than the number of characters in the original message.
Conclusion¶
We have shown how the substitution cipher works using a simplified example where a message is sent as an array of digits representing the position of each letter of the original message in the Cyrillic alphabet (lower case). The next step is to adapt the model to send byte-by-byte messages by replacing the code in the blocks Подстановка
and Обратная подстановка
.