Пример #1
0
 /**
  * Decompress Public Key
  * 
  * Accepts a y_byte, 02 or 03 indicating whether the Y coordinate is
  * odd or even, and $passpoint, which is simply a hexadecimal X coordinate.
  * Using this data, it is possible to deconstruct the original 
  * uncompressed public key.
  *
  * @param $key
  * @return array|bool
  */
 public static function decompress_public_key($key)
 {
     $y_byte = substr($key, 0, 2);
     $x_coordinate = substr($key, 2);
     $x = gmp_strval(gmp_init($x_coordinate, 16), 10);
     $curve = \SECcurve::curve_secp256k1();
     $generator = \SECcurve::generator_secp256k1();
     try {
         $x3 = \NumberTheory::modular_exp($x, 3, $curve->getPrime());
         $y2 = gmp_add($x3, $curve->getB());
         $y0 = \NumberTheory::square_root_mod_prime(gmp_strval($y2, 10), $curve->getPrime());
         if ($y0 == FALSE) {
             return FALSE;
         }
         $y1 = gmp_strval(gmp_sub($curve->getPrime(), $y0), 10);
         $y_coordinate = $y_byte == '02' ? \gmp_Utils::gmp_mod2(gmp_init($y0, 10), 2) == '0' ? $y0 : $y1 : (\gmp_Utils::gmp_mod2(gmp_init($y0, 10), 2) !== '0' ? $y0 : $y1);
         $y_coordinate = str_pad(gmp_strval($y_coordinate, 16), 64, '0', STR_PAD_LEFT);
         $point = new \Point($curve, gmp_strval(gmp_init($x_coordinate, 16), 10), gmp_strval(gmp_init($y_coordinate, 16), 10), $generator->getOrder());
     } catch (\Exception $e) {
         return FALSE;
     }
     return array('x' => $x_coordinate, 'y' => $y_coordinate, 'point' => $point, 'public_key' => '04' . $x_coordinate . $y_coordinate);
 }
 public static function bcmath_squareRootModP($prime, $verbose = false)
 {
     $start_time = microtime(true);
     if ($verbose) {
         echo "Testing primes for modulus " . $prime . "<br />";
     }
     flush();
     $squares = array();
     for ($root = 0; bccomp($root, bcadd(1, bcdiv($prime, 2))) < 0; $root = bcadd($root, 1)) {
         $sq = bcpowmod($root, 2, $prime);
         $calculated = NumberTheory::square_root_mod_prime($sq, $prime);
         $calc_sq = bcpowmod($calculated, 2, $prime);
         if (bccomp($calculated, $root) != 0 && bccomp(bcsub($prime, $calculated), $root) != 0) {
             $error_tally++;
             echo "FAILED TO FIND " . $root . " AS sqrt(" . $sq . ") mod {$prime} . Said {$calculated} (" . ($prime - $calculated) . ") <br />\n";
             flush();
         } else {
             if ($verbose) {
                 echo "SUCCESS TO FIND " . $root . " AS sqrt(" . $sq . ") mod {$prime} . Said {$calculated} (" . ($prime - $calculated) . ") <br />\n";
             }
             flush();
         }
     }
     $end_time = microtime(true);
     $time_res = $end_time - $start_time;
     echo "<br />Square roots mod " . $prime . " took: " . $time_res . " seconds. <br />";
     flush();
 }
Пример #3
0
 public function decompress_public_key($key)
 {
     // Initialize
     $y_byte = substr($key, 0, 2);
     $x_coordinate = substr($key, 2);
     // Set variables
     $x = gmp_strval(gmp_init($x_coordinate, 16), 10);
     $curve = SECcurve::curve_secp256k1();
     $generator = SECcurve::generator_secp256k1();
     // Decode
     try {
         $x3 = NumberTheory::modular_exp($x, 3, $curve->getPrime());
         $y2 = gmp_add($x3, $curve->getB());
         $y0 = NumberTheory::square_root_mod_prime(gmp_strval($y2, 10), $curve->getPrime());
         if ($y0 === false) {
             return false;
         }
         $y1 = gmp_strval(gmp_sub($curve->getPrime(), $y0), 10);
         $y_coordinate = $y_byte == '02' ? gmp_Utils::gmp_mod2(gmp_init($y0, 10), 2) == '0' ? $y0 : $y1 : (gmp_Utils::gmp_mod2(gmp_init($y0, 10), 2) !== '0' ? $y0 : $y1);
         $y_coordinate = str_pad(gmp_strval($y_coordinate, 16), 64, '0', STR_PAD_LEFT);
         $point = new Point($curve, gmp_strval(gmp_init($x_coordinate, 16), 10), gmp_strval(gmp_init($y_coordinate, 16), 10), $generator->getOrder());
     } catch (Exception $e) {
         return false;
     }
     // Return
     return array('x' => $x_coordinate, 'y' => $y_coordinate, 'point' => $point, 'public_key' => '04' . $x_coordinate . $y_coordinate);
 }