xore($ix); $t = $tiger_t1[$c->gb(0)]->xor_($tiger_t2[$c->gb(2)]); $t->xore($tiger_t3[$c->gb(4)]); $t->xore($tiger_t4[$c->gb(6)]); $a->sube($t); $t = $tiger_t4[$c->gb(1)]->xor_($tiger_t3[$c->gb(3)]); $t->xore($tiger_t2[$c->gb(5)]); $t->xore($tiger_t1[$c->gb(7)]); $b->adde($t); $mulf($b); } function tiger_pass(Uint64 &$a,Uint64 &$b,Uint64 &$c, array $is, $mulf) { tiger_round($a,$b,$c,$is[0], $mulf); tiger_round($b,$c,$a,$is[1], $mulf); tiger_round($c,$a,$b,$is[2], $mulf); tiger_round($a,$b,$c,$is[3], $mulf); tiger_round($b,$c,$a,$is[4], $mulf); tiger_round($c,$a,$b,$is[5], $mulf); tiger_round($a,$b,$c,$is[6], $mulf); tiger_round($b,$c,$a,$is[7], $mulf); } $tiger_c1 = Uint64::from_hex("A5A5A5A5A5A5A5A5"); $tiger_c2 = Uint64::from_hex("0123456789ABCDEF"); function tiger_key_sched(array $is) { global $tiger_c1, $tiger_c2; $is[0]->sube($is[7]->xor_($tiger_c1)); $is[1]->xore($is[0]); $is[2]->adde($is[1]); $is[3]->sube($is[1]->not_()->shlie(19)->xore($is[2])); $is[4]->xore($is[3]); $is[5]->adde($is[4]); $is[6]->sube($is[4]->not_()->shrie(23)->xore($is[5])); $is[7]->xore($is[6]); $is[0]->adde($is[7]); $is[1]->sube($is[7]->not_()->shlie(19)->xore($is[0])); $is[2]->xore($is[1]); $is[3]->adde($is[2]); $is[4]->sube($is[2]->not_()->shrie(23)->xore($is[3])); $is[5]->xore($is[4]); $is[6]->adde($is[5]); $is[7]->sube($is[6]->xor_($tiger_c2)); return $is; } function tiger_block(array $is, array $res) { $mulf5 = function(Uint64 &$m) { $m=$m->shli(2)->adde($m); }; $mulf7 = function(Uint64 &$m) { $m=$m->shli(3)->sube($m); }; $mulf9 = function(Uint64 &$m) { $m=$m->shli(3)->adde($m); }; $r0 = clone $res[0]; $r1 = clone $res[1]; $r2 = clone $res[2]; tiger_pass($r0,$r1,$r2,$is,$mulf5); $is = tiger_key_sched($is); tiger_pass($r2,$r0,$r1,$is,$mulf7); $is = tiger_key_sched($is); tiger_pass($r1,$r2,$r0,$is,$mulf9); $r0->xore($res[0]); $r1->sube($res[1]); $r2->adde($res[2]); return array($r0,$r1,$r2); } //strlen($is) must be <= 63 function tiger_end($is, Uint64 $tlen, array $res) { $length = strlen($is); $is .= "\001"; while (strlen($is) % 8) $is .= "\000"; if(strlen($is) == 64) { $res = tiger_block(Uint64::arr_from_les($is), $res); $is = ""; } while (strlen($is) < 56) $is .= "\000"; $arr = Uint64::arr_from_les($is); $arr[7] = $tlen->shli(3); $res = tiger_block($arr, $res); return $res; } /** Return the hash of the desired string as 3 Uint64s **/ function tiger($str) { $length=strlen($str); //Process the data $bs=str_split($str,64); $lb=array_pop($bs); if(strlen($lb) == 64) { array_push($bs,$lb); $lb=""; } return tiger_end($lb, Uint64::from_int($length),array_reduce($bs, function($v, $w) { return tiger_block(Uint64::arr_from_les($w),$v); }, array(Uint64::from_hex("0123456789ABCDEF"), Uint64::from_hex("FEDCBA9876543210"), Uint64::from_hex("F096A5B4C3B2E187") ) )); } /** Return the data that needs to be stored to call tigerp2 **/ function tigerp1($password, $salt) { $hs = strlen($password); $n = 128-($hs%64); $data = $password . substr($salt,0,$n); $hs = $hs + $n; //Process the data $bs=str_split($data,64); $h = array_reduce($bs, function($v, $w) { return tiger_block(Uint64::arr_from_les($w),$v); }, array(Uint64::from_hex("0123456789ABCDEF"), Uint64::from_hex("FEDCBA9876543210"), Uint64::from_hex("F096A5B4C3B2E187") ) ); return array( 'h' => $h, 'r' => $salt, 'n' => $n, 'hs' => $hs); } /** end processing the request started in tigerp1, adding any extra data**/ function tigerp2($h, $r, $n, $hs, $s) { $data = substr($r,$n) . $s; $thd = $hs + strlen($data); //Process the data $bs=str_split($data,64); $lb=array_pop($bs); if(strlen($lb) == 64) { array_push($bs,$lb); $lb=""; } return tiger_end($lb, Uint64::from_int($thd),array_reduce($bs, function($v, $w) { return tiger_block(Uint64::arr_from_les($w),$v); },$h)); } // /*Example code*/ // function t_hash($str) { // foreach (tiger($str) as $v) // for ($i= 0; $i <8; $i++) // printf("%02X",$v->gb($i)); // echo "\n"; // t_hash2($str); // } // // //Example using tigerp1 and tigerp2 // function t_hash2($str) { // $psalt=openssl_random_pseudo_bytes (128, $strong); // //You should assure strong is true here // $s1 = tigerp1($str,$psalt); // //s1 contains all the data we need to store // //tsalt is the salt used once for protocol run // for ($i= 0; $i < 100; $i++) { // $tsalt=openssl_random_pseudo_bytes (32, $strong); // //You should assure strong is true here // $ress = tigerp2($s1['h'],$s1['r'],$s1['n'],$s1['hs'],$tsalt); // $resc = tiger($str . $psalt . $tsalt); // if ($ress != $resc) { // echo "Error calculating partial hashes!\n"; // } // } // } // // t_hash(""); // t_hash("abc"); // t_hash("Tiger"); // /* Hash of 512-bit strings */ // t_hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"); // t_hash("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"); // t_hash("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"); // /* Hash of two-block strings strings */ // t_hash("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge."); // t_hash("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996."); // t_hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"); ?>