Jump to content

Implementing MD5 algorithm


techusky

Recommended Posts

I am trying to write a PHP script that implements the MD5 algorithm just so that I can better understand MD5's inner-workings. For those of you already familiar with how MD5 works, could you help me figure out why my script is not producing the correct output?

 

<?php
$string = "";

$a = "01100111010001010010001100000001"; // 0x67452301
$b = "11101111110011011010101110001001"; // 0xEFCDAB89
$c = "10011000101110101101110011111110"; // 0x98BADCFE
$d = "00010000001100100101010001110110"; // 0x10325476

$aa = $a;
$bb = $b;
$cc = $c;
$dd = $d;

// PADDED BINARY FOR NULL STRING, I.E.: ""
$binary_md5 = "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
$binary_md5_words = strlen($binary_md5) / 32;

// SPLIT BINARY INTO 16 32-BIT WORDS
for($i = 1; $i <= $binary_md5_words; $i++) {
    $m[] = substr($binary_md5, ($i - 1) * 32, 32);
}

// GENERATE T-VALUES
for($i = 0; $i < 64; $i++) {
    $T[] = Pad(decbin(floor(4294967296 * abs(sin($i+1)))), 32);
}

/*
// PRINT THE M[K] ARRAY
echo "<h1>m[k] Array</h1><br>";
print_r($m);
echo "<br><br>";

// PRINT THE T[t] ARRAY
echo "<h1>T[t] Array</h1><br>";
print_r($T);
echo "<br><br>";

// TEST ANDxy
echo "<h1>Test ANDxy</h1><br>";
echo "$m[0]<br>$T[0]<br>";
echo ANDxy($m[0], $T[0]);
echo "<br><br>";

// TEST ORxy
echo "<h1>Test ORxy</h1><br>";
echo "$m[0]<br>$T[0]<br>";
echo ORxy($m[0], $T[0]);
echo "<br><br>";

// TEST ADDxy
echo "<h1>Test ADDxy</h1><br>";
echo "$m[0]<br>$T[0]<br>";
echo ADDxy($m[0], $T[0]);
echo "<br><br>";

// TEST XORxy
echo "<h1>Test XORxy</h1><br>";
echo "$m[0]<br>$T[0]<br>";
echo XORxy($m[0], $T[0]);
echo "<br><br>";

// TEST NOTx
echo "<h1>Test NOTx</h1><br>";
echo "$m[0]<br>";
echo NOTx($m[0]);
echo "<br><br>";

// TEST SHIFTleft
echo "<h1>Test SHIFTleft</h1><br>";
echo "$m[0]<br>";
echo SHIFTleft($m[0], 1);
echo "<br><br>";

// TEST F
echo "<h1>Test F</h1><br>";
echo "X = $m[0]<br>Y = $m[1]<br>Z = $m[2]<br>F = ";
echo F($m[0], $m[1], $m[2]);
$step1 = ANDxy($m[0], $m[1]);
$step2 = ANDxy(NOTx($m[0]), $m[2]);
$step3 = ORxy($step1, $step2);
echo "<br>F = $step3";
echo "<br><br>";

// TEST H
echo "<h1>Test H</h1><br>";
echo "X = $m[0]<br>Y = $m[1]<br>Z = $m[2]<br>F = ";
echo H($m[0], $m[1], $m[2]);
echo "<br><br>";
*/

// ROUND 1
$a = ff($a, $b, $c, $d, $m, 0, 7, $T[0]);
$d = ff($d, $a, $b, $c, $m, 1, 12, $T[1]);
$c = ff($c, $d, $a, $b, $m, 2, 17, $T[2]);
$b = ff($b, $c, $d, $a, $m, 3, 22, $T[3]);

$a = ff($a, $b, $c, $d, $m, 4, 7, $T[4]);
$d = ff($d, $a, $b, $c, $m, 5, 12, $T[5]);
$c = ff($c, $d, $a, $b, $m, 6, 17, $T[6]);
$b = ff($b, $c, $d, $a, $m, 7, 22, $T[7]);

$a = ff($a, $b, $c, $d, $m, 8, 7, $T[8]);
$d = ff($d, $a, $b, $c, $m, 9, 12, $T[9]);
$c = ff($c, $d, $a, $b, $m, 10, 17, $T[10]);
$b = ff($b, $c, $d, $a, $m, 11, 22, $T[11]);

$a = ff($a, $b, $c, $d, $m, 12, 17, $T[12]);
$d = ff($d, $a, $b, $c, $m, 13, 12, $T[13]);
$c = ff($c, $d, $a, $b, $m, 14, 17, $T[14]);
$b = ff($b, $c, $d, $a, $m, 15, 22, $T[15]);

// ROUND 2
$a = gg($a, $b, $c, $d, $m, 1, 5, $T[16]);
$d = gg($d, $a, $b, $c, $m, 6, 9, $T[17]);
$c = gg($c, $d, $a, $b, $m, 11, 14, $T[18]);
$b = gg($b, $c, $d, $a, $m, 0, 20, $T[19]);

$a = gg($a, $b, $c, $d, $m, 5, 5, $T[20]);
$d = gg($d, $a, $b, $c, $m, 10, 9, $T[21]);
$c = gg($c, $d, $a, $b, $m, 15, 14, $T[22]);
$b = gg($b, $c, $d, $a, $m, 4, 20, $T[23]);

$a = gg($a, $b, $c, $d, $m, 9, 5, $T[24]);
$d = gg($d, $a, $b, $c, $m, 14, 9, $T[25]);
$c = gg($c, $d, $a, $b, $m, 3, 14, $T[26]);
$b = gg($b, $c, $d, $a, $m, 8, 20, $T[27]);

$a = gg($a, $b, $c, $d, $m, 13, 5, $T[28]);
$d = gg($d, $a, $b, $c, $m, 2, 9, $T[29]);
$c = gg($c, $d, $a, $b, $m, 7, 14, $T[30]);
$b = gg($b, $c, $d, $a, $m, 12, 20, $T[31]);

// ROUND 3
$a = hh($a, $b, $c, $d, $m, 5, 4, $T[32]);
$d = hh($d, $a, $b, $c, $m, 8, 11, $T[33]);
$c = hh($c, $d, $a, $b, $m, 11, 16, $T[34]);
$b = hh($b, $c, $d, $a, $m, 14, 23, $T[35]);

$a = hh($a, $b, $c, $d, $m, 1, 4, $T[36]);
$d = hh($d, $a, $b, $c, $m, 4, 11, $T[37]);
$c = hh($c, $d, $a, $b, $m, 7, 16, $T[38]);
$b = hh($b, $c, $d, $a, $m, 10, 23, $T[39]);

$a = hh($a, $b, $c, $d, $m, 13, 4, $T[40]);
$d = hh($d, $a, $b, $c, $m, 0, 11, $T[41]);
$c = hh($c, $d, $a, $b, $m, 3, 16, $T[42]);
$b = hh($b, $c, $d, $a, $m, 6, 23, $T[43]);

$a = hh($a, $b, $c, $d, $m, 9, 4, $T[44]);
$d = hh($d, $a, $b, $c, $m, 12, 11, $T[45]);
$c = hh($c, $d, $a, $b, $m, 15, 16, $T[46]);
$b = hh($b, $c, $d, $a, $m, 2, 23, $T[47]);

// ROUND 4
$a = ii($a, $b, $c, $d, $m, 0, 6, $T[48]);
$d = ii($d, $a, $b, $c, $m, 7, 10, $T[49]);
$c = ii($c, $d, $a, $b, $m, 14, 15, $T[50]);
$b = ii($b, $c, $d, $a, $m, 5, 21, $T[51]);

$a = ii($a, $b, $c, $d, $m, 12, 6, $T[52]);
$d = ii($d, $a, $b, $c, $m, 3, 10, $T[53]);
$c = ii($c, $d, $a, $b, $m, 10, 15, $T[54]);
$b = ii($b, $c, $d, $a, $m, 1, 21, $T[55]);

$a = ii($a, $b, $c, $d, $m, 8, 6, $T[56]);
$d = ii($d, $a, $b, $c, $m, 15, 10, $T[57]);
$c = ii($c, $d, $a, $b, $m, 6, 15, $T[58]);
$b = ii($b, $c, $d, $a, $m, 13, 21, $T[59]);

$a = ii($a, $b, $c, $d, $m, 4, 6, $T[60]);
$d = ii($d, $a, $b, $c, $m, 11, 10, $T[61]);
$c = ii($c, $d, $a, $b, $m, 2, 15, $T[62]);
$b = ii($b, $c, $d, $a, $m, 9, 21, $T[63]);

$a = ADDxy($a, $aa);
$b = ADDxy($b, $bb);
$c = ADDxy($c, $cc);
$d = ADDxy($d, $dd);

// ECHO RESULTS
echo "<h1>String</h1><br>";
echo "String: '$string'<br>";
$md5 = md5($string);
echo "MD5: $md5<br><br>";
$md5_1 = substr($md5, 0, ;
$md5_2 = substr($md5, 8, ;
$md5_3 = substr($md5, 16, ;
$md5_4 = substr($md5, 24, ;
echo "A = $md5_1<br>B = $md5_2<br>C = $md5_3<br>D = $md5_4<br><br>";
$md5_bin_a = Pad(decbin(hexdec($md5_1)), 32); 
$md5_bin_b = Pad(decbin(hexdec($md5_2)), 32); 
$md5_bin_c = Pad(decbin(hexdec($md5_3)), 32); 
$md5_bin_d = Pad(decbin(hexdec($md5_4)), 32); 
echo "A = $md5_bin_a<br>B = $md5_bin_b<br>C = $md5_bin_c<br>D = $md5_bin_d<br><br>";
echo "<h1>Results</h1><br>";
echo "A = $a<br>B = $b<br>C = $c<br>D = $d<br><br>";
$a_dec = bindec($a);
$b_dec = bindec($b);
$c_dec = bindec($c);
$d_dec = bindec($d);
$a_hex = dechex($a_dec);
$b_hex = dechex($b_dec);
$c_hex = dechex($c_dec);
$d_hex = dechex($d_dec);
echo "A = $a_hex<br>B = $b_hex<br>C = $c_hex<br>D = $d_hex<br><br>";

// FUNCTIONS
function ff($a, $b, $c, $d, $m, $k, $s, $t) {
    //a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
    return ADDxy($b, SHIFTleft(ADDxy(ADDxy(ADDxy($a, F($b, $c, $d)), $m[$k]), $t), $s));
}

function gg($a, $b, $c, $d, $m, $k, $s, $t) {
    //a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
    return ADDxy($b, SHIFTleft(ADDxy(ADDxy(ADDxy($a, G($b, $c, $d)), $m[$k]), $t), $s));
}

function hh($a, $b, $c, $d, $m, $k, $s, $t) {
    //a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
    return ADDxy($b, SHIFTleft(ADDxy(ADDxy(ADDxy($a, H($b, $c, $d)), $m[$k]), $t), $s));
}

function ii($a, $b, $c, $d, $m, $k, $s, $t) {
    //a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
    return ADDxy($b, SHIFTleft(ADDxy(ADDxy(ADDxy($a, I($b, $c, $d)), $m[$k]), $t), $s));
}

function F($X, $Y, $Z) {
    //return ($X & $Y) | ((~$X) & $Z);
    return ORxy(ANDxy($X, $Y), ANDxy(NOTx($X), $Z));
}

function G($X, $Y, $Z) {
    //return ($X & $Z) | ($Y & (~$Z));
    return ORxy(ANDxy($X, $Z), ANDxy($Y, NOTx($Z)));
}

function H($X, $Y, $Z) {
    //return $X ^ $Y ^ $Z;
    return XORxy(XORxy($X, $Y), $Z);
}

function I($X, $Y, $Z) {
    //return $Y ^ ($X | (~$Z));
    return XORxy($Y, ORxy($X, NOTx($Z)));
}

function Pad($binary, $pad_length) {
    $pad_length = $pad_length - strlen($binary);
    for($i = 0; $i < $pad_length; $i++) {
        $padding .= '0';
    }
    return $padding . $binary;
}

function mod($val, $div) {
    $r = $val - (floor($val/$div)*$div);
    return $r;
}
function ANDxy($x, $y) {
    $x_dec = bindec($x);
    $y_dec = bindec($y);
    
    $result = $x_dec & $y_dec;
    $result = Pad(decbin($result), strlen($x));
    
    return $result;   
}

function ORxy($x, $y) {
    $x_dec = bindec($x);
    $y_dec = bindec($y);
    
    $result = $x_dec | $y_dec;
    $result = Pad(decbin($result), strlen($x));
    
    return $result;   
}

function ADDxy($x, $y) {
    $x_dec = bindec($x);
    $y_dec = bindec($y);
    
    $result = mod($x_dec + $y_dec, pow(2, 32));
    $result = Pad(decbin($result), strlen($x));
    
    return $result;   
}

function XORxy($x, $y) {
    $x_dec = bindec($x);
    $y_dec = bindec($y);
    
    $result = $x_dec ^ $y_dec;
    $result = Pad(decbin($result), strlen($x));
    
    return $result;   
}

function NOTx($x) {
    $x_dec = bindec($x);
    
    $result = ~$x_dec;
    $result = Pad(decbin($result), strlen($x));
    
    return $result;
}

function SHIFTleft($x, $y) {
    $x_dec = bindec($x);
    
    $result = $x_dec << $y;
    $result = Pad(decbin($result), strlen($x));
    
    return $result;   
}

function SHIFTright($x, $y) {
    $x_dec = bindec($x);
    
    $result = $x_dec >> $y;
    $result = Pad(decbin($result), strlen($x));
    
    return $result;   
}
?>

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.