Add simpleid-1.0.5
diff --git a/simpleid/www/bignum.inc.php b/simpleid/www/bignum.inc.php
new file mode 100644
index 0000000..78fefd7
--- /dev/null
+++ b/simpleid/www/bignum.inc.php
@@ -0,0 +1,286 @@
+<?php
+/*
+ * SimpleID
+ *
+ * Copyright (C) Kelvin Mo 2009
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+
+/**
+ * Abstraction library for multiple precision mathematics. This file uses either
+ * the GNU Multiple Precision Arithmic Libary (GMP) if it is installed, or the
+ * default BCMath library if it is not installed.
+ *
+ * @package simpleid
+ * @filesource
+ */
+
+
+if (function_exists('gmp_init')) {
+ /**
+ * Defines whether the GMP library is available.
+ */
+ define('BIGNUM_GMP', true);
+} else {
+ /** @ignore */
+ define('BIGNUM_GMP', false);
+}
+
+/**
+ * Returns whether either the GMP or the BCMath library is installed. If neither
+ * of these libraries are installed, the functions in this file will not work.
+ *
+ * @return bool true if either GMP or BCMath is installed.
+ */
+function bignum_loaded() {
+ return (function_exists('gmp_init') || function_exists('bcadd'));
+}
+
+/**
+ * Creates a bignum.
+ *
+ * @param mixed $str An integer, a string in base 2 to 36, or a byte stream in base 256
+ * @param int $base an integer between 2 and 36, or 256
+ * @return resource a bignum
+ */
+function bignum_new($str, $base = 10) {
+ switch ($base) {
+ case 10:
+ if (BIGNUM_GMP) {
+ return gmp_init($str, 10);
+ } else {
+ return $str;
+ }
+ break;
+ case 256:
+ $bytes = array_merge(unpack('C*', $str));
+
+ $num = bignum_new(0);
+
+ foreach ($bytes as $byte) {
+ $num = bignum_mul($num, 256);
+ $num = bignum_add($num, bignum_new($byte));
+ }
+ return $num;
+ break;
+ default:
+ if (!is_integer($base) || ($base < 2) || ($base > 36)) return FALSE;
+
+ $num = bignum_new(0);
+
+ for ($i = 0; $i < strlen($str); $i++) {
+ $num = bignum_mul($num, $base);
+ $num = bignum_add($num, bignum_new(base_convert($str[$i], $base, 10)));
+ }
+ return $num;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Converts a bignum into a string representation (base 2 to 36) or a byte stream
+ * (base 256)
+ *
+ * @param resource $num the bignum
+ * @param int $base an integer between 2 and 36, or 256
+ * @return string the converted bignum
+ */
+function bignum_val($num, $base = 10) {
+ switch ($base) {
+ case 10:
+ if (BIGNUM_GMP) {
+ $base10 = gmp_strval($num, 10);
+ } else {
+ $base10 = $num;
+ }
+
+ return $base10;
+ break;
+
+ case 256:
+ $cmp = bignum_cmp($num, 0);
+ if ($cmp < 0) {
+ return FALSE;
+ }
+
+ if ($cmp == 0) {
+ return "\x00";
+ }
+
+ $bytes = array();
+
+ while (bignum_cmp($num, 0) > 0) {
+ array_unshift($bytes, bignum_mod($num, 256));
+ $num = bignum_div($num, 256);
+ }
+
+ if ($bytes && ($bytes[0] > 127)) {
+ array_unshift($bytes, 0);
+ }
+
+ $byte_stream = '';
+ foreach ($bytes as $byte) {
+ $byte_stream .= pack('C', $byte);
+ }
+
+ return $byte_stream;
+ break;
+ default:
+ if (!is_integer($base) || ($base < 2) || ($base > 36)) return FALSE;
+
+ $cmp = bignum_cmp($num, 0);
+ if ($cmp < 0) {
+ return FALSE;
+ }
+
+ if ($cmp == 0) {
+ return "0";
+ }
+
+ $str = '';
+ while (bignum_cmp($num, 0) > 0) {
+ $r = intval(bignum_val(bignum_mod($num, $base)));
+ $str = base_convert($r, 10, $base) . $str;
+ $num = bignum_div($num, $base);
+ }
+
+ return $str;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Adds two bignums
+ *
+ * @param resource $a
+ * @param resource $b
+ * @return resource a bignum representing a + b
+ */
+function bignum_add($a, $b) {
+ if (BIGNUM_GMP) {
+ return gmp_add($a, $b);
+ } else {
+ return bcadd($a, $b);
+ }
+}
+
+/**
+ * Multiplies two bignums
+ *
+ * @param resource $a
+ * @param resource $b
+ * @return resource a bignum representing a * b
+ */
+function bignum_mul($a, $b) {
+ if (BIGNUM_GMP) {
+ return gmp_mul($a, $b);
+ } else {
+ return bcmul($a, $b);
+ }
+}
+
+/**
+ * Divides two bignums
+ *
+ * @param resource $a
+ * @param resource $b
+ * @return resource a bignum representing a / b
+ */
+function bignum_div($a, $b) {
+ if (BIGNUM_GMP) {
+ return gmp_div($a, $b);
+ } else {
+ return bcdiv($a, $b);
+ }
+}
+
+/**
+ * Raise base to power exp
+ *
+ * @param resource $base the base
+ * @param mixed $exp the exponent, as an integer or a bignum
+ * @return resource a bignum representing base ^ exp
+ */
+function bignum_pow($base, $exp) {
+ if (BIGNUM_GMP) {
+ if (is_resource($exp) && (get_resource_type($exp) == 'gmp')) $exp = gmp_intval($exp);
+ return gmp_pow($base, $exp);
+ } else {
+ return bcpow($base, $exp);
+ }
+}
+
+/**
+ * Returns n modulo d
+ *
+ * @param resource $n
+ * @param resource $d
+ * @return resource a bignum representing n mod d
+ */
+function bignum_mod($n, $d) {
+ if (BIGNUM_GMP) {
+ return gmp_mod($n, $d);
+ } else {
+ return bcmod($n, $d);
+ }
+}
+
+/**
+ * Raise a number into power with modulo
+ *
+ * @param resource $base the base
+ * @param resource $exp the exponent
+ * @param resource $mod the modulo
+ * @return resource a bignum representing base ^ exp mod mod
+ */
+function bignum_powmod($base, $exp, $mod) {
+ if (BIGNUM_GMP) {
+ return gmp_powm($base, $exp, $mod);
+ } elseif (function_exists('bcpowmod')) {
+ return bcpowmod($base, $exp, $mod);
+ } else {
+ $square = bignum_mod($base, $mod);
+ $result = 1;
+ while (bignum_cmp($exp, 0) > 0) {
+ if (bignum_mod($exp, 2)) {
+ $result = bignum_mod(bignum_mul($result, $square), $mod);
+ }
+ $square = bignum_mod(bignum_mul($square, $square), $mod);
+ $exp = bignum_div($exp, 2);
+ }
+ return $result;
+ }
+}
+
+/**
+ * Compares two bignum
+ *
+ * @param resource $a
+ * @param resource $b
+ * @return int positive value if a > b, zero if a = b and a negative value if a < b
+ */
+function bignum_cmp($a, $b) {
+ if (BIGNUM_GMP) {
+ return gmp_cmp($a, $b);
+ } else {
+ return bccomp($a, $b);
+ }
+}
+?>