public function GOST_verifies($hash, Signature $signature)
 {
     if (extension_loaded('gmp') && USE_EXT == 'GMP') {
         $G = $this->generator;
         //P
         $n = $this->generator->getOrder();
         //q
         $point = $this->point;
         //Q
         $r = $signature->getR();
         $s = $signature->getS();
         if (gmp_cmp($r, 1) < 0 || gmp_cmp($r, gmp_sub($n, 1)) > 0) {
             return false;
         }
         if (gmp_cmp($s, 1) < 0 || gmp_cmp($s, gmp_sub($n, 1)) > 0) {
             return false;
         }
         //step 3 GOST
         $e = gmp_Utils::gmp_mod2($hash, $n);
         if (gmp_cmp($e, '0') === 0) {
             $e = gmp_init('1');
         }
         // step 4 GOST
         $v = gmp_strval(gmp_invert($e, $n));
         // step 5 GOST
         $z1 = gmp_Utils::gmp_mod2(gmp_mul($s, $v), $n);
         $z2 = gmp_Utils::gmp_mod2(gmp_mul(gmp_neg($r), $v), $n);
         // step 6 GOST
         $C = Point::add(Point::mul($z1, $G), Point::mul($z2, $point));
         $R = gmp_Utils::gmp_mod2($C->getX(), $n);
         if (0) {
             echo "n - " . $n . "\n";
             echo "h - " . $hash . "\n";
             echo "e - " . gmp_Utils::gmp_dechex($e) . "\n";
             echo "v - " . gmp_Utils::gmp_dechex($v) . "\n";
             echo "r - " . $r . "\n";
             echo "s - " . $s . "\n";
             echo "z1 - " . gmp_Utils::gmp_dechex($z1) . "\nz2 - " . gmp_Utils::gmp_dechex($z2) . "\n";
             echo "Q - " . $point . "\nG - " . $G . "\n";
             echo "C - " . $C . "\nR - " . $R . "\n";
         }
         if (gmp_cmp($R, $r) == 0) {
             return true;
         } else {
             return false;
         }
     } else {
         throw new ErrorException("Please install GMP");
     }
 }
function privkey2pubkey($ECDSA, $secp256k1_G)
{
    // this is function that needs the phpecc stuff - rewrite when binary module available
    $privKey = gmp_Utils::gmp_hexdec($ECDSA);
    $pubKey = new PublicKey($secp256k1_G, Point::mul($privKey, $secp256k1_G));
    $xcoord = strtoupper(gmp_Utils::gmp_dechex($pubKey->getPoint()->getX()));
    $xcoord = str_pad($xcoord, 64, '0', STR_PAD_LEFT);
    $ycoord = strtoupper(gmp_Utils::gmp_dechex($pubKey->getPoint()->getY()));
    $ycoord = str_pad($ycoord, 64, '0', STR_PAD_LEFT);
    return '04' . $xcoord . $ycoord;
}