From 4a86439812ef0ca400db9367f8c04c8defe6e6ac Mon Sep 17 00:00:00 2001 From: Snack Date: Fri, 10 Oct 2014 23:53:24 +0900 Subject: [PATCH] README and PHP --- README.md | 25 +++++ md6.php | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 README.md create mode 100644 md6.php diff --git a/README.md b/README.md new file mode 100644 index 0000000..b0098b8 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# md6 + +md6 FTW + +## Supports + +* php + +## LICENSE + +``` + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2014 Snack + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. +``` \ No newline at end of file diff --git a/md6.php b/md6.php new file mode 100644 index 0000000..66f203c --- /dev/null +++ b/md6.php @@ -0,0 +1,267 @@ +hex($data); + * echo $result; // 7bfaa624f661a683be2a3b2007493006a30a7845ee1670e499927861a8e74cce + * + */ +class md6hash { + private function to_word($input) { + $output = array(); + + for($i = 0 ; $i < count($input) ; $i += 8) { + array_push($output, array( + (($input[$i ] << 24) | ($input[$i+1] << 16) | ($input[$i+2] << 8) | ($input[$i+3])), + (($input[$i+4] << 24) | ($input[$i+5] << 16) | ($input[$i+6] << 8) | ($input[$i+7])) + )); + } + + return $output; + } + + private function from_word($input) { + $output = array(); + + for($i = 0 ; $i < count($input) ; $i += 1) { + array_push($output, ($input[$i][0] >> 24) & 0xff); + array_push($output, ($input[$i][0] >> 16) & 0xff); + array_push($output, ($input[$i][0] >> 8) & 0xff); + array_push($output, ($input[$i][0] >> 0) & 0xff); + array_push($output, ($input[$i][1] >> 24) & 0xff); + array_push($output, ($input[$i][1] >> 16) & 0xff); + array_push($output, ($input[$i][1] >> 8) & 0xff); + array_push($output, ($input[$i][1] >> 0) & 0xff); + } + + return $output; + } + + private function _xor($x, $y) { + return array($x[0] ^ $y[0], $x[1] ^ $y[1]); + } + + private function _and($x, $y) { + return array($x[0] & $y[0], $x[1] & $y[1]); + } + private function _shl($x, $n) { + $a = $x[0]; + $b = $x[1]; + + if($n >= 32) { + return array(($b << ($n - 32)) & 0xffffffff, 0x00000000); + } + else { + return array((($a << $n) | ($b >> (32 - $n))) & 0xffffffff, ($b << $n) & 0xffffffff); + } + } + + private function _shr($x, $n) { + $a = $x[0]; + $b = $x[1]; + + if($n >= 32) { + return array(0x00000000, $a >> ($n - 32)); + } + else { + return array(($a >> $n) & 0xffffffff, (($a << (32 - $n)) | ($b >> $n)) & 0xffffffff); + } + } + + private function crop($size, $hash, $right = false) { + $length = floor(($size + 7) / 8); + $remain = $size % 8; + + if($right) { + $hash = array_slice($hash, count($hash) - $length); + } + else { + $hash = array_slice($hash, 0, $length); + } + if($remain > 0) { + $hash[$length - 1] &= (0xff << (8 - $remain)) & 0xff; + } + + return $hash; + } + + private function bytes($input) { + $output = array(); + $length = strlen($input); + + for($i = 0 ; $i < $length ; $i++) { + array_push($output, ord($input[$i])); + } + + return $output; + } + + private function f($N) { + $S = array_merge(array(), $this->S0); + $A = array_merge(array(), $N); + + for($j = 0, $i = $this->n ; $j < $this->r ; $j += 1, $i += 16) { + for($s = 0 ; $s < 16 ; $s += 1) { + $x = array_merge(array(), $S); + $x = $this->_xor($x, $A[$i + $s - $this->t[5]]); + $x = $this->_xor($x, $A[$i + $s - $this->t[0]]); + $x = $this->_xor($x, $this->_and($A[$i + $s - $this->t[1]], $A[$i + $s - $this->t[2]])); + $x = $this->_xor($x, $this->_and($A[$i + $s - $this->t[3]], $A[$i + $s - $this->t[4]])); + $x = $this->_xor($x, $this->_shr($x, $this->rs[$s])); + $A[$i + $s] = $this->_xor($x, $this->_shl($x, $this->ls[$s])); + } + + $S = $this->_xor($this->_xor($this->_shl($S, 1), $this->_shr($S, 63)), $this->_and($S, $this->Sm)); + } + return array_slice($A, count($A) - 16); + } + + private function mid($B, $C, $i, $p, $z) { + $U = array( + (($this->ell & 0xff) << 24) | (($i / 0xffffffff) & 0xffffff), + $i & 0xffffffff + ); + + $V = array( + (($this->r & 0xfff) << 16) | (($this->L & 0xff) << 8) | (($z & 0xf) << 4) | (($p & 0xf000) >> 12), + (($p & 0xfff) << 20) | (($this->k & 0xff) << 12) | (($this->d & 0xfff)) + ); + + return $this->f(array_merge($this->Q, $this->K, array($U, $V), $C, $B)); + } + + private function par($M) { + $P = 0; + $B = array(); + $C = array(); + + $z = count($M) > $this->b ? 0 : 1; + + while(count($M) < 1 || (count($M) % $this->b) > 0) { + array_push($M, 0x00); + $P += 8; + } + + $M = $this->to_word($M); + + while(count($M) > 0) { + array_push($B, array_slice($M, 0, ($this->b / 8))); + $M = array_slice($M, $this->b / 8); + } + + for($i = 0, $p = 0, $l = count($B) ; $i < $l ; $i += 1, $p = 0) { + $p = ($i === (count($B) - 1)) ? $P : 0; + $C = array_merge($C, $this->mid($B[$i], array(), $i, $p, $z)); + } + + return $this->from_word($C); + } + + private function seq($M) { + $P = 0; + $B = array(); + $C = array( + array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0), + array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0), + array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0), + array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0), array(0x0, 0x0) + ); + + while(count($M) < 1 || (count($M) % ($this->b - $this->c)) > 0) { + array_push($M, 0x00); + $P += 8; + } + + $M = $this->to_word($M); + + while(count($M) > 0) { + array_push($B, array_slice($M, 0, (($this->b - $this->c) / 8))); + $M = array_slice(($this->b - $this->c) / 8); + } + + for($i = 0, $p = 0, $l = count($B) ; $i < $l ; $i += 1, $p = 0) { + $p = ($i === (count($B) - 1)) ? $P : 0; + $z = ($i === (count($B) - 1)) ? 1 : 0; + $C = $this->mid($B[$i], $C, $i, $p, $z); + } + + return $this->from_word($C); + } + + private $b, $c, $n, $d, $K, $k, $r, $L, $ell, $S0, $Sm, $Q, $t, $rs, $ls; + + private function _hash($data, $size, $key, $levels) { + $this->b = 512; + $this->c = 128; + + $this->n = 89; + + $this->d = $size; + $this->M = $data; + + $this->K = array_slice($key, 0, 64); + $this->k = count($this->K); + + while(count($this->K) < 64) { + array_push($this->K, 0x00); + } + + $this->K = $this->to_word($this->K); + + $this->r = max(($this->k ? 80 : 0), (40 + ($this->d / 4))); + + $this->L = $levels; + $this->ell = 0; + + $this->S0 = array(0x01234567, 0x89abcdef); + $this->Sm = array(0x7311c281, 0x2425cfa0); + + $this->Q = array( + array(0x7311c281, 0x2425cfa0), array(0x64322864, 0x34aac8e7), array(0xb60450e9, 0xef68b7c1), + array(0xe8fb2390, 0x8d9f06f1), array(0xdd2e76cb, 0xa691e5bf), array(0x0cd0d63b, 0x2c30bc41), + array(0x1f8ccf68, 0x23058f8a), array(0x54e5ed5b, 0x88e3775d), array(0x4ad12aae, 0x0a6d6031), + array(0x3e7f16bb, 0x88222e0d), array(0x8af8671d, 0x3fb50c2c), array(0x995ad117, 0x8bd25c31), + array(0xc878c1dd, 0x04c4b633), array(0x3b72066c, 0x7a1552ac), array(0x0d6f3522, 0x631effcb) + ); + + $this->t = array(17, 18, 21, 31, 67, 89); + $this->rs = array(10, 5, 13, 10, 11, 12, 2, 7, 14, 15, 7, 13, 11, 7, 6, 12); + $this->ls = array(11, 24, 9, 16, 15, 9, 27, 15, 6, 2, 29, 8, 15, 5, 31, 9); + + do { + $this->ell += 1; + + $this->M = $this->ell > $this->L ? $this->seq($this->M) : $this->par($this->M); + } while(count($this->M) !== $this->c); + + return $this->crop($this->d, $this->M, true); + } + + private function _prehash($data, $size, $key, $levels) { + $data = $this->bytes($data); + $key = $this->bytes($key); + + if($size <= 0) $size = 1; + if($size > 512) $size = 512; + + return $this->_hash($data, $size, $key, $levels); + } + + public function hex($data = "", $size = 256, $key = "", $levels = 64) { + $hash = $this->_prehash($data, $size, $key, $levels); + $hex = ""; + foreach($hash as $v) $hex .= str_pad(dechex($v), 2, "0", STR_PAD_LEFT); + return $hex; + } + + public function raw($data = "", $size = 256, $key = "", $levels = 64) { + $hash = $this->_prehash($data, $size, $key, $levels); + $raw = ""; + foreach($hash as $v) $raw .= chr($v); + return $raw; + } +} \ No newline at end of file