1

This problem is more mathematic than programming question. I have function which is decoding license key and checking its correctness.

See code:

ushort local6 = rand1;    // generated random = 0x2ff2
ushort local1 = rand2;    // = 0x780e
ushort local8 = rand3;    // = 0x1e3c
ushort local4 = rand4;    // = 0xf521
ushort temp1 = 0;    // always zero
ushort temp2 = 0;    // always zero

// THIS loop
for (int i = 0; i < 8; i++)
{
    local6 += stack2[0 + 6 * i];
    local1 += stack2[1 + 6 * i];
    local8 += stack2[2 + 6 * i];
    local4 += stack2[3 + 6 * i];
    temp1 = (ushort)(local6 ^ local8);
    temp1 += stack2[4 + 6 * i];
    temp2 = (ushort)((local1 ^ local4) + temp1);
    temp2 += stack2[5 + 6 * i];
    temp1 += temp2;
    local6 = (ushort)(local6 ^ temp2);
    local4 ^= temp1;
    temp1 ^= local1;
    local1 = (ushort)(local8 ^ temp2);
    local8 = temp1;
}

// Results after loop:
// local6 = 0x518a
// local1 = 0x33e5
// local8 = 0x8bca
// local4 = 0x57de

// validate date, checksums etc.
if (_validate(local6, local8, local1, local4))
    return "Key " + rand1 + "-" + "rand2" + "-" + "rand3" + "-" + "rand4" + " is valid!";
else
    return "Key invalid!";

To make it simplier lets assume:

ushort[] stack2 = new ushort[52];

for (int i = 0; i < stack2.Length; i++)
{
    stack2[i] = (ushort)i;
}

Question is; Is this loop reversable? I mean is it possible to retrieve values

rand1, rand2, rand3, rand4 

from values taken after loop:

local6, local1, local8, local4 

with knowledge of the code of loop function? I am almost sure this is not possible but want to know what You think about this.

Code I'm sharing is mine invention and I truly believe this kind of loop can be good protection versus reverse engineers (serial crackers) unless they bruteforcing.

myś
  • 94
  • 1
  • 5
  • Sorry to clog up your comments. But this instantly reminded me of my "obfuscate an order id" answer on this question: http://stackoverflow.com/a/18473308/2573395. I would say (without having thought about it that hard) that unless you reverse engineer the code it would be hard to crack, even if you had access to a large number of generated keys. Unless, for that large number of keys you know their sequential order, and you attempt to correlate bytes using multiple permutations of selected potentially applicable bit/mix operations. – Alex Sep 01 '13 at 18:03
  • I think this belongs on crypto SE. – usr Sep 01 '13 at 18:19
  • Why do you think it's not possible? From what I see, it's trivial, albeit a bit tedious. However, isn't the important bit the validation function, which you have omitted. To generate a serial, you first need to fabricate values `local6` etc that pass the validation, and then reverse the loop. Reversing the loop on its own does not seem to be enough. – phant0m Sep 05 '13 at 20:16
  • You may want to try crypto.stackexchange.com – chux - Reinstate Monica Sep 11 '13 at 19:44
  • BTW: why not `... = new ushort[48]`? – chux - Reinstate Monica Sep 11 '13 at 19:49

2 Answers2

1

I'd try putting this into an SMT solver like Z3. The stack can be replaced with constants. temp2 is also constant at every point. The only thing making the reversing hard would be temp2. Hopefully, the SMT solver can deal with that.

I suspect that there is quite low diffusion here because I don't see any rotation.

What also makes it more easy to reverse is that temp1 and temp2 are reinitialized inside the loop at every iteration. It would be harder if they were carried along the entire computation.

Why don't you just use a cryptographic hash like SHA256?

usr
  • 168,620
  • 35
  • 240
  • 369
1

It might be hard, but i don't see any theoretical one-way computation. Everything seems reversable.

SdSdsdsd
  • 123
  • 10