2

I am writing two functions that encrypt and decrypt messages using an affine cipher. For some reason, my encryption and decryption are off by a few letters. I feel the issue is related to the ASCII numbers not matching the a=0, z=25 format. Could someone please help me figure out what's going on?

Cleopatra should encrypt to whkcjilxi,

MZDVEZC should decrypt to anthony

But instead, I'm getting

Cleopatra = ZKNFMLOAL and

MZDVEZC = NAGUBAL.

main function:

int main() {
    plaintext = "cleopatra";
    ciphertext = affine_encrypt(plaintext, 7, 8);

    cout << "4. Encryption of the plaintext: " << plaintext << endl;
    cout << "   Key: 7x+8" << endl;
    cout << "   Ciphertext: " << ciphertext;
    cout << endl << endl;

    ciphertext = "MZDVEZC";
    plaintext = affine_decrypt(ciphertext, 5, 12);

    cout << "5. Decryption of the ciphertext: " << ciphertext << endl;
    cout << "   Key: 5x+12" << endl;
    cout << "   Inverse of 5 is " << affineInverse(5) << endl;
    cout << "   Plaintext: " << plaintext << endl << endl;
    return 0;
}
string affine_decrypt(string message, int a, int b)
{
    string dtxt;
    for (int i = 0; i < message.length(); i++)
    {
        dtxt = dtxt + (char)(((affineInverse(a)*(message[i] - b) % 26)) + 65);
    }

    return dtxt;
}

string affine_encrypt(string message, int a, int b)
{
    string ctext = "";

    for (int i = 0; i < message.length(); i++)
    {
        ctext = ctext + (char)((((a * message[i]) + b) % 26) + 65);
    }

    return ctext;
}

int affineInverse(int input)
{
    int check = 0;

    for (int i = 0; i < 26; i++)
    {
        check = (input * i) % 26;

        if (check == 1)
        {
            check = i;
        }
    }

    return check;
}
kelalaka
  • 5,064
  • 5
  • 27
  • 44
namlay557
  • 25
  • 1
  • 5

1 Answers1

1

You forgot to subtract a from the characters before applying the affine encryption

ctext = ctext + (char)((((a * ( message[i] - 'a' ) ) + b) % 26) + 65);

If you are using capital letters, you should use 'A'. In general, it is a good idea to convert all of them into upper or lower case. Usually in classical Cryptography upper case is preferred.

Checking the decryption is left yo you.

update: The traps in decryption:

You forgot to substruct 'A' from the message[i]

When you substruct message[i] - 'A' - 26 the result can be negative. You have to make sure that it is positive.

This inline function

inline int positive_modulo(int i, int n) {
    return (i % n + n) % n;
}

from this answer helps you to get always a positive result from modulus.

Also, from the programmatical way, first try to decrypt what you encrypt.

kelalaka
  • 5,064
  • 5
  • 27
  • 44
  • Great answer, but that 'left to you' reminds me of my math textbooks. We leave proving to you as an exercise. – Sean Brookins Oct 01 '19 at 18:10
  • @SeanBrookins Well, kind of. It is a good idea to leave some of the codings for the beginners. – kelalaka Oct 01 '19 at 18:16
  • I've actually been stuck trying to figure out the error in my decryption code since this post, it only seems to be off on certain letters. Any chance I could get some help with figuring it out? – namlay557 Oct 01 '19 at 18:23