~adamzammit/quexs/quexscativm

« back to all changes in this revision

Viewing changes to include/limesurvey/admin/classes/core/sha256.php

  • Committer: azammitdcarf
  • Date: 2008-10-15 04:55:53 UTC
  • Revision ID: svn-v4:fd4a0071-7450-0410-a91b-842f6942ebe7:trunk:6
Import from DCARF SVN

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
 
 
4
/*******************************************************************************
 
5
 *
 
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
 
9
 *
 
10
 *      ? Copyright 2005 Developer's Network. All rights reserved.
 
11
 *      This is licensed under the Lesser General Public License (LGPL)
 
12
 *     
 
13
 *      Thanks to CertainKey Inc. for providing some example outputs in Javascript
 
14
 *
 
15
 *----- Version 1.0.1 ----------------------------------------------------------
 
16
 *
 
17
 *      Syntax:
 
18
 *            string SHA256::hash( string message[, string format ])
 
19
 *
 
20
 *      Description:
 
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)
 
25
 *
 
26
 *            Failures return FALSE.
 
27
 *
 
28
 *      Usage:
 
29
 *            $hash = SHA256::hash('string to hash');
 
30
 *
 
31
 ******************************************************************************/
 
32
 
 
33
 
 
34
//      hashing class state and storage object. Abstract base class only.
 
35
class hashData
 
36
{
 
37
        //      final hash
 
38
        var $hash = null;
 
39
}
 
40
 
 
41
 
 
42
//      hashing class. Abstract base class only.
 
43
class hash
 
44
{
 
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)
 
50
 
 
51
        //      perform a hash on a string
 
52
        function hash($str, $mode = 'hex')
 
53
        {
 
54
                trigger_error('hash::hash() NOT IMPLEMENTED', E_USER_WARNING);
 
55
                return false;
 
56
        }
 
57
 
 
58
        //      chop the resultant hash into $length byte chunks
 
59
        function hashChunk($str, $length, $mode = 'hex')
 
60
        {
 
61
                trigger_error('hash::hashChunk() NOT IMPLEMENTED', E_USER_WARNING);
 
62
                return false;
 
63
        }
 
64
       
 
65
        //      perform a hash on a file
 
66
        function hashFile($filename, $mode = 'hex')
 
67
        {
 
68
                trigger_error('hash::hashFile() NOT IMPLEMENTED', E_USER_WARNING);
 
69
                return false;
 
70
        }
 
71
 
 
72
        //      chop the resultant hash into $length byte chunks
 
73
        function hashChunkFile($filename, $length, $mode = 'hex')
 
74
        {
 
75
                trigger_error('hash::hashChunkFile() NOT IMPLEMENTED', E_USER_WARNING);
 
76
                return false;
 
77
        }
 
78
}
 
79
 
 
80
 
 
81
//      ------------
 
82
 
 
83
 
 
84
class SHA256Data extends hashData
 
85
{
 
86
        //      buffer
 
87
        var $buf = array();
 
88
       
 
89
        //      padded data
 
90
        var $chunks = null;
 
91
       
 
92
        function SHA256Data($str)
 
93
        {
 
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);
 
98
               
 
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
 
105
               
 
106
                $str .= chr(0x80) . str_repeat(chr(0), $k) . $l;
 
107
               
 
108
                assert('strlen($str) % 64 == 0');
 
109
               
 
110
                //      break the binary string into 512-bit blocks
 
111
                preg_match_all( '#.{64}#', $str, $this->chunks );
 
112
                $this->chunks = $this->chunks[0];
 
113
               
 
114
                //      H(0)
 
115
                /*
 
116
                $this->hash = array
 
117
                (
 
118
                        (int)0x6A09E667, (int)0xBB67AE85,
 
119
                        (int)0x3C6EF372, (int)0xA54FF53A,
 
120
                        (int)0x510E527F, (int)0x9B05688C,
 
121
                        (int)0x1F83D9AB, (int)0x5BE0CD19,
 
122
                );
 
123
                */
 
124
               
 
125
                $this->hash = array
 
126
                (
 
127
                        1779033703,          -1150833019,
 
128
                        1013904242,          -1521486534,
 
129
                        1359893119,          -1694144372,
 
130
                        528734635,             1541459225,
 
131
                );
 
132
        }
 
133
}
 
134
 
 
135
 
 
136
//      static class. Access via SHA256::hash()
 
137
class SHA256 extends hash
 
138
{
 
139
        function hash($str, $mode = 'hex')
 
140
        {
 
141
                static $modes = array( 'hex', 'bin', 'bit' );
 
142
                $ret = false;
 
143
               
 
144
                if(!in_array(strtolower($mode), $modes))
 
145
                {
 
146
                        trigger_error('mode specified is unrecognized: ' . $mode, E_USER_WARNING);
 
147
                }
 
148
                else
 
149
                {
 
150
                        $data =& new SHA256Data($str);
 
151
 
 
152
                        SHA256::compute($data);
 
153
 
 
154
                        $func = array('SHA256', 'hash' . $mode);
 
155
                        if(is_callable($func))
 
156
                        {
 
157
                                $func = 'hash' . $mode;
 
158
                                $ret = SHA256::$func($data);
 
159
                                //$ret = call_user_func($func, $data);
 
160
                        }
 
161
                        else
 
162
                        {
 
163
                                trigger_error('SHA256::hash' . $mode . '() NOT IMPLEMENTED.', E_USER_WARNING);
 
164
                        }
 
165
                }
 
166
               
 
167
                return $ret;
 
168
        }
 
169
       
 
170
        //      ------------
 
171
        //      begin internal functions
 
172
       
 
173
        //      32-bit summation
 
174
        function sum()
 
175
        {
 
176
                $T = 0;
 
177
                for($x = 0, $y = func_num_args(); $x < $y; $x++)
 
178
                {
 
179
                        //      argument
 
180
                        $a = func_get_arg($x);
 
181
                       
 
182
                        //      carry storage
 
183
                        $c = 0;
 
184
                       
 
185
                        for($i = 0; $i < 32; $i++)
 
186
                        {
 
187
                                //      sum of the bits at $i
 
188
                                $j = (($T >> $i) & 1) + (($a >> $i) & 1) + $c;
 
189
                                //      carry of the bits at $i
 
190
                                $c = ($j >> 1) & 1;
 
191
                                //      strip the carry
 
192
                                $j &= 1;
 
193
                                //      clear the bit
 
194
                                $T &= ~(1 << $i);
 
195
                                //      set the bit
 
196
                                $T |= $j << $i;
 
197
                        }
 
198
                }
 
199
               
 
200
                return $T;
 
201
        }
 
202
       
 
203
       
 
204
        //      compute the hash
 
205
        function compute(&$hashData)
 
206
        {
 
207
                static $vars = 'abcdefgh';
 
208
                static $K = null;
 
209
               
 
210
                if($K === null)
 
211
                {
 
212
                        /*
 
213
                        $K = array(
 
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
 
230
                                );
 
231
                        */
 
232
                        $K = array (
 
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,
 
249
                                );
 
250
                }
 
251
               
 
252
                $W = array();
 
253
                for($i = 0, $numChunks = sizeof($hashData->chunks); $i < $numChunks; $i++)
 
254
                {
 
255
                        //      initialize the registers
 
256
                        for($j = 0; $j < 8; $j++)
 
257
                                ${$vars{$j}} = $hashData->hash[$j];
 
258
                       
 
259
                        //      the SHA-256 compression function
 
260
                        for($j = 0; $j < 64; $j++)
 
261
                        {
 
262
                                if($j < 16)
 
263
                                {
 
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;
 
268
                                        $W[$j] = $T1;
 
269
                                }
 
270
                                else
 
271
                                {
 
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]);
 
273
                                }
 
274
 
 
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));
 
277
                                $h = $g;
 
278
                                $g = $f;
 
279
                                $f = $e;
 
280
                                $e = SHA256::sum($d, $T1);
 
281
                                $d = $c;
 
282
                                $c = $b;
 
283
                                $b = $a;
 
284
                                $a = SHA256::sum($T1, $T2);
 
285
                        }
 
286
                       
 
287
                        //      compute the next hash set
 
288
                        for($j = 0; $j < 8; $j++)
 
289
                                $hashData->hash[$j] = SHA256::sum(${$vars{$j}}, $hashData->hash[$j]);
 
290
                }
 
291
        }
 
292
       
 
293
       
 
294
        //      set up the display of the hash in hex.
 
295
        function hashHex(&$hashData)
 
296
        {
 
297
                $str = '';
 
298
               
 
299
                reset($hashData->hash);
 
300
                do
 
301
                {
 
302
                        $str .= sprintf('%08x', current($hashData->hash));
 
303
                }
 
304
                while(next($hashData->hash));
 
305
               
 
306
                return $str;
 
307
        }
 
308
       
 
309
       
 
310
        //      set up the output of the hash in binary
 
311
        function hashBin(&$hashData)
 
312
        {
 
313
                $str = '';
 
314
               
 
315
                reset($hashData->hash);
 
316
                do
 
317
                {
 
318
                        $str .= pack('N', current($hashData->hash));
 
319
                }
 
320
                while(next($hashData->hash));
 
321
               
 
322
                return $str;
 
323
        }
 
324
}
 
325
 
 
326
 
 
327
//--------------
 
328
//      REMOVAL ALL FUNCTIONS AFTER THIS WHEN NOT TESTING
 
329
//--------------
 
330
 
 
331
//      format a string into 4 byte hex chunks
 
332
function hexerize($str)
 
333
{
 
334
        $n = 0;
 
335
        $b = 0;
 
336
        if(is_array($str))
 
337
        {
 
338
                reset($str);
 
339
                $o = 'array(' . sizeof($str) . ')::' . "\n\n";
 
340
                while($s = current($str))
 
341
                {
 
342
                        $o .= hexerize($s);
 
343
                        next($str);
 
344
                }
 
345
                $o .= 'end array;'."\n";
 
346
        }
 
347
        else
 
348
        {
 
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)
 
353
                {
 
354
                        $o .= sprintf('%02X', ord($str{$i}));
 
355
                        //      only process when 32-bits have passed through
 
356
                        if($i != 0 && $b == 3)
 
357
                        {
 
358
                                //      process new line points
 
359
                                if($n == 3)
 
360
                                        $o .= "\n";
 
361
                                else
 
362
                                        $o .= ' ';
 
363
                                ++$n;
 
364
                                $n %= 4;
 
365
                        }
 
366
                }
 
367
        }
 
368
       
 
369
        return $o . "\n";
 
370
}
 
371
 
 
372
 
 
373
//      testing functions
 
374
 
 
375
function test1()
 
376
{
 
377
        $it = 1;
 
378
       
 
379
        echo '<pre>';
 
380
 
 
381
        $test = array('abc','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq');
 
382
       
 
383
        foreach($test as $str)
 
384
        {
 
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";
 
393
        }
 
394
 
 
395
        echo '</pre>';
 
396
}
 
397
 
 
398
function test2()
 
399
{
 
400
        $it = 1;
 
401
       
 
402
        echo '<pre>';
 
403
       
 
404
        $test = array('abc','abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq');
 
405
       
 
406
        foreach($test as $str)
 
407
        {
 
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());
 
413
                echo $o;
 
414
                echo 'processing took ' . (($e2 - $s2 + $e1 - $s1) / $it) . ' seconds.' . "\n\n\n";
 
415
        }
 
416
       
 
417
        echo '</pre>';
 
418
}
 
419
 
 
420
function testSum()
 
421
{
 
422
        echo '<pre>';
 
423
       
 
424
        echo SHA256::sum(1,2,3,4,5,6,7,8,9,10);
 
425
       
 
426
        echo '</pre>';
 
427
}
 
428
 
 
429
function testSpeedHash($it = 10)
 
430
{
 
431
        $it = intval($it);
 
432
        if($it === 0)
 
433
                $it = 10;
 
434
       
 
435
        set_time_limit(-1);
 
436
       
 
437
        echo '<pre>' . "\n";
 
438
       
 
439
        $test = array(
 
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',
 
448
                );
 
449
       
 
450
        foreach($test as $str => $hash)
 
451
        {
 
452
                echo 'Testing ' . var_export($str,true) . "\n";
 
453
                echo 'Start time: ' . date('Y-m-d H:i:s') . "\n";
 
454
                if($it > 1)
 
455
                {
 
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";
 
460
                }
 
461
               
 
462
                $t = 0;
 
463
                for($x = 0; $x < $it; $x++)
 
464
                {
 
465
                        list($s1,$s2) = explode(' ', microtime());
 
466
                        $o = SHA256::hash($str);
 
467
                        list($e1,$e2) = explode(' ', microtime());
 
468
                        $t += $e2 - $s2 + $e1 - $s1;
 
469
                }
 
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";
 
472
        }
 
473
       
 
474
        echo '</pre>';
 
475
}
 
476
 
 
477
//testSpeedHash(1);
 
478
 
 
479
//--------------
 
480
//      END REMOVAL HERE
 
481
//--------------
 
482
 
 
483
/* EOF :: Document Settings: tab:4; */
 
484
 
 
485
?>
 
 
b'\\ No newline at end of file'