Calling all reverse engineers

Hi everybody, I wrote a encryption algorithm (uses a single password to encrypt and decrypt) and would really like to test how it stands up to people who knows how to reverse engineer an encrypted string. Any suggestions and comments is welcome :) Thank you very much!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * This algorith encrypts a string explicitly using the password provided.
 * It shifts the original letter by a value determined beforehand (nPwordShifts)
 *
 * The algorithm to calculate the shifts:
 *
 * (nPword total calculated in function nCalculatePwordTotal)
 *
 * Shift = ( floor( nPwordTotal / int(nCurrentLetter) ) ) + ( nPwordTotal % int(nCurrenLetter) );
 *
 * At encryption the shift is added to the current letter and at decryption the shift is deducted from the current letter.
 *
 * The '~' (tilde) character is used when the shift is greater than 186 (186 will cause the letter to be in the extended ASCII range
 * or if the shift is bigger not even in the ASCII range). For each '~' (tilde) character 93 will be deducted from the shift value.
 *
 */

#include <string>

int nCalculatePwordTotal(std::string cPassword)
{
    int nPwordTotal=0;
    int nLength=cPassword.length();
    for (int nIndex=0; nIndex<nLength; nIndex++)//This forces the password letter to be in the correct order
    {
        if (nIndex%2==0)
        {
            nPwordTotal+=int(cPassword[nIndex]);
        }
        else
        {
            nPwordTotal+= 2 * int(cPassword[nIndex]);
        }
    }
    return nPwordTotal;
}

int* CalculatnPasswordShifts(int nLength, std::string cPassword)
{
    int nPwordTotal=nCalculatePwordTotal(cPassword);
    int* nPwordShifts = new int[nLength];
    for (int nIndex=0; nIndex<nLength; nIndex++)
    {
        nPwordShifts[nIndex] = int(nPwordTotal / int(cPassword[nIndex])); //All letters of password need to be correct
        nPwordShifts[nIndex] += nPwordTotal % int(cPassword[nIndex]);
    }
    return nPwordShifts;
}

std::string Encryption(std::string cOriginal, std::string cPassword)
{
    int nLength=cPassword.length();
    int* nPwordShifts = CalculatnPasswordShifts(nLength, cPassword);
    int nCurrentP=nLength; //Current letter in pword used
    nCurrentP--;
    nLength = cOriginal.length();
    std::string cChanged; //Will store changed std::string
    for (int nIndex=0; nIndex < nLength; nIndex++)
    {
        int nASCII = int(cOriginal[nIndex]);
        nASCII += nPwordShifts[nCurrentP];
        if (nASCII < 126)
        {
            cChanged+=char(nASCII);
        }
        else
        {
            nASCII-=93;
            while (nASCII > 125)
            {
                cChanged+='~'; // Prevents overflow
                nASCII -= 93;
            }
            cChanged+=char(nASCII);
        }
        if (nCurrentP == 0)
        {
            nCurrentP = cPassword.length();
            nCurrentP--;
        }
        else
        {
            nCurrentP--;
        }
    }
    delete[] nPwordShifts;
    return cChanged;
}

std::string Decryption(std::string cOriginal, std::string cPassword)
{
    int nLength=cPassword.length();
    int *nPwordShifts = CalculatnPasswordShifts(nLength, cPassword);
    int nCurrentP=nLength; //Current letter in pword used
    nCurrentP--;
    nLength = cOriginal.length();
    std::string cChanged; //Will store changed std::string
    for (int nIndex=0; nIndex<nLength; nIndex++)
    {
        int nTemp=0;
        while (cOriginal[nIndex] == '~')
        {
            nIndex++;
            nTemp += 93;
        }
        int nASCII = int(cOriginal[nIndex]);
        nASCII -= nPwordShifts[nCurrentP];
        if (nASCII > 31)
        {
            cChanged+=char(nASCII);
        }
        else
        {
            nASCII+= 93;
            nASCII+= nTemp;
            cChanged+=char(nASCII);
        }
        if (nCurrentP == 0)
        {
            nCurrentP = cPassword.length();
            nCurrentP--;
        }
        else
        {
            nCurrentP--;
        }
    }
    delete[] nPwordShifts;
    return cChanged;
}


EDIT: Updated the script
Last edited on
Reading code with no description of how the algorithm works and with poor variable names is a real pain.

Some notes:
Your functions are long, I see a lot of duplicated code between the function. This is a sign that you need to refactor and make new functions to handle this duplicated code. This will also make your code easier to read and follow.

Memory leaks. You have them. Deal with them, or don't make explicit calls to new.
Can't really do much (if anything) without seeing example of a string that was encrypted using your code
Thanks for the suggestions, I updated the script where I removed duplicate code, added description of the algorithm and also fixed the memory leaks. Also here is a encrypted string :

}Xl&|%/J;b+v}{/X4U+}v{"a3e~'+2/Xa>Ul$}+/E<`}ztxpX1mt,?

Decrypted string: "Thanks for all the help guys! I really appreciate it."
Password used: "CPPForum"

Again, thanks!
The algorithm is non-bijective.
Example:
1
2
3
std::string s = "~",
	p = "0";
std::cout <<(s == Decryption(Encryption(s, p), p))<<std::endl;
I should add the "~" character is the only character in the printable part of the ASCII table (excluding the extended ASCII table) that is doesn't support as it uses the "~" character as a marker (explained in the top comment section of the script). Running the script that helios provided with anything else except "~" will output 1, meaning it is functioning correctly. Also only using one character as the password will only shift all the letters by one making the encryption very weak.
Last edited on
Bump! Any suggestions guys?
If I should add or change anything, please tell me... I'm really eager to get this tested!
Topic archived. No new replies allowed.