narse has asked for the wisdom of the Perl Monks concerning the following question:

I am translating c code into perl to make it more portable, but I have run into a problems I do not not know how to solve. The software receives a string from the server and must respond by returning a string generated from the original (lock and key). The translation involves several bitwise xors and nibble swaps.
Let me quote the c code written by Eric Proveteau because he is better at explaining this.
the key is quite easily :) computed from the lock key[x]= ns(lock[x]^lock[x-1]) ns is a nibble swap (switch the upper 4 bits with the lower 4 bits) exception: ey[0] is a bit different let's name A and B the 2 last bytes of the lock key[0]= ns(lock[0]^A^B^0x05) ; 0x05 is a kind of magic nibble
Here is the code I have written attempting to follow the specification: (@lock_arr is the string to change, each character is at its own index)
$key_arr[0] = pack 'h2', unpack 'H2', ( $lock_arr[0] ^ $lock_arr[@lock_arr - 1] ^ $lock_arr[@lock_arr - 2] ); for (my $i=1; $i<@lock_arr; $i++) { $key_arr[$i] = pack 'h2', unpack 'H2', ($lock_arr[$i] ^ $lock_arr[$i-1]); }
As far as I know, I have two problems here.
1. I haven't been able to figure out the syntax to add 0x05 into the first operation.
2. I have no way to show this works without asking the server.
Are there better ways to do this and is there a way to display the contents of @key_arr in a way that would make sense?

Replies are listed 'Best First'.
Re: Low level operations
by Zaxo (Archbishop) on Oct 08, 2002 at 23:48 UTC

    1. is pretty easy,

    $key_arr[0] = pack 'h2', unpack 'H2', ( $lock_arr[0] ^ $lock_arr[-1] # ^ $lock_arr[-2] ^ 5 ); # not quite right ^ $lock_arr[-2] ^ chr(5) );

    I simplified the end of array indexing a bit.

    You can view the results with

    print unpack 'H*', join '', @lock_arr; print unpack 'H*', join '', @key_arr;

    You appear to have split the lock phrase into an array for convenience. Another approach would be with substr. I'd combine both operations in a single sub which takes the lock string or array as an argument and returns the key:

    sub keycalc { my @key = @_; for (0..$#key) { $key[$_] = pack 'h2', unpack 'H2', ($_ ? $key[$_] ^ $key[$_ - 1] # : $key[-1] ^ $key[-2] ^ 5); # same error : $key[-1] ^ $key[-2] ^ chr(5)); } @key; } print unpack( 'H*', join '', @lock_arr), $/; print unpack( 'H*', join '', keycalc( @lock_arr)), $/;

    Update: Oops! you need the numeric 5 as a character, Fixed with chr, as indicated.

    After Compline,
    Zaxo

      I am using something like your keycalc sub now, although there are two problems. First, using $key[$_] as the destination confuses $key[$_-1]. The main problem is the use of ... ^ 5. I have tried this before and it gives me an error. Quoting '5' however does execute. Will this work? I do not know how perl actually handles strings so I do not know if this will give me the result I am looking for,
Re: Low level operations
by thor (Priest) on Oct 09, 2002 at 04:14 UTC
    I hope that you're not using this for any sort of secure operation (i.e. if a client can send back the correct key, they are trusted). The reason is that you are not relying on anything that only the client would know, only the algorithm (which, incidentally you just posted on the internet). This is intrisically weak. If you are looking for something more robust, check out zero knowledge proofs.

    thor

      "only the algorithm (which, incidentally you just posted on the internet)."

      This is actually a good thing. All crypto algorithms should be open.It builds trust and people are able to see how the algorithm works so they can sort the good algorithms from the bad ones.
      The security issue is how the algorithm is implemented in software.

        An algorithm which consists of moving a few bits around and then an xor is not a good crypto algorithm.
        And I agree whole heartedly that making crypto algorithms public increases their ability to be trusted through peer review. However, if the original poster were relying on the algotithm alone for security, then he shot himself in the foot (again). Also, to call this a crypto algorighm is like calling ROT-13 an crypto algorithm. To paraphrase Kelly Bundy from 'Married with Children': "You may as well have locked it with a piece of chewing gum".

        thor

      I believe the original purpose was to make sure people arn't doing what I am doing and use unofficial clients. I would not do this if i could avoid it :). I'm just following the protocol.