4

Vigenere ciphers are supposedly easy to use (well, to some extent), but when converting it directly into program code, that's a whole other story. Apparently.

Here's the Vigenere Square: Vigenere Square from Wikipedia

Let's say I have a method that can encrypt text using the Vigenere Square cipher, while still maintaining the spaces and special characters (or most of them).

static string EncryptedText(string plaintext, string keyword)
{
    string tempStore = "";
    string KeyToUse = ExpandKey(RemoveAllNonAlpha(plaintext), keyword);
    string[] tempList;
    int iSelector = 0;

    for (int ii = 0; ii < RemoveAllNonAlpha(plaintext).Length; ii++)
    {
        tempList = GetNewAlphaList(KeyToUse[ii].ToString());
        if (RemoveAllNonAlpha(plaintext)[ii].ToString() != " ")
        {
            iSelector = NeverOver26(GetNumericFromLetter(RemoveAllNonAlpha(plaintext)[ii].ToString())) - 1;

            tempStore += tempList[iSelector].ToLower();
        }
        else
        {
            tempStore += " ";
        }
    }

    return ReplaceAllNonAlpha(tempStore, plaintext);
}

If we assume that for the above, the following functions are as so...

string ExpandKey(string input) => Lengthen the key until it matches the plaintext.

string RemoveAllNonAlpha(string input) => Basically remove anything that is not an alphabet. Uses Regex Replace.

int GetNumericFromLetter(string char) => Just converts a letter to a number, with A = 1, and Z = 26. Adapted version of this accepted answer.

string ReplaceAllNonAlpha(string processed, string original) => Basically it just checks the original string, and then replaces all the non alphabetical characters. It's mainly using a regex string to check if a character is not an alphabet.

int NeverOver26(int input) => Basically it just subtracts 26 from the value whenever it goes over 26.

string[] GetNewAlphaList(string char) => Generates a column or row of the vigenere cipher to lookup from, with the letter passed in being the first letter in the array. For example, if the passed letter is "L", then it returns { "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" }.

Now, the above snippet of code has been found to be working perfectly, and could be said to be literally translated from the way humans would use the Vigenere Square table.

However, the decryption method doesn't seem to like the approach, though:

static string DecryptedText(string ciphertext, string keyword)
{
    //Broken, non deciphering
    string tempStore = "";
    string KeyToUse = ExpandKey(RemoveAllNonAlpha(ciphertext), keyword);
    string[] tempList;

    for (int ii = 0; ii < RemoveAllNonAlpha(ciphertext).Length; ii++)
    {
        tempList = GetNewAlphaList(RemoveAllNonAlpha(ciphertext)[ii].ToString());

        for (int iii = 0; iii < tempList.Length; iii++)
        {
            if (tempList[iii].ToString().ToLower() == KeyToUse[ii].ToString().ToLower())
            {
                tempStore+= GetAlphaFromNumber(iii).ToLower();
                break;
            }
        }
    }

    return ReplaceAllNonAlpha(tempStore, ciphertext);
}

In the (not working as expected) decryption method, we can see that it uses most of the same functions as the encryption method, with the addition of...

string GetAlphaFromNumber(int input) => Does the exact opposite of GetNumericFromLetter() Adapted version of this accepted answer.

It has been determined that the issue is within the second for-loop of the decryption method itself. It is a sort of primitive lookup process, where it just looks within a string array that corresponds to a row/column of the Vigenere Square table.

Is there something wrong with the logic, or just something wrong with the code itself? Pseudocode is okay, I do admit I'm not quite sure how to translate the human method of decoding using the Vigenere Square table into pseudocode (then finally into the language of choice I am using)

Please note, that I am aware of these questions, and I am not looking for how to do it, but rather, where I went wrong:

I guess my question is very similar to this question, though I doubt the issue is the same:


Testing Encryption...

Input: ATTACK ON DAWN. LOL

Keyword: LEMON

Output: lxfopv ef rnhr. xcy


Testing Decryption...

Input: lxfopv ef rnhr. xcy

Keyword: LEMON

Output: ahhayq ah xaen. pmp

Results checked using: http://planetcalc.com/2468/

Community
  • 1
  • 1
Kaitlyn
  • 789
  • 10
  • 27
  • 1
    tbh this is where you set breakpoints and step through the code to see what is happening to find where you went wrong. Just remember, for the decryption part you need to **subtract** the key value, not add it. – user1666620 Nov 19 '15 at 15:23
  • I'm **not exactly adding or subtracting. It's all more of a lookup process.** The encryption, for example, looks up the column that matches the letter of the plaintext it is currently processing, then uses the the letter of the keyword at the same position to locate it's ciphertext version. I'm trying to do the same for the decryption method. – Kaitlyn Nov 19 '15 at 15:25
  • well, that's probably where the error is. – user1666620 Nov 19 '15 at 15:26
  • I know there is most likely an error in the lookup process. In fact, the decryption method used to be exactly the same as the encryption method until I noticed the gaping flaw. It seems to get the first letter, correct, but then it gets the rest wrong for some reason. Though I am confused myself on how to reverse the process properly. – Kaitlyn Nov 19 '15 at 15:30
  • can't help you unless you show where the lookup is done. tbh i'm not sure it's getting the first letter "correct" through good design, or simply because you lucked out with the key. Again, set breakponts and debug the code. – user1666620 Nov 19 '15 at 15:30
  • The lookup is done in the decryption method itself. The GetNewAlphaList, for instance, just returns { "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" } for the first letter of the input for the decryption test. The ExpandKey will return LEMONLEMONLEMON for use in the decryption. The GetNewAlphaList is returning the correct rows, though. (I checked already with the breakpoints prior to asking the question, actually) – Kaitlyn Nov 19 '15 at 15:33
  • I don't think the code you've provided is sufficient to solve the problem. You need to narrow down where the error is coming from. Check your inputs of each method, ensure they are expected. Check the outputs of each method and make sure they are what you expect them to be. – user1666620 Nov 19 '15 at 15:53
  • What if I said that the code is meant to be looked at as a form of pseudocode? (Because that's how I kind of plan things) I know the beginning part of the pseudocode (Getting the correct row) is not wrong, at the very least. Though if you are unable to assist with pseudocode, I would prefer someone's else opinions in that case, no offense though. – Kaitlyn Nov 19 '15 at 16:05
  • i don't understand. you have code that produces an error, but you don't want to show that code, only pseudocode? – user1666620 Nov 19 '15 at 16:08
  • The whole code looks a bit long. And I basically did narrow down the issue, it's something to do within the second for-loop of the decryption method. The functions are clearly explained as to what they do. – Kaitlyn Nov 19 '15 at 16:10
  • 1
    probably my last comment on this - but if your functions actually did what you think they are meant to do, then I don't think you would have a problem. I recommend you post the code for your `GetAlphaFromNumber` method. Best of luck. – user1666620 Nov 19 '15 at 16:15
  • @user1666620 The code for GetAlphaFromNumber (and GetNumericFromAlpha) is just a renamed function from http://stackoverflow.com/questions/1951517/convert-a-to-1-b-to-2-z-to-26-and-then-aa-to-27-ab-to-28-column-indexes-to (the accepted answer) – Kaitlyn Nov 19 '15 at 16:17
  • @user1666620 nvm, I just found out that apparently I was really still using the wrong method of looking up the value. I was looking for "X" on the left side, then looking along with the key, and taking the value at the top of the column for the plaintext. – Kaitlyn Nov 19 '15 at 17:22
  • @user1666620 I doubt you will even be reading this now, but I apologize if I seemed like I was rude and unwilling to provide code. I was just merely trying to follow MVCE, for a change. – Kaitlyn Nov 19 '15 at 17:41

1 Answers1

2

It turns out that I was using the wrong method of looking up the table in the first place. There was nothing wrong with the coding of my program, as it worked as intended. It was just the way it was looking up the values, or in other words, the logic that was wrong. Below is the amended code for the decryption method, which now works fine:

internal static string DecryptedText(string ciphertext, string keyword)
{
    string tempStore = "";
    string KeyToUse = ExpandKey(RemoveAllNonAlpha(ciphertext), keyword);
    string[] tempList;
    int iSelector = 0;

    for (int ii = 0; ii < RemoveAllNonAlpha(ciphertext).Length; ii++)
    {
        tempList = GetNewAlphaList(KeyToUse[ii].ToString());

        for (int iii = 0; iii < tempList.Length; iii++)
        {
            ////seperated the two to verify they were not returning the wrong values
            //string FromList = tempList[iii].ToString().ToLower();
            //string FromCipher = RemoveAllNonAlpha(ciphertext)[ii].ToString().ToLower();

            if (tempList[iii].ToString().ToLower() ==  RemoveAllNonAlpha(ciphertext)[ii].ToString().ToLower())//if (FromList == FromCipher)
            {
                tempStore += GetAlphaFromNumber(iii).ToLower();
                break;
            }
        }
    }
        
    return ReplaceAllNonAlpha(tempStore, ciphertext);
}

Testing Encryption...

Input: this is just a simple test. complete with punctuations galore, wohoo!

Keyword: stackoverflowisthebest

Output: laiu sg eyjy l geuhel xfwl. vgfpnohz azys dqvumbeumggk zanyfz, afmzc!


Testing Decryption...

Input: laiu sg eyjy l geuhel xfwl. vgfpnohz azys dqvumbeumggk zanyfz, afmzc!

Keyword: stackoverflowisthebest

Output: this is just a simple test. complete with punctuations galore, wohoo!


Guess it's time for me to try to find a way for it to preserve the capitalization as well after conversion.

Community
  • 1
  • 1
Kaitlyn
  • 789
  • 10
  • 27
  • 1
    In terms of security, conserving punctuation and capitalisation gives the attacker more information to work with, e.g., a lone capital letter would probably translate to "I", while a lowercase letter would translate to "a" and the next word would start with a consonant. If you want to preserve capitalisation, etc, consider using an extended alphabet, which can include things like lowercase letters, uppercase letters, numbers and punctuation. – Reti43 Nov 26 '15 at 01:36