Monday, October 19, 2015

Atbash Cipher

I think this is the easiest ciphers. In the plain text if we get 'A' then we replace it with 'Z' character. Similarly 'B' -> 'Y', 'C' -> 'X'.... I guess you get the idea, so each time you get a character you replace with the character from the end of English alphabet sequence. So here is the lookup table you can use to implement this cipher

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
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

I used following code implement this cipher.

int AtbashCipher(char* strPlainText, int nSize, char* strCipherText)
{
int nReturnValue = 0;

if (nSize <= 0 || strPlainText == NULL || strCipherText == NULL)
{
return ERR_INVALIDINPUTPARAMETERS;
}


for (int i = 0; i < nSize; i++)
{
//Idea here is replace A->Z, B->Y, C->X .....
if (strPlainText[i] >= 65 && strPlainText[i] <= 90)
{
//Capital Letters
strCipherText[i] = 90 - (strPlainText[i] - 65);
}
else if (strPlainText[i] >= 97 && strPlainText[i] <= 122)
{
//small Letters
strCipherText[i] = 122 - (strPlainText[i] - 97);
}
}

return nReturnValue;
}

I guess same function can be used for decrypting the cipher text. Will be testing it soon and updating this blog.

Is it a strong cipher? Definitely not. This is even looks like a special case of caeser cipher with key value = 25.


To understand Atbash cipher I read website -> http://practicalcryptography.com/ciphers/classical-era/atbash-cipher/

Suppose plain text is "Harsha Kadekar" then cipher text would be "Szihsz Pzwvpzi"

Tuesday, October 13, 2015

Socket communication in windows

There are many website which teach you socket communication in windows using winsock. So if you have come to this site looking for some tutorial I would recommend you to go directly to microsoft website. Then why I am writing this blog you ask - well this is kind of a remembrance post of what I did in socket communication. 

I have started developing a basic Http server [If you have followed my previous posts then sorry for one more started project]. In this first step is establishing the socket communication between client and server. So as of now I am able to do the socket communication between server and client. Basically server will wait for a client connection, once connected to client will wait to receive a message from the client. Then displays the received message. It will send a message to client and finally closes the connection. For handling client connections it is creating a new thread each time a new connection is created with client. To test server I have created a basic client. Client will connect to the server, send a message and wait for message from server. Once received, it will display that message and closes the connection.

Steps for socket connection from server side- 
  1. Create a socket
  2. Bind to the socket
  3. Wait for client connections i.e. listen to connections
  4. Accept those connections
  5. Send/Receive messages from/to that connection
  6. Shutdown the connection
  7. Close the socket
Before creating the socket we need to initialize the winsock which we do using WSAStartup function. Then we need to define the address, protocal and socket types for which socket being created. Once these are defined then we will create a socket. Once socket is created, that socket has to be binded to the address and port like 8080 port. After this server will listen for new connections from the clients. Using accept function call we accept the new client connection. Once accepted we can send messages to client as well as receive messages from client. Once done we shutdown the connection, close the socket and cleanup the winsock using WSACleanup.

WSAStartup(MAKEWORD(2, 2), &wsData)


structServerAddrInfo.ai_family = AF_INET;
structServerAddrInfo.ai_socktype = SOCK_STREAM;
structServerAddrInfo.ai_protocol = IPPROTO_TCP;
structServerAddrInfo.ai_flags = AI_PASSIVE;

nReturnValue = getaddrinfo(NULL, "8080", &structServerAddrInfo, &structServerAddrResult);

scListenSocket = socket(structServerAddrResult->ai_family, structServerAddrResult->ai_socktype, structServerAddrResult->ai_protocol);

nReturnValue = bind(scListenSocket, structServerAddrResult->ai_addr, structServerAddrResult->ai_addrlen);

nReturnValue = listen(scListenSocket, SOMAXCONN);

scClientSocket = accept(scListenSocket, NULL, NULL)

nReturnValue = recv(scClientSocket, szRecieveMsg, 512, 0);

nReturnValue = send(scClientSocket, sTestMessage, 35, 0);

nReturnValue = shutdown(scClientSocket, SD_SEND);

closesocket(scClientSocket);

WSACleanup();

Steps for socket connection in client:
  1. Create socket
  2. Connect to server
  3. Send/Receive messages to/from server
  4. Close socket
Similar to server here also first we need to call WSAStartup function. Once done create a socket that can connect to server using same port and server address. Once connected to server client can send messages to server as well as recieve messages from the server. Once all done, it can close the socket created. Finally call the WSACleanup()

nReturnValue = WSAStartup(MAKEWORD(2, 2), &wsData);

structClientaddr.ai_family = AF_INET;
structClientaddr.ai_protocol = IPPROTO_TCP;
structClientaddr.ai_socktype = SOCK_STREAM;

nReturnValue = getaddrinfo(sServerName, "8080", &structClientaddr, &structServeraddrInfo);

scConnectSocket = socket(structAddrIterator->ai_family, structAddrIterator->ai_socktype, structAddrIterator->ai_protocol);

nReturnValue = connect(scConnectSocket, structAddrIterator->ai_addr, structAddrIterator->ai_addrlen);

nReturnValue = send(scConnectSocket, sTestMessage, strnlen_s(sTestMessage, 33), 0);

nReturnValue = recv(scConnectSocket, szRecieveMessage, 512, 0);

closesocket(scConnectSocket);

WSACleanup();


I agree, I have not explained it in deep, may be sometime later. Code of this can be found at gitbhub

Sunday, October 4, 2015

Breaking Caesar Cipher by brute force

I started learning about cryptography. Given a data we do some transformation or certain steps on the data such that data looses or hides its original form. Any person who sees that new form does not recognizes whats its original form. This is encryption. Again we can use certain steps on new form of data to get back the original form of data. This is decryption. 

PlainText --> Encryption Engine -> Cryptic Text

Cryptic Text --> Decryption Engine -> Plain Text.

Ciphers are nothing but those encryption engines which will generate the cryptic message given a plain message. There are different types of ciphers. I will be explaining one of the oldest ciphers. Caesar Cipher. Yes as name suggests it was used by Julius Caesar. This is a simple cipher. Given a plain text, each character in that message will be replaced by another symbol. There is a concept of key. Key place a very important role is conversion of text to cryptic text as well as reversing the cryptic text to plain text. So key will be present with the person who is preparing the cryptic text. And also the same key will be present with the person to whom the message needs to b passed.
English alphabet has totally 26 characters. Now in Caesar cipher, these English alphabet will be replaced again by English alphabet. Example if character is 'b' and key is 3 then b will be replaced by 'e'.  Suppose character is 'z' then it will be replaced by 'c'. So number of possible keys are 25 i.e. number of English alphabet -1. Basically it means I can replace a character x with 25 other characters.

for (int i = 0; i < nSize; i++)
{
if (strPlainText[i] >= 65 && strPlainText[i] <= 90)
{
//Capital letters
nTemp = strPlainText[i] + *pKey;

if (nTemp > 90)
{
nTemp = nTemp - 26;
}
strCipherText[i] = nTemp;
}
else if (strPlainText[i] >= 97 && strPlainText[i] <= 122)
{
//small letters
nTemp = strPlainText[i] + *pKey;

if (nTemp > 122)
{
nTemp = nTemp - 26;
}
strCipherText[i] = nTemp;
}
else
{
strCipherText[i] = strPlainText[i];
}
}

In simple words this is doing ch = (pt + k)mod 26. where pt is the character from plain text, k is the key and ch is character from cipher text. In code I am trying to first check whether character obtained is a small letter alphabet or capital letter aplhabet. If not then it is a numeric or some other symbols. Those characters are not touched. If it is a smaller letter than it will be replaced by cipher text of smaller letter. If it is a capital letter I am replacing the with cipher text of capital letter. 

Deciphering is a simple step. pt = (ch - k)mod26. ch is the character from cipher text, k is the key and pt is the character from plain text. 

for (int i = 0; i < nSize; i++)
{
if (strCipherText[i] >= 65 && strCipherText[i] <= 90)
{
nTemp = strCipherText[i] - nKey;
if (nTemp < 65)
{
nTemp = 26 + nTemp;
}
strPlainText[i] = nTemp;
}
else if (strCipherText[i] >= 97 && strCipherText[i] <= 122)
{
nTemp = strCipherText[i] - nKey;
if (nTemp < 97)
{
nTemp = 26 + nTemp;
}
strPlainText[i] = nTemp;
}
else
{
strPlainText[i] = strCipherText[i];
}
}

Breaking the cipher - Now if I have the text but I don't have the key. In this case I know that possible keys are from 1-25. Try all these on the cipher text. They check the answer which makes the correct sense of the text. 

for (int i = 1; i < 25; i++)
{
memset(strKey, '\0', 5);
sprintf_s(strKey, "\n%d\n", i);
fwrite(strKey, sizeof(char), strnlen_s(strKey,6), fpOutputFile);
for (int j = 0; j < nSize; j++)
{
if (strCipheredText[j] >= 65 && strCipheredText[j] <= 90)
{
nTemp = strCipheredText[j] - i;
if (nTemp < 65)
{
nTemp = 26 + nTemp;
}
strPlainText[j] = nTemp;
}
else if (strCipheredText[j] >= 97 && strCipheredText[j] <= 122 )
{
nTemp = strCipheredText[j] - i;
if (nTemp < 97)
{
nTemp = 26 + nTemp;
}
strPlainText[j] = nTemp;

}
else
{
strPlainText[j] = strCipheredText[j];
}
}
fwrite(strPlainText, sizeof(char), strnlen_s(strPlainText, nSize), fpOutputFile);
memset(strPlainText, '\0', nSize+1);
}

As you can see, I am trying all the 25 keys and storing the result in a file. 

If plain text was "Harsha Kadekar" and key was 13 then cryptic text was "Unefun Xnqrxne"


And I am learning from book -> Cryptography and Network Security: Principles and practices by William Stallings.

Saturday, October 3, 2015

Comparing running time for various algorithms

I was trying to compare different algorithms based on input size. I have implemented all these algorithms in C. Following table gives you how the order of growth is affecting practical implementation.

n
Bubble Sort
Insertion Sort
Merge Sort
Selection Sort
100
0 ms
0 ms
0 ms
0 ms
1000
0 ms
0 ms
0 ms
0 ms
10000
250 ms
62 ms
0 ms
94 ms
50000
6546 ms
1563 ms
16 ms
2328 ms
100000
26687 ms
6266 ms
47 ms
9291 ms

0 means it has taken very less or negligible time.

So it looks like Merge sort is clear winner. Followed by insertion sort, selection sort and finally Bubble sort.

Same thing I applied for Matrix Multiplication.

N
Brute Force (n^3)
Strassen
128
16 ms
1391 ms
512
656 ms
68078 ms
1024
7297 ms
474781 ms
10000
3.64 hours
Did not stop even after 24 hours


(Actually even if it had stopped answer would be wrong as 10000 is not power of 2)

As you can see it looks like Strassen is not yet all beating brute force in any way. Then I came across following points in Wikipedia (https://en.wikipedia.org/wiki/Strassen_algorithm)

Practical implementations of Strassen's algorithm switch to standard methods of matrix multiplication for small enough submatrices, for which those algorithms are more efficient. The particular crossover point for which Strassen's algorithm is more efficient depends on the specific implementation and hardware. Earlier authors had estimated that Strassen's algorithm is faster for matrices with widths from 32 to 128 for optimized implementations.[1]However, it has been observed that this crossover point has been increasing in recent years, and a 2010 study found that even a single step of Strassen's algorithm is often not beneficial on current architectures, compared to a highly optimized traditional multiplication, until matrix sizes exceed 1000 or more, and even for matrix sizes of several thousand the benefit is typically marginal at best (around 10% or less)

Similar things are discussed in some of the coding forums ->  http://stackoverflow.com/questions/13559928/why-is-my-strassens-matrix-multiplication-slow?rq=1
So based on above comments I changed implementation. I kept Crossover value as 32. That is if sub matrix size is 32x32 than Strassen's algorithm instead of calling its own algorithm with smaller size, it will call Brute force algorithm to do the lower size matrix multiplication.

N
Brute Force (n^3)
Strassen
64
0 ms
16 ms
128
16 ms
16 ms
256
125 ms
110 ms
512
1078 ms
937 ms
1024
14468 ms
6282 ms

Clearly Strassen is overtaking brute force. Now I tried with crossover value as 16. Again Strassen was very close to Brute force but could not beat it. For value 128, Strassen was able to beat Brute force only after N size of 512.
In my case Strassen algorithm takes 2-3 times more memory than Brute Force like for n = 1024 i.e. 1024*1024 matrix brute force took 21 MB where as Strassens algorithm took 48 MB.