+/*****************************************************************************
+ * DoExtShuffle: extended shuffle
+ *****************************************************************************
+ * This is even uglier.
+ *****************************************************************************/
+static void DoExtShuffle( uint32_t * p_bordel )
+{
+ uint32_t i_ret;
+
+ i_ret = FirstPass( p_bordel );
+
+ SecondPass( p_bordel, i_ret );
+
+ ThirdPass( p_bordel );
+
+ FourthPass( p_bordel );
+}
+
+static uint32_t FirstPass( uint32_t * p_bordel )
+{
+ uint32_t i, i_cmd, i_ret = 5;
+
+ TinyShuffle1( p_bordel );
+
+ for( ; ; )
+ {
+ for( ; ; )
+ {
+ p_bordel[ 1 ] += 0x10000000;
+ p_bordel[ 3 ] += 0x12777;
+
+ if( (p_bordel[ 10 ] & 1) && i_ret )
+ {
+ i_ret--;
+ p_bordel[ 1 ] -= p_bordel[ 2 ];
+ p_bordel[ 11 ] += p_bordel[ 12 ];
+ break;
+ }
+
+ if( (p_bordel[ 1 ] + p_bordel[ 2 ]) >= 0x7D0 )
+ {
+ switch( ((p_bordel[ 3 ] ^ 0x567F) >> 2) & 7 )
+ {
+ case 0:
+ for( i = 0; i < 3; i++ )
+ {
+ if( p_bordel[ i + 10 ] > 0x4E20 )
+ {
+ p_bordel[ i + 1 ] += p_bordel[ i + 2 ];
+ }
+ }
+ break;
+ case 4:
+ p_bordel[ 1 ] -= p_bordel[ 2 ];
+ /* no break */
+ case 3:
+ p_bordel[ 11 ] += p_bordel[ 12 ];
+ break;
+ case 6:
+ p_bordel[ 3 ] ^= p_bordel[ 4 ];
+ /* no break */
+ case 8:
+ p_bordel[ 13 ] &= p_bordel[ 14 ];
+ /* no break */
+ case 1:
+ p_bordel[ 0 ] |= p_bordel[ 1 ];
+ if( i_ret )
+ {
+ return i_ret;
+ }
+ break;
+ }
+
+ break;
+ }
+ }
+
+ for( i = 0, i_cmd = 0; i < 16; i++ )
+ {
+ if( p_bordel[ i ] < p_bordel[ i_cmd ] )
+ {
+ i_cmd = i;
+ }
+ }
+
+ if( i_ret && i_cmd != 5 )
+ {
+ i_ret--;
+ }
+ else
+ {
+ if( i_cmd == 5 )
+ {
+ p_bordel[ 8 ] &= p_bordel[ 6 ] >> 1;
+ p_bordel[ 3 ] <<= 1;
+ }
+
+ for( i = 0; i < 3; i++ )
+ {
+ p_bordel[ 11 ] += 1;
+ if( p_bordel[ 11 ] & 5 )
+ {
+ p_bordel[ 8 ] += p_bordel[ 9 ];
+ }
+ else if( i_ret )
+ {
+ i_ret--;
+ i_cmd = 3;
+ goto break2;
+ }
+ }
+
+ i_cmd = (p_bordel[ 15 ] + 0x93) >> 3;
+ if( p_bordel[ 15 ] & 0x100 )
+ {
+ i_cmd ^= 0xDEAD;
+ }
+ }
+
+ switch( i_cmd & 3 )
+ {
+ case 0:
+ while( p_bordel[ 11 ] & 1 )
+ {
+ p_bordel[ 11 ] >>= 1;
+ p_bordel[ 12 ] += 1;
+ }
+ /* no break */
+ case 2:
+ p_bordel[ 14 ] -= 0x19FE;
+ break;
+ case 3:
+ if( i_ret )
+ {
+ i_ret--;
+ p_bordel[ 5 ] += 5;
+ continue;
+ }
+ break;
+ }
+
+ i_cmd = ((p_bordel[ 3 ] + p_bordel[ 4 ] + 10) >> 1) - p_bordel[ 4 ];
+ break;
+ }
+break2:
+
+ switch( i_cmd & 3 )
+ {
+ case 0:
+ p_bordel[ 14 ] >>= 1;
+ break;
+ case 1:
+ p_bordel[ 5 ] <<= 2;
+ break;
+ case 2:
+ p_bordel[ 12 ] |= 5;
+ break;
+ case 3:
+ p_bordel[ 15 ] &= 0x55;
+ if( i_ret )
+ {
+ p_bordel[ 2 ] &= 0xB62FC;
+ return i_ret;
+ }
+ break;
+ }
+
+ TinyShuffle2( p_bordel );
+
+ return i_ret;
+}
+
+static void SecondPass( uint32_t * p_bordel, uint32_t i_tmp )
+{
+ uint32_t i, i_cmd, i_jc = 5;
+
+ TinyShuffle3( p_bordel );
+
+ for( i = 0, i_cmd = 0; i < 16; i++ )
+ {
+ if( p_bordel[ i ] > p_bordel[ i_cmd ] )
+ {
+ i_cmd = i;
+ }
+ }
+
+ switch( i_cmd )
+ {
+ case 0:
+ if( p_bordel[ 1 ] < p_bordel[ 8 ] )
+ {
+ p_bordel[ 5 ] += 1;
+ }
+ break;
+ case 4:
+ if( (p_bordel[ 9 ] & 0x7777) == 0x3333 )
+ {
+ p_bordel[ 5 ] -= 1;
+ }
+ else
+ {
+ i_jc--;
+ if( p_bordel[ 1 ] < p_bordel[ 8 ] )
+ {
+ p_bordel[ 5 ] += 1;
+ }
+ break;
+ }
+ /* no break */
+ case 7:
+ p_bordel[ 2 ] -= 1;
+ p_bordel[ 1 ] -= p_bordel[ 5 ];
+ for( i = 0; i < 3; i++ )
+ {
+ switch( p_bordel[ 1 ] & 3 )
+ {
+ case 0:
+ p_bordel[ 1 ] += 1;
+ /* no break */
+ case 1:
+ p_bordel[ 3 ] -= 8;
+ break;
+ case 2:
+ p_bordel[ 13 ] &= 0xFEFEFEF7;
+ break;
+ case 3:
+ p_bordel[ 8 ] |= 0x80080011;
+ break;
+ }
+ }
+ return;
+ case 10:
+ p_bordel[ 4 ] -= 1;
+ p_bordel[ 5 ] += 1;
+ p_bordel[ 6 ] -= 1;
+ p_bordel[ 7 ] += 1;
+ break;
+ default:
+ p_bordel[ 15 ] ^= 0x18547EFF;
+ break;
+ }
+
+ for( i = 3; i--; )
+ {
+ switch( ( p_bordel[ 12 ] + p_bordel[ 13 ] + p_bordel[ 6 ] ) % 5 )
+ {
+ case 0:
+ p_bordel[ 12 ] -= 1;
+ /* no break */
+ case 1:
+ p_bordel[ 12 ] -= 1;
+ p_bordel[ 13 ] += 1;
+ break;
+ case 2:
+ p_bordel[ 13 ] += 4;
+ /* no break */
+ case 3:
+ p_bordel[ 12 ] -= 1;
+ break;
+ case 4:
+ i_jc--;
+ p_bordel[ 5 ] += 1;
+ p_bordel[ 6 ] -= 1;
+ p_bordel[ 7 ] += 1;
+ i = 3; /* Restart the whole loop */
+ break;
+ }
+ }
+
+ TinyShuffle4( p_bordel );
+
+ for( ; ; )
+ {
+ TinyShuffle5( p_bordel );
+
+ switch( ( p_bordel[ 2 ] * 2 + 15 ) % 5 )
+ {
+ case 0:
+ if( ( p_bordel[ 3 ] + i_tmp ) <=
+ ( p_bordel[ 1 ] + p_bordel[ 15 ] ) )
+ {
+ p_bordel[ 3 ] += 1;
+ }
+ break;
+ case 4:
+ p_bordel[ 10 ] -= 0x13;
+ break;
+ case 3:
+ p_bordel[ 5 ] >>= 2;
+ break;
+ }
+
+ if( !( p_bordel[ 2 ] & 1 ) || i_jc == 0 )
+ {
+ break;
+ }
+
+ i_jc--;
+ p_bordel[ 2 ] += 0x13;
+ p_bordel[ 12 ] += 1;
+ }
+
+ p_bordel[ 2 ] &= 0x10076000;
+}
+
+static void ThirdPass( uint32_t * p_bordel )
+{
+ uint32_t i_cmd;
+
+ i_cmd = ((p_bordel[ 7 ] + p_bordel[ 14 ] + 10) >> 1) - p_bordel[ 14 ];
+ i_cmd = i_cmd % 10;
+
+ switch( i_cmd )
+ {
+ case 0:
+ p_bordel[ 1 ] <<= 1;
+ p_bordel[ 2 ] <<= 2;
+ p_bordel[ 3 ] <<= 3;
+ break;
+ case 6:
+ p_bordel[ i_cmd + 3 ] &= 0x5EDE36B;
+ p_bordel[ 5 ] += p_bordel[ 8 ];
+ p_bordel[ 4 ] += p_bordel[ 7 ];
+ p_bordel[ 3 ] += p_bordel[ 6 ];
+ p_bordel[ 2 ] += p_bordel[ 5 ];
+ /* no break */
+ case 2:
+ p_bordel[ 1 ] += p_bordel[ 4 ];
+ p_bordel[ 0 ] += p_bordel[ 3 ];
+ TinyShuffle6( p_bordel );
+ return; /* jc = 4 */
+ case 3:
+ if( (p_bordel[ 11 ] & p_bordel[ 2 ]) > 0x211B )
+ {
+ p_bordel[ 6 ] += 1;
+ }
+ break;
+ case 4:
+ p_bordel[ 7 ] += 1;
+ /* no break */
+ case 5:
+ p_bordel[ 9 ] ^= p_bordel[ 2 ];
+ break;
+ case 7:
+ p_bordel[ 2 ] ^= (p_bordel[ 1 ] & p_bordel[ 13 ]);
+ break;
+ case 8:
+ p_bordel[ 0 ] -= p_bordel[ 11 ] & p_bordel[ 15 ];
+ return; /* jc = 4 */
+ case 9:
+ p_bordel[ 6 ] >>= (p_bordel[ 14 ] & 3);
+ break;
+ }
+
+ SWAP( p_bordel[ 0 ], p_bordel[ 10 ] );
+
+ TinyShuffle6( p_bordel );
+
+ return; /* jc = 5 */
+}
+
+static void FourthPass( uint32_t * p_bordel )
+{
+ uint32_t i, j;
+
+ TinyShuffle7( p_bordel );
+
+ switch( p_bordel[ 5 ] % 5)
+ {
+ case 0:
+ p_bordel[ 0 ] += 1;
+ break;
+ case 2:
+ p_bordel[ 11 ] ^= (p_bordel[ 3 ] + p_bordel[ 6 ] + p_bordel[ 8 ]);
+ break;
+ case 3:
+ for( i = 4; i < 15 && (p_bordel[ i ] & 5) == 0; i++ )
+ {
+ SWAP( p_bordel[ i ], p_bordel[ 15 - i ] );
+ }
+ break;
+ case 4:
+ p_bordel[ 12 ] -= 1;
+ p_bordel[ 13 ] += 1;
+ p_bordel[ 2 ] -= 0x64;
+ p_bordel[ 3 ] += 0x64;
+ TinyShuffle8( p_bordel );
+ return;
+ }
+
+ for( i = 0, j = 0; i < 16; i++ )
+ {
+ if( p_bordel[ i ] > p_bordel[ j ] )
+ {
+ j = i;
+ }
+ }
+
+ switch( p_bordel[ j ] % 100 )
+ {
+ case 0:
+ SWAP( p_bordel[ 0 ], p_bordel[ j ] );
+ break;
+ case 8:
+ p_bordel[ 1 ] >>= 1;
+ p_bordel[ 2 ] <<= 1;
+ p_bordel[ 14 ] >>= 3;
+ p_bordel[ 15 ] <<= 4;
+ break;
+ case 57:
+ p_bordel[ j ] += p_bordel[ 13 ];
+ break;
+ case 76:
+ p_bordel[ 1 ] += 0x20E;
+ p_bordel[ 5 ] += 0x223D;
+ p_bordel[ 13 ] -= 0x576;
+ p_bordel[ 15 ] += 0x576;
+ return;
+ case 91:
+ p_bordel[ 2 ] -= 0x64;
+ p_bordel[ 3 ] += 0x64;
+ p_bordel[ 12 ] -= 1;
+ p_bordel[ 13 ] += 1;
+ break;
+ case 99:
+ p_bordel[ 0 ] += 1;
+ p_bordel[ j ] += p_bordel[ 13 ];
+ break;
+ }
+
+ TinyShuffle8( p_bordel );
+}
+
+/*****************************************************************************
+ * TinyShuffle[12345678]: tiny shuffle subroutines
+ *****************************************************************************
+ * These standalone functions are little helpers for the shuffling process.
+ *****************************************************************************/
+static void TinyShuffle1( uint32_t * p_bordel )
+{
+ uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2;
+
+ if( p_bordel[ 5 ] > 0x7D0 )
+ {
+ i_cmd -= 0x305;
+ }
+
+ switch( i_cmd & 3 )
+ {
+ case 0:
+ p_bordel[ 5 ] += 5;
+ break;
+ case 1:
+ p_bordel[ 4 ] -= 1;
+ break;
+ case 2:
+ if( p_bordel[ 4 ] & 5 )
+ {
+ p_bordel[ 1 ] ^= 0x4D;
+ }
+ /* no break */
+ case 3:
+ p_bordel[ 12 ] += 5;
+ break;
+ }
+}
+
+static void TinyShuffle2( uint32_t * p_bordel )
+{
+ uint32_t i, j;
+
+ for( i = 0, j = 0; i < 16; i++ )
+ {
+ if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) )
+ {
+ j = i;
+ }
+ }
+
+ if( j > 5 )
+ {
+ for( ; j < 15; j++ )
+ {
+ p_bordel[ j ] += p_bordel[ j + 1 ];
+ }
+ }
+ else
+ {
+ p_bordel[ 2 ] &= 0xB62FC;
+ }
+}
+
+static void TinyShuffle3( uint32_t * p_bordel )
+{
+ uint32_t i_cmd = p_bordel[ 6 ] + 0x194B;
+
+ if( p_bordel[ 6 ] > 0x2710 )