Skip to content

Instantly share code, notes, and snippets.

@natmchugh
Created March 29, 2014 13:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natmchugh/9854115 to your computer and use it in GitHub Desktop.
Save natmchugh/9854115 to your computer and use it in GitHub Desktop.
Pure PHP MD4 implementation
<?php
function preProcess($message) {
$message .= chr(128);
while (((strlen($message) + 8) % 64) !== 0) {
$message .= chr(0);
}
return $message;
}
function rotl($x, $n) {
return ($x << $n) | ($x >> (32 - $n));
}
function f($x, $y, $z) {
return ($x & $y) | (~$x & $z);
}
function g($x, $y, $z)
{
return ($x & $y) | ($x & $z) | ($y & $z);
}
function h($x, $y, $z)
{
return $x ^ $y ^ $z;
}
function md4_hash($message) {
list($a, $b, $c, $d) = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476];
$originalSize = strlen($message) * 8;
$message = preProcess($message);
$chunks = str_split($message, 64);
foreach ($chunks as $chunk) {
$words = str_split($chunk, 4);
foreach ($words as $i => $chrs) {
$chrs = str_split($chrs);
$word = '';
$chrs = array_reverse($chrs);
foreach ($chrs as $chr) {
$word .= sprintf('%08b', ord($chr));
}
$words[$i] = bindec($word);
}
if (count($words) < 64) {
$words[] = 0x00000000ffffffff & $originalSize;
$words[] = 0xffffffff00000000 & $originalSize;
}
list($aa, $bb, $cc, $dd) = [$a, $b, $c, $d];
foreach ([0, 4, 8, 12] as $i) {
$a = rotl($a + f($b, $c, $d) + $words[$i+0] & 0xffffffff, 3);
$d = rotl($d + f($a, $b, $c) + $words[$i+1] & 0xffffffff, 7);
$c = rotl($c + f($d, $a, $b) + $words[$i+2] & 0xffffffff, 11);
$b = rotl($b + f($c, $d, $a) + $words[$i+3] & 0xffffffff, 19) ;
}
foreach ([0, 1, 2, 3] as $i) {
$a = rotl($a + g($b, $c, $d) + $words[$i+0] + 0x5a827999 & 0xffffffff, 3);
$d = rotl($d + g($a, $b, $c) + $words[$i+4] + 0x5a827999 & 0xffffffff, 5);
$c = rotl($c + g($d, $a, $b) + $words[$i+8] + 0x5a827999 & 0xffffffff, 9);
$b = rotl($b + g($c, $d, $a) + $words[$i+12] + 0x5a827999 & 0xffffffff, 13);
}
foreach ([0, 2, 1, 3] as $i) {
$a = rotl($a + h($b, $c, $d) + $words[$i+0] + 0x6ed9eba1 & 0xffffffff, 3);
$d = rotl($d + h($a, $b, $c) + $words[$i+8] + 0x6ed9eba1 & 0xffffffff, 9);
$c = rotl($c + h($d, $a, $b) + $words[$i+4] + 0x6ed9eba1 & 0xffffffff, 11);
$b = rotl($b + h($c, $d, $a) + $words[$i+12] + 0x6ed9eba1 & 0xffffffff, 15);
}
$a = $a + $aa & 0xffffffff;
$b = $b + $bb & 0xffffffff;
$c = $c + $cc & 0xffffffff;
$d = $d + $dd & 0xffffffff;
}
$x = pack('V4', $a, $b, $c, $d);
return bin2hex($x);
}
echo md4_hash('message digest'),PHP_EOL;
echo hash('md4', 'message digest'),PHP_EOL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment