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; }