Created
December 16, 2011 22:41
-
-
Save cypres/1488359 to your computer and use it in GitHub Desktop.
SkipJack32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* A 32-bit block cipher based on skipjack. | |
* In common: F-table, G-permutation, key schedule. | |
* Different: 24 round feistel structure. | |
* | |
* Ported to PHP from C implementation at: | |
* http://www.qualcomm.com.au/PublicationsDocs/skip32.c | |
* | |
* Might not work as expected on 32-bit processors due to PHP lacking a unsigned 32-bit integer. | |
* | |
* @author Panu Rissanen <[email protected]> | |
* @author Greg Rose, QUALCOMM Australia | |
* @author Hans Duedal <[email protected]> | |
* | |
* @license Without copyright, no rights reserved. | |
*/ | |
class SkipJack32 | |
{ | |
private static $ftable = array ( | |
0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, | |
0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, | |
0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, | |
0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, | |
0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, | |
0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, | |
0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, | |
0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, | |
0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, | |
0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, | |
0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, | |
0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, | |
0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, | |
0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, | |
0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, | |
0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 | |
); | |
private static function g($key, $k, $w) { | |
$g1 = ($w>>8)&0xff; | |
$g2 = $w&0xff; | |
$g3 = self::$ftable[$g2 ^ $key[(4*$k)%10]] ^ $g1; | |
$g4 = self::$ftable[$g3 ^ $key[(4*$k+1)%10]] ^ $g2; | |
$g5 = self::$ftable[$g4 ^ $key[(4*$k+2)%10]] ^ $g3; | |
$g6 = self::$ftable[$g5 ^ $key[(4*$k+3)%10]] ^ $g4; | |
return (($g5<<8) + $g6); | |
} | |
private static function skip32($key, $value, $encrypt=true) { | |
// direction | |
$k = null; | |
$kstep = null; | |
if ($encrypt) { | |
$kstep = 1; | |
$k = 0; | |
} else { | |
$kstep = -1; | |
$k = 23; | |
} | |
// pack into two 16-bit words | |
$wl = (($value >> 16) & 0xFFFF); | |
$wr = ($value & 0xFFFF); | |
// 24 feistel rounds, doubled up | |
for ($i=0;$i<24/2;++$i) { | |
$wr = $wr ^ (self::g($key, $k, $wl) ^ $k); | |
$k += $kstep; | |
$wl = $wl ^ (self::g($key, $k, $wr) ^ $k); | |
$k += $kstep; | |
} | |
$wr = $wr << 16; | |
return $wr + $wl; | |
} | |
/** | |
* Encrypt a 32-bit integer using the skipjack algo. | |
* Returns an integer, if you want the data convert it with pack('N'). | |
* Ie: var_dump(bin2hex(pack('N',SkipJack32::encrypt('0123456789', 0xdeadbeef)))); | |
* | |
* @param string $key 10-byte key string | |
* @param integer $value | |
* @return number | |
*/ | |
public static function encrypt($key, $value) { | |
return self::skip32(array_slice(unpack("C10",$key),0),$value,true); | |
} | |
/** | |
* Decrypt a 32-bit integer encrypted with SkipJack32. | |
* Returns an integer, use pack('N') to get the binary data instead. | |
* Ie. var_dump(bin2hex(pack('N',SkipJack32::decrypt('0123456789', 0x8de4f05a)))); | |
* | |
* @param string $key 10-byte key string | |
* @param integer $value | |
* @return number | |
*/ | |
public static function decrypt($key, $value) { | |
return self::skip32(array_slice(unpack("C10",$key),0),$value,false); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment