r otor m achine
3.2 Basic Concept
A rotor machine has a keyboard and a series of rotors, where the out-put pins of one rotor are connected to the inout-put of another. Moreover, a rotor is a mechanical wheel wired to perform a general substitution.
So, the number of general substitution for each letter in the plaintext actually depends on the number of rotors. Figure 3.1 depicts a simple rotor machine.
AB DE GF H C AB
DE GF H C
AB DE GF H C AB
DE GF H C
Figure 3.1 A three-rotor machine for an eight-letter alphabet before and after the first rotor has rotated one place.
For example, in a three-rotor machine, the first rotor might substitute A » E, the second rotor might substitute E » K, and the third rotor might substitute K » Y. Therefore, after encryption, A will become Y. To protect data frequency analysis, some of the rotors shift after each output. In rotor machine encryption, a combination of sev-eral rotors and shifting of n number of rotors leads to a 26n. A large number of combinations makes it harder to break the code.
3.3 Systematization
It is relatively straightforward to create a machine to perform simple substitution in monoalphabetic algorithms. However, it is challeng-ing to create a machine that can perform polyalphabetic substitutions.
In the case of the rotor machine, the idea is to change the wiring of the machine with each keystroke. The wiring is placed inside a rotor.
After a keystroke, the rotor is rotated with a gear. Therefore, a key-stroke that outputs an S might generate an A the next time. Hence, for every keystroke a new substitution takes place.
3.4 Algorithm
Step 0: Select how many rotors will be used and make the rotors ready by placing 26 unique random character pairs.
Step 1: To encrypt, for each character in the alphabet set, for each rotor, find the match from the rotor pair sequentially.
After each encryption, rotate the rotors accordingly.
Step 2: To decrypt, apply the same procedure of step 1, with reverse sequential order of the rotors.
3.5 Implementation
#include <iostream>
#include <queue>
#include <vector>
#include <cstdlib>
#include <string>
using namespace std;
typedef pair<int,int>Rotor_Pair;
class Enigma {
public:
voidcreate_rotor(vector <Rotor_Pair>&rtq);
voidshow_rotor(vector <Rotor_Pair>&rtq);
voidmanage_rotors ();
void encrypt();
void decrypt();
chartranspos_en (char ch);
chartranspos_de (char ch);
voiddisplay_rotors ();
private:
vector<Rotor_Pair>first_rotor;
vector<Rotor_Pair>second_rotor;
vector<Rotor_Pair>third_rotor;
vector< vector <Rotor_Pair>>all_rotors;
int count;
};
void Enigma::create_rotor(vector <Rotor_Pair>&rtq) {
vector<int>temp_q;
int current = rand()% 26 + 1;
intnum = rand()% 26 + 1;
rtq.push_back(make_pair(current,num));
temp_q.push_back(num);
for (inti = 0; i< 25; i++) { current = current% 26 + 1;
bool exist = true;
//Selecting unique random pairs for each of the rotors
while (exist) { exist = false;
num = rand()% 26 + 1;
for (vector <int> :: iterator it = temp_q.begin(); it
! = temp_q.end(); it++) { if ((*it) = = num) {
exist = true;
break;
} } }
temp_q.push_back(num);
Rotor_Pairrp = make_pair(current,num);
rtq.push_back(rp);
} }
void Enigma :: show_rotor (vector <Rotor_Pair>&rtq) {
vector<Rotor_Pair>temp_q;
temp_q = rtq;
cout<<endl;
for (unsigned inti = 0; i<26; i++) { Rotor_Pairrp = rtq[i];
cout<<rp.first<< “\t” <<rp.second<<endl;
} }
void Enigma :: manage_rotors () {
count = 0;
srand (5);
create_rotor(first_rotor); //Creating the first rotor all_rotors.push_back(first_rotor);//Assign the first rotor
create_rotor(second_rotor); //Creating the second rotor all_rotors.push_back(second_rotor); //Assign the second rotor
create_rotor(third_rotor); //Creating the third rotor all_rotors.push_back(third_rotor); //Assign the third rotor
}
void Enigma :: display_rotors () {
for (vector < vector <Rotor_Pair>> :: iterator it = all_rotors.begin(); it ! = all_rotors.end(); it++) { show_rotor(*it);
} }
char Enigma :: transpos_en (char ch) {
count++;
ch = toupper (ch);
intpos = ch - 65 + 1; //Converting ASCII to decimal
int index = 0;
// Finding the specific position for each of the character
for (vector <Rotor_Pair> :: iterator it = first_rotor.
begin(); it ! = first_rotor.end(); it++) { if ((*it).second = = pos) break;
else index++;
}
// Rotating the first rotor
Rotor_Pairtrp = first_rotor.front();
first_rotor.erase(first_rotor.begin());
first_rotor.push_back(trp);
pos = (second_rotor[index]).first;
index = 0;
// Finding the specific position for each of the character
for (vector <Rotor_Pair> :: iterator it = second_
rotor.begin(); it ! = second_rotor.end(); it++) { if ((*it).second = = pos) break;
else index++;
}
// Rotating the second rotor if (count% 26 = = 0) {
// Finding the specific position for each of the character
for (vector <Rotor_Pair> :: iterator it = third_rotor.
begin(); it ! = second_rotor.end(); it++) { if ((*it).second = = pos) break;
}
// Rotating the third rotor if (count% 676 = = 0) {
void Enigma :: encrypt () {
// Input the data to encrypt
cout<< “Put a text to encrypt” <<endl;
string input, output;
getline(cin, input);
// For each input character, call “transpos_en”
function if found in alphabet set
for (string :: iterator it = input.begin(); it ! = input.end(); it++) {
if (isalpha(*it))
output + = transpos_en(*it);
else output + = 32;
}
cout<< output <<endl;
}
char Enigma :: transpos_de (char ch) {
count++;
ch = toupper (ch);
intpos = ch - 65 + 1; //Converting ASCII to Deciaml int index = 0;
// Finding the specific position for each of the character
for (vector <Rotor_Pair> :: iterator it = third_rotor.
begin(); it ! = third_rotor.end(); it++) { if ((*it).first = = pos) break;
else index++;
}
// Rotating the third rotor if (count% 676 = = 0) {
// Finding the specific position for each of the character
for (vector <Rotor_Pair> :: iterator it = second_
rotor.begin(); it ! = second_rotor.end(); it++) { if ((*it).first = = pos) break;
else index++;
}
// Rotating the second rotor if (count% 26 = = 0) {
Rotor_Pairtrp = second_rotor.front();
second_rotor.erase(second_rotor.begin());
second_rotor.push_back(trp);
}
pos = (first_rotor[index]).second;
index = 0;
// Finding the specific position for each of the character
for (vector <Rotor_Pair> :: iterator it = first_rotor.
begin(); it ! = first_rotor.end(); it++) { if ((*it).first = = pos) break;
else index++;
}
// Rotating the first rotor
Rotor_Pairtrp = first_rotor.front();
first_rotor.erase(first_rotor.begin());
first_rotor.push_back(trp);
ch = pos - 1 + 65;//Converting Decimal to ASCII returntolower(ch);
}
void Enigma :: decrypt () {
// Input the data to decrypt
cout<< “Put a text to decrypt” <<endl;
string input, output;
getline(cin, input);
// initializing the rotor settings int count = 0;
for (vector < vector <Rotor_Pair>> :: iterator p = all_rotors.begin(); p ! = all_rotors.end(); p++) {
if (count = = 0) first_rotor = *p;
else if (count = = 1) second_rotor = *p;
elsethird_rotor = *p;
count++;
}
display_rotors(); //Showing the rotor pairs
//For each input character, call “transpos_de”
function if found in alphabet set
for (string :: iterator it = input.begin(); it ! = input.end(); it++) {
if (isalpha(*it))
output + = transpos_de(*it);
else output + = 32;
}
cout<< output <<endl;
}
int main() {
Enigma enigma;
enigma.manage_rotors();//Creating the rotors and populate them with character pairs
enigma.display_rotors(); //Show the rotor pairs enigma.encrypt();//Encryption
enigma.decrypt(); //Decryption return 0;
}
3.6 Limitations
The technique used in the rotor machine was very strong if used correctly and securely. However, the German messages encrypted with the rotor machine Enigma were deciphered by the Allies during World War II. It has been claimed that as a result of this cryptanaly-sis, World War II was shortened by 2 years. Using a reasonably small range of probable initial permutations, Polish mathematician and cryptologist Marian Rejewski was able to find the possible message keys. What he assumed, and later on discovered to be true, was that most of the time the German operators would choose very simple message keys, like AAA or XYZ or ABC. So, he expected that if he made lists of all the possible message keys, many simple keys would appear. Then that list could be used to find the key. His technique was proven to be correct when he managed to break a lot of ciphertext within a very short time.
Reference
1. Karl de Leeuw. The Dutch invention of the rotor machine, 1915–1923.
Cryptologia, 27(1), 73–94, 2003.
4 5