How about generating many logins from a password?
To start, algorithm 1 looks like the weakest link. Algorithm 2 is a one directional hash function and there's no way you can extract the characters by only knowing the magic number and the password bias. It involves some advanced math work and time. I explain the process of breaking Algorithm 2 in the second section.
Suppose :
log_bias = 0xfec0135a
pass_bias = 0xdeadbeef
Let's look at algorithm 1:
1) log_chunk = 0xlogin(0)login(1)login(n - 2)login(n - 1);
2) log_checksum = Sum(login, 0, n);
3) log_magicnumber = log_chunk ^ log_checksum ^ log_bias;
This algorithm shows two potential weaknesses. One, if you take the magic number and xor it with the log_bias constant you obtain :
log_chunk ^ log_checksum.
Two, log_chunk is a concatenation in hex of the first two characters and the last two characters and it provides a frame for the login; therefore, we can generate our own characters and give that variable a value.
After getting rid of the bias and choosing a value for the chunk, we can obtain a value for log_checksum.
log_checksum = (log_magicnumber ^ log_bias) ^ log_chunk;
What's left to do is to find a sequence of numbers representing characters which sum is the checksum.
How?
Well, if you look at the ASCII table you'll see that printable characters go from 33 to 126. If we generate a random value b between 33 and 126 and subtract it from the checksum we obtain a character value b and reduce the checksum value by b : log_checksum -= b. Repeat this operation until checksum value goes below 126 and only store characters which diff = (log_checksum - b) is greater or equal than 33. This way, all characters will be printable.
After filling the middle of the login string it can be represented as follows :
login = A B b0 b1 b2 ... bj C D
with A, B, C, D the characters we chose, and bi the characters generated from the checksum.
This reverse engineering approach is a cheap smart hack that targets the weakest hash function of the process and it will definitely work and save you time. From one password you'll obtain multiple logins : this is called a hash collision.
Here's an example output of this code:
Login: Vasya_Pupkin
Password: 011c0d0f090e00
Login check : 0xa8a17eee
Password check : 0xa8a17eee
Check success :)
Valid login for pass_magicnumber 0xa8a17eee: Va[JiIUpHBI]in, length = 14
Valid login for pass_magicnumber 0xa8a17eee: VaU[^OnyD^fin, length = 13
Valid login for pass_magicnumber 0xa8a17eee: Va|IkH`y`i2in, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VaTziSl^oK>in, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VawNzAOGWktin, length = 13
Valid login for pass_magicnumber 0xa8a17eee: Vaeh]bmzbwin, length = 12
Valid login for pass_magicnumber 0xa8a17eee: VaugjXcNEvBin, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VaJoMwQ{p[8in, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VatBZwR`R|Ein, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VaIy[lkZQbKin, length = 13
All the listed valid logins will work for the password "011c0d0f090e00".
If you alter the password a bit, say : "011c0d0f090efe", here's what you get :
Login: VaNpNa^Twin
Password: 011c0d0f090efe
Login check : 0xa8a17e10
Password check : 0xa8a17e10
Check success :)
Valid login for pass_magicnumber 0xa8a17e10: VaeOTUkOG8in, length = 12
Valid login for pass_magicnumber 0xa8a17e10: VaUDFEzBx>in, length = 12
Valid login for pass_magicnumber 0xa8a17e10: Va|gktoein, length = 10
Valid login for pass_magicnumber 0xa8a17e10: VaaPRTogiin, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VaFEzBpktin, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VafCCzmQrin, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VaFDWMHSNC<in, length = 13
Valid login for pass_magicnumber 0xa8a17e10: VaSvoIgR\in, length = 11
Valid login for pass_magicnumber 0xa8a17e10: Va[{eLdl?in, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VaPaoDPXFDin, length = 12
Now, let's talk about generating passwords from a login magic number.
You'll have to attack this function :
log_magicnumber = b ^ ((log_magicnumber << 5) + 1) ^ pass_bias
If you look closely, you'll see that current log_magicnumber is computed using the previous log_magicnumber value transformed and mixed up with an unknown byte value and a known bias.
Iteratively, it looks like this:
log_magicnumber(i) = b ^ ((log_magicnumber(i - 1) << 5) + 1) ^ pass_bias
If we xor the pass_magicnumber and the pass_bias we're left with :
b ^ ((log_magicnumber << 5) + 1)
After generating all possible values of b (0-9 and a-f, 16 possibilities total) and deriving the corresponding value of log_magicnumber for each possible value of b, we apply the same step on these magic number values to obtain another value & we go on 8 times (the password string being a 64 bit value = 8 bytes with a minimum length of 6 bytes). We discard the two left-most bytes if set to zero and pack all the bytes into a password string; we then verify with the password magic number algorithm if the password's magic number matches the login's.
This approach amounts to creating an 8 stage tree where each node has 16 children. This means that we'll have to generate 16 to the power of 8 characters : 16^8 = (2^4)^8 = 2^32 = 4.294.967.296 characters (4GB) and combine them in strings of 6 to 8 characters with each string being checked for validation. It was fun to code :)