/** * @param string $byteString * @param null|integer $byteSize * @param MathAdapterInterface $math * @throws \Exception */ public function __construct($byteString = '', $byteSize = null, MathAdapterInterface $math = null) { $this->math = $math ?: EccFactory::getAdapter(); if ($byteSize !== null) { // Check the integer doesn't overflow its supposed size if ($this->math->cmp(strlen($byteString), $byteSize) > 0) { throw new \Exception('Byte string exceeds maximum size'); } } else { $byteSize = strlen($byteString); } $this->size = $byteSize; $this->buffer = $byteString; }
/** * Parse $bytes bytes from the string, and return the obtained buffer * * @param integer $bytes * @param bool $flipBytes * @return Buffer * @throws \Exception */ public function readBytes($bytes, $flipBytes = false) { $string = substr($this->string, $this->getPosition(), $bytes); $length = strlen($string); if ($length == 0) { throw new ParserOutOfRange('Could not parse string of required length (empty)'); } elseif ($this->math->cmp($length, $bytes) !== 0) { throw new ParserOutOfRange('Could not parse string of required length (too short)'); } $this->position += $bytes; if ($flipBytes) { $string = Buffertools::flipBytes($string); } return new Buffer($string, $length, $this->math); }
/** * 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\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'); }
/** * Returns the number of bits used to store this number. Non-singicant upper bits are not counted. * * @param MathAdapterInterface $adapter * @param int|string $x * @return number * * @link https://www.openssl.org/docs/crypto/BN_num_bytes.html */ public static function bnNumBits(MathAdapterInterface $adapter, $x) { if ($adapter->cmp($x, '0') == 0) { return 0; } $log2 = 0; while ($x = $adapter->rightShift($x, 1)) { $log2++; } return $log2 + 1; }
/** * {@inheritDoc} * @see \Mdanter\Ecc\PointInterface::mul() */ public function mul($n) { if ($this->isInfinity()) { return $this->curve->getInfinity(); } if ($this->adapter->cmp($this->order, '0') > 0) { $n = $this->adapter->mod($n, $this->order); } if ($this->adapter->cmp($n, '0') == 0) { return $this->curve->getInfinity(); } $r = [$this->curve->getInfinity(), clone $this]; $n = $this->adapter->baseConvert($n, 10, 2); $k = strlen($n); for ($i = 0; $i < $k; $i++) { $j = $n[$i]; $this->cswap($r[0], $r[1], $j ^ 1); $r[0] = $r[0]->add($r[1]); $r[1] = $r[1]->getDouble(); $this->cswap($r[0], $r[1], $j ^ 1); } $r[0]->validate(); return $r[0]; }
/** * @param $integer * @param $bitSize * @return bool */ public function isNegative($integer, $bitSize) { return $this->math->cmp($this->math->rightShift($integer, $this->fixSize($bitSize)), '1') == 0; }