megacolorboy

Abdush Shakoor's Weblog

Writings, experiments & ideas.

The Cryptopals Crypto Challenges: Set 1 - Single-Byte XOR Cipher

Write a method that decrypts a hexadecimal message that has been XOR'd against a single character.

This is the third challenge of Set 1 in The Cryptopals Crypto Challenges website. Previously, I spoke about these challenges and provided walkthroughs for the previous challenges, if you haven't read them, here are the links:

For this challenge, you have to write a method that decodes a Hexadecimal string:

1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736

That has been XOR'd against a single character. You must find the key and decrypt the message.

If you have read the previous article, it was clearly setup for this problem. There are so many ways to solve this problem but the most efficient way to solve it is by using a Frequency table.

Assuming the message is supposed to be in English, when decrypted, we need to only generate a frequency table using the given Hexadecimal string that shows the frequencies of each alphabet. The character that has the highest frequency is the key required, which is then used to perform an XOR (\^) operation against each character, to decrypt the encrypted message.

Let's have a look at the code:

//Return Character frequency of a string
map<char, int> CryptoLib::frequency_table(string str)
{
    map<char, int> m;
    map<char, int>::iterator it;

    for(int i=0; i<str.size(); i++)
    {
        char ch = str[i];
        it = m.find(ch);

        if(it == m.end())
        {
            m.insert(make_pair(ch,1));
        }
        else
        {
            it->second++;
        }
    }

    return m;
}

//Return character with the highest frequency
char CryptoLib::ret_high_freq_char(map<char, int> m)
{
    int max_count = 0;
    char max_char;

    for(auto p: m)
    {
        if(isalpha(p.first))
        {
            if(p.second > max_count)
            {
                max_char = p.first;
                max_count = p.second;
            }
        }
    }
    return max_char;
}

//Single Byte XOR
string CryptoLib::singleByteXOR(string str)
{
    string newStr = "";

    //1. Convert Hexadecimal to Binary
    str = add_spaces(con_hex_2_bin(str), 8);

    //2. Convert Binary to Decimals
    vector<int> v = con_bin_2_dec(str, 7.0);


    // What's happening here?
    // 4. Generate a frequency table using the characters from the ASCII string
    // 5. Look for characters that are English and also has the highest frequency
    // 6. The character that has the highest frequency is the KEY!

    //The key
    unsigned char a = toupper(ret_high_freq_char(frequency_table(con_dec_2_ascii(v))));

    //7. Perform XOR with the KEY against each character
    for(int i=0; i<v.size(); i++)
    {
        unsigned char b = v[i];
        unsigned char c = b ^ a;
        newStr += c;
    }

    //8. Decoded message
    return newStr;
}

Final code:

//CryptoPals Set 1 Challenge 3
#include "crypto.h"

int main()
{
    CryptoLib crypt;

    //Test case provided
    string str = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736";
    cout << "DECODED: " << crypt.singleByteXOR(str) << endl;
    return 0;
}   

Decrypted message:

Key with the highest frequency: 'X'
Message: Cooking MC's like a pound of bacon

Note: This solution and the library named crypto.h was built using the C++ programming language. The source code for this solution can be found on Github.

Stay tuned for the next challenge!

The Cryptopals Crypto Challenges: Set 1 - Detect Single-Character XOR

Write a method that derives which string that has a length of 60 characters has been encrypted using Single-Byte XOR cipher.

This is the fourth challenge of Set 1 in The Cryptopals Crypto Challenges website. Previously, I spoke about these challenges and provided walkthroughs for the previous challenges, if you haven't read them, here are the links:

For this challenge, given a list of encrypted strings, you must derive which string (that has a length of 60 characters) is encrypted using Single-Byte XOR Cipher.

Similar to the previous post, this is more about breaking the Single-Byte XOR Cipher technique. Remember, you can solve this challenge only if you were able to solve the previous challenge because you'll have to tweak some of the previous code in this challenge.

How to detect Single-Byte XOR?

In the previous challenge, we're able to determine the key as we had one string but how do we do that with 300+ strings in a file except now that we also have to determine if the string is encrypted using Single-Byte XOR Cipher or not?

Here's comes the interesting part:

  1. Select the string that has the most english letters from the file
  2. Perform a Brute-force XOR on the string with the most english letters in which each character is XOR'd against every character from the ASCII table (256 characters)
  3. Pick the most english string after brute-forcing with each character
  4. Display the final result

Let's have a look at the code:

Implementation of the method(s):

//Return Character frequency of a string
map<char, int> CryptoLib::frequency_table(string str)
{
    map<char, int> m;
    map<char, int>::iterator it;

    for(int i=0; i<str.size(); i++)
    {
        char ch = str[i];
        it = m.find(ch);

        if(it == m.end())
        {
            m.insert(make_pair(ch,1));
        }
        else
        {
            it->second++;
        }
    }

    return m;
}

//Return integer with the highest frequency of alphabets
int CryptoLib::high_frequency_count(map<char,int>m)
{
    int count = 0;
    for(auto p: m)
    {
        if(isalpha(p.first))
        {
            // cout << p.first << ":" << p.second << " ";
            count += p.second;
        }
    }
    return count;
}

//Detect string with Single Byte XOR
string CryptoLib::detectSingleByteXOR(vector<int> maxV)
{
    string final = "";
    int maxCount = 0;

    /*
        2. Perform a Brute-force XOR on the string that has
        the most english letters in which each character is XOR'd against
        every character from the ASCII table (256 characters)
    */
    for(int i=0; i<256; i++)
    {
        string temp = "";
        unsigned char a = i;
        for(int j=0; j<maxV.size(); j++)
        {
            unsigned char b = maxV[j];
            unsigned char c = b ^ a;
            temp += tolower(c);
        }

        //3. Select the string that has the most english letters. again.
        int count = high_frequency_count(frequency_table(temp));
        if(count > maxCount)
        {
            maxCount = count;
            final = temp;
        }
    }

    //4. Display the most "english" text as the final result
    return final;
}

Final code:

//Cryptopals Set 1 Challenge 4
#include "crypto.h"

int main()
{
    CryptoLib crypt;

    ifstream infile;
    string str;
    int maxCount = 0;
    string maxString = "";
    vector<int> maxV;

    infile.open("enctext.txt");

    //if the file is not there
    if(!infile)
    {
        cout << "Unable to open the file";
        exit(1);
    }

    while(infile >> str)
    {
        //Only look for strings with 60 char length
        if(str.size() == 60)
        {
            str = crypt.add_spaces(crypt.con_hex_2_bin(str), 8);
            vector<int> v1 = crypt.con_bin_2_dec(str, 7.0);
            string newStr = crypt.con_dec_2_ascii(v1);

            //1. Select the string that has the most english letters
            int count = crypt.high_frequency_count(crypt.frequency_table(newStr));
            if(count > maxCount)
            {
                maxCount = count;
                maxString = newStr;
                maxV = v1;
            } 
        }
    }

    //2. Pass the list of decimals to the function (for now)
    cout << crypt.detectSingleByteXOR(maxV) << endl;
    return 0;
}

Decrypted message:

Message: Now that the party is jumping.

Note: This solution and the library named crypto.h was built using the C++ programming language. The source code for this solution can be found on Github.

Stay tuned for the next challenge!

The Cryptopals Crypto Challenges: Set 1 - Fixed XOR

Write a method that takes two strings of fixed equal length and produce their XOR combination.

This is the second challenge of Set 1 in The Cryptopals Crypto Challenges website. Previously, I spoke about these challenges and provided a walkthrough for the first challenge, if you haven't read them, here are the links:

For this challenge, you must write a method that takes two strings of fixed equal length and produce their XOR combination:

When you feed the following Hexadecimal string:

1c0111001f010100061a024b53535009181c

And perform an XOR operation against another Hexadecimal string:

686974207468652062756c6c277320657965

The method should return the following result:

746865206b696420646f6e277420706c6179

Like the first challenge, this is sort of a warmup and a simple challenge to tackle. Just to give you a heads up, every challenge that you solve in this set would all make sense, in the end, as the challenges will get tougher and much more interesting.

How do I solve this?

As I mentioned above, this problem is simple and pretty straightforward. In my previous post, I talked about Bitwise Manipulations and it's operators, I will be using the XOR (\^) operator, if you want to know more about it, check out my previous post. Also, I will reuse some of the functions that I had used in the first challenge. So let's dive in to the code:

Methods that are being reused:

//Hashmap that contain hex key and binary values
map<char, string> CryptoLib::gen_hex_table()
{
    map<char, string> map;

    map['0'] = "0000";
    map['1'] = "0001";
    map['2'] = "0010";
    map['3'] = "0011";
    map['4'] = "0100";
    map['5'] = "0101";
    map['6'] = "0110";
    map['7'] = "0111";
    map['8'] = "1000";
    map['9'] = "1001";
    map['a'] = "1010";
    map['b'] = "1011";
    map['c'] = "1100";
    map['d'] = "1101";
    map['e'] = "1110";
    map['f'] = "1111";

    return map;
}

//Convert hex to string
string CryptoLib::con_hex_2_bin(string hexStr)
{
    map<char,string> m = gen_hex_table();

    string newStr = "";
    for(int i=0; i<hexStr.size(); i++)
    {
        if(isdigit(hexStr[i]))
        {
            newStr += m.find(hexStr[i])->second;
        }
        else
        {
            newStr += m.find(hexStr[i])->second;
        }
        // newStr += m.find(hexStr[i])->second;
    }
    return newStr;
}

//Convert binary to decimal
vector<int> CryptoLib::con_bin_2_dec(string str, double power)
{
    vector<int> v;
    string newStr = "";
    istringstream iss(str);
    string x;

    while(iss >> x)
    {
        double p = power;
        double decimal = 0.0;

        for(int i=0; i<x.size(); i++)
        {
            if(x[i] == '1')
            {
                decimal += pow(2.0, p);
            }
            p--;
        }
        v.push_back((int)decimal);
    }
    return v;
}

//Add spaces between strings
string CryptoLib::add_spaces(string str, int spaces)
{
    string newStr = "";
    int count = 0;

    for(int i=0; i<str.size(); i++)
    {

        // newStr += str[i];
        if(count == spaces)
        {
            newStr += " ";
            i--;
            count = 0;
        }
        else
        {
            newStr += str[i];
            count++;
        }
    }

    return newStr;
}

//Convert ASCII to HEX
string CryptoLib::con_ascii_2_hex(string str)
{
    stringstream ss;
    for(int i=0; i<str.size(); i++)
    {
        ss << std::hex << (int)str[i];
    }
    return ss.str();
}

Implementation of the method:

//Fixed XOR implementation
string CryptoLib::fixedXOR(string str1, string str2)
{
    //Check if the length of both the strings are equal
    if(str1.size() != str2.size())
    {
        return "The strings are not of equal length.";
    }
    else
    {
        string newStr = "";

        //Step 1. convert hex to binary of 8 bits
        str1 = add_spaces(con_hex_2_bin(str1), 8);
        str2 = add_spaces(con_hex_2_bin(str2), 8);

        //Step 2. convert binary to decimal
        vector<int> v1 = con_bin_2_dec(str1, 7.0);
        vector<int> v2 = con_bin_2_dec(str2, 7.0);

        //Step 3. XOR the decimals of v1 with decimals of v2
        for(int i=0; i<v1.size(); i++)
        {
            //Get the char of the first string
            unsigned char a = v1[i];

            //Get the char of the second string
            unsigned char b = v2[i];

            //Perform XOR operation against each other
            unsigned char c = a ^ b;

            //Concatenate the string
            newStr += c;
        }

        //ASCII result: the kid don't play.

        //Final result - Convert the ASCII string to Hexadecimal
        return con_ascii_2_hex(newStr); 
    }
}

Final code:

//CryptoPals Set 1 Challenge 2
#include "crypto.h"

int main()
{
    CryptoLib crypt;

    //The test cases provided
    string str1 = "1c0111001f010100061a024b53535009181c";
    string str2 = "686974207468652062756c6c277320657965";

    cout << crypt.fixedXOR(str1, str2) << endl;
    return 0;
}

Note: This solution and the library named crypto.h was built using the C++ programming language. The source code for this solution can be found on Github.

Stay tuned for the next challenge!

Base64 Encoding / Decoding using Bitwise Manipulation in C++

An alternate solution to the previous post on how to encode/decode hexadecimals to Base64 and vice-versa using Bitwise Manipulation.

In the previous post, I provided the walkthrough for the first challenge of Set 1 in The Cryptopals Crypto Challenges website but then I realized that I didn't write a method that could decode the Base64 string back to it's original Hexadecimal format. So I went back to the website again and found an important rule that I should have not ignored, at the very beginning:

Cryptopals Rule:

Always operate on raw bytes, never on encoded strings. Only use Hex and Base64 for pretty-printing.

Although, the solution I had provided in the first one works, but there's no way that I could go back to displaying the original Hexadecimal string. So I went on Wikipedia and did some research on Base64 and I figured out that I should brush up my knowledge on Bitwise Manipulation as I never had a use for it until now.

In this post, which should be pretty much straightforward (and probably longer too), I will be talking about Bitwise Manipulation and it's operators and also provide an alternate walkthrough for the first challenge of The Cryptopals Crypto Challenges.

What is Bitwise Manipulation?

Bitwise Manipulation is a low-level, algorithmic technique used to manipulate bits or data that are shorter than a word. This technique is mostly used on embedded controls, data compression, encryption algorithms and error-detection.

As I mentioned above, most programmers don't get to use this technique a lot as most programming languages allows the programmer to work on abstractions directly instead of bits that represent those abstractions.

A program that implements bitwise manipulation, makes use of the following operators:

  • Bit Shifts (<< / >>)
  • AND (&)
  • OR (|)
  • NOT (!)
  • XOR (\^)

Bit Shift operations

Let's take a look at both the left << and right >> shift operators. So if you use either of them, you would be shifting x number of bits to left or right in a variable.

Let's say we have the number x = 4, and it's binary form is 00000100 and we wanted to shift by 4 bits to the left, we just have to call x << 4, the result would be 00100000, which means x = 64. Shifting to the left is the equivalent of multiplication by the power of n because 4x2^4^ = 64. Similarly, shifting to the right is the equivalent of division by the power of n because 4 / 2^4^ = 4 and it's binary form would be 00000100.

AND, OR and NOT operations

The bitwise operator AND is useful, when you want to check a bit is on or off i.e. 0 or 1. Whereas for the bitwise operator OR is the exact opposite, if either bit is on, then the result will be 1, else it will be 0. Finally, the bitwise operator NOT is used for inverting the bits in a binary, for example, if you had a binary string of 00101000, you'd get 11010111, it is used best when you want to turn off a bit combined with the AND operator.

XOR operator

Relax, this ain't scary, this is also known as Exclusive-OR. This operator works when both bits that are compared are either 0 or 1, then the result will be 0, else it will be 1. So if you perform an XOR on 01001000 and 01000100, the result will be 00001100.

I hope that by now, you must have understood the basic concept of Bitwise Manipulation, if not, then spend some time reading about it before scrolling down to the next topic i.e. on how it's applied to encode and decode Hexadecimal strings to Base64 strings and vice-versa.

Base64 Encoding

Before you get started, please keep a couple of things in your mind:

  • Each Hexadecimal character has 4 bits (Base 16)
  • Each Base64 character has 6 bits (Base 32)
  • We will be using the standard MIME-Base64 Encoding, thus we will have to use '+' and '/' characters as well

Now that we have the facts, doing a simple math states that every 3 Hexadecimal characters is equal to 2 Base64 characters, since the least common multiple between 4 and 6 is 12. In order to do this, we are going to make use of our Bitwise Operators, let's have a look at the method:

//Base64 Encoder
string CryptoLib::b64_encode(string str)
{
    string newStr = "";
    string ref = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    //Number of bytes per 12 bits
    int bytes = str.size() / 3;
    int padding = str.size() % 3;

    //Padding must be either 0 or 1
    if(padding > 1)
    {
        return newStr;
    }

    //Number of characters to be encoded is 3

    int count = bytes * 3;

    unsigned long long h = 0;

    int i = 0;
    for(i=0; i<count; i+=3) //iterate every 3 chars
    {
        //Get every 3 chars
        char a[2] = {str[i], 0};
        char b[2] = {str[i+1], 0};
        char c[2] = {str[i+2], 0};

        //Now, convert each hex character (base 16) to it's equivalent decimal number
        //and merge them into one variable
        h = strtoull(a, nullptr, 16) << 8; //shift left by 8 bits
        h |= strtoull(b, nullptr, 16) << 4; //shift left by 4 bits
        h |= strtoull(c, nullptr, 16); //no shift required only the first 2 characters need

        //HEX: 0x3F -> DEC: 63 -> ASCII: ?

        newStr += ref[0x3F & (h >> 6)]; //first b64 char; shift to right by 6 bits
        newStr += ref[0x3F & h]; //second b64 char
    }

    //if padding is required
    //Follows the same pattern as the above.
    if(padding == 1)
    {
        char a[2] = {str[i], 0};
        h = strtoull(a, nullptr, 16) << 8; // shift left by 8 bits
        newStr += ref[0x3F & (h >> 6)];
        newStr += '='; //add this towards the end of the encoded string
    }

    return newStr;
}

If you're wondering on how to convert an ASCII string, all you have to do is convert the ASCII string to a Hexadecimal string and then use this method to give you the Base64 encoded string.

Base64 Decoding

What if you wanted to get back to the original string? Well, that's what we are going to do next. Unlike the previous post, you might have noticed that I didn't use any Hashmaps for encoding the Base64 characters, I wanted to try a different approach and also thought of increasing speed and efficiency and of course, keeping it simple.

Let's take a look at the method:

//Base64 Decoder
string CryptoLib::b64_decode(string str)
{
    string newStr = "";
    string ref = "0123456789abcdef";

    //Check if this is a valid b64 string
    if(str.size() % 2 != 0)
    {
        return newStr;
    }

    //Number of bytes for hexadecimals
    int bytes = str.size() / 2;
    int count = bytes build.sh content convert.sh make_entry.py output ssg.py ssg.pyc templates transfer.sh venv 2;

    unsigned long long h = 0;
    for(int i=0; i<count; i+=2) //iterate every 2 chars
    {
        for(int j=0; j<2; j++)
        {
            h <<= 6; //shift 6 bits to the left

            //Check if the value is in the range of A-Z
            if(str[i+j] >= 0x41 && str[i+j] <= 0x5a)
            {
                h |= str[i+j] - 0x41;
            }
            //Check if the value is in the range of a-z
            else if(str[i+j] >= 0x61 && str[i+j] <= 0x7a)
            {
                h |= str[i+j] - 0x47;
            }
            //Check if the value is in the range of 0-9
            else if(str[i+j] >= 0x30 && str[i+j] <= 0x39)
            {
                h |= str[i+j] + 0x04;
            }
            //Check if the value is a '+'
            else if(str[i+j] == 0x2b)
            {
                h |= 0x3e;
            }
            //Check if the value is a '/'
            else if(str[i+j] == 0x2f)
            {
                h |= 0x3f;
            }
            //Check if the value is a '='
            else if(str[i+j] == 0x3d)
            {
                if(count - (i+j) == 1)
                {
                    newStr += ref[0xf & (h >> 8)];
                }
            }
        }
        //Shift to the right by 8 bits
        newStr += ref[0xf & (h >> 8)];
        //Shift to the right by 4 bits
        newStr += ref[0xf & (h >> 4)];
        newStr += ref[0xf & h];
    }

    return newStr;
}

In the final code, I just converted an ASCII string to Base64 string, let's have a look at it:

Methods to convert ASCII string to Hexadecimal string and vice-versa:

//Convert ASCII to HEX
string CryptoLib::con_ascii_2_hex(string str)
{
    stringstream ss;
    for(int i=0; i<str.size(); i++)
    {
        ss << std::hex << (int)str[i];
    }
    return ss.str();
}

//Convert HEX to ASCII
string CryptoLib::con_hex_2_ascii(string str)
{
    string newStr = "";
    str = add_spaces(con_hex_2_bin(str), 8);
    vector v = con_bin_2_dec(str, 7.0);

    for(int i=0; i<v.size(); i++)
    {
        newStr += (char)v[i];
    }
    return newStr;
}

Final Code:

//CryptoPals Set 1 Challenge 1
#include "crypto.h"

int main()
{
    CryptoLib crypt;

    string str = crypt.con_ascii_2_hex("Hello World");
    string enc = crypt.b64_encode(str); 
    cout << "ENCODED: " << enc << endl;

    string dec = crypt.con_hex_2_ascii(crypt.b64_decode(enc));
    cout << "DECODED: " << dec << endl;
    return 0;
}

Note: This solution and the library named crypto.h was built using the C++ programming language. The source code for this solution can be found on Github.

Hope you guys liked reading this article!

Until next time, then!

The Cryptopals Crypto Challenges: Set 1 - Convert Hex to Base64

Convert Hexadecimal strings to encoded Base64 strings.

This is the first challenge of Set 1 in The Cryptopals Crypto Challenges website. If you want to know more about these challenges, look at my previous post.

For this challenge, you need to be able to convert Hexadecimal strings to encoded Base64 strings:

The string:

49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d

Should produce:

SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t

Not only is this challenge just a warmup but it is also designed to make you feel comfortable in dealing with raw bytes as Base64 is used to encode binary information and Hexadecimal is used to view the raw bytes.

How to convert from Hexadecimal to Base64?

Well, it's simpler than you think! You will have to go through the following steps:

  1. Convert hexadecimal string to binary string
  2. Split the binary string into 4 pieces of 6 bits each
  3. Convert the binary string to decimal
  4. Compare each decimal against each character in a reference string of 64 characters

Convert hexadecimal string to binary string

Before converting to binary, you should compare each character against a hashmap table of hardcoded hexadecimal keys and binary values.

//Hashmap that contain hex key and binary values
map<char, string> CryptoLib::gen_hex_table()
{
    map<char, string> map;

    map['0'] = "0000";
    map['1'] = "0001";
    map['2'] = "0010";
    map['3'] = "0011";
    map['4'] = "0100";
    map['5'] = "0101";
    map['6'] = "0110";
    map['7'] = "0111";
    map['8'] = "1000";
    map['9'] = "1001";
    map['a'] = "1010";
    map['b'] = "1011";
    map['c'] = "1100";
    map['d'] = "1101";
    map['e'] = "1110";
    map['f'] = "1111";

    return map;
}

//Convert hex to string
string CryptoLib::con_hex_2_bin(string hexStr)
{
    map<char,string> m = gen_hex_table();

    string newStr = "";
    for(int i=0; i <hexStr.size(); i++)
    {
        if(isdigit(hexStr[i]))
        {
            newStr += m.find(hexStr[i])->second;
        }
        else
        {
            newStr += m.find(hexStr[i])->second;
        }
        // newStr += m.find(hexStr[i])->second;
    }
    return newStr;
}

Split the binary string into 4 pieces of 6 bits each

Base64 represents data in the form of ASCII format that follows a Radix-64 representation. Each character is picked from a set of 64 characters, which means that I'll only need 6 bits represent each character because 26 = 64 characters.

//Add spaces between strings
string CryptoLib::add_spaces(string str, int spaces)
{
    string newStr = "";
    int count = 0;

    for(int i=0; i<str.size(); i++)
    {

        // newStr += str[i];
        if(count == spaces)
        {
            newStr += " ";
            i--;
            count = 0;
        }
        else
        {
            newStr += str[i];
            count++;
        }
    }

    return newStr;
}

Convert the binary string to decimal

Before converting, you should know that a decimal number is equal to the sum of binary digits (d~n~) times their power of 2 (2n).

Let's say you have a binary string of 111001, it's decimal would be 1x25 + 1x24 + 1x23 + 0x22 + 0x21 + 1x20 = 57

//Convert binary to decimal
vector<int> CryptoLib::con_bin_2_dec(string str, double power)
{
    vector<int> v;
    string newStr = "";
    istringstream iss(str);
    string x;

    while(iss >> x)
    {
        double p = power;
        double decimal = 0.0;

        for(int i=0; i<x.size(); i++)
        {
            if(x[i] == '1')
            {
                decimal += pow(2.0, p);
            }
            p--;
        }
        v.push_back((int)decimal);
    }
    return v;
}

Compare each decimal against each character in a reference string of 64 characters

At this stage, all you have to do is find and concatenate each character (using the reference string) based on each decimal and return your encoded Base64 string as the final output.

//Convert HEX to Base 64
string CryptoLib::con_hex_2_b64(string str)
{
    string b64 = "";
    string ref = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    string newStr = add_spaces(con_hex_2_bin(str), 6);

    vector<int> v = con_bin_2_dec(newStr, 5.0);

    for(int i=0; i<v.size(); i++)
    {
        b64 += ref[v[i]];
    }

    return b64;
}

Here's the final section of the code:

//CryptoPals Set 1 Challenge 1
#include "crypto.h"

int main()
{
    CryptoLib crypt;

    //Test case provided from the site
    string str = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
    cout << crypt.con_hex_2_b64(str) << endl;
    return 0;
}

Note: This solution and the library named crypto.h was built using the C++ programming language. The source code for this solution can be found on Github.

Stay tuned for the next challenge.

The Cryptopals Crypto Challenges

Came across an interesting website that hosts cryptographic challenges based on real world cryptography.

Last week, I came across an interesting website named The Cryptopals Crypto Challenges (also known as The Matasano Crypto Challenges) that hosts cryptographic challenges based on real-world cryptography that makes use of various ciphers and secure protocols.

What is it about?

These challenges were developed by a security team called NCC Security, which is developed as a tool for teaching Cryptography.

Currently, there are eight sets of problems in which each set gets progressively harder as you solve them. As I'm writing this post, I'm solving the first set of problems, these problems are designed in such a way that you get to build own cryptographic functions/utilities and exploit them. Most importantly, not only do these challenges give you an overview on how to build secure cryptographic systems but also you'll get an understanding on how they're being attacked.

In the first few challenges, I was exposed to some crypto math but these concepts weren't that hard as it was more practical and gentler:

Also, I found myself using different techniques to solve these challenges such as:

  • String manipulation
  • Lookup tables / Hashmaps
  • Conversion of string to integer and vice-versa
  • Bitwise operators

Like I had mentioned above, this is also designed as a tool to learn cryptography, which means you don't really need to have prior knowledge of cryptography and security. It's all about doing your own research on various algorithms, implementing the solution and then breaking your own solution.

Why do I want to do this?

I found it as a good opportunity to sharpen my C++ programming skills and learn more about cryptographical theory and it's applications. If you're curious and passionate enough to solve puzzles, this is your chance!

What's next?

I will be posting walkthroughs (on how I solved every problem in each set) on my blog and also provide solutions to those problems on my GitHub repository.

Stay tuned!

New feature: Share your reaction

Rolled out a new feature to collect emotional intelligence, which would help me to make better blog posts in the future.

Last night, I was thinking on how to improve my blog posts and post better articles. My head went through questions like:

  • What do people feel when they read my articles?
  • Do they find it interesting?
  • Is it boring?
  • Is it likeable?

But, in order to do that, I'll require some simple analytics on how people react to my articles on my blog. Taking inspiration from web applications like Facebook, Instagram, Twitter and Medium, I decided to build a small feature named "Share your reaction", from scratch, that would contain six different emotions.

The six different emotions used in this new feature

From today onwards, you can start reacting to my blog posts by clicking the "React!" button (which can be found below every article), select an emotion and help me improve and post better articles in my blog in the future.

In case, you're wondering, the data that is collected is completely anonymous as I'm not collecting any IP address or any of your private and sensitive information.

Hope you guys like the new feature!

Leave me alone, I just want to write code!

Do you think that programmers don't have to interact with people? This article will give you an insight.

The title of this post might be "clickbait" but there are some software developers who believe that they are supposed to just write code and not interact with people.

There are a lot of books that deal with sort of topic but in today's article, I will be borrowing heavily from my career experience and a favorite book of mine named Soft Skills: The Software Developer's Life Manual to talk about how important it is for a software developer to interact with people.

I'm a software developer, why should I interact with people?

Earlier, I used to be under the impression that software developers are supposed to be glued in to their screens like a Hollywood hacker and just write code. But hey, I'm sure that I'm not the only one who had been thinking in that direction.

In fact, a portion of our time is being spent on interacting with people because not only are we writing code-logic for the computer to understand but it is mainly written for humans to aid in solving their daily problems. If that's not the scenario that means we'd all be talking to computers in binary form or machine language.

As time passed by, I learnt that in order to become a better software developer, you really should know how to deal with people (but I still like being glued to my two HD monitors!).

My current workspace

Think about it, where do the project requirements come from? Is it from computers? No, it's from people. Can your code send you an email to fix the new bug? No, people can.

A few examples:

  • Sitting down on weekly meetings with your boss or clients
  • Communicating with team members about the problem that you're working on and strategizing a way to solve that problem

If you still have the same mindset, you'd better rethink on that again because just like any other profession, you will have to interact with people.

How do I deal with people?

Like I had mentioned, at the very beginning of this article, there are a lot of books based on this topic but I'll try to keep it short and talk about a few points that might give you an idea on how to deal with people:

Everybody needs to feel essential

Let's face it, everyone loves to take the spotlight and would like to make everyone listen to them but there's nothing wrong about it as it's one of humanity's most desperate and deepest desires that help motivate us to achieve some of our greatest goals in our career, life and society.

Likewise, you're not the only one who has got amazing ideas, every individual does. It's very easy for you to discard one's idea, so that you can present yours instead but when you make this error, it might backfire on you i.e. you'll find others not listening to your ideas because you didn't value theirs in the first place.

So, always make it a point, if you want people to accept your ideas and think it's valuable, you'll also have to do the same thing, in return, for everyone else.

Try not to criticize

Back in my university days, when I was working on my graduation project, I used to face a lot of criticism from a fellow Computer Science Professor, who thought negativity is an effective way to motivate an individual and responded to all faults with harsh criticism but I feel that's a wrong method to motivate an individual.

If you want to inspire or motivate people to do their best, you should encourage them with positivity than harsh negativity, this could help boost their self esteem and performance as a software developer.

On the contrary, a little bit of critical feedback to help improve one's problem solving skills is totally fine.

Consider what the other person needs

During my career, I learnt that I should think about what's important to the other individual and what they want than what's important to me and what I want.

Whenever you enter in a conversation with your team member or boss, make sure you see things from their perspective. Try to understand their requirements and then when it's your turn, phrase the dialog in ways that your implementation matches their requirement.

Having shifted your mindset to this direction, you'll be making the person feel more essential and be more open to their ideas. In return, you can use leverage it in ways where people would deal with you in a favorable manner and value your ideas and skillset.

Stay away from arguments

One of the most common things that most software developers do is that they falsely believe that pure solid reasoning is enough to make another person accept your style of thinking because they assume that the latter might think about things from a logical perspective. Believe me, even I did this when talking to a lot of people.

But then, we all have this sort of nature in which we tend to pride ourselves on our own intellectual prowess but a slight difference in opinion, it hits us right in our ego and opens up a potential door for arguments.

For this reason, at all costs, it's best to avoid arguments of any sorts because talking in terms of logic and pure reasoning would do little to convince a screaming toddler. Whenever you reach a point of disagreement on how things should be done, it is best to determine whether or not that particular direction is the right way to reach the top of the hill and especially, if it involves another individual, weigh the pros and cons of a decision.

I'd like to share an interesting quote:

"I have to come to the conclusion that there is only one way under high heaven to get the best of an argument — and that is to avoid it. Avoid it as you would avoid rattlesnakes and earthquakes." - Dale Carnegie, How to Win Friends and Influence People (1936)

Probably, it wouldn't hurt much if you try to look for an opportunity to give up and admit that you're wrong on a small matter but, perhaps, it could be a big deal to the other person, which will help you build a good image and respect with them and can be leveraged in the future.

In conclusion

Being a good software developer isn't about being really skilled at coding (although, it's an imperative skillset!) but it's also about having good soft skills. If you ever thought that you have never worked on your soft skills, then this is time right for you to begin as you'll find your career much more enjoyable and accumulate a lot of skills and benefits in the future that will help you down the lane.

Hope you liked reading this article!

Au Revoir!