4
/*******************************************************************************
6
* SHA256 static class for PHP4
7
* implemented by feyd _at_ devnetwork .dot. net
8
* specification from http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
10
* ? Copyright 2005 Developer's Network. All rights reserved.
11
* This is licensed under the Lesser General Public License (LGPL)
13
* Thanks to CertainKey Inc. for providing some example outputs in Javascript
15
*----- Version 1.0.1 ----------------------------------------------------------
18
* string SHA256::hash( string message[, string format ])
21
* SHA256::hash() is a static function that must be called with `message`
22
* and optionally `format`. Possible values for `format` are:
23
* 'bin' binary string output
24
* 'hex' default; hexidecimal string output (lower case)
26
* Failures return FALSE.
29
* $hash = SHA256::hash('string to hash');
31
******************************************************************************/
34
// hashing class state and storage object. Abstract base class only.
42
// hashing class. Abstract base class only.
45
// The base modes are:
46
// 'bin' - binary output (most compact)
47
// 'bit' - bit output (largest)
48
// 'oct' - octal output (medium-large)
49
// 'hex' - hexidecimal (default, medium)
51
// perform a hash on a string
52
function hash($str, $mode = 'hex')
54
trigger_error('hash::hash() NOT IMPLEMENTED', E_USER_WARNING);
58
// chop the resultant hash into $length byte chunks
59
function hashChunk($str, $length, $mode = 'hex')
61
trigger_error('hash::hashChunk() NOT IMPLEMENTED', E_USER_WARNING);
65
// perform a hash on a file
66
function hashFile($filename, $mode = 'hex')
68
trigger_error('hash::hashFile() NOT IMPLEMENTED', E_USER_WARNING);
72
// chop the resultant hash into $length byte chunks
73
function hashChunkFile($filename, $length, $mode = 'hex')
75
trigger_error('hash::hashChunkFile() NOT IMPLEMENTED', E_USER_WARNING);
84
class SHA256Data extends hashData
92
function SHA256Data($str)
94
$M = strlen($str); // number of bytes
95
$L1 = ($M >> 28) & 0x0000000F; // top order bits
96
$L2 = $M << 3; // number of bits
97
$l = pack('N*', $L1, $L2);
99
// 64 = 64 bits needed for the size mark. 1 = the 1 bit added to the
100
// end. 511 = 511 bits to get the number to be at least large enough
101
// to require one block. 512 is the block size.
102
$k = $L2 + 64 + 1 + 511;
103
$k -= $k % 512 + $L2 + 64 + 1;
104
$k >>= 3; // convert to byte count
106
$str .= chr(0x80) . str_repeat(chr(0), $k) . $l;
108
assert('strlen($str) % 64 == 0');
110
// break the binary string into 512-bit blocks
111
preg_match_all( '#.{64}#', $str, $this->chunks );
112
$this->chunks = $this->chunks[0];
118
(int)0x6A09E667, (int)0xBB67AE85,
119
(int)0x3C6EF372, (int)0xA54FF53A,
120
(int)0x510E527F, (int)0x9B05688C,
121
(int)0x1F83D9AB, (int)0x5BE0CD19,
127
1779033703, -1150833019,
128
1013904242, -1521486534,
129
1359893119, -1694144372,
130
528734635, 1541459225,
136
// static class. Access via SHA256::hash()
137
class SHA256 extends hash
139
function hash($str, $mode = 'hex')
141
static $modes = array( 'hex', 'bin', 'bit' );
144
if(!in_array(strtolower($mode), $modes))
146
trigger_error('mode specified is unrecognized: ' . $mode, E_USER_WARNING);
150
$data =& new SHA256Data($str);
152
SHA256::compute($data);
154
$func = array('SHA256', 'hash' . $mode);
155
if(is_callable($func))
157
$func = 'hash' . $mode;
158
$ret = SHA256::$func($data);
159
//$ret = call_user_func($func, $data);
163
trigger_error('SHA256::hash' . $mode . '() NOT IMPLEMENTED.', E_USER_WARNING);
171
// begin internal functions
177
for($x = 0, $y = func_num_args(); $x < $y; $x++)
180
$a = func_get_arg($x);
185
for($i = 0; $i < 32; $i++)
187
// sum of the bits at $i
188
$j = (($T >> $i) & 1) + (($a >> $i) & 1) + $c;
189
// carry of the bits at $i
205
function compute(&$hashData)
207
static $vars = 'abcdefgh';
214
(int)0x428A2F98, (int)0x71374491, (int)0xB5C0FBCF, (int)0xE9B5DBA5,
215
(int)0x3956C25B, (int)0x59F111F1, (int)0x923F82A4, (int)0xAB1C5ED5,
216
(int)0xD807AA98, (int)0x12835B01, (int)0x243185BE, (int)0x550C7DC3,
217
(int)0x72BE5D74, (int)0x80DEB1FE, (int)0x9BDC06A7, (int)0xC19BF174,
218
(int)0xE49B69C1, (int)0xEFBE4786, (int)0x0FC19DC6, (int)0x240CA1CC,
219
(int)0x2DE92C6F, (int)0x4A7484AA, (int)0x5CB0A9DC, (int)0x76F988DA,
220
(int)0x983E5152, (int)0xA831C66D, (int)0xB00327C8, (int)0xBF597FC7,
221
(int)0xC6E00BF3, (int)0xD5A79147, (int)0x06CA6351, (int)0x14292967,
222
(int)0x27B70A85, (int)0x2E1B2138, (int)0x4D2C6DFC, (int)0x53380D13,
223
(int)0x650A7354, (int)0x766A0ABB, (int)0x81C2C92E, (int)0x92722C85,
224
(int)0xA2BFE8A1, (int)0xA81A664B, (int)0xC24B8B70, (int)0xC76C51A3,
225
(int)0xD192E819, (int)0xD6990624, (int)0xF40E3585, (int)0x106AA070,
226
(int)0x19A4C116, (int)0x1E376C08, (int)0x2748774C, (int)0x34B0BCB5,
227
(int)0x391C0CB3, (int)0x4ED8AA4A, (int)0x5B9CCA4F, (int)0x682E6FF3,
228
(int)0x748F82EE, (int)0x78A5636F, (int)0x84C87814, (int)0x8CC70208,
229
(int)0x90BEFFFA, (int)0xA4506CEB, (int)0xBEF9A3F7, (int)0xC67178F2
233
1116352408, 1899447441, -1245643825, -373957723,
234
961987163, 1508970993, -1841331548, -1424204075,
235
-670586216, 310598401, 607225278, 1426881987,
236
1925078388, -2132889090, -1680079193, -1046744716,
237
-459576895, -272742522, 264347078, 604807628,
238
770255983, 1249150122, 1555081692, 1996064986,
239
-1740746414, -1473132947, -1341970488, -1084653625,
240
-958395405, -710438585, 113926993, 338241895,
241
666307205, 773529912, 1294757372, 1396182291,
242
1695183700, 1986661051, -2117940946, -1838011259,
243
-1564481375, -1474664885, -1035236496, -949202525,
244
-778901479, -694614492, -200395387, 275423344,
245
430227734, 506948616, 659060556, 883997877,
246
958139571, 1322822218, 1537002063, 1747873779,
247
1955562222, 2024104815, -2067236844, -1933114872,
248
-1866530822, -1538233109, -1090935817, -965641998,
253
for($i = 0, $numChunks = sizeof($hashData->chunks); $i < $numChunks; $i++)
255
// initialize the registers
256
for($j = 0; $j < 8; $j++)
257
${$vars{$j}} = $hashData->hash[$j];
259
// the SHA-256 compression function
260
for($j = 0; $j < 64; $j++)
264
$T1 = ord($hashData->chunks[$i]{$j*4 }) & 0xFF; $T1 <<= 8;
265
$T1 |= ord($hashData->chunks[$i]{$j*4+1}) & 0xFF; $T1 <<= 8;
266
$T1 |= ord($hashData->chunks[$i]{$j*4+2}) & 0xFF; $T1 <<= 8;
267
$T1 |= ord($hashData->chunks[$i]{$j*4+3}) & 0xFF;
272
$W[$j] = SHA256::sum(((($W[$j-2] >> 17) & 0x00007FFF) | ($W[$j-2] << 15)) ^ ((($W[$j-2] >> 19) & 0x00001FFF) | ($W[$j-2] << 13)) ^ (($W[$j-2] >> 10) & 0x003FFFFF), $W[$j-7], ((($W[$j-15] >> 7) & 0x01FFFFFF) | ($W[$j-15] << 25)) ^ ((($W[$j-15] >> 18) & 0x00003FFF) | ($W[$j-15] << 14)) ^ (($W[$j-15] >> 3) & 0x1FFFFFFF), $W[$j-16]);
275
$T1 = SHA256::sum($h, ((($e >> 6) & 0x03FFFFFF) | ($e << 26)) ^ ((($e >> 11) & 0x001FFFFF) | ($e << 21)) ^ ((($e >> 25) & 0x0000007F) | ($e << 7)), ($e & $f) ^ (~$e & $g), $K[$j], $W[$j]);
276
$T2 = SHA256::sum(((($a >> 2) & 0x3FFFFFFF) | ($a << 30)) ^ ((($a >> 13) & 0x0007FFFF) | ($a << 19)) ^ ((($a >> 22) & 0x000003FF) | ($a << 10)), ($a & $b) ^ ($a & $c) ^ ($b & $c));
280
$e = SHA256::sum($d, $T1);
284
$a = SHA256::sum($T1, $T2);
287
// compute the next hash set
288
for($j = 0; $j < 8; $j++)
289
$hashData->hash[$j] = SHA256::sum(${$vars{$j}}, $hashData->hash[$j]);
294
// set up the display of the hash in hex.
295
function hashHex(&$hashData)
299
reset($hashData->hash);
302
$str .= sprintf('%08x', current($hashData->hash));
304
while(next($hashData->hash));
310
// set up the output of the hash in binary
311
function hashBin(&$hashData)
315
reset($hashData->hash);
318
$str .= pack('N', current($hashData->hash));
320
while(next($hashData->hash));
328
// REMOVAL ALL FUNCTIONS AFTER THIS WHEN NOT TESTING
331
// format a string into 4 byte hex chunks
332
function hexerize($str)
339
$o = 'array(' . sizeof($str) . ')::' . "\n\n";
340
while($s = current($str))
345
$o .= 'end array;'."\n";
349
if(is_integer($str) || is_float($str))
350
$str = pack('N',$str);
351
$o = 'string(' . strlen($str) . ')' . "::\n";
352
for($i = 0, $j = strlen($str); $i < $j; $i++, $b = $i % 4)
354
$o .= sprintf('%02X', ord($str{$i}));
355
// only process when 32-bits have passed through
356
if($i != 0 && $b == 3)
358
// process new line points
381
$test = array('abc','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq');
383
foreach($test as $str)
385
echo 'Testing ' . var_export($str,true) . "\n";
386
list($s1,$s2) = explode(' ', microtime());
387
for($x = 0; $x < $it; $x++)
388
$data =& new SHA256Data($str);
389
list($e1,$e2) = explode(' ', microtime());
390
echo hexerize($data->chunks);
391
echo hexerize($data->hash);
392
echo 'processing took ' . (($e2 - $s2 + $e1 - $s1) / $it) . ' seconds.' . "\n\n\n";
404
$test = array('abc','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq');
406
foreach($test as $str)
408
echo 'Testing ' . var_export($str,true) . "\n";
409
list($s1,$s2) = explode(' ', microtime());
410
for($x = 0; $x < $it; $x++)
411
$o = SHA256::hash($str);
412
list($e1,$e2) = explode(' ', microtime());
414
echo 'processing took ' . (($e2 - $s2 + $e1 - $s1) / $it) . ' seconds.' . "\n\n\n";
424
echo SHA256::sum(1,2,3,4,5,6,7,8,9,10);
429
function testSpeedHash($it = 10)
440
''=>'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
441
'abc'=>'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
442
'message digest'=>'f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650',
443
'secure hash algorithm'=>'f30ceb2bb2829e79e4ca9753d35a8ecc00262d164cc077080295381cbd643f0d',
444
'SHA256 is considered to be safe'=>'6819d915c73f4d1e77e4e1b52d1fa0f9cf9beaead3939f15874bd988e2a23630',
445
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'=>'248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1',
446
'For this sample, this 63-byte string will be used as input data'=>'f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342',
447
'This is exactly 64 bytes long, not counting the terminating byte'=>'ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8',
450
foreach($test as $str => $hash)
452
echo 'Testing ' . var_export($str,true) . "\n";
453
echo 'Start time: ' . date('Y-m-d H:i:s') . "\n";
456
list($s1,$s2) = explode(' ', microtime());
457
$o = SHA256::hash($str);
458
list($e1,$e2) = explode(' ', microtime());
459
echo 'estimated time to perform test: ' . (($e2 - $s2 + $e1 - $s1) * $it) . ' seconds for ' . $it . ' iterations.' . "\n";
463
for($x = 0; $x < $it; $x++)
465
list($s1,$s2) = explode(' ', microtime());
466
$o = SHA256::hash($str);
467
list($e1,$e2) = explode(' ', microtime());
468
$t += $e2 - $s2 + $e1 - $s1;
470
echo var_export($o,true) . ' == ' . var_export($hash,true) . ' ' . (strcasecmp($o,$hash)==0 ? 'PASSED' : 'FAILED') . "\n";
471
echo 'processing took ' . ($t / $it) . ' seconds.' . "\n\n\n";
483
/* EOF :: Document Settings: tab:4; */
b'\\ No newline at end of file'