2.4.x) for 128-bit Rijndael. // generates a 256-bit sequence key by hashing the passed string with SHA256 // it isn't recommended to use this method, rather, you should generate a random // key with GenerateRandomSequenceKey() instead // returns the sequence key as a hex string function GenerateSequenceKeyFromString($passphrase) { return hash('sha256', $passphrase); } // generates a random 256-bit sequence key // returns the sequence key as a hex string function GenerateRandomSequenceKey() { $randomness = get_loaded_extensions(); $randomness[] = php_uname(); $randomness[] = memory_get_usage(); $randomness = implode(microtime(), $randomness); return hash('sha256', $randomness); } // pack the 128 bit number into a binary string (bcmath style number to binary) function pack128( $num ) { $pack = '' ; while( $num ) { $pack .= chr( bcmod( $num, 256 ) ) ; $num = bcdiv( $num, 256 ) ; } return $pack ; } // unpack the 128 bit integer from a binary string (binary to bcmath style number) function unpack128( $pack ) { $pack = str_split( strrev( $pack )) ; $num = '0' ; foreach( $pack as $char ) { $num = bcmul( $num, 256 ) ; $num = bcadd( $num, ord( $char )) ; } return $num ; } // calculate the number of characters in a crypto block for a character set of given length. function blockchars( $length ) { return floor(128/(log($length, 2))); } // returnes the number of codes per crypto block function blockcodes($blockchars, $codesize) { return floor($blockchars/$codesize); } // sort the character set function sortchars($charset) { $newchars = str_split($charset,1); sort($newchars); return implode('',$newchars); } // returns lotto numbers function getlotto($key, $code) { $sk = pack("H*", $key); $n_bits = pack128($code); $enc_bits = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $sk, $n_bits, MCRYPT_MODE_ECB, str_repeat( "\0", 16 )); $numdec = unpack128($enc_bits); $chars = ""; for ($i = 0; $i < 5; $i++) { $chars .= bcadd(bcmod($numdec,56),1); if ($i < 4) $chars .= ", "; else $chars .= " / "; $numdec = bcdiv($numdec,56); } $chars .= bcadd(bcmod($numdec,46),1); $numdec = bcdiv($numdec,46); return $chars; } // returns the nth number function getnum($key, $code, $codemin, $codemax) { $codelength = 1; $length = 1+$codemax-$codemin; $blockchars = blockchars($length); $blockcodes = blockcodes($blockchars, $codelength); $blocknum = bcdiv($code,$blockcodes); $codenum = bcmod($code,$blockcodes); $sk = pack("H*", $key); $n_bits = pack128($blocknum); $enc_bits = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $sk, $n_bits, MCRYPT_MODE_ECB, str_repeat( "\0", 16 )); $numdec = unpack128($enc_bits); $skip = $codenum * $codelength; if ($skip) $numdec = bcdiv($numdec,bcpow($length,$skip)); $chars = ""; for ($i = 0; $i < $codelength; $i++) { $chars .= bcadd(bcmod($numdec,$length),1); $numdec = bcdiv($numdec,$length); } return $chars; } // returns the nth code function getcode($key, $code, $charset, $codelength) { $charset = sortchars($charset); $length = strlen($charset); $blockchars = blockchars($length); $blockcodes = blockcodes($blockchars, $codelength); $blocknum = bcdiv($code,$blockcodes); $codenum = bcmod($code,$blockcodes); $sk = pack("H*", $key); $n_bits = pack128($blocknum); $enc_bits = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $sk, $n_bits, MCRYPT_MODE_ECB, str_repeat( "\0", 16 )); $numdec = unpack128($enc_bits); $chars = ""; for ($i = 0; $i < $blockchars; $i++) { $chars .= substr($charset,bcmod($numdec,$length),1); $numdec = bcdiv($numdec,$length); } return substr($chars,$codenum*$codelength,$codelength); } // returns the nth code function getonecode($key, $code, $charset, $codelength) { $charset = sortchars($charset); $length = strlen($charset); $blockchars = blockchars($length); $blockcodes = blockcodes($blockchars, $codelength); $blocknum = bcdiv($code,$blockcodes); $codenum = bcmod($code,$blockcodes); $sk = pack("H*", $key); $n_bits = pack128($blocknum); $enc_bits = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $sk, $n_bits, MCRYPT_MODE_ECB, str_repeat( "\0", 16 )); $numdec = unpack128($enc_bits); $skip = bcmul($codenum,$codelength); if ($skip) $numdec = bcdiv($numdec,bcpow($length,$skip)); $chars = ""; for ($i = 0; $i < $codelength; $i++) { $chars .= substr($charset,bcmod($numdec,$length),1); $numdec = bcdiv($numdec,$length); } return $chars; } // return an array of the codes requested function getcodes($key, $code, $num, $charset, $codelength) { $charset = sortchars($charset); $length = strlen($charset); $blockchars = blockchars($length); $blockcodes = blockcodes($blockchars, $codelength); $firstblocknum = bcdiv($code,$blockcodes); $firstcodenum = bcmod($code,$blockcodes); $lastblocknum = bcdiv(bcadd($code,$num),$blockcodes); $lastcodenum = bcmod(bcadd($code,$num),$blockcodes); $codes = array(); $sk = pack("H*", $key); # echo "$firstblocknum $firstcodenum $lastblocknum $lastcodenum\n"; for ($i = $firstblocknum; bccomp($i,$lastblocknum)<=0; $i=bcadd($i,1)) { $n_bits = pack128($i); $enc_bits = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $sk, $n_bits, MCRYPT_MODE_ECB, str_repeat( "\0", 16 )); $numdec = unpack128($enc_bits); $skip = 0; if (bccomp($i,$firstblocknum) == 0) { $skip = $firstcodenum; if ($skip) $numdec = bcdiv($numdec,bcpow($length,$skip*$codelength)); } for ($j = $skip; $j < $blockcodes; $j++) { if (bccomp($i,$lastblocknum) == 0 and $j == $lastcodenum) { $j = $blockcodes; break; } $chars = ""; for ($k = 0; $k < $codelength; $k++) { $chars .= substr($charset,bcmod($numdec,$length),1); $numdec = bcdiv($numdec,$length); } array_push($codes, $chars); # echo "$i $j $chars\n"; } } return $codes; } function testppp3($key, $hashnum, $charset) { $charset = sortchars($charset); $length = strlen($charset); $blockchars = blockchars($length); $sk = pack("H*", $key); $n_bits = pack128($hashnum); $enc_bits = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $sk, $n_bits, MCRYPT_MODE_ECB, str_repeat( "\0", 16 )); $numdec = unpack128($enc_bits); $chars = ""; for ($i = 0; $i < $blockchars; $i++) { $chars .= substr($charset,bcmod($numdec,$length),1); $numdec = bcdiv($numdec,$length); } return $chars; } // returns the number of codes than can fit on one row of a paper function getPaperWidth($codelength) { return floor(35/($codelength+1)); } // prints a card block // this only does the first card. It needs to be fixed to do any card. function printcard($key,$charset,$codelength,$cardnum) { $rows = 10; $cols = getPaperWidth($codelength); $total = $rows*$cols; echo " "; for ($i = 0; $i < $cols; $i++) { echo str_pad(chr(ord("A")+$i), $codelength+1, " ", STR_PAD_BOTH); } echo "\n"; $codes = getcodes($key,bcmul($cardnum,$total),$total,$charset,$codelength); for ($i = 0; $i < $total; $i++) { $code = $codes[$i]; if ($i % $cols == 0) printf("%2s: ",ceil(($i+1)/$cols)); if ($i % $cols < $cols-1) echo "$code "; else echo "$code\n"; } } ?> PPPv3-PHP Test

PPPv3-PHP Test

Requirements Check

Lotto Numbers

First four lotto numbers based on "zombie" key:
"; echo getlotto($key,1)."
"; echo getlotto($key,2)."
"; echo getlotto($key,3)."
"; ?>

Random (Port) Numbers

First four Port numbers based on "zombie" key:
"; echo getnum($key,1,1025,65535)."
"; echo getnum($key,2,1025,65535)."
"; echo getnum($key,3,1025,65535)."
"; ?>

Sample output

First Sample Card based on "zombie" key:


Sample output

First Sample Card based on "zombie" key using 6 digit numbers:


Sample output

First Sample Card based on "zombie" key using 5 of "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ":