代码无法与 gmp_invert("2",$p) 一起使用,为什么?

问题描述 投票:0回答:1

完整代码

<?php

class BitcoinECDSA {
    public $k, $p, $G;

    public function __construct() {
        $this->p = gmp_init('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16);
        $this->G = ['x' => gmp_init('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
                     'y' => gmp_init('32670510020758816978083085130507043184471273380659243275938904335757337482424')];

        
    }

    public function doublePoint($pt) {
        $p = $this->p;
        $slope = gmp_mod(gmp_mul(gmp_invert(gmp_mod(gmp_mul(gmp_init(2), $pt['y']), $p), $p), gmp_add(gmp_mul(gmp_init(3), gmp_pow($pt['x'], 2)), gmp_init(0))), $p);
        return ['x' => gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt['x']), $pt['x']), $p),
                'y' => gmp_mod(gmp_sub(gmp_mul($slope, gmp_sub($pt['x'], gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt['x']), $pt['x']), $p))), $pt['y']), $p)];
    }

    public function addPoints($pt1, $pt2) {
        if (gmp_cmp($pt1['x'], $pt2['x']) === 0 && gmp_cmp($pt1['y'], $pt2['y']) === 0) return $this->doublePoint($pt1);
        $slope = gmp_mod(gmp_mul(gmp_sub($pt1['y'], $pt2['y']), gmp_invert(gmp_sub($pt1['x'], $pt2['x']), $this->p)), $this->p);
        return ['x' => gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt1['x']), $pt2['x']), $this->p),
                'y' => gmp_mod(gmp_sub(gmp_mul($slope, gmp_sub($pt1['x'], gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt1['x']), $pt2['x']), $this->p))), $pt1['y']), $this->p)];
    }

    public function mulPoint($k, $pG) {
        $k = gmp_init($k, 10);
        $kBin = gmp_strval($k, 2);
        $lastPoint = $pG;
        for ($i = 1; $i < strlen($kBin); $i++) {
            $lastPoint = $kBin[$i] === '1' ? $this->addPoints($this->doublePoint($lastPoint), $pG) : $this->doublePoint($lastPoint);
        }
        return $lastPoint;
    }

    public function getPubKeyPoints() {
        if (!isset($this->k)) throw new \Exception('No Private Key defined');
        $pubKey = $this->mulPoint($this->k, $this->G);
        return ['x' => $pubKey['x'],
                'y' => $pubKey['y']];
    }

    public function getPubKey(array $pubKeyPts = []) {
        if (empty($pubKeyPts)) $pubKeyPts = $this->getPubKeyPoints();
          return  $pubKeyPts;
    }

    public function setPrivateKey($k) {

        $this->k = $k;
    }
}

// Ensure $p is a GMP number
$p = gmp_init('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16);

// Initialize the private key as a GMP object
echo $k = gmp_invert("2",$p);


// $k = "57896044618658097711785492504343953926634992332820282019728792003954417335832";

$bitcoinECDSA = new BitcoinECDSA();
$bitcoinECDSA->setPrivateKey($k);
$s = $bitcoinECDSA->getPubKey();
print_r($s);

?>

错误信息:

警告:gmp_init():无法将变量转换为 GMP - 类型错误

问题代码(代码底部):

// Initialize the private key as a GMP object
echo $k = gmp_invert("2",$p);

// $k = "57896044618658097711785492504343953926634992332820282019728792003954417335832";

这里,

gmp_invert("2",$p) = 57896044618658097711785492504343953926634992332820282019728792003954417335832

如果我取消评论

// $k = "57896044618658097711785492504343953926634992332820282019728792003954417335832";

效果很好。但它不适用于

gmp_invert("2",$p)
。 为什么?

php
1个回答
0
投票

出现此问题是因为 gmp_invert 返回 GMP 对象,而不是字符串。我不应该对 gmp_invert 的结果使用 gmp_init 。相反,我可以直接使用结果。这是更正后的代码:

<?php

class BitcoinECDSA {
    public $k, $p, $G;

    public function __construct() {
        $this->p = gmp_init('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16);
        $this->G = ['x' => gmp_init('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
                     'y' => gmp_init('32670510020758816978083085130507043184471273380659243275938904335757337482424')];


    }

    public function doublePoint($pt) {
        $p = $this->p;
        $slope = gmp_mod(gmp_mul(gmp_invert(gmp_mod(gmp_mul(gmp_init(2), $pt['y']), $p), $p), gmp_add(gmp_mul(gmp_init(3), gmp_pow($pt['x'], 2)), gmp_init(0))), $p);
        return ['x' => gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt['x']), $pt['x']), $p),
                'y' => gmp_mod(gmp_sub(gmp_mul($slope, gmp_sub($pt['x'], gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt['x']), $pt['x']), $p))), $pt['y']), $p)];
    }

    public function addPoints($pt1, $pt2) {
        if (gmp_cmp($pt1['x'], $pt2['x']) === 0 && gmp_cmp($pt1['y'], $pt2['y']) === 0) return $this->doublePoint($pt1);
        $slope = gmp_mod(gmp_mul(gmp_sub($pt1['y'], $pt2['y']), gmp_invert(gmp_sub($pt1['x'], $pt2['x']), $this->p)), $this->p);
        return ['x' => gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt1['x']), $pt2['x']), $this->p),
                'y' => gmp_mod(gmp_sub(gmp_mul($slope, gmp_sub($pt1['x'], gmp_mod(gmp_sub(gmp_sub(gmp_pow($slope, 2), $pt1['x']), $pt2['x']), $this->p))), $pt1['y']), $this->p)];
    }

    public function mulPoint($k, $pG) {
        $k = $k; //gmp_init($k, 10);
        $kBin = gmp_strval($k, 2);
        $lastPoint = $pG;
        for ($i = 1; $i < strlen($kBin); $i++) {
            $lastPoint = $kBin[$i] === '1' ? $this->addPoints($this->doublePoint($lastPoint), $pG) : $this->doublePoint($lastPoint);
        }
        return $lastPoint;
    }

    public function getPubKeyPoints() {
        if (!isset($this->k)) throw new \Exception('No Private Key defined');
        $pubKey = $this->mulPoint($this->k, $this->G);
        return ['x' => $pubKey['x'],
                'y' => $pubKey['y']];
    }

    public function getPubKey(array $pubKeyPts = []) {
        if (empty($pubKeyPts)) $pubKeyPts = $this->getPubKeyPoints();
          return  $pubKeyPts;
    }

    public function setPrivateKey($k) {

        $this->k = $k;
    }
}

// Ensure $p is a GMP number
$p = gmp_init('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16);

// Initialize the private key as a GMP object
$k = gmp_invert("2", $p);
//$k = "57896044618658097711785492504343953926634992332820282019728792003954417335832";

$bitcoinECDSA = new BitcoinECDSA();
$bitcoinECDSA->setPrivateKey($k);
$s = $bitcoinECDSA->getPubKey();
print_r($s);

?>
© www.soinside.com 2019 - 2024. All rights reserved.