Author

Topic: An exercise in hacking for someone (Read 4287 times)

full member
Activity: 286
Merit: 100
August 16, 2013, 11:06:14 PM
#3
I'm going to have to go with no.  http://ideone.com/0hpVxd

The problem is that the fact that the bit's values are consistent to their location.
For example, the outermost bytes only mix with the outermost bytes and the innermost bytes only mix with the innermost bytes.
The only time that doesn't occur is when the "+1" happens to cause a carry to happen.

You can see from the example that the lower input values yield very easy to "reverse" numbers.  If you know the input number was small, simply take the back half of the hash, and reverse the bit order.
With larger input values, the pattern isn't as apparent, but you can still tell that it's there.


My other major concern is how the algorithm would handle messages with length greater than 64 bits.  Most hash algorithms use a compression function for this, but from the code below, there doesn't seem to be one.  If your

Lastly, even if this algorithm had iteration and a compression function, the fact that the output length is only 64 bits is quite troubling.  Even if you had compression and iteration functions, any input message longer than 64 bits would also have a "collision" message that's less than 64 bits.  The digest length alone makes it 2^64 times less secure than MD5.


Sorry mate.  Embarrassed

Thank you very much for your constructive criticism - something not many people I know actually give.

The aim of some of the different methods that I have tried is to get something which is fast, but if unsecure can be doubled in rounds without slowing encryption to a crawl.

The current iteration of Isenberg also rotates the result of the first rotation by 45 degrees clockwise, XORs it with the first rotation, and rotates that by 45 degrees counterclockwise, and XORs with the second rotation.

Since 64 bit digest, as you pointed out, was too small, I guess the next logical step is something like SSE2, with 256 bit digest words.

The search continues, I guess.

EDIT: Tipped you for your answer.

Matthew:out
full member
Activity: 168
Merit: 100
August 16, 2013, 11:33:26 AM
#2
I'm going to have to go with no.  http://ideone.com/0hpVxd

The problem is that the fact that the bit's values are consistent to their location.
For example, the outermost bytes only mix with the outermost bytes and the innermost bytes only mix with the innermost bytes.
The only time that doesn't occur is when the "+1" happens to cause a carry to happen.

You can see from the example that the lower input values yield very easy to "reverse" numbers.  If you know the input number was small, simply take the back half of the hash, and reverse the bit order.
With larger input values, the pattern isn't as apparent, but you can still tell that it's there.


My other major concern is how the algorithm would handle messages with length greater than 64 bits.  Most hash algorithms use a compression function for this, but from the code below, there doesn't seem to be one.  If your

Lastly, even if this algorithm had iteration and a compression function, the fact that the output length is only 64 bits is quite troubling.  Even if you had compression and iteration functions, any input message longer than 64 bits would also have a "collision" message that's less than 64 bits.  The digest length alone makes it 2^64 times less secure than MD5.


Sorry mate.  Embarrassed
full member
Activity: 286
Merit: 100
August 15, 2013, 11:43:29 AM
#1
In a small flash of inspiration, I came up with a new cypher (which I call "Isenberg" after a friend of mine). Important thing is - is it secure? (I doubt it, personally, but it does seem to resist preimage attacks(!)) To test this, I need firepower which I personally don't have.

This is the code I used (the hash function is hashword()) which is really rather simple when you get down to it.

Code:
#include

#define U64 unsigned long long
#define C64(x) x##ULL

U64 flipDiagA1H8(U64 x) {
   U64 t;
   const U64 k1 = C64(0x5500550055005500);
   const U64 k2 = C64(0x3333000033330000);
   const U64 k4 = C64(0x0f0f0f0f00000000);
   t  = k4 & (x ^ (x << 28));
   x ^=       t ^ (t >> 28) ;
   t  = k2 & (x ^ (x << 14));
   x ^=       t ^ (t >> 14) ;
   t  = k1 & (x ^ (x <<  7));
   x ^=       t ^ (t >>  7) ;
   return x;
}

U64 flipVertical(U64 x) {
    return  ( (x << 56)                           ) |
            ( (x << 40) & C64(0x00ff000000000000) ) |
            ( (x << 24) & C64(0x0000ff0000000000) ) |
            ( (x <<  8) & C64(0x000000ff00000000) ) |
            ( (x >>  8) & C64(0x00000000ff000000) ) |
            ( (x >> 24) & C64(0x0000000000ff0000) ) |
            ( (x >> 40) & C64(0x000000000000ff00) ) |
            ( (x >> 56) );
}

U64 hashword(U64 x)
{
   // Made up of four parts
   // Flip along antidiagonal
   U64 x1 = flipDiagA1H8(x);

   // Flip vertically
   x1 = flipVertical(x1);

   // XOR
   x1 = x ^ x1;

   // Add one

   x1++;

   return x1;
}

int main()
{
   U64 input = 0;
   U64 output = 0;
   int collisions = 0;

   for (; input < 0xFFFFFFF; input++) {
      output = hashword(input);
      if (output == input) {
         printf("%d hashes to itself!\n", input);
      }
   }
   return 0;
}

I have no significant amount of bitcoins to offer as a reward, but it might prove useful as a small challenge.

Matthew:out
Jump to: