コード例 #1
0
 public static function test_signature_validity($Msg, $Qx, $Qy, $R, $S, $expected, $verbose = false)
 {
     $p192 = NISTcurve::generator_192();
     $curve_192 = NISTcurve::curve_192();
     $pubk = new PublicKey($p192, new Point($curve_192, $Qx, $Qy));
     $got = $pubk->verifies(PrivateKey::digest_integer($Msg), new Signature($R, $S));
     if (bccomp($got, $expected) == 0) {
         if ($verbose) {
             print "Signature tested as expected: received " . var_export($got, true) . ", expected " . var_export($expected, true) . ".<br />";
         }
         flush();
     } else {
         print "*** Signature test failed: received " . var_export($got, true) . ", expected " . var_export($expected, true) . ".<br />";
     }
     flush();
 }
コード例 #2
0
function recoverPubKey($r, $s, $e, $recoveryFlags, $G)
{
    $isYEven = ($recoveryFlags & 1) != 0;
    $isSecondKey = ($recoveryFlags & 2) != 0;
    $curve = $G->getCurve();
    $signature = new Signature($r, $s);
    // Precalculate (p + 1) / 4 where p is the field order
    static $p_over_four;
    // XXX just assuming only one curve/prime will be used
    if (!$p_over_four) {
        $p_over_four = gmp_div(gmp_add($curve->getPrime(), 1), 4);
    }
    // 1.1 Compute x
    if (!$isSecondKey) {
        $x = $r;
    } else {
        $x = gmp_add($r, $G->getOrder());
    }
    // 1.3 Convert x to point
    $alpha = gmp_mod(gmp_add(gmp_add(gmp_pow($x, 3), gmp_mul($curve->getA(), $x)), $curve->getB()), $curve->getPrime());
    $beta = NumberTheory::modular_exp($alpha, $p_over_four, $curve->getPrime());
    // If beta is even, but y isn't or vice versa, then convert it,
    // otherwise we're done and y == beta.
    if (isBignumEven($beta) == $isYEven) {
        $y = gmp_sub($curve->getPrime(), $beta);
    } else {
        $y = $beta;
    }
    // 1.4 Check that nR is at infinity (implicitly done in construtor)
    $R = new Point($curve, $x, $y, $G->getOrder());
    $point_negate = function ($p) {
        return new Point($p->curve, $p->x, gmp_neg($p->y), $p->order);
    };
    // 1.6.1 Compute a candidate public key Q = r^-1 (sR - eG)
    $rInv = NumberTheory::inverse_mod($r, $G->getOrder());
    $eGNeg = $point_negate(Point::mul($e, $G));
    $Q = Point::mul($rInv, Point::add(Point::mul($s, $R), $eGNeg));
    // 1.6.2 Test Q as a public key
    $Qk = new PublicKey($G, $Q);
    if ($Qk->verifies($e, $signature)) {
        return $Qk;
    }
    return false;
}
コード例 #3
0
 /**
  * Check Sig
  *
  * This function will check a provided DER encoded $sig, a digest of
  * the message to be signed - $hash (the output of _create_txin_signature_hash()),
  * and the $key for the signature to be tested against.
  * Returns TRUE if the signature is valid for this $hash and $key,
  * otherwise returns FALSE.
  *
  * @param    string $sig
  * @param    string $hash
  * @param    string $key
  * @return    boolean
  */
 public static function _check_sig($sig, $hash, $key)
 {
     $signature = self::decode_signature($sig);
     $test_signature = new \Signature(gmp_init($signature['r'], 16), gmp_init($signature['s'], 16));
     $generator = \SECcurve::generator_secp256k1();
     $curve = $generator->getCurve();
     if (strlen($key) == '66') {
         $decompress = BitcoinLib::decompress_public_key($key);
         $public_key_point = $decompress['point'];
     } else {
         $x = gmp_strval(gmp_init(substr($key, 2, 64), 16), 10);
         $y = gmp_strval(gmp_init(substr($key, 66, 64), 16), 10);
         $public_key_point = new \Point($curve, $x, $y, $generator->getOrder());
     }
     $public_key = new \PublicKey($generator, $public_key_point);
     $hash = gmp_init($hash, 16);
     return $public_key->verifies($hash, $test_signature) == TRUE;
 }
コード例 #4
0
ファイル: rawtx.php プロジェクト: nachatate/synala
 public function validate_signature($sig, $hash, $key)
 {
     // Initialize
     $signature = $this->decode_signature($sig);
     $test_signature = new Signature(gmp_init($signature['r'], 16), gmp_init($signature['s'], 16));
     $generator = SECcurve::generator_secp256k1();
     $curve = $generator->getCurve();
     // Check key
     if (strlen($key) == '66') {
         $client = new BIP32();
         $decompress = $client->decompress_public_key($key);
         $public_key_point = $decompress['point'];
     } else {
         $x = gmp_strval(gmp_init(substr($key, 2, 64), 16), 10);
         $y = gmp_strval(gmp_init(substr($key, 66, 64), 16), 10);
         $public_key_point = new Point($curve, $x, $y, $generator->getOrder());
     }
     // Get hash
     $public_key = new PublicKey($generator, $public_key_point);
     $hash = gmp_init($hash, 16);
     // Return
     return $public_key->verifies($hash, $test_signature) === true;
 }