colonymech / docs / www / colonyscout / internal / includes / jCryption-1.1.php @ f59acf11
History | View | Annotate | Download (15.6 KB)
1 |
<?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 |
?>
|