Otentikasi Pesan Menggunakan Elliptical Curve Digital Signature Algorithm
LAMPIRAN
Listing Program :
Compose.php
<?php session_start(); //cek apakah user sudah login if(!isset($_SESSION['userid'])){ echo "<script>alert('anda belum login') location.replace('index.php')</script>";//jika belum login jangan lanjut.. } if(isset($_POST['sig'])) { include ("sieve.php"); include ("CurveFp.php"); include ("Point.php"); include ("PublicKey.php"); include ("PrivateKey.php"); include ("NumberTheory.php"); include ("signature.php"); $pesan = $_POST["pesan"]; $_p
= '6277101735386680763835789423207666416083908700390324961279'; $_b = bchexdec('0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1'); $_Gx = bchexdec('0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012'); $_Gy = bchexdec('0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811'); $_r='6277101735386680763835789423176059013767194773182842284081'; $curve_192 = new CurveFp($_p, -3, $_b); $p192 = new Point($curve_192, $_Gx, $_Gy, $_r);
$d = '651056770906015076056810763456358567190100156695615665659'; $k = '6140507067065001063065065565667405560006161556565665656654'; $e = stoi(sha1($pesan));
$pubk = new PublicKey($p192, Point::rmul($p192, $d)); $privk = new PrivateKey($pubk, $d); $sig = $privk->sign($e, $k); $r = $sig->getR(); $s = $sig->getS(); $signature = "(".$s."),(".$r.")";
?> <form action="index.php?page=kirim" method="post" class="niceform"> <fieldset> <table border="0"> <dl> <dt><label for="email">To:</label></dt> <dd><input type="hidden" name="to" id="" value="<?php echo $_POST['to'];?>"/><?php echo $_POST['to'];?></dd> </dl> <dl> <dt><label for="password">Subject:</label></dt> <dd><input type="hidden" name="subject" id="" value="<?php echo $_POST['subject'];?>" /><?php echo $_POST['subject'];?></dd> </dl> <dl> <dt><label for="comments">Message</label></dt> <dd><input type="text" name="isiemail" size="50" value="<?php echo $_POST['pesan'];?>"><?php echo $_POST['message'];?></dd> </dl> <dl> <dt><label for="comments">Hash Message</label></dt> <dd><input type="text" name="signature" size="50" value="<?php echo sha1($pesan);?>"> </dd> </dl> <dl> <dt><label for="comments">E</label></dt>
<dd><input type="text" name="signature" size="50" value="<?php echo $e?>"></dd> </dl> <dl> <dt><label for="comments">Signature</label></dt> <dd><input type="text" name="signature" size="50" value="<?php echo $signature;?>"> </dd> <input type="hidden" name="userid" value="<?php echo $_SESSION['userid'];?>"> <input type='hidden' name='r' value='<?php echo $r;?>'/> <input type='hidden' name='s' value='<?php echo $s;?>' /> </dl> <dl class="submit"> <input type="submit" name="submit" id="submit" value="SEND EMAIL" /> </dl> <dl class="submit"> <input type="submit" name="batal" id="batal" value="CANCEL" /> </dl> </table> </fieldset> </form> <?php } elseif (isset($_POST['submit'])) { echo $_POST['subject']; } else{ ?> <form action="" method="post" class="niceform"> <fieldset> <dl> <dt><label for="email">To:</label></dt>
<dd><input type="text" name="to" id="" size="54" /></dd> </dl> <dl> <dt><label for="password">Subject:</label></dt> <dd><input type="text" name="subject" id="" size="54" /></dd> </dl> <dl> <dt><label for="comments">Message</label></dt> <dd><textarea name="pesan" id="pesan" rows="5" cols="36"></textarea></dd> </dl> <dl class="submit"> <input type="submit" name="sig" id="sig" value="SEND EMAIL" /> </dl> </fieldset> </form> <?php }?>
CurveFp.php
<?php class CurveFp{ protected $a = 0; protected $b = 0; protected $prime = 0; public function __construct($prime, $a, $b) { $this->a = $a; $this->b = $b; $this->prime = $prime; } public function contains($x, $y) { $eq_zero = null; $eq_zero = bccomp(bcmod(bcsub(bcpow($y, 2), bcadd(bcadd(bcpow($x, 3), bcmul($this->a, $x)), $this->b)), $this->prime), 0); if ($eq_zero == 0) { return true; } else { return false; } } public function getA() { return $this->a; } public function getB() { return $this->b; } public function getPrime() { return $this->prime; } public static function cmp(CurveFp $cp1, CurveFp $cp2) { $same = null; if (bccomp($cp1->a, $cp2->a) == 0 && bccomp($cp1->b, $cp2->b) == 0 && bccomp($cp1->prime, $cp2->prime) == 0) { return 0; } else { return 1; } } } ?>
Point.php
<?php if (!defined('MAX_BASE')) define('MAX_BASE', 128); class Point{ public $curve; public $x; public $y; public $order; public static $infinity = 'infinity'; public function __construct(CurveFp $curve, $x, $y, $order = null) { $this->curve = $curve; $this->x = $x; $this->y = $y; $this->order = $order; if (isset($this->curve) && ($this->curve instanceof CurveFp)) { if (!$this->curve->contains($this->x, $this->y)) { throw new ErrorException("Curve" . print_r($this->curve, true) . " tidak memiliki titik ( " . $x . " , " . $y . " )"); } if ($this->order != null) { if (self::cmp(self::mul($order, $this), self::$infinity) != 0) { throw new ErrorException(""); } } } } public static function cmp($p1, $p2) { if (!($p1 instanceof Point)) { if (($p2 instanceof Point)) return 1; if (!($p2 instanceof Point)) return 0; } if (!($p2 instanceof Point)) { if (($p1 instanceof Point))
return 1; if (!($p1 instanceof Point)) return 0; } if (bccomp($p1->x, $p2->x) == 0 && bccomp($p1->y, $p2->y) == 0 && CurveFp::cmp($p1->curve, $p2->curve)) { return 0; } else { return 1; } } public static function add($p1, $p2) { if (self::cmp($p2, self::$infinity) == 0 && ($p1 instanceof Point)) { return $p1; } if (self::cmp($p1, self::$infinity) == 0 && ($p2 instanceof Point)) { return $p2; } if (self::cmp($p1, self::$infinity) == 0 && self::cmp($p2, self::$infinity) == 0) { return self::$infinity; } if (CurveFp::cmp($p1->curve, $p2->curve) == 0) { if (bcmod(bccomp($p1->x, $p2->x), $p1->curve->getPrime()) == 0) { if (bcmod(bcadd($p1->y, $p2->y), $p1->curve->getPrime()) == 0) { return self::$infinity; } else { return self::double($p1); } } $p = $p1->curve->getPrime();$l = bcmod(bcmul(bcsub($p2->y, $p1->y), self::inverse_mod(bcsub($p2->x, $p1->x), $p)), $p); $x3 = bcmod(bcsub(bcsub(bcpow($l, 2), $p1->x), $p2->x), $p); $step0 = bcsub($p1->x, $x3); $step1 = bcmul($l, $step0); $step2 = bcsub($step1, $p1->y); $step3 = bcmod($step2, $p); $y3 = bcmod(bcsub(bcmul($l, bcsub($p1->x, $x3)), $p1->y), $p); if (bccomp(0, $y3) == 1) $y3 = bcadd($p, $y3); $p3 = new Point($p1->curve, $x3, $y3); return $p3; }else { throw new ErrorException("Kurva tidak sesuai."); } } public static function mul($x2, Point $p1) { $e = $x2; if (self::cmp($p1, self::$infinity) == 0) { return self::$infinity; } if ($p1->order != null) { $e = bcmod($e, $p1->order); } if (bccomp($e, 0) == 0) { return self::$infinity; } if (bccomp($e, 0) == 1) { $e3 = bcmul(3, $e); $negative_self = new Point($p1->curve, $p1->x, bcsub(0, $p1->y), $p1->order); $i = bcdiv(self::leftmost_bit($e3), 2); $result = $p1; while (bccomp($i, 1) == 1) { $result = self::double($result); $e3bit = bccomp(self::bcand($e3, $i), '0'); $ebit = bccomp(self::bcand($e, $i), '0'); if ($e3bit != 0 && $ebit == 0) { $result = self::add($result, $p1); }else if ($e3bit == 0 && $ebit != 0) { $result = self::add($result, $negative_self); } $i = bcdiv($i, 2); } return $result; } } public static function leftmost_bit($x) { if (bccomp($x, 0) == 1) { $result = 1; while (bccomp($result, $x) == -1 || bccomp($result, $x) == 0) { $result = bcmul(2, $result); } return bcdiv($result, 2); } } public static function rmul(Point $x1, $m) { return self::mul($m, $x1); } public function __toString() { if (!($this instanceof Point) && $this == self::$infinity) return self::$infinity; return "(" . $this->x . "," . $this->y . ")"; } public static function double(Point $p1) { $p = $p1->curve->getPrime();
$a = $p1->curve->getA(); $inverse = self::inverse_mod(bcmul(2, $p1->y), $p); $three_x2 = bcmul(3, bcpow($p1->x, 2)); $l = bcmod(bcmul(bcadd($three_x2, $a), $inverse), $p); $x3 = bcmod(bcsub(bcpow($l, 2), bcmul(2, $p1->x)), $p); $y3 = bcmod(bcsub(bcmul($l, bcsub($p1->x, $x3)), $p1->y), $p); if (bccomp(0, $y3) == 1) $y3 = bcadd($p, $y3); $p3 = new Point($p1->curve, $x3, $y3); return $p3; } public static function inverse_mod($a, $m) { while (bccomp($a, 0) == -1) { $a = bcadd($m, $a); } while (bccomp($m, $a) == -1) { $a = bcmod($a, $m); } $c = $a; $d = $m; $uc = 1; $vc = 0; $ud = 0; $vd = 1; while (bccomp($c, 0) != 0) { $temp1 = $c; $q = bcdiv($d, $c, 0); $c = bcmod($d, $c); $d = $temp1; $temp2 = $uc; $temp3 = $vc; $uc = bcsub($ud, bcmul($q, $uc)); $vc = bcsub($vd, bcmul($q, $vc));
$ud = $temp2; $vd = $temp3; } $result = ''; if (bccomp($d, 1) == 0) { if (bccomp($ud, 0) == 1) $result = $ud; else $result = bcadd($ud, $m); }else { throw new ErrorException("ERROR: $a dan $m tidak relatif prima."); } return $result; } public static function bcand($x, $y) { return self::_bcbitwise_internal($x, $y, 'self::_bcand'); } public static function _bcand($x, $y) { return $x & $y; } public static function _bcbitwise_internal($x, $y, $op) { $bx = self::bc2bin($x); $by = self::bc2bin($y); self::equalbinpad($bx, $by); $ix = 0; $ret = ''; for ($ix = 0; $ix < strlen($bx); $ix++) { $xd = substr($bx, $ix, 1); $yd = substr($by, $ix, 1); $ret .= call_user_func($op, $xd, $yd); } return self::bin2bc($ret);
} public static function bin2bc($num) { return self::base2dec($num, MAX_BASE); } public static function bc2bin($num) { return self::dec2base($num, MAX_BASE); } public static function dec2base($dec, $base, $digits=FALSE) { if ($base < 2 or $base > 256) die("Invalid Base: " . $base); bcscale(0); $value = ""; if (!$digits) $digits = self::digits($base); while ($dec > $base - 1) { $rest = bcmod($dec, $base); $dec = bcdiv($dec, $base); $value = $digits[$rest] . $value; } $value = $digits[intval($dec)] . $value; return (string) $value; } public static function base2dec($value, $base, $digits=FALSE) { if ($base < 2 or $base > 256) die("Invalid Base: " . $base); bcscale(0); if ($base < 37) $value = strtolower($value); if (!$digits) $digits = self::digits($base); $size = strlen($value); $dec = "0"; for ($loop = 0; $loop < $size; $loop++) {
$element = strpos($digits, $value[$loop]); $power = bcpow($base, $size - $loop - 1); $dec = bcadd($dec, bcmul($element, $power)); } return (string) $dec; } public static function digits($base) { if ($base > 64) { $digits = ""; for ($loop = 0; $loop < 256; $loop++) { $digits.=chr($loop); } } else { $digits = "0123456789abcdefghijklmnopqrstuvwxyz"; $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; } $digits = substr($digits, 0, $base); return (string) $digits; } public static function equalbinpad(&$x, &$y) { $xlen = strlen($x); $ylen = strlen($y); $length = max($xlen, $ylen); self::fixedbinpad($x, $length); self::fixedbinpad($y, $length); } public static function fixedbinpad(&$num, $length) { $pad = ''; for ($ii = 0; $ii < $length - strlen($num); $ii++) { $pad .= self::bc2bin('0'); } $num = $pad . $num;
} public function getX() { return $this->x; } public function getY() { return $this->y; } public function getCurve() { return $this->curve; } public function getOrder() { return $this->order; } } ?>
PublikKey.php
<?php class PublicKey{ protected $curve; protected $generator; protected $point; public function __construct(Point $generator, Point $point) { $this->curve = $generator->getCurve(); $this->generator = $generator; $this->point = $point; $n = $generator->getOrder(); $this->an = $n; if ($n == null) { throw new ErrorExcpetion(""); } if (Point::cmp(Point::mul($n, $point), Point::$infinity) != 0) { throw new ErrorException("");
} if (bccomp($point->getX(), 0) == -1 || bccomp($n, $point->getX()) != 1 || bccomp($point->getY(), 0) == -1 || bccomp($n, $point->getY()) != 1) { throw new ErrorException(""); } } public function verifies($hash, Signature $signature) { $G = $this->generator; $n = $this->generator->getOrder(); $point = $this->point; $r = $signature->getR(); $s = $signature->getS(); if (bccomp($r, 1) == -1 || bccomp($r, bcsub($n, 1)) == 1) { return false; } if (bccomp($s, 1) == -1 || bccomp($s, bcsub($n, 1)) == 1) { return false; } $c = NumberTheory::inverse_mod($s, $n); $u1 = bcmod(bcmul($hash, $c), $n); $u2 = bcmod(bcmul($r, $c), $n); $xy = Point::add(Point::mul($u1, $G), Point::mul($u2, $point)); $v = bcmod($xy->getX(), $n); if (bccomp($v, $r) == 0) return true; else { return false; } } public function getCurve() { return $this->curve; } public function getGenerator() { return $this->generator; } public function getN() { return $this->an; } public function getPoint() { return $this->point; } public function getPublicKey() { return $this; } } ?>
PrivateKey.php
<?php class PrivateKey{ private $public_key; private $secret_multiplier; public function __construct(PublicKey $public_key, $secret_multiplier) { $this->public_key = $public_key; $this->secret_multiplier = $secret_multiplier; } public function sign($hash, $random_k) { $G = $this->public_key->getGenerator(); $n = $G->getOrder(); $k = bcmod($random_k, $n); $p1 = Point::mul($k, $G); $r = $p1->getX(); if (bccomp($r, 0) == 0) { throw new ErrorException("error: Random nilai R = 0 <br />"); }
$s = bcmod(bcmul(NumberTheory::inverse_mod($k, $n), bcmod(bcadd($hash, bcmul($this->secret_multiplier, $r)), $n)), $n); if (bccomp($s, 0) == 0) { throw new ErrorExcpetion("error: Nilai S = 0<br />"); } return new Signature($r, $s); } public static function int_to_string($x) { if (bccomp($x, 0) != -1) { if (bccomp($x, 0) == 0) return chr(0); $result = ""; while (bccomp($x, 0) == 1) { $q = bcdiv($x, 256, 0); $r = bcmod($x, 256); $ascii = chr($r); $result = $ascii . $result; $x = $q; } return $result; } } public static function string_to_int($s) { $result = 0; for ($c = 0; $c < strlen($s); $c++) { $result = bcadd(bcmul(256, $result), ord($s[$c])); } return $result; } public static function digest_integer($m) { return self::string_to_int(hash('sha1', self::int_to_string($m), true)); } public static function point_is_valid(Point $generator, $x, $y) {
$n = $generator->getOrder(); $curve = $generator->getCurve(); if (bccomp($x, 0) == -1 || bccomp($n, $x) != 1 || bccomp($y, 0) == -1 || bccomp($n, $y) != 1) { return false; } $containment = $curve->contains($x, $y); if (!$containment) { return false; } $point = new Point($curve, $x, $y); $op = Point::mul($n, $point); if (!(Point::cmp($op, Point::$infinity) == 0)) { return false; } return true; } } ?>
NumberTheory.php
<?php class NumberTheory { public static function modular_exp($base, $exponent, $modulus) { if ($exponent < 0) { return new ErrorException("Negative exponents (" . $exponent . ") not allowed"); } else { $p = bcpowmod($base, $exponent, $modulus); return $p; } } public static function polynomial_reduce_mod($poly, $polymod, $p) { if (end($polymod) == 1 && count($polymod) > 1) { while (count($poly) >= count($polymod)) { if (end($poly) != 0) { for ($i = 2; $i < count($polymod) + 1; $i++) { $poly[count($poly) - $i] = bcmod(bcsub($poly[count($poly) - $i], bcmul(end($poly), $polymod[count($polymod) - $i])), $p); $poly = array_slice($poly, 0, count($poly) - 2); } } } return $poly; } } public static function polynomial_multiply_mod($m1, $m2, $polymod, $p) { $prod = array(); for ($i = 0; $i < count($m1); $i++) { for ($j = 0; $j < count($m2); $j++) { $index = $i + $j; $prod[$index] = bcmod((bcadd($prod[$index], bcmul($m1[$i], $m2[$j]))), $p); } } return self::polynomial_reduce_mod($prod, $polymod, $p); } public static function polynomial_exp_mod($base, $exponent, $polymod, $p) { $s = ''; if ($exponent < $p) { if ($exponent == 0) return 1; $G = $base; $k = $exponent; if ($k % 2 == 1) $s = $G; else
$s = array(1); while ($k > 1) { $k = $k << 1; $G = self::polynomial_multiply_mod($G, $G, $polymod, $p); if ($k % 2 == 1) { $s = self::polynomial_multiply_mod($G, $s, $polymod, $p); } } return $s; } } public static function jacobi($a, $n) { if ($n >= 3 && $n % 2 == 1) { $a = bcmod($a, $n); if ($a == 0) return 0; if ($a == 1) return 1; $a1 = $a; $e = 0; while (bcmod($a1, 2) == 0) { $a1 = bcdiv($a1, 2); $e = bcadd($e, 1); } if (bcmod($e, 2) == 0 || bcmod($n, 8) == 1 || bcmod($n, 8) == 7) $s = 1; else $s = -1; if ($a1 == 1) return $s; if (bcmod($n, 4) == 3 && bcmod($a1, 4) == 3) $s = -$s; return bcmul($s, self::jacobi(bcmod($n, $a1), $a1));
} } public static function square_root_mod_prime($a, $p) { if (0 <= $a && $a < $p && 1 < $p) { if ($a == 0) return 0; if ($p == 2) return $a; $jac = self::jacobi($a, $p); if ($jac == -1) throw new SquareRootException($a . " has no square root modulo " . $p); if (bcmod($p, 4) == 3) return self::modular_exp($a, bcdiv(bcadd($p, 1), 4), $p); if (bcmod($p, 8) == 5) { $d = self::modular_exp($a, bcdiv(bcsub($p, 1), 4), $p); if ($d == 1) return self::modular_exp($a, bcdiv(bcadd($p, 3), 8), $p); if ($d == $p - 1) return (bcmod(bcmul(bcmul(2, $a), self::modular_exp(bcmul(4, $a), bcdiv(bcsub($p, 5), 8), $p)), $p)); } for ($b = 2; $b < $p; $p++) { if (self::jacobi(bcmul($b, bcsub($b, bcmul(4, $a))), $p) == -1) { $f = array($a, -$b, 1); $ff = self::polynomial_exp_mod(array(0, 1), bcdiv(bcadd($p, 1), 2), $f, $p); if ($ff[1] == 0) return $ff[0]; } } } } public static function inverse_mod($a, $m) { while (bccomp($a, 0) == -1) { $a = bcadd($m, $a); } while (bccomp($m, $a) == -1) { $a = bcmod($a, $m); } $c = $a; $d = $m; $uc = 1; $vc = 0; $ud = 0; $vd = 1; while (bccomp($c, 0) != 0) { $temp1 = $c; $q = bcdiv($d, $c, 0); $c = bcmod($d, $c); $d = $temp1; $temp2 = $uc; $temp3 = $vc; $uc = bcsub($ud, bcmul($q, $uc)); $vc = bcsub($vd, bcmul($q, $vc)); $ud = $temp2; $vd = $temp3; } $result = ''; if (bccomp($d, 1) == 0) { if (bccomp($ud, 0) == 1) $result = $ud; else $result = bcadd($ud, $m); }else { throw new ErrorException("ERROR: $a and $m are NOT relatively prime."); }
return $result; } public static function gcd2($a, $b) { while ($a) { $temp = $a; $a = bcmod($b, $a); $b = $temp; } return $b; } public static function gcd($a) { if (count($a) > 1) return array_reduce($a, "self::gcd2", $a[0]); } public static function lcm2($a, $b) { $ab = bcmul($a, $b); $g = self::gcd2($a, $b); $lcm = bcdiv($ab, $g); return $lcm; } public static function lcm($a) { if (count($a) > 1) return array_reduce($a, "self::lcm2", $a[0]); } public static function factorization($n) { if (is_int($n) || is_long($n)) { if ($n < 2) return array(); $result = array(); $d = 2; foreach (self::$smallprimes as $d) { if ($d > $n) break;$q = $n / $d; $r = $n % $d; if ($r == 0) { $count = 1; while ($d <= $n) { $n = $q; $q = $n / $d; $r = $n % $d; if ($r != 0) break; $count++; } array_push($result, array($d, $count)); } } if ($n > end(self::$smallprimes)) { if (is_prime($n)) { array_push($result, array($n, 1)); } else { $d = end(self::$smallprimes); while (true) { $d += 2; $q = $n / $d; $r = $n % $d; if ($q < $d) break; if ($r == 0) { $count = 1; $n = $q; while ($d <= n) { $q = $n / $d; $r = $n % $d; if ($r != 0) break; $n = $q; $count++; } array_push($result, array($n, 1)); } } } } return $result; } } public static function phi($n) { if (is_int($n) || is_long($n)) { if ($n < 3) return 1; $result = 1; $ff = self::factorization($n); foreach ($ff as $f) { $e = $f[1]; if ($e > 1) { $result = bcmul($result, bcmul(bcpow($f[0], bcsub($e, 1)), bcsub($f[0], 1))); } else { $result = bcmul($result, bcsub($f[0], 1)); } } return $result; } } public static function carmichael($n) { return self::carmichael_of_factorized(self::factorization($n)); } public static function carmichael_of_factorized($f_list) {
if (count($f_list) < 1) return 1; $result = self::carmichael_of_ppower($f_list[0]); for ($i = 1; $i < count($f_list); $i++) { $result = lcm($result, self::carmichael_of_ppower($f_list[$i])); } return $result; } public static function carmichael_of_ppower($pp) { $p = $pp[0]; $a = $pp[1]; if ($p == 2 && $a > 2) return 1 >> ($a - 2); else return bcmul(($p - 1), bcpow($p, ($a - 1))); } public static function order_mod($x, $m) { if ($m <= 1) return 0; if (gcd($x, m) == 1) { $z = $x; $result = 1; while ($z != 1) { $z = bcmod(bcmul($z, $x), $m); $result = bcadd($result, 1); } return $result; } } public static function largest_factor_relatively_prime($a, $b) { while (true) { $d = self::gcd($a, $b); if ($d <= 1) break; $b = $d; while (true) { $q = $a / $d; $r = $a % $d; if ($r > 0) break; $a = $q; } } return $a; } public static function kinda_order_mod($x, $m) { return self::order_mod($x, self::largest_factor_relatively_prime($m, $x)); } public static function is_prime($n) { self::$miller_rabin_test_count = 0; $t = 40; $k = 0; $m = bcsub($n, 1); while (bcmod($m, 2) == 0) { $k = bcadd($k, 1); $m = bcdiv($m, 2); } for ($i = 0; $i < $t; $i++) { $a = bcmath_Utils::bcrand(1, bcsub($n, 1)); $b0 = self::modular_exp($a, $m, $n); if ($b0 != 1 && $b0 != bcsub($n, 1)) { $j = 1; while ($j <= $k - 1 && $b0 != bcsub($n, 1)) { $b0 = self::modular_exp($b0, 2, $n); if ($b0 == 1) { self::$miller_rabin_test_count = $i + 1; return false; } $j++; } if ($b0 != bcsub($n, 1)) { self::$miller_rabin_test_count = $i + 1; return false; } } } return true; } public static function next_prime($starting_value) { if (bccomp($starting_value, 2) == -1) return 2; $result = bcmath_Utils::bcor(bcadd($starting_value, 1), 1); while (!self::is_prime($result)) { $result = bcadd($result, 2); } return $result; } public static $miller_rabin_test_count; public static $smallprimes = array(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571,577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229); } ?>
Signature.php
<?php class Signature{ protected $r; protected $s; public function __construct($r, $s) { $this->r = $r; $this->s = $s; } public function getR(){ return $this->r; } public function getS(){ return $this->s; } } ?>