| 1 |
<?php
|
| 2 |
/*
|
| 3 |
** PHP implementation of the PvPGN Password Hash Algorithm.
|
| 4 |
|
| 5 |
** Copyright 2004 Aaron (aaron@pvpgn.org)
|
| 6 |
|
| 7 |
** This code is available under the GNU Lesser General Public License:
|
| 8 |
** http://www.gnu.org/licenses/lgpl.txt
|
| 9 |
|
| 10 |
** This code in general is based on:
|
| 11 |
** Copyright 2002 - 2003 Marcus Campbell
|
| 12 |
** http://www.tecknik.net/sha-1/
|
| 13 |
** Based on the JavaScript SHA-1 implementation by Paul Johnston
|
| 14 |
** http://pajhome.org.uk/
|
| 15 |
|
| 16 |
** the safe_rol function is taken from an PHP SHA-1 implementation
|
| 17 |
** written by Chris Monson (chris@bouncingchairs.net)
|
| 18 |
** Most recent version available on http://bouncingchairs.net
|
| 19 |
** (Based on the SHA algorithm as given in "Applied Cryptography")
|
| 20 |
|
| 21 |
*/
|
| 22 |
function str2blks_pvpgn($str) {
|
| 23 |
$nblk = ((strlen($str) + 8) >> 6) + 1;
|
| 24 |
|
| 25 |
for($i=0; $i < $nblk * 16; $i++) $blks[$i] = 0;
|
| 26 |
for($i=0; $i < strlen($str); $i++) {
|
| 27 |
$blks[$i >> 2] |= ord(substr($str, $i, 1)) << ( ($i % 4) * 8);
|
| 28 |
}
|
| 29 |
return $blks;
|
| 30 |
}
|
| 31 |
function safe_add($x, $y) {
|
| 32 |
$lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
|
| 33 |
$msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);
|
| 34 |
return ($msw << 16) | ($lsw & 0xFFFF);
|
| 35 |
}
|
| 36 |
|
| 37 |
function safe_not( $num ) {
|
| 38 |
$lsw = (~($num & 0xFFFF)) & 0xFFFF;
|
| 39 |
$msw = (~($num >> 16)) & 0xFFFF;
|
| 40 |
return ($msw << 16) | $lsw;
|
| 41 |
}
|
| 42 |
|
| 43 |
function safe_rol( $num, $amt ) {
|
| 44 |
$leftmask = 0xffff | (0xffff << 16);
|
| 45 |
$leftmask <<= 32 - $amt;
|
| 46 |
$rightmask = 0xffff | (0xffff << 16);
|
| 47 |
$rightmask <<= $amt;
|
| 48 |
$rightmask = safe_not($rightmask);
|
| 49 |
|
| 50 |
$remains = $num & $leftmask;
|
| 51 |
$remains >>= 32 - $amt;
|
| 52 |
$remains &= $rightmask;
|
| 53 |
|
| 54 |
$res = ($num << $amt) | $remains;
|
| 55 |
|
| 56 |
return $res;
|
| 57 |
}
|
| 58 |
|
| 59 |
function ft($t, $b, $c, $d) {
|
| 60 |
if($t < 20) return ($b & $c) | ((safe_not($b)) & $d);
|
| 61 |
if($t < 40) return $d ^ $c ^ $b;
|
| 62 |
if($t < 60) return ($c & $b) | ($d & $c) | ($d & $b);
|
| 63 |
return $d ^ $c ^ $b;
|
| 64 |
}
|
| 65 |
|
| 66 |
function kt($t) {
|
| 67 |
if ($t < 20) {
|
| 68 |
return 0x5a82 << 16 | 0x7999;
|
| 69 |
} else if ($t < 40) {
|
| 70 |
return 0x6ed9 << 16 | 0xeba1;
|
| 71 |
} else if ($t < 60) {
|
| 72 |
return 0x8f1b << 16 | 0xbcdc;
|
| 73 |
} else {
|
| 74 |
return 0xca62 << 16 | 0xc1d6;
|
| 75 |
}
|
| 76 |
}
|
| 77 |
function pvpgn_hash($str) {
|
| 78 |
$x = str2blks_pvpgn($str);
|
| 79 |
|
| 80 |
$a = 0x6745 << 16 | 0x2301;
|
| 81 |
$b = 0xefcd << 16 | 0xab89;
|
| 82 |
$c = 0x98ba << 16 | 0xdcfe;
|
| 83 |
$d = 0x1032 << 16 | 0x5476;
|
| 84 |
$e = 0xc3d2 << 16 | 0xe1f0;
|
| 85 |
|
| 86 |
for($i = 0; $i < sizeof($x); $i += 16) {
|
| 87 |
$olda = $a;
|
| 88 |
$oldb = $b;
|
| 89 |
$oldc = $c;
|
| 90 |
$oldd = $d;
|
| 91 |
$olde = $e;
|
| 92 |
|
| 93 |
for($j = 0; $j < 16; $j++) {
|
| 94 |
$w[$j] = $x[$i+$j];
|
| 95 |
}
|
| 96 |
|
| 97 |
for($j = 0; $j < 64; $j++) {
|
| 98 |
$ww = $w[$j] ^ $w[$j+8] ^ $w[$j+2] ^ $w[$j+13];
|
| 99 |
$w[$j+16] = 1 << ($ww%32);
|
| 100 |
}
|
| 101 |
|
| 102 |
for($j = 0; $j < 80; $j++) {
|
| 103 |
if ($j<20)
|
| 104 |
{
|
| 105 |
$t = safe_add(safe_add(safe_rol($a, 5), ft($j, $b, $c, $d)), safe_add(safe_add($e, $w[$j]), kt($j)));
|
| 106 |
}
|
| 107 |
else
|
| 108 |
{
|
| 109 |
$t = safe_add(safe_add(safe_rol($t, 5), ft($j, $b, $c, $d)), safe_add(safe_add($e, $w[$j]), kt($j)));
|
| 110 |
}
|
| 111 |
$e = $d;
|
| 112 |
$d = $c;
|
| 113 |
$c = safe_rol($b, 30);
|
| 114 |
$b = $a;
|
| 115 |
$a = $t;
|
| 116 |
}
|
| 117 |
$a = safe_add($t, $olda);
|
| 118 |
$b = safe_add($b, $oldb);
|
| 119 |
$c = safe_add($c, $oldc);
|
| 120 |
$d = safe_add($d, $oldd);
|
| 121 |
$e = safe_add($e, $olde);
|
| 122 |
}
|
| 123 |
return sprintf("%08x%08x%08x%08x%08x",$a,$b,$c,$d,$e);
|
| 124 |
}
|
| 125 |
|
| 126 |
?> |