| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 | 
							- <?php
 
- namespace Elliptic\Curve\EdwardsCurve;
 
- use BN\BN;
 
- class Point extends \Elliptic\Curve\BaseCurve\Point
 
- {
 
-     public $x;
 
-     public $y;
 
-     public $z;
 
-     public $t;
 
-     public $zOne;
 
-     
 
-     function __construct($curve, $x = null, $y = null, $z = null, $t = null) {
 
-         parent::__construct($curve, 'projective');
 
-         if ($x == null && $y == null && $z == null) {
 
-             $this->x = $this->curve->zero;
 
-             $this->y = $this->curve->one;
 
-             $this->z = $this->curve->one;
 
-             $this->t = $this->curve->zero;
 
-             $this->zOne = true;
 
-         } else {
 
-             $this->x = new BN($x, 16);
 
-             $this->y = new BN($y, 16);
 
-             $this->z = $z ? new BN($z, 16) : $this->curve->one;
 
-             $this->t = $t ? new BN($t, 16) : null;
 
-             if (!$this->x->red)
 
-                 $this->x = $this->x->toRed($this->curve->red);
 
-             if (!$this->y->red)
 
-                 $this->y = $this->y->toRed($this->curve->red);
 
-             if (!$this->z->red)
 
-                 $this->z = $this->z->toRed($this->curve->red);
 
-             if ($this->t && !$this->t->red)
 
-                 $this->t = $this->t->toRed($this->curve->red);
 
-             $this->zOne = $this->z == $this->curve->one;
 
-             // Use extended coordinates
 
-             if ($this->curve->extended && !$this->t) {
 
-                 $this->t = $this->x->redMul($this->y);
 
-                 if (!$this->zOne)
 
-                     $this->t = $this->t->redMul($this->z->redInvm());
 
-             }
 
-         }
 
-     }
 
-     public static function fromJSON($curve, $obj) {
 
-         return new Point($curve, 
 
-             isset($obj[0]) ? $obj[0] : null, 
 
-             isset($obj[1]) ? $obj[1] : null, 
 
-             isset($obj[2]) ? $obj[2] : null
 
-             );
 
-     }
 
-     public function inspect() {
 
-         if ($this->isInfinity())
 
-             return '<EC Point Infinity>';
 
-         return '<EC Point x: ' . $this->x->fromRed()->toString(16, 2) .
 
-             ' y: ' . $this->y->fromRed()->toString(16, 2) .
 
-             ' z: ' . $this->z->fromRed()->toString(16, 2) . '>';
 
-     }
 
-     public function isInfinity() {
 
-         // XXX This code assumes that zero is always zero in red
 
-         return $this->x->cmpn(0) == 0 &&
 
-             $this->y->cmp($this->z) == 0;
 
-     }
 
-     public function _extDbl() {
 
-         // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
 
-         //     #doubling-dbl-2008-hwcd
 
-         // 4M + 4S
 
-         // A = X1^2
 
-         $a = $this->x->redSqr();
 
-         // B = Y1^2
 
-         $b = $this->y->redSqr();
 
-         // C = 2 * Z1^2
 
-         $c = $this->z->redSqr();
 
-         $c = $c->redIAdd($c);
 
-         // D = a * A
 
-         $d = $this->curve->_mulA($a);
 
-         // E = (X1 + Y1)^2 - A - B
 
-         $e = $this->x->redAdd($this->y)->redSqr()->redISub($a)->redISub($b);
 
-         // G = D + B
 
-         $g = $d->redAdd($b);
 
-         // F = G - C
 
-         $f = $g->redSub($c);
 
-         // H = D - B
 
-         $h = $d->redSub($b);
 
-         // X3 = E * F
 
-         $nx = $e->redMul($f);
 
-         // Y3 = G * H
 
-         $ny = $g->redMul($h);
 
-         // T3 = E * H
 
-         $nt = $e->redMul($h);
 
-         // Z3 = F * G
 
-         $nz = $f->redMul($g);
 
-         return $this->curve->point($nx, $ny, $nz, $nt);
 
-     }
 
-     public function _projDbl() {
 
-         // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
 
-         //     #doubling-dbl-2008-bbjlp
 
-         //     #doubling-dbl-2007-bl
 
-         // and others
 
-         // Generally 3M + 4S or 2M + 4S
 
-         // B = (X1 + Y1)^2
 
-         $b = $this->x->redAdd($this->y)->redSqr();
 
-         // C = X1^2
 
-         $c = $this->x->redSqr();
 
-         // D = Y1^2
 
-         $d = $this->y->redSqr();
 
-         if ($this->curve->twisted) {
 
-             // E = a * C
 
-             $e = $this->curve->_mulA($c);
 
-             // F = E + D
 
-             $f = $e->redAdd($d);
 
-             if ($this->zOne) {
 
-                 // X3 = (B - C - D) * (F - 2)
 
-                 $nx = $b->redSub($c)->redSub($d)->redMul($f->redSub($this->curve->two));
 
-                 // Y3 = F * (E - D)
 
-                 $ny = $f->redMul($e->redSub($d));
 
-                 // Z3 = F^2 - 2 * F
 
-                 $nz = $f->redSqr()->redSub($f)->redSub($f);
 
-             } else {
 
-                 // H = Z1^2
 
-                 $h = $this->z->redSqr();
 
-                 // J = F - 2 * H
 
-                 $j = $f->redSub($h)->redISub($h);
 
-                 // X3 = (B-C-D)*J
 
-                 $nx = $b->redSub($c)->redISub($d)->redMul($j);
 
-                 // Y3 = F * (E - D)
 
-                 $ny = $f->redMul($e->redSub($d));
 
-                 // Z3 = F * J
 
-                 $nz = $f->redMul($j);
 
-             }
 
-         } else {
 
-             // E = C + D
 
-             $e = $c->redAdd($d);
 
-             // H = (c * Z1)^2
 
-             $h = $this->curve->_mulC($this->c->redMul($this->z))->redSqr();
 
-             // J = E - 2 * H
 
-             $j = $e->redSub($h)->redSub($h);
 
-             // X3 = c * (B - E) * J
 
-             $nx = $this->curve->_mulC($b->redISub($e))->redMul($j);
 
-             // Y3 = c * E * (C - D)
 
-             $ny = $this->curve->_mulC($e)->redMul($c->redISub($d));
 
-             // Z3 = E * J
 
-             $nz = $e->redMul($j);
 
-         }
 
-         return $this->curve->point($nx, $ny, $nz);
 
-     }
 
-     public function dbl() {
 
-         if ($this->isInfinity())
 
-             return $this;
 
-         // Double in extended coordinates
 
-         if ($this->curve->extended)
 
-             return $this->_extDbl();
 
-         else
 
-             return $this->_projDbl();
 
-     }
 
-     public function _extAdd($p) {
 
-         // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
 
-         //     #addition-add-2008-hwcd-3
 
-         // 8M
 
-         // A = (Y1 - X1) * (Y2 - X2)
 
-         $a = $this->y->redSub($this->x)->redMul($p->y->redSub($p->x));
 
-         // B = (Y1 + X1) * (Y2 + X2)
 
-         $b = $this->y->redAdd($this->x)->redMul($p->y->redAdd($p->x));
 
-         // C = T1 * k * T2
 
-         $c = $this->t->redMul($this->curve->dd)->redMul($p->t);
 
-         // D = Z1 * 2 * Z2
 
-         $d = $this->z->redMul($p->z->redAdd($p->z));
 
-         // E = B - A
 
-         $e = $b->redSub($a);
 
-         // F = D - C
 
-         $f = $d->redSub($c);
 
-         // G = D + C
 
-         $g = $d->redAdd($c);
 
-         // H = B + A
 
-         $h = $b->redAdd($a);
 
-         // X3 = E * F
 
-         $nx = $e->redMul($f);
 
-         // Y3 = G * H
 
-         $ny = $g->redMul($h);
 
-         // T3 = E * H
 
-         $nt = $e->redMul($h);
 
-         // Z3 = F * G
 
-         $nz = $f->redMul($g);
 
-         return $this->curve->point($nx, $ny, $nz, $nt);
 
-     }
 
-     public function _projAdd($p) {
 
-         // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
 
-         //     #addition-add-2008-bbjlp
 
-         //     #addition-add-2007-bl
 
-         // 10M + 1S
 
-         // A = Z1 * Z2
 
-         $a = $this->z->redMul($p->z);
 
-         // B = A^2
 
-         $b = $a->redSqr();
 
-         // C = X1 * X2
 
-         $c = $this->x->redMul($p->x);
 
-         // D = Y1 * Y2
 
-         $d = $this->y->redMul($p->y);
 
-         // E = d * C * D
 
-         $e = $this->curve->d->redMul($c)->redMul($d);
 
-         // F = B - E
 
-         $f = $b->redSub($e);
 
-         // G = B + E
 
-         $g = $b->redAdd($e);
 
-         // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
 
-         $tmp = $this->x->redAdd($this->y)->redMul($p->x->redAdd($p->y))->redISub($c)->redISub($d);
 
-         $nx = $a->redMul($f)->redMul($tmp);
 
-         if ($this->curve->twisted) {
 
-             // Y3 = A * G * (D - a * C)
 
-             $ny = $a->redMul($g)->redMul($d->redSub($this->curve->_mulA($c)));
 
-             // Z3 = F * G
 
-             $nz = $f->redMul($g);
 
-         } else {
 
-             // Y3 = A * G * (D - C)
 
-             $ny = $a->redMul($g)->redMul($d->redSub($c));
 
-             // Z3 = c * F * G
 
-             $nz = $this->curve->_mulC($f)->redMul($g);
 
-         }
 
-         return $this->curve->point($nx, $ny, $nz);
 
-     }
 
-     public function add($p) {
 
-         if ($this->isInfinity())
 
-             return $p;
 
-         if ($p->isInfinity())
 
-             return $this;
 
-         if ($this->curve->extended)
 
-             return $this->_extAdd($p);
 
-         else
 
-             return $this->_projAdd($p);
 
-     }
 
-     public function mul($k) {
 
-         if ($this->_hasDoubles($k))
 
-             return $this->curve->_fixedNafMul($this, $k);
 
-         else
 
-             return $this->curve->_wnafMul($this, $k);
 
-     }
 
-     public function mulAdd($k1, $p, $k2) {
 
-         return $this->curve->_wnafMulAdd(1, [ $this, $p ], [ $k1, $k2 ], 2, false);
 
-     }
 
-     public function jmulAdd($k1, $p, $k2) {
 
-         return $this->curve->_wnafMulAdd(1, [ $this, $p ], [ $k1, $k2 ], 2, true);
 
-     }
 
-     public function normalize() {
 
-         if ($this->zOne)
 
-             return $this;
 
-         // Normalize coordinates
 
-         $zi = $this->z->redInvm();
 
-         $this->x = $this->x->redMul($zi);
 
-         $this->y = $this->y->redMul($zi);
 
-         if ($this->t)
 
-             $this->t = $this->t->redMul($zi);
 
-         $this->z = $this->curve->one;
 
-         $this->zOne = true;
 
-         return $this;
 
-     }
 
-     public function neg() {
 
-         return $this->curve->point($this->x->redNeg(),
 
-             $this->y,
 
-             $this->z,
 
-             ($this->t != null) ? $this->t->redNeg() : null);
 
-     }
 
-     public function getX() {
 
-         $this->normalize();
 
-         return $this->x->fromRed();
 
-     }
 
-     public function getY() {
 
-         $this->normalize();
 
-         return $this->y->fromRed();
 
-     }
 
-     public function eq($other) {
 
-         return $this == $other ||
 
-             $this->getX()->cmp($other->getX()) == 0 &&
 
-             $this->getY()->cmp($other->getY()) == 0;
 
-     }
 
-     public function eqXToP($x) {
 
-         $rx = $x->toRed($this->curve->red)->redMul($this->z);
 
-         if ($this->x->cmp($rx) == 0)
 
-             return true;
 
-         $xc = $x->_clone();
 
-         $t = $this->curve->redN->redMul($this->z);
 
-         for (;;) {
 
-             $xc->iadd($this->curve->n);
 
-             if ($xc->cmp($this->curve->p) >= 0)
 
-                 return false;
 
-             $rx->redIAdd($t);
 
-             if ($this->x->cmp($rx) == 0)
 
-                 return true;
 
-         }
 
-         return false;
 
-     }
 
-     // Compatibility with BaseCurve
 
-     public function toP() { return $this->normalize(); }
 
-     public function mixedAdd($p) { return $this->add($p); }
 
- }
 
 
  |