/** * {@inheritDoc} * @see \Mdanter\Ecc\EcMathInterface::cmp() */ public function cmp($input) { $type = $this->identify($input); if ($this->dataType == 'point' && $type == 'point') { return $this->data->cmp($input); } if ($this->dataType == 'int' && $type == 'int') { return $this->math->cmp($this->data, $input); } throw new \LogicException('Cannot compare values of different types'); }
/** * @param PointInterface $point * @return string */ public function serialize(PointInterface $point) { $length = CurveOidMapper::getByteSize($point->getCurve()) * 2; if ($this->debug) { error_log('Detected length: ' . $length); error_log('Unpadded:' . $this->adapter->decHex($point->getX())); error_log('Unpadded len:' . strlen($this->adapter->decHex($point->getX()))); error_log('Padded: ' . str_pad($this->adapter->decHex($point->getX()), $length, '0', STR_PAD_LEFT)); } $hexString = '04'; $hexString .= str_pad($this->adapter->decHex($point->getX()), $length, '0', STR_PAD_LEFT); $hexString .= str_pad($this->adapter->decHex($point->getY()), $length, '0', STR_PAD_LEFT); if ($this->debug) { error_log('Resulting length: ' . strlen($hexString)); error_log('Hex: ' . $hexString); } return $hexString; }
/** * Initialize a new instance. * * @param MathAdapterInterface $adapter * @param GeneratorPoint $generator * @param PointInterface $point * @throws \LogicException * @throws \RuntimeException */ public function __construct(MathAdapterInterface $adapter, GeneratorPoint $generator, PointInterface $point) { $this->curve = $generator->getCurve(); $this->generator = $generator; $this->point = $point; $this->adapter = $adapter; $n = $generator->getOrder(); if ($n == null) { throw new \LogicException("Generator must have order."); } if (!$point->mul($n)->isInfinity()) { throw new \RuntimeException("Generator point order is bad."); } if ($adapter->cmp($point->getX(), 0) < 0 || $adapter->cmp($n, $point->getX()) <= 0 || $adapter->cmp($point->getY(), 0) < 0 || $adapter->cmp($n, $point->getY()) <= 0) { throw new \RuntimeException("Generator point has x and y out of range."); } }
/** * {@inheritDoc} * @see \Mdanter\Ecc\PointInterface::cmp() */ public function cmp(PointInterface $other) { if ($other->isInfinity() && $this->isInfinity()) { return 0; } if ($other->isInfinity() || $this->isInfinity()) { return 1; } $math = $this->adapter; $equal = $math->cmp($this->x, $other->getX()) == 0; $equal &= $math->cmp($this->y, $other->getY()) == 0; $equal &= $this->isInfinity() == $other->isInfinity(); $equal &= $this->curve->equals($other->getCurve()); if ($equal) { return 0; } return 1; }
/** * @param int|string $tweak * @return PublicKeyInterface */ public function tweakMul($tweak) { $point = $this->point->mul($tweak); return $this->ecAdapter->getPublicKey($point, $this->compressed); }
/** * @param $compressed * @param PointInterface $point * @return string */ public function getPrefix($compressed, PointInterface $point) { return $compressed ? $this->ecAdapter->getMath()->isEven($point->getY()) ? PublicKey::KEY_COMPRESSED_EVEN : PublicKey::KEY_COMPRESSED_ODD : PublicKey::KEY_UNCOMPRESSED; }
/** * {@inheritDoc} * @see \Mdanter\Ecc\Crypto\EcDH\EcDHInterface::calculateSharedKey() */ public function calculateSharedKey() { $this->calculateKey(); return $this->secretKey->getX(); }
/** * attempt to calculate the public key recovery param by trial and error * * @param $r * @param $s * @param $e * @param PointInterface $Q * @return int * @throws \Exception */ private static function calcPubKeyRecoveryParam($r, $s, $e, PointInterface $Q) { $math = EccFactory::getAdapter(); $generator = EccFactory::getSecgCurves($math)->generator256k1(); for ($i = 0; $i < 4; $i++) { if ($pubKey = self::recoverPubKey($r, $s, $e, $i, $generator)) { if ($pubKey->getPoint()->getX() == $Q->getX() && $pubKey->getPoint()->getY() == $Q->getY()) { return $i; } } } throw new \Exception("Failed to find valid recovery factor"); }