root / docs / www / colonyscout / internal / includes / jCryption-1.1.php @ f59acf11
History | View | Annotate | Download (15.6 KB)
1 | f59acf11 | Dan Shope | <?php
|
---|---|---|---|
2 | /**
|
||
3 | * jCryption
|
||
4 | *
|
||
5 | * PHP versions 4 and 5
|
||
6 | *
|
||
7 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
||
8 | * that is available through the world-wide-web at the following URI:
|
||
9 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||
10 | * the PHP License and are unable to obtain it through the web, please
|
||
11 | * send a note to license@php.net so we can mail you a copy immediately.
|
||
12 | *
|
||
13 | * Many of the functions in this class are from the PEAR Crypt_RSA package ...
|
||
14 | * So most of the credits goes to the original creator of this package Alexander Valyalkin
|
||
15 | * you can get the package under http://pear.php.net/package/Crypt_RSA
|
||
16 | *
|
||
17 | * I just changed, added, removed and improved some functions to fit the needs of jCryption
|
||
18 | *
|
||
19 | * @author Daniel Griesser <daniel.griesser@jcryption.org>
|
||
20 | * @copyright 2009 Daniel Griesser
|
||
21 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||
22 | * @version 1.0.1
|
||
23 | * @link http://jcryption.org/
|
||
24 | */
|
||
25 | class jCryption { |
||
26 | |||
27 | var $_key_len; |
||
28 | var $_e; |
||
29 | |||
30 | /**
|
||
31 | * Constructor
|
||
32 | *
|
||
33 | * @access public
|
||
34 | */
|
||
35 | function jCryption($e = "\x01\x00\x01") { |
||
36 | $this->_e = $e; |
||
37 | } |
||
38 | |||
39 | /**
|
||
40 | * Generates the Keypair with the given keyLength the encryption key e ist set staticlly
|
||
41 | * set to 65537 for faster encryption.
|
||
42 | *
|
||
43 | * @param int $keyLength
|
||
44 | * @return array
|
||
45 | * @access public
|
||
46 | */
|
||
47 | function generateKeypair($keyLength) { |
||
48 | $this->_key_len = intval($keyLength); |
||
49 | if ($this->_key_len < 8) { |
||
50 | $this->_key_len = 8; |
||
51 | } |
||
52 | |||
53 | // set [e] to 0x10001 (65537)
|
||
54 | $e = $this->bin2int($this->_e); |
||
55 | |||
56 | // generate [p], [q] and [n]
|
||
57 | $p_len = intval(($this->_key_len + 1) / 2); |
||
58 | $q_len = $this->_key_len - $p_len; |
||
59 | $p1 = $q1 = 0; |
||
60 | do {
|
||
61 | // generate prime number [$p] with length [$p_len] with the following condition:
|
||
62 | // GCD($e, $p - 1) = 1
|
||
63 | |||
64 | do {
|
||
65 | $p = $this->getPrime($p_len); |
||
66 | $p1 = $this->dec($p); |
||
67 | $tmp = $this->GCD($e, $p1); |
||
68 | } while (!$this->isOne($tmp)); |
||
69 | // generate prime number [$q] with length [$q_len] with the following conditions:
|
||
70 | // GCD($e, $q - 1) = 1
|
||
71 | // $q != $p
|
||
72 | |||
73 | do {
|
||
74 | $q = $this->getPrime($q_len); |
||
75 | //$q = 102238965184417281201422828818276460200050705922822343263269460146519295919831;
|
||
76 | $q1 = $this->dec($q); |
||
77 | $tmp = $this->GCD($e, $q1); |
||
78 | } while (!$this->isOne($tmp) && !$this->cmpAbs($q, $p)); |
||
79 | |||
80 | // if (p < q), then exchange them
|
||
81 | if ($this->cmpAbs($p, $q) < 0) { |
||
82 | $tmp = $p; |
||
83 | $p = $q; |
||
84 | $q = $tmp; |
||
85 | $tmp = $p1; |
||
86 | $p1 = $q1; |
||
87 | $q1 = $tmp; |
||
88 | } |
||
89 | // calculate n = p * q
|
||
90 | $n = $this->mul($p, $q); |
||
91 | |||
92 | } while ($this->bitLen($n) != $this->_key_len); |
||
93 | |||
94 | // calculate d = 1/e mod (p - 1) * (q - 1)
|
||
95 | $pq = $this->mul($p1, $q1); |
||
96 | $d = $this->invmod($e, $pq); |
||
97 | |||
98 | // store RSA keypair attributes
|
||
99 | $keypair = array('n'=>$n, 'e'=>$e, 'd'=>$d, 'p'=>$p, 'q'=>$q); |
||
100 | |||
101 | return $keypair; |
||
102 | } |
||
103 | |||
104 | function useKeys($keys,$keyLength) { |
||
105 | $this->_key_len = intval($keyLength); |
||
106 | if ($this->_key_len < 8) { |
||
107 | $this->_key_len = 8; |
||
108 | } |
||
109 | |||
110 | // set [e] to 0x10001 (65537)
|
||
111 | $e = $this->bin2int($this->_e); |
||
112 | |||
113 | // generate [p], [q] and [n]
|
||
114 | $p_len = intval(($this->_key_len + 1) / 2); |
||
115 | $q_len = $this->_key_len - $p_len; |
||
116 | $p1 = $q1 = 0; |
||
117 | do {
|
||
118 | do {
|
||
119 | $q = $keys[rand(0,count($keys))]; |
||
120 | $p = $keys[rand(0,count($keys))]; |
||
121 | $p1 = $this->dec($p); |
||
122 | $q1 = $this->dec($q); |
||
123 | } while (!$this->cmpAbs($q, $p)); |
||
124 | |||
125 | |||
126 | // if (p < q), then exchange them
|
||
127 | if ($this->cmpAbs($p, $q) < 0) { |
||
128 | $tmp = $p; |
||
129 | $p = $q; |
||
130 | $q = $tmp; |
||
131 | $tmp = $p1; |
||
132 | $p1 = $q1; |
||
133 | $q1 = $tmp; |
||
134 | } |
||
135 | // calculate n = p * q
|
||
136 | $n = $this->mul($p, $q); |
||
137 | |||
138 | } while ($this->bitLen($n) != $this->_key_len); |
||
139 | |||
140 | // calculate d = 1/e mod (p - 1) * (q - 1)
|
||
141 | $pq = $this->mul($p1, $q1); |
||
142 | $d = $this->invmod($e, $pq); |
||
143 | |||
144 | // store RSA keypair attributes
|
||
145 | $keypair = array('n'=>$n, 'e'=>$e, 'd'=>$d, 'p'=>$p, 'q'=>$q); |
||
146 | |||
147 | return $keypair; |
||
148 | } |
||
149 | |||
150 | /**
|
||
151 | * Finds greatest common divider (GCD) of $num1 and $num2
|
||
152 | *
|
||
153 | * @param string $num1
|
||
154 | * @param string $num2
|
||
155 | * @return string
|
||
156 | * @access public
|
||
157 | */
|
||
158 | function GCD($num1, $num2) { |
||
159 | do {
|
||
160 | $tmp = bcmod($num1, $num2); |
||
161 | $num1 = $num2; |
||
162 | $num2 = $tmp; |
||
163 | } while (bccomp($num2, '0')); |
||
164 | return $num1; |
||
165 | } |
||
166 | |||
167 | /**
|
||
168 | * Performs Miller-Rabin primality test for number $num
|
||
169 | * with base $base. Returns true, if $num is strong pseudoprime
|
||
170 | * by base $base. Else returns false.
|
||
171 | *
|
||
172 | * @param string $num
|
||
173 | * @param string $base
|
||
174 | * @return bool
|
||
175 | * @access private
|
||
176 | */
|
||
177 | function _millerTest($num, $base) { |
||
178 | if (!bccomp($num, '1')) { |
||
179 | // 1 is not prime ;)
|
||
180 | return false; |
||
181 | } |
||
182 | $tmp = bcsub($num, '1'); |
||
183 | |||
184 | $zero_bits = 0; |
||
185 | while (!bccomp(bcmod($tmp, '2'), '0')) { |
||
186 | $zero_bits++;
|
||
187 | $tmp = bcdiv($tmp, '2'); |
||
188 | } |
||
189 | |||
190 | $tmp = $this->powmod($base, $tmp, $num); |
||
191 | if (!bccomp($tmp, '1')) { |
||
192 | // $num is probably prime
|
||
193 | return true; |
||
194 | } |
||
195 | |||
196 | while ($zero_bits--) { |
||
197 | if (!bccomp(bcadd($tmp, '1'), $num)) { |
||
198 | // $num is probably prime
|
||
199 | return true; |
||
200 | } |
||
201 | $tmp = $this->powmod($tmp, '2', $num); |
||
202 | } |
||
203 | // $num is composite
|
||
204 | return false; |
||
205 | } |
||
206 | |||
207 | /**
|
||
208 | * Transforms binary representation of large integer into its native form.
|
||
209 | *
|
||
210 | * Example of transformation:
|
||
211 | * $str = "\x12\x34\x56\x78\x90";
|
||
212 | * $num = 0x9078563412;
|
||
213 | *
|
||
214 | * @param string $str
|
||
215 | * @return string
|
||
216 | * @access public
|
||
217 | */
|
||
218 | function bin2int($str) { |
||
219 | $result = '0'; |
||
220 | $n = strlen($str); |
||
221 | do {
|
||
222 | $result = bcadd(bcmul($result, '256'), ord($str {--$n} )); |
||
223 | } while ($n > 0); |
||
224 | return $result; |
||
225 | } |
||
226 | |||
227 | /**
|
||
228 | * Transforms large integer into binary representation.
|
||
229 | *
|
||
230 | * Example of transformation:
|
||
231 | * $num = 0x9078563412;
|
||
232 | * $str = "\x12\x34\x56\x78\x90";
|
||
233 | *
|
||
234 | * @param string $num
|
||
235 | * @return string
|
||
236 | * @access public
|
||
237 | */
|
||
238 | function int2bin($num) { |
||
239 | $result = ''; |
||
240 | do {
|
||
241 | $result .= chr(bcmod($num, '256')); |
||
242 | $num = bcdiv($num, '256'); |
||
243 | } while (bccomp($num, '0')); |
||
244 | return $result; |
||
245 | } |
||
246 | |||
247 | /**
|
||
248 | * Calculates pow($num, $pow) (mod $mod)
|
||
249 | *
|
||
250 | * @param string $num
|
||
251 | * @param string $pow
|
||
252 | * @param string $mod
|
||
253 | * @return string
|
||
254 | * @access public
|
||
255 | */
|
||
256 | function powmod($num, $pow, $mod) { |
||
257 | if (function_exists('bcpowmod')) { |
||
258 | // bcpowmod is only available under PHP5
|
||
259 | return bcpowmod($num, $pow, $mod); |
||
260 | } |
||
261 | |||
262 | // emulate bcpowmod
|
||
263 | $result = '1'; |
||
264 | do {
|
||
265 | if (!bccomp(bcmod($pow, '2'), '1')) { |
||
266 | $result = bcmod(bcmul($result, $num), $mod); |
||
267 | } |
||
268 | $num = bcmod(bcpow($num, '2'), $mod); |
||
269 | $pow = bcdiv($pow, '2'); |
||
270 | } while (bccomp($pow, '0')); |
||
271 | return $result; |
||
272 | } |
||
273 | |||
274 | /**
|
||
275 | * Calculates $num1 * $num2
|
||
276 | *
|
||
277 | * @param string $num1
|
||
278 | * @param string $num2
|
||
279 | * @return string
|
||
280 | * @access public
|
||
281 | */
|
||
282 | function mul($num1, $num2) { |
||
283 | return bcmul($num1, $num2); |
||
284 | } |
||
285 | |||
286 | /**
|
||
287 | * Calculates $num1 % $num2
|
||
288 | *
|
||
289 | * @param string $num1
|
||
290 | * @param string $num2
|
||
291 | * @return string
|
||
292 | * @access public
|
||
293 | */
|
||
294 | function mod($num1, $num2) { |
||
295 | return bcmod($num1, $num2); |
||
296 | } |
||
297 | |||
298 | /**
|
||
299 | * Compares abs($num1) to abs($num2).
|
||
300 | * Returns:
|
||
301 | * -1, if abs($num1) < abs($num2)
|
||
302 | * 0, if abs($num1) == abs($num2)
|
||
303 | * 1, if abs($num1) > abs($num2)
|
||
304 | *
|
||
305 | * @param string $num1
|
||
306 | * @param string $num2
|
||
307 | * @return int
|
||
308 | * @access public
|
||
309 | */
|
||
310 | function cmpAbs($num1, $num2) { |
||
311 | return bccomp($num1, $num2); |
||
312 | } |
||
313 | |||
314 | /**
|
||
315 | * Tests $num on primality. Returns true, if $num is strong pseudoprime.
|
||
316 | * Else returns false.
|
||
317 | *
|
||
318 | * @param string $num
|
||
319 | * @return bool
|
||
320 | * @access private
|
||
321 | */
|
||
322 | function isPrime($num) { |
||
323 | static $primes = null; |
||
324 | static $primes_cnt = 0; |
||
325 | if (is_null($primes)) { |
||
326 | // generate all primes up to 10000
|
||
327 | $primes = array(); |
||
328 | for ($i = 0; $i < 10000; $i++) { |
||
329 | $primes[] = $i; |
||
330 | } |
||
331 | $primes[0] = $primes[1] = 0; |
||
332 | for ($i = 2; $i < 100; $i++) { |
||
333 | while (!$primes[$i]) { |
||
334 | $i++;
|
||
335 | } |
||
336 | $j = $i; |
||
337 | for ($j += $i; $j < 10000; $j += $i) { |
||
338 | $primes[$j] = 0; |
||
339 | } |
||
340 | } |
||
341 | $j = 0; |
||
342 | for ($i = 0; $i < 10000; $i++) { |
||
343 | if ($primes[$i]) { |
||
344 | $primes[$j++] = $primes[$i]; |
||
345 | } |
||
346 | } |
||
347 | $primes_cnt = $j; |
||
348 | } |
||
349 | |||
350 | // try to divide number by small primes
|
||
351 | for ($i = 0; $i < $primes_cnt; $i++) { |
||
352 | if (bccomp($num, $primes[$i]) <= 0) { |
||
353 | // number is prime
|
||
354 | return true; |
||
355 | } |
||
356 | if (!bccomp(bcmod($num, $primes[$i]), '0')) { |
||
357 | // number divides by $primes[$i]
|
||
358 | return false; |
||
359 | } |
||
360 | } |
||
361 | |||
362 | /*
|
||
363 | try Miller-Rabin's probable-primality test for first
|
||
364 | 7 primes as bases
|
||
365 | */
|
||
366 | for ($i = 0; $i < 7; $i++) { |
||
367 | if (!$this->_millerTest($num, $primes[$i])) { |
||
368 | // $num is composite
|
||
369 | return false; |
||
370 | } |
||
371 | } |
||
372 | // $num is strong pseudoprime
|
||
373 | return true; |
||
374 | } |
||
375 | |||
376 | /**
|
||
377 | * Produces a better random number
|
||
378 | * for seeding mt_rand()
|
||
379 | *
|
||
380 | * @access private
|
||
381 | */
|
||
382 | function _makeSeed() { |
||
383 | return hexdec(sha1(sha1(microtime()*mt_rand()).md5(microtime()*mt_rand()))); |
||
384 | } |
||
385 | |||
386 | /**
|
||
387 | * Generates prime number with length $bits_cnt
|
||
388 | *
|
||
389 | * @param int $bits_cnt
|
||
390 | * @access public
|
||
391 | */
|
||
392 | function getPrime($bits_cnt) { |
||
393 | $bytes_n = intval($bits_cnt / 8); |
||
394 | $bits_n = $bits_cnt % 8; |
||
395 | do {
|
||
396 | $str = ''; |
||
397 | mt_srand($this->_makeSeed());
|
||
398 | for ($i = 0; $i < $bytes_n; $i++) { |
||
399 | $str .= chr(sha1(mt_rand() * microtime()) & 0xff); |
||
400 | } |
||
401 | $n = mt_rand() * microtime() & 0xff; |
||
402 | |||
403 | $n |= 0x80; |
||
404 | $n >>= 8 - $bits_n; |
||
405 | $str .= chr($n); |
||
406 | $num = $this->bin2int($str); |
||
407 | |||
408 | // search for the next closest prime number after [$num]
|
||
409 | if (!bccomp(bcmod($num, '2'), '0')) { |
||
410 | $num = bcadd($num, '1'); |
||
411 | } |
||
412 | while (!$this->isPrime($num)) { |
||
413 | $num = bcadd($num, '2'); |
||
414 | } |
||
415 | |||
416 | } while ($this->bitLen($num) != $bits_cnt); |
||
417 | return $num; |
||
418 | } |
||
419 | |||
420 | /**
|
||
421 | * Calculates $num - 1
|
||
422 | *
|
||
423 | * @param string $num
|
||
424 | * @return string
|
||
425 | * @access public
|
||
426 | */
|
||
427 | function dec($num) { |
||
428 | return bcsub($num, '1'); |
||
429 | } |
||
430 | |||
431 | /**
|
||
432 | * Returns true, if $num is equal to one. Else returns false
|
||
433 | *
|
||
434 | * @param string $num
|
||
435 | * @return bool
|
||
436 | * @access public
|
||
437 | */
|
||
438 | function isOne($num) { |
||
439 | return !bccomp($num, '1'); |
||
440 | } |
||
441 | |||
442 | /**
|
||
443 | * Finds inverse number $inv for $num by modulus $mod, such as:
|
||
444 | * $inv * $num = 1 (mod $mod)
|
||
445 | *
|
||
446 | * @param string $num
|
||
447 | * @param string $mod
|
||
448 | * @return string
|
||
449 | * @access public
|
||
450 | */
|
||
451 | function invmod($num, $mod) { |
||
452 | $x = '1'; |
||
453 | $y = '0'; |
||
454 | $num1 = $mod; |
||
455 | do {
|
||
456 | $tmp = bcmod($num, $num1); |
||
457 | $q = bcdiv($num, $num1); |
||
458 | $num = $num1; |
||
459 | $num1 = $tmp; |
||
460 | |||
461 | $tmp = bcsub($x, bcmul($y, $q)); |
||
462 | $x = $y; |
||
463 | $y = $tmp; |
||
464 | } while (bccomp($num1, '0')); |
||
465 | if (bccomp($x, '0') < 0) { |
||
466 | $x = bcadd($x, $mod); |
||
467 | } |
||
468 | return $x; |
||
469 | } |
||
470 | |||
471 | /**
|
||
472 | * Returns bit length of number $num
|
||
473 | *
|
||
474 | * @param string $num
|
||
475 | * @return int
|
||
476 | * @access public
|
||
477 | */
|
||
478 | function bitLen($num) { |
||
479 | $tmp = $this->int2bin($num); |
||
480 | $bit_len = strlen($tmp) * 8; |
||
481 | $tmp = ord($tmp {strlen($tmp) - 1} ); |
||
482 | if (!$tmp) { |
||
483 | $bit_len -= 8; |
||
484 | } else {
|
||
485 | while (!($tmp & 0x80)) { |
||
486 | $bit_len--;
|
||
487 | $tmp <<= 1; |
||
488 | } |
||
489 | } |
||
490 | return $bit_len; |
||
491 | } |
||
492 | |||
493 | /**
|
||
494 | * Calculates bitwise or of $num1 and $num2,
|
||
495 | * starting from bit $start_pos for number $num1
|
||
496 | *
|
||
497 | * @param string $num1
|
||
498 | * @param string $num2
|
||
499 | * @param int $start_pos
|
||
500 | * @return string
|
||
501 | * @access public
|
||
502 | */
|
||
503 | function bitOr($num1, $num2, $start_pos) { |
||
504 | $start_byte = intval($start_pos / 8); |
||
505 | $start_bit = $start_pos % 8; |
||
506 | $tmp1 = $this->int2bin($num1); |
||
507 | |||
508 | $num2 = bcmul($num2, 1 << $start_bit); |
||
509 | $tmp2 = $this->int2bin($num2); |
||
510 | if ($start_byte < strlen($tmp1)) { |
||
511 | $tmp2 |= substr($tmp1, $start_byte); |
||
512 | $tmp1 = substr($tmp1, 0, $start_byte).$tmp2; |
||
513 | } else {
|
||
514 | $tmp1 = str_pad($tmp1, $start_byte, "\0").$tmp2; |
||
515 | } |
||
516 | return $this->bin2int($tmp1); |
||
517 | } |
||
518 | |||
519 | /**
|
||
520 | * Returns part of number $num, starting at bit
|
||
521 | * position $start with length $length
|
||
522 | *
|
||
523 | * @param string $num
|
||
524 | * @param int start
|
||
525 | * @param int length
|
||
526 | * @return string
|
||
527 | * @access public
|
||
528 | */
|
||
529 | function subint($num, $start, $length) { |
||
530 | $start_byte = intval($start / 8); |
||
531 | $start_bit = $start % 8; |
||
532 | $byte_length = intval($length / 8); |
||
533 | $bit_length = $length % 8; |
||
534 | if ($bit_length) { |
||
535 | $byte_length++;
|
||
536 | } |
||
537 | $num = bcdiv($num, 1 << $start_bit); |
||
538 | $tmp = substr($this->int2bin($num), $start_byte, $byte_length); |
||
539 | $tmp = str_pad($tmp, $byte_length, "\0"); |
||
540 | $tmp = substr_replace($tmp, $tmp {$byte_length - 1} & chr(0xff >> (8 - $bit_length)), $byte_length - 1, 1); |
||
541 | return $this->bin2int($tmp); |
||
542 | } |
||
543 | |||
544 | /**
|
||
545 | * Converts a hex string to bigint string
|
||
546 | *
|
||
547 | * @param string $hex
|
||
548 | * @return string
|
||
549 | * @access public
|
||
550 | */
|
||
551 | function hex2bint($hex) { |
||
552 | $result = '0'; |
||
553 | for ($i = 0; $i < strlen($hex); $i++) { |
||
554 | $result = bcmul($result, '16'); |
||
555 | if ($hex[$i] >= '0' && $hex[$i] <= '9') { |
||
556 | $result = bcadd($result, $hex[$i]); |
||
557 | } else if ($hex[$i] >= 'a' && $hex[$i] <= 'f') { |
||
558 | $result = bcadd($result, '1'.('0' + (ord($hex[$i]) - ord('a')))); |
||
559 | } else if ($hex[$i] >= 'A' && $hex[$i] <= 'F') { |
||
560 | $result = bcadd($result, '1'.('0' + (ord($hex[$i]) - ord('A')))); |
||
561 | } |
||
562 | } |
||
563 | return $result; |
||
564 | } |
||
565 | |||
566 | /**
|
||
567 | * Converts a hex string to int
|
||
568 | *
|
||
569 | * @param string $hex
|
||
570 | * @return int
|
||
571 | * @access public
|
||
572 | */
|
||
573 | function hex2int($hex) { |
||
574 | $result = 0; |
||
575 | for ($i = 0; $i < strlen($hex); $i++) { |
||
576 | $result *= 16; |
||
577 | if ($hex[$i] >= '0' && $hex[$i] <= '9') { |
||
578 | $result += ord($hex[$i]) - ord('0'); |
||
579 | } else if ($hex[$i] >= 'a' && $hex[$i] <= 'f') { |
||
580 | $result += 10 + (ord($hex[$i]) - ord('a')); |
||
581 | } else if ($hex[$i] >= 'A' && $hex[$i] <= 'F') { |
||
582 | $result += 10 + (ord($hex[$i]) - ord('A')); |
||
583 | } |
||
584 | } |
||
585 | return $result; |
||
586 | } |
||
587 | |||
588 | /**
|
||
589 | * Converts a bigint string to the ascii code
|
||
590 | *
|
||
591 | * @param string $bigint
|
||
592 | * @return string
|
||
593 | * @access public
|
||
594 | */
|
||
595 | function bint2char($bigint) { |
||
596 | $message = ''; |
||
597 | while (bccomp($bigint, '0') != 0) { |
||
598 | $ascii = bcmod($bigint, '256'); |
||
599 | $bigint = bcdiv($bigint, '256', 0); |
||
600 | $message .= chr($ascii); |
||
601 | } |
||
602 | return $message; |
||
603 | } |
||
604 | |||
605 | /**
|
||
606 | * Removes the redundacy in den encrypted string
|
||
607 | *
|
||
608 | * @param string $string
|
||
609 | * @return mixed
|
||
610 | * @access public
|
||
611 | */
|
||
612 | function redundacyCheck($string) { |
||
613 | $r1 = substr($string, 0, 2); |
||
614 | $r2 = substr($string, 2); |
||
615 | $check = $this->hex2int($r1); |
||
616 | $value = $r2; |
||
617 | $sum = 0; |
||
618 | for ($i = 0; $i < strlen($value); $i++) { |
||
619 | $sum += ord($value[$i]); |
||
620 | } |
||
621 | if ($check == ($sum & 0xFF)) { |
||
622 | return $value; |
||
623 | } else {
|
||
624 | return NULL; |
||
625 | } |
||
626 | } |
||
627 | |||
628 | /**
|
||
629 | * Decrypts a given string with the $dec_key and the $enc_mod
|
||
630 | *
|
||
631 | * @param string $encrypted
|
||
632 | * @param int $dec_key
|
||
633 | * @param int $enc_mod
|
||
634 | * @return string
|
||
635 | * @access public
|
||
636 | */
|
||
637 | function decrypt($encrypted, $dec_key, $enc_mod) { |
||
638 | $blocks = explode(' ', $encrypted); |
||
639 | $result = ""; |
||
640 | $max = count($blocks); |
||
641 | for ($i = 0; $i < $max; $i++) { |
||
642 | $dec = $this->hex2bint($blocks[$i]); |
||
643 | $dec = $this->powmod($dec, $dec_key, $enc_mod); |
||
644 | $ascii = $this->bint2char($dec); |
||
645 | $result .= $ascii; |
||
646 | } |
||
647 | return $this->redundacyCheck($result); |
||
648 | } |
||
649 | |||
650 | /**
|
||
651 | * Converts a given decimal string to any base between 2 and 36
|
||
652 | *
|
||
653 | * @param string $decimal
|
||
654 | * @param int $base
|
||
655 | * @return string
|
||
656 | */
|
||
657 | function dec2string($decimal, $base) { |
||
658 | |||
659 | $string = null; |
||
660 | |||
661 | $base = (int) $base; |
||
662 | if ($base < 2 | $base > 36 | $base == 10) { |
||
663 | echo 'BASE must be in the range 2-9 or 11-36'; |
||
664 | exit;
|
||
665 | } |
||
666 | |||
667 | $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
||
668 | |||
669 | $charset = substr($charset, 0, $base); |
||
670 | |||
671 | do {
|
||
672 | $remainder = bcmod($decimal, $base); |
||
673 | $char = substr($charset, $remainder, 1); |
||
674 | $string = "$char$string"; |
||
675 | $decimal = bcdiv(bcsub($decimal, $remainder), $base); |
||
676 | } while ($decimal > 0); |
||
677 | |||
678 | return strtolower($string); |
||
679 | } |
||
680 | |||
681 | function getE() { |
||
682 | return $this->_e; |
||
683 | } |
||
684 | |||
685 | function generatePrime($length) { |
||
686 | $this->_key_len = intval($length); |
||
687 | if ($this->_key_len < 8) { |
||
688 | $this->_key_len = 8; |
||
689 | } |
||
690 | |||
691 | $e = $this->bin2int("\x01\x00\x01"); |
||
692 | |||
693 | $p_len = intval(($this->_key_len + 1) / 2); |
||
694 | do {
|
||
695 | $p = $this->getPrime($p_len); |
||
696 | $p1 = $this->dec($p); |
||
697 | $tmp = $this->GCD($e, $p1); |
||
698 | } while (!$this->isOne($tmp)); |
||
699 | |||
700 | return $p; |
||
701 | } |
||
702 | |||
703 | } |
||
704 | |||
705 | ?> |