Thread: bit level permutation function

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    57

    Question bit level permutation function

    Im trying to write a bit level permutation function for a block cipher, only the catch is you go from working with 4 bit unsigned integers, to one unsigned 64 bit integer.

    So the permutation is you take this one 64 bit integer and for all the bits you apply the rule that bit i goes to 16i mod 63, except for the last bit which is mapped to itself. The inverse appears to be the same, only the rule changes to 4i mod 63.

    I've implemented them both but they don't seem to be actual inverses, anyone mind taking a look? I'm not sure where my errors are or if I picked a good way to tackle this.

    Thanks
    Code:
    unsigned char bitGet(unsigned char x, int bit) {
    	switch(bit) {
    		case 0:
    			return (x & 0x1);
    		case 1:
    			return (x & 0x2);
    		case 2:
    			return (x & 0x4);
    		case 3:
    			return (x & 0x8);
    	}
    
    	return (-1);
    }
    
    unsigned char bitSet(unsigned char x, int bit) {
    	switch(bit) {
    		case 0:
    			return (x | 0x1);
    		case 1:
    			return (x | 0x2);
    		case 2:
    			return (x | 0x4);
    		case 3:
    			return (x | 0x8);
    	}
    
    	return (-1);
    }
    
    unsigned char bitClear(unsigned char x, int bit) {
    	switch(bit) {
    		case 0:
    			return (x & 0xE);
    		case 1:
    			return (x & 0xD);
    		case 2:
    			return (x & 0xB);
    		case 3:
    			return (x & 0x7);
    	}
    
    	return (-1);
    }
    
    void pLayer(unsigned char dst[16]) {
    	int i, j;
    	int srcIndex, srcBit;
    	int dstIndex, dstBit;
    	unsigned char src[16];
    	
    	/* Copy orginal data */
    	memcpy(dst, src, sizeof(unsigned char[16]));
    	
    	/* Start main permutation */
    	for(i = 0; i < 63; ++i) {
    		/* Relative index */
    		j = (16*i) % 63;
    		
    		/* Locations */
    		srcIndex = i / 4;
    		srcBit = i % 4;
    		dstIndex = j / 4;
    		dstBit = j % 4;
    		
    		/* debug */
    		printf("%i(%i.%i)->%i(%i.%i)\n", i, srcIndex, srcBit, j, dstIndex, dstBit);
    		
    		/* Permutate */
    		if(bitGet(src[srcIndex], srcBit) > 0)
    			dst[dstIndex] = bitSet(dst[dstIndex], dstBit);
    		else
    			dst[dstIndex] = bitClear(dst[dstIndex], dstBit);
    	}
    	
    	/* Special case - last bit */
    	if(bitGet(src[15], 3) > 0)
    		dst[15] = bitSet(dst[15], 3);
    	else
    		dst[15] = bitClear(dst[15], 3);
    }
    
    void INVpLayer(unsigned char dst[16]) {
    	int i, j;
    	int srcIndex, srcBit;
    	int dstIndex, dstBit;
    	unsigned char src[16];
    	
    	/* Copy orginal data */
    	memcpy(dst, src, sizeof(unsigned char[16]));
    	
    	/* Start main permutation */
    	for(i = 0; i < 63; ++i) {
    		/* Relative index */
    		j = (4*i) % 63;
    		
    		/* Locations */
    		srcIndex = i / 4;
    		srcBit = i % 4;
    		dstIndex = j / 4;
    		dstBit = j % 4;
    		
    		/* debug */
    		printf("%i(%i.%i)->%i(%i.%i)\n", i, srcIndex, srcBit, j, dstIndex, dstBit);
    		
    		/* Permutate */
    		if(bitGet(src[srcIndex], srcBit) > 0)
    			dst[dstIndex] = bitSet(dst[dstIndex], dstBit);
    		else
    			dst[dstIndex] = bitClear(dst[dstIndex], dstBit);
    	}
    	
    	/* Special case - last bit */
    	if(bitGet(src[15], 3) > 0)
    		dst[15] = bitSet(dst[15], 3);
    	else
    		dst[15] = bitClear(dst[15], 3);
    }

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    I havn't read your full code but what I see about bitGet function
    1. you can simplify it using << operator
    Code:
    unsigned char bitGet(unsigned char x, int bit) 
    {
        unsigned char mask = 1 << bit;
        if(bit >=0 && bit < 4)
            return x & mask;
    
        return 0xFF;
    }
    2. it never returns negative values, so checking return value >0 - you will get true for bit value 1 and for error value as well

    if you want to return 0 and 1 in case when parameters as valid - you can use >> operator:

    Code:
    unsigned char bitGet(unsigned char x, int bit) 
    {
        if(bit >=0 && bit < 4)
            return (x>>bit) & 0x1;
    
        return 0xFF;
    }
    in this case it will be easier to test the return value
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    57
    Ok, nice idea. Ill have to play with that. I forgot that I could shift so easily.

    Anyone happen to see anything else? I still haven't made any progress towards this yet.

    Thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM

Tags for this Thread