/** * Point multiplication method 2P = R where * s = (3xP2 + a)/(2yP) mod p * xR = s2 - 2xP mod p * yR = -yP + s(xP - xR) mod p * * @param PointInterface $point * @param CurveParameterInterface * @return PointInterface */ public static function pointDouble(PointInterface $point, CurveParameterInterface $parameters = null) { if ($point->isInfinity()) { return $point; } if (null === $parameters) { $parameters = new Secp256k1(); } $p = $parameters->pHex(); $a = $parameters->aHex(); $s = 0; $R = array('x' => 0, 'y' => 0); // Critical math section try { $m = Math::add(Math::mul(3, Math::mul($point->getX(), $point->getX())), $a); $o = Math::mul(2, $point->getY()); $n = Math::invertm($o, $p); $n2 = Math::mod($o, $p); $st = Math::mul($m, $n); $st2 = Math::mul($m, $n2); $s = Math::mod($st, $p); $s2 = Math::mod($st2, $p); $xmul = Math::mul(2, $point->getX()); $smul = Math::mul($s, $s); $xsub = Math::sub($smul, $xmul); $xmod = Math::mod($xsub, $p); $R['x'] = $xmod; $ysub = Math::sub($point->getX(), $R['x']); $ymul = Math::mul($s, $ysub); $ysub2 = Math::sub(0, $point->getY()); $yadd = Math::add($ysub2, $ymul); $R['y'] = Math::mod($yadd, $p); } catch (\Exception $e) { throw new \Exception('Error in Util::pointDouble(): ' . $e->getMessage()); } return new Point($R['x'], $R['y']); }