Parallel Programming Project Report
Parallel Programming Project Report
Secret writing has been used for thousands of years; probably for as long as we have had secrets to
keep. These may be messages in war, messages between corporations, or just personal secret messages.
Even languages may be thought of as a kind of code. When we send secret messages there are three
types of participants. The sender, the intended recipient or receiver, and possibly the interceptor or ‘bad
guy’. The act of disguising your message is known as encryption, and the original message is called the
plaintext. The encrypted plaintext is known as the ciphertext (or cryptogram), and the act of turning the
ciphertext back into the original plaintext is decryption. Steganography is the act of physically hiding
your message; in ancient times you might write your message on the shell of a boiled egg using special
ink that would soak through the porous outer shell. When the egg was cracked and peeled, your secret
message would be found written on the egg white. In the 20th century, agents involved in espionage
would use the microdot, shrinking their entire message smaller than could be seen by the naked eye.
Codes on the other hand involve turning words or phrases into other words. For example, a command
such as ‘attack at midnight’ might simply become ‘eagle’. The problem with codes is that they involve
carrying a codebook, essentially a dictionary, to translate what you want to say into code. If this book
falls into enemy hands then your code is revealed and is now useless, and replacing each code book is
not something that can be done frequently. Also, a code may not have the flexibility to deal with all
messages you might conceivably wish to send. In comparison, ciphers work on the level of the individual
letters of your message. Ciphers may replace letters in a message with other letters, or numbers, or
symbols. For example, if ‘a’ becomes 0, ‘b’ becomes 1, ‘c’ becomes 2 and so on, then a word like ‘secret’
becomes ‘18 4 2 17 4 19’. (Note, counting from ‘a’ as zero is a necessary convention that we will
continue to use later on). This provides a much greater flexibility in our messages. Ciphers comes in two
parts: The first part is the algorithm; this is simply the method of encryption. The second part is the key.
The idea is these work together like a lock-and-key and, for the code breaker, having one without the
other is just half the problem. The key may change frequently meaning the greater the number of keys
the more difficult the cipher becomes break by brute force (an exhaustive check of all possible keys).
Secret writing has always been a constant struggle between the code maker and the code breaker.
Cryptography is the study of making secret messages, whereas cryptanalysis is the study of breaking
those secret messages. Cryptology is the collective name for both cryptography and cryptanalysis; the
word cryptology coming from the Greek words kryptos meaning hidden and logos meaning word.
1 Monoalphabetic Ciphers 1.1 The Caesar Shift We begin with a simple cipher as described by Julius
Caesar in the Gallic Wars. In it he describes taking two alphabets, from a to z, one above the other.
However, the second alphabet is shifted three places to the left. The top alphabet represents letters in
the plaintext, while the the alphabet underneath shows what these letters become in the ciphertext.
Note, throughout this course I will represent the plaintext in lowercase letters, and the ciphertext in
uppercase letters. plaintext a b c d e f g h i j k l m n o p q r s t u v w x y z ciphertext D E F G H I J K L M N O
P Q R S T U V W X Y Z A B C So, a plaintext message like veni, vidi, vici becomes YHQL, YLGL, YLFL in the
ciphertext. Clearly, the shift does not have to be 3, (it can be 4, 5, etc). The idea of shifting the alphabet
is the algorithm, and the size of the shift is the key. This is not a very secure cipher since there are only
26 keys (including plain English when you shift by 26). This cipher can be quickly broken by a simple
exhaustive check of all 26 possible keys. (The original strength of this cipher may have come from
Caesar’s enemies not realising he was using a cipher at all). A set is a collection of objects (numbers,
letters, symbols, or other objects). Let A denote the set of letters alphabet a, b, c, ..., z. Let P denote the
alphabet of the plaintext, usually P = A. Let C denote the ciphertext alphabet, this set may or may not be
the same as A. A monoalphabetic cipher is a rule which associates each letter of P with a unique letter in
C. Furthermore, different letters in P are sent to different objects in C. This means the size of C is equal
to or greater than the size of P, and each letter in P is paired with an image in C. This will allow us to
define an inverse rule from C to P that will decrypt our messages from the ciphertext back to the original
plaintext
Vigen`ere Cipher
The following cipher is named after the 16th century French diplomat Blaise de Vigen`ere. Imagine we
want to encrypt the message: ‘shaken not stirred’. We start by constructing a Vigen`ere Square: Notice,
each line of the Vigen`ere Square is a Caesar Shift, starting with a shift of zero, and ending with a shift of
25.
Next we need a keyword. Let’s use the word BOND. We write that repeatedly above our message:
Keyword: B O N D B O N D B O N D B O N D
Plaintext: s h a k e n n o t s t i r r e d To encrypt the first letter: go to row ‘B’ in the square - the first
letter of the keyword; next find column ‘s’ - the first letter of the plaintext; and where they meet in the
middle is the first letter of the ciphertext ‘T’. For the next letter do the same again: go to row ‘O’ and
column ‘h’, and where they meet is the second letter of the ciphertext ‘V’. Continuing in this way we get:
19 Keyword: B O N D B O N D B O N D B O N D Plaintext: s h a k e n n o t s t i r r e d Ciphertext: T V N N F
B A R U G G L S F R G Notice, the same letter in the plaintext may now be enciphered as different letters
in the ciphertext depending on its position.
Also notice, two letters that are the same in the ciphertext may come from two different letters in the
plaintext. If the keyword has length l, let k1, k2, . . . , kl be the letters of the keyword. If pi is the plaintext
letter in the ith position, then the ciphertext letter in the same position, ci , is given by ci = pi + k(i mod l)
mod 26. Given the keyword, we may decrypt our ciphertext by simply reversing this algorithm. The
effect of the Vigen`ere cipher is to disguise the frequencies. The longer the keyword the more effect it
has on frequency.
#include <iostream>
#include <istream>
#include <ostream>
#include <fstream>
#include <cstdlib>
#include <string>
the rot13 function
std::string rot13(std::string s
static std::string const lcalph = "abcdefghijklmnopqrstuvwxyz", ucalph =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string result;
std::string::size_type pos;
result.reserve(s.length());
for (std::string::iterator it = s.begin(); it != s.end(); ++it)
{ if ((pos = lcalph.find(*it)) != std::string::npos result.push_back(lcalph[(pos + 13)
% 26]);
else
result.push_back(*it);
return result;
std::string line;
while (std::getline(is, line))
return false;
return is.eof();
std::ifstream file;
file.open(argv[i], std::ios::in);
if (!file)
std::cerr << argv[0] << ": could not open for reading: " << argv[i]
<< "\n";
return EXIT_FAILURE;
if (!rot13_stream(file))
{
if (file.eof())
// no error occurred for file, so the error must have been in output
else
std::cerr << argv[0] << ": error reading from " << argv[i]
<< "\n";
return EXIT_FAILURE;
file.clear();
file.close();
if (!file)
std::cerr << argv[0] << ": warning: closing failed for " << argv[i]
<< "\n";
return EXIT_SUCCESS;
#include "mpi.h"
#include <iostream>
#include <string.h>
#include <string>
#include <stdlib.h>
#include <ctype.h>
#define id rank
#define TAG 0
if (rank == 0)
{
cout << "\n----------------------------------------------------\n";
cout << "ENCRYPTION USING VIGENERE CIPHER";
cout << "\n----------------------------------------------------\n";
if (rank == 0)
{
// Sending key - one character to one process
// cout << "Inside root process\n";
for (int i = 1; i <= keylen; i++)
{
// cout << "Sending " << key[i - 1] << " to " << i << endl;
MPI_Ssend(&key[i - 1], 1, MPI_CHAR, i, TAG, MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
#include "mpi.h"
#include <iostream>
#include <string.h>
#include <string>
#include <stdlib.h>
#include <ctype.h>
#define id rank
#define TAG 0
string str;
char key[50];
string decrypted;
int len, keylen;
char key_character, decrypted_character, character_to_decrypt;
if (rank == 0)
{
cout << "\n----------------------------------------------------\n";
cout << "DECRYPTION USING VIGENERE CIPHER";
cout << "\n----------------------------------------------------\n";
if (rank == 0)
{
for (int i = 1; i <= keylen; i++)
{
MPI_Ssend(&key[i - 1], 1, MPI_CHAR, i, TAG, MPI_COMM_WORLD);
}
if (rank == 0)
{
cout << "\nThe decrypted string is: " << decrypted;
cout << endl;
}
MPI_Finalize();
return 0;
}