/**
* Generates an uncompressed and compressed EC public key.
*
* @param \Bitpay\PrivateKey $privateKey
* @return \Bitpay\PublicKey
* @throws \Exception
*/
public function generate(PrivateKey $privateKey = null)
{
if ($privateKey instanceof PrivateKey) {
$this->setPrivateKey($privateKey);
}
if (!empty($this->hex)) {
return $this;
}
if (is_null($this->privateKey)) {
throw new \Exception('Please `setPrivateKey` before you generate a public key');
}
if (!$this->privateKey->isGenerated()) {
$this->privateKey->generate();
}
if (!$this->privateKey->isValid()) {
throw new \Exception('Private Key is invalid and cannot be used to generate a public key');
}
$point = new Point('0x' . substr(Secp256k1::G, 2, 64), '0x' . substr(Secp256k1::G, 66, 64));
$R = Util::doubleAndAdd('0x' . $this->privateKey->getHex(), $point);
$RxHex = Util::encodeHex($R->getX());
$RyHex = Util::encodeHex($R->getY());
$RxHex = str_pad($RxHex, 64, '0', STR_PAD_LEFT);
$RyHex = str_pad($RyHex, 64, '0', STR_PAD_LEFT);
$this->x = $RxHex;
$this->y = $RyHex;
$this->hex = sprintf('%s%s', $RxHex, $RyHex);
$this->dec = Util::decodeHex($this->hex);
return $this;
}