예제 #1
0
 /**
  * @param $a
  * @param $p
  * @return int|string
  */
 public function squareRootModP($a, $p)
 {
     if (0 <= $a && $a < $p && 1 < $p) {
         if ($a == 0) {
             return 0;
         }
         if ($p == 2) {
             return $a;
         }
         $jac = $this->adapter->jacobi($a, $p);
         if ($jac == -1) {
             throw new \LogicException($a . " has no square root modulo " . $p);
         }
         if ($this->adapter->mod($p, 4) == 3) {
             return $this->adapter->powmod($a, $this->adapter->div($this->adapter->add($p, 1), 4), $p);
         }
         if ($this->adapter->mod($p, 8) == 5) {
             $d = $this->adapter->powmod($a, $this->adapter->div($this->adapter->sub($p, 1), 4), $p);
             if ($d == 1) {
                 return $this->adapter->powmod($a, $this->adapter->div($this->adapter->add($p, 3), 8), $p);
             }
             if ($d == $p - 1) {
                 return $this->adapter->mod($this->adapter->mul($this->adapter->mul(2, $a), $this->adapter->powmod($this->adapter->mul(4, $a), $this->adapter->div($this->adapter->sub($p, 5), 8), $p)), $p);
             }
             //shouldn't get here
         }
         for ($b = 2; $b < $p; $b++) {
             if ($this->adapter->jacobi($this->adapter->sub($this->adapter->mul($b, $b), $this->adapter->mul(4, $a)), $p) == -1) {
                 $f = array($a, -$b, 1);
                 $ff = $this->polynomialPowMod(array(0, 1), $this->adapter->div($this->adapter->add($p, 1), 2), $f, $p);
                 if ($ff[1] == 0) {
                     return $ff[0];
                 }
                 // if we got here no b was found
             }
         }
     }
     throw new \InvalidArgumentException('Unable to calculate square root mod p!');
 }
예제 #2
0
 /**
  * @param $base
  * @param $exponent
  * @return mixed
  */
 public function pow($base, $exponent)
 {
     return $this->adapter->powmod($base, $exponent, $this->modulus);
 }