mirror of
https://github.com/danog/tgseclib.git
synced 2024-12-15 18:37:00 +01:00
220 lines
4.4 KiB
PHP
220 lines
4.4 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* Curve methods common to all curves
|
||
|
*
|
||
|
* PHP version 5 and 7
|
||
|
*
|
||
|
* @category Crypt
|
||
|
* @package ECDSA
|
||
|
* @author Jim Wigginton <terrafrost@php.net>
|
||
|
* @copyright 2017 Jim Wigginton
|
||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||
|
* @link http://pear.php.net/package/Math_BigInteger
|
||
|
*/
|
||
|
|
||
|
namespace phpseclib\Crypt\ECDSA\BaseCurves;
|
||
|
|
||
|
use phpseclib\Math\Common\FiniteField;
|
||
|
use phpseclib\Math\BigInteger;
|
||
|
|
||
|
/**
|
||
|
* Base
|
||
|
*
|
||
|
* @package Prime
|
||
|
* @author Jim Wigginton <terrafrost@php.net>
|
||
|
* @access public
|
||
|
*/
|
||
|
abstract class Base
|
||
|
{
|
||
|
/**
|
||
|
* Doubles
|
||
|
*
|
||
|
* @var object[]
|
||
|
*/
|
||
|
protected $doubles;
|
||
|
|
||
|
/**
|
||
|
* NAF Points
|
||
|
*
|
||
|
* @var int[]
|
||
|
*/
|
||
|
private $naf;
|
||
|
|
||
|
/**
|
||
|
* The Order
|
||
|
*
|
||
|
* @var BigInteger
|
||
|
*/
|
||
|
protected $order;
|
||
|
|
||
|
/**
|
||
|
* Finite Field Integer factory
|
||
|
*
|
||
|
* @var \phpseclib\Math\FiniteField\Integer
|
||
|
*/
|
||
|
protected $factory;
|
||
|
|
||
|
/**
|
||
|
* Returns a random integer
|
||
|
*
|
||
|
* @return object
|
||
|
*/
|
||
|
public function randomInteger()
|
||
|
{
|
||
|
return $this->factory->randomInteger();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Converts a BigInteger to a FiniteField integer
|
||
|
*
|
||
|
* @return object
|
||
|
*/
|
||
|
public function convertInteger(BigInteger $x)
|
||
|
{
|
||
|
return $this->factory->newInteger($x);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the length, in bytes, of the modulo
|
||
|
*
|
||
|
* @return integer
|
||
|
*/
|
||
|
public function getLengthInBytes()
|
||
|
{
|
||
|
return $this->factory->getLengthInBytes();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the length, in bits, of the modulo
|
||
|
*
|
||
|
* @return integer
|
||
|
*/
|
||
|
public function getLength()
|
||
|
{
|
||
|
return $this->factory->getLength();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Multiply a point on the curve by a scalar
|
||
|
*
|
||
|
* Uses the montgomery ladder technique as described here:
|
||
|
*
|
||
|
* https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder
|
||
|
* https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function multiplyPoint(array $p, FiniteField\Integer $d)
|
||
|
{
|
||
|
$alreadyInternal = isset($p[2]);
|
||
|
$r = $alreadyInternal ?
|
||
|
[[], $p] :
|
||
|
[[], $this->convertToInternal($p)];
|
||
|
|
||
|
$d = $d->toBits();
|
||
|
for ($i = 0; $i < strlen($d); $i++) {
|
||
|
$d_i = (int) $d[$i];
|
||
|
$r[1 - $d_i] = $this->addPoint($r[0], $r[1]);
|
||
|
$r[$d_i] = $this->doublePoint($r[$d_i]);
|
||
|
}
|
||
|
|
||
|
return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates a random scalar multiplier
|
||
|
*
|
||
|
* @return FiniteField
|
||
|
*/
|
||
|
public function createRandomMultiplier()
|
||
|
{
|
||
|
static $one;
|
||
|
if (!isset($one)) {
|
||
|
$one = new BigInteger(1);
|
||
|
}
|
||
|
|
||
|
$dA = BigInteger::randomRange($one, $this->order->subtract($one));
|
||
|
return $this->factory->newInteger($dA);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the Order
|
||
|
*/
|
||
|
public function setOrder(BigInteger $order)
|
||
|
{
|
||
|
$this->order = $order;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the Order
|
||
|
*
|
||
|
* @return \phpseclib\Math\BigInteger
|
||
|
*/
|
||
|
public function getOrder()
|
||
|
{
|
||
|
return $this->order;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Use a custom defined modular reduction function
|
||
|
*
|
||
|
* @return object
|
||
|
*/
|
||
|
public function setReduction(callable $func)
|
||
|
{
|
||
|
$this->factory->setReduction($func);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the affine point
|
||
|
*
|
||
|
* @return object[]
|
||
|
*/
|
||
|
public function convertToAffine(array $p)
|
||
|
{
|
||
|
return $p;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Converts an affine point to a jacobian coordinate
|
||
|
*
|
||
|
* @return object[]
|
||
|
*/
|
||
|
public function convertToInternal(array $p)
|
||
|
{
|
||
|
return $p;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Negates a point
|
||
|
*
|
||
|
* @return object[]
|
||
|
*/
|
||
|
public function negatePoint(array $p)
|
||
|
{
|
||
|
$temp = [
|
||
|
$p[0],
|
||
|
$p[1]->negate()
|
||
|
];
|
||
|
if (isset($p[2])) {
|
||
|
$temp[] = $p[2];
|
||
|
}
|
||
|
return $temp;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Multiply and Add Points
|
||
|
*
|
||
|
* @return int[]
|
||
|
*/
|
||
|
public function multiplyAddPoints(array $points, array $scalars)
|
||
|
{
|
||
|
$p1 = $this->convertToInternal($points[0]);
|
||
|
$p2 = $this->convertToInternal($points[1]);
|
||
|
$p1 = $this->multiplyPoint($p1, $scalars[0]);
|
||
|
$p2 = $this->multiplyPoint($p2, $scalars[1]);
|
||
|
$r = $this->addPoint($p1, $p2);
|
||
|
return $this->convertToAffine($r);
|
||
|
}
|
||
|
}
|