| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 | 
							- <?php
 
- namespace Elliptic\Curve\ShortCurve;
 
- use BN\BN;
 
- class JPoint extends \Elliptic\Curve\BaseCurve\Point
 
- {
 
-     public $x;
 
-     public $y;
 
-     public $z;
 
-     public $zOne;
 
-     function __construct($curve, $x, $y, $z)
 
-     {
 
-         parent::__construct($curve, "jacobian");
 
-         if( $x == null && $y == null && $z == null )
 
-         {
 
-             $this->x = $this->curve->one;
 
-             $this->y = $this->curve->one;
 
-             $this->z = new BN(0);
 
-         }
 
-         else
 
-         {
 
-             $this->x = new BN($x, 16);
 
-             $this->y = new BN($y, 16);
 
-             $this->z = new BN($z, 16);
 
-         }
 
-         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);
 
-         return $this->zOne = $this->z == $this->curve->one;
 
-     }
 
-     public function toP()
 
-     {
 
-         if( $this->isInfinity() )
 
-             return $this->curve->point(null, null);
 
-         $zinv = $this->z->redInvm();
 
-         $zinv2 = $zinv->redSqr();
 
-         $ax = $this->x->redMul($zinv2);
 
-         $ay = $this->y->redMul($zinv2)->redMul($zinv);
 
-         return $this->curve->point($ax, $ay);
 
-     }
 
-     public function neg() {
 
-         return $this->curve->jpoint($this->x, $this->y->redNeg(), $this->z);
 
-     }
 
-     public function add($p)
 
-     {
 
-         // O + P = P
 
-         if( $this->isInfinity() )
 
-             return $p;
 
-         // P + O = P
 
-         if( $p->isInfinity() )
 
-             return $this;
 
-         // 12M + 4S + 7A
 
-         $pz2 = $p->z->redSqr();
 
-         $z2 = $this->z->redSqr();
 
-         $u1 = $this->x->redMul($pz2);
 
-         $u2 = $p->x->redMul($z2);
 
-         $s1 = $this->y->redMul($pz2->redMul($p->z));
 
-         $s2 = $p->y->redMul($z2->redMul($this->z));
 
-         $h = $u1->redSub($u2);
 
-         $r = $s1->redSub($s2);
 
-         if( $h->isZero() )
 
-         {
 
-             if( ! $r->isZero() )
 
-                 return $this->curve->jpoint(null, null, null);
 
-             else
 
-                 return $this->dbl();
 
-         }
 
-         $h2 = $h->redSqr();
 
-         $h3 = $h2->redMul($h);
 
-         $v = $u1->redMul($h2);
 
-         $nx = $r->redSqr()->redIAdd($h3)->redISub($v)->redISub($v);
 
-         $ny = $r->redMul($v->redISub($nx))->redISub($s1->redMul($h3));
 
-         $nz = $this->z->redMul($p->z)->redMul($h);
 
-         return $this->curve->jpoint($nx, $ny, $nz);
 
-     }
 
-     public function mixedAdd($p)
 
-     {
 
-         // O + P = P
 
-         if( $this->isInfinity() )
 
-             return $p->toJ();
 
-         // P + O = P
 
-         if( $p->isInfinity() )
 
-             return $this;
 
-         // 8M + 3S + 7A
 
-         $z2 = $this->z->redSqr();
 
-         $u1 = $this->x;
 
-         $u2 = $p->x->redMul($z2);
 
-         $s1 = $this->y;
 
-         $s2 = $p->y->redMul($z2)->redMul($this->z);
 
-         $h = $u1->redSub($u2);
 
-         $r = $s1->redSub($s2);
 
-         if( $h->isZero() )
 
-         {
 
-             if( ! $r->isZero() )
 
-                 return $this->curve->jpoint(null, null, null);
 
-             else
 
-                 return $this->dbl();
 
-         }
 
-         $h2 = $h->redSqr();
 
-         $h3 = $h2->redMul($h);
 
-         $v = $u1->redMul($h2);
 
-         $nx = $r->redSqr()->redIAdd($h3)->redISub($v)->redISub($v);
 
-         $ny = $r->redMul($v->redISub($nx))->redISub($s1->redMul($h3));
 
-         $nz = $this->z->redMul($h);
 
-         return $this->curve->jpoint($nx, $ny, $nz);
 
-     }
 
-     public function dblp($pow = null)
 
-     {
 
-         if( $pow == 0 || $this->isInfinity() )
 
-             return $this;
 
-         if( $pow == null )
 
-             return $this->dbl();
 
-         if( $this->curve->zeroA || $this->curve->threeA )
 
-         {
 
-             $r = $this;
 
-             for($i = 0; $i < $pow; $i++)
 
-                 $r = $r->dbl();
 
-             return $r;
 
-         }
 
-         // 1M + 2S + 1A + N * (4S + 5M + 8A)
 
-         // N = 1 => 6M + 6S + 9A
 
-         $jx = $this->x;
 
-         $jy = $this->y;
 
-         $jz = $this->z;
 
-         $jz4 = $jz->redSqr()->redSqr();
 
-         //Reuse results
 
-         $jyd = $jy->redAdd($jy);
 
-         for($i = 0; $i < $pow; $i++)
 
-         {
 
-             $jx2 = $jx->redSqr();
 
-             $jyd2 = $jyd->redSqr();
 
-             $jyd4 = $jyd2->redSqr();
 
-             $c = $jx2->redAdd($jx2)->redIAdd($jx2)->redIAdd($this->curve->a->redMul($jz4));
 
-             $t1 = $jx->redMul($jyd2);
 
-             $nx = $c->redSqr()->redISub($t1->redAdd($t1));
 
-             $t2 = $t1->redISub($nx);
 
-             $dny = $c->redMul($t2);
 
-             $dny = $dny->redIAdd($dny)->redISub($jyd4);
 
-             $nz = $jyd->redMul($jz);
 
-             if( ($i + 1) < $pow)
 
-                 $jz4 = $jz4->redMul($jyd4);
 
-             $jx = $nx;
 
-             $jz = $nz;
 
-             $jyd = $dny;
 
-         }
 
-         return $this->curve->jpoint($jx, $jyd->redMul($this->curve->tinv), $jz);
 
-     }
 
-     public function dbl()
 
-     {
 
-         if( $this->isInfinity() )
 
-             return $this;
 
-         if( $this->curve->zeroA )
 
-             return $this->_zeroDbl();
 
-         elseif( $this->curve->threeA )
 
-             return $this->_threeDbl();
 
-         return $this->_dbl();
 
-     }
 
-     private function _zOneDbl($withA)
 
-     {
 
-         $xx = $this->x->redSqr();
 
-         $yy = $this->y->redSqr();
 
-         $yyyy = $yy->redSqr();
 
-         // S = 2 * ((X1 + YY)^2 - XX - YYYY)
 
-         $s = $this->x->redAdd($yy)->redSqr()->redISub($xx)->redISub($yyyy);
 
-         $s = $s->redIAdd($s);
 
-         // M = 3 * XX + a; a = 0
 
-         $m = null;
 
-         if( $withA )
 
-             $m = $xx->redAdd($xx)->redIAdd($xx)->redIAdd($this->curve->a);
 
-         else
 
-             $m = $xx->redAdd($xx)->redIAdd($xx);
 
-         // T = M ^ 2 - 2*S
 
-         $t = $m->redSqr()->redISub($s)->redISub($s);
 
-         $yyyy8 = $yyyy->redIAdd($yyyy);
 
-         $yyyy8 = $yyyy8->redIAdd($yyyy8);
 
-         $yyyy8 = $yyyy8->redIAdd($yyyy8);
 
-         $ny = $m->redMul($s->redISub($t))->redISub($yyyy8);
 
-         $nz = $this->y->redAdd($this->y);
 
-         return $this->curve->jpoint($t, $ny, $nz);
 
-     }
 
-     private function _zeroDbl()
 
-     {
 
-         // Z = 1
 
-         if( $this->zOne )
 
-         {
 
-             // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
 
-             //     #doubling-mdbl-2007-bl
 
-             // 1M + 5S + 14A
 
-             return $this->_zOneDbl(false);
 
-         }
 
-         // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
 
-         //     #doubling-dbl-2009-l
 
-         // 2M + 5S + 13A
 
-         $a = $this->x->redSqr();
 
-         $b = $this->y->redSqr();
 
-         $c = $b->redSqr();
 
-         // D = 2 * ((X1 + B)^2 - A - C)
 
-         $d = $this->x->redAdd($b)->redSqr()->redISub($a)->redISub($c);
 
-         $d = $d->redIAdd($d);
 
-         $e = $a->redAdd($a)->redIAdd($a);
 
-         $f = $e->redSqr();
 
-         $c8 = $c->redIAdd($c);
 
-         $c8 = $c8->redIAdd($c8);
 
-         $c8 = $c8->redIAdd($c8);
 
-         // X3 = F - 2 * D
 
-         $nx = $f->redISub($d)->redISub($d);
 
-         // Y3 = E * (D - X3) - 8 * C
 
-         $ny = $e->redMul($d->redISub($nx))->redISub($c8);
 
-         // Z3 = 2 * Y1 * Z1
 
-         $nz = $this->y->redMul($this->z);
 
-         $nz = $nz->redIAdd($nz);
 
-         return $this->curve->jpoint($nx, $ny, $nz);
 
-     }
 
-     private function _threeDbl()
 
-     {
 
-         if( $this->zOne )
 
-         {
 
-             // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
 
-             //     #doubling-mdbl-2007-bl
 
-             // 1M + 5S + 15A
 
-             // XX = X1^2
 
-             $xx = $this->x->redSqr();
 
-             // YY = Y1^2
 
-             $yy = $this->y->redSqr();
 
-             // YYYY = YY^2
 
-             $yyyy = $yy->redSqr();
 
-             // S = 2 * ((X1 + YY)^2 - XX - YYYY)
 
-             $s = $this->x->redAdd($yy)->redSqr()->redISub($xx)->redISub($yyyy);
 
-             $s = $s->redIAdd($s);
 
-             // M = 3 * XX + a
 
-             $m = $xx->redAdd($xx)->redIAdd($xx)->redIAdd($this->curve->a);
 
-             // T = M^2 - 2 * S
 
-             $t = $m->redSqr()->redISub($s)->redISub($s);
 
-             // X3 = T
 
-             $nx = $t;
 
-             // Y3 = M * (S - T) - 8 * YYYY
 
-             $yyyy8 = $yyyy->redIAdd($yyyy);
 
-             $yyyy8 = $yyyy8->redIAdd($yyyy8);
 
-             $yyyy8 = $yyyy8->redIAdd($yyyy8);
 
-             $ny = $m->redMul($s->redISub($t))->redISub($yyyy8);
 
-             // Z3 = 2 * Y1
 
-             $nz = $this->y->redAdd($this->y);
 
-         } else {
 
-             // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
 
-             // 3M + 5S
 
-             // delta = Z1^2
 
-             $delta = $this->z->redSqr();
 
-             // gamma = Y1^2
 
-             $gamma = $this->y->redSqr();
 
-             // beta = X1 * gamma
 
-             $beta = $this->x->redMul($gamma);
 
-             // alpha = 3 * (X1 - delta) * (X1 + delta)
 
-             $alpha = $this->x->redSub($delta)->redMul($this->x->redAdd($delta));
 
-             $alpha = $alpha->redAdd($alpha)->redIAdd($alpha);
 
-             // X3 = alpha^2 - 8 * beta
 
-             $beta4 = $beta->redIAdd($beta);
 
-             $beta4 = $beta4->redIAdd($beta4);
 
-             $beta8 = $beta4->redAdd($beta4);
 
-             $nx = $alpha->redSqr()->redISub($beta8);
 
-             // Z3 = (Y1 + Z1)^2 - gamma - delta
 
-             $nz = $this->y->redAdd($this->z)->redSqr()->redISub($gamma)->redISub($delta);
 
-             $ggamma8 = $gamma->redSqr();
 
-             $ggamma8 = $ggamma8->redIAdd($ggamma8);
 
-             $ggamma8 = $ggamma8->redIAdd($ggamma8);
 
-             $ggamma8 = $ggamma8->redIAdd($ggamma8);
 
-             // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
 
-             $ny = $alpha->redMul($beta4->redISub($nx))->redISub($ggamma8);
 
-         }
 
-         return $this->curve->jpoint($nx, $ny, $nz);
 
-     }
 
-     private function _dbl()
 
-     {
 
-         // 4M + 6S + 10A
 
-         $jx = $this->x;
 
-         $jy = $this->y;
 
-         $jz = $this->z;
 
-         $jz4 = $jz->redSqr()->redSqr();
 
-         $jx2 = $jx->redSqr();
 
-         $jy2 = $jy->redSqr();
 
-         $c = $jx2->redAdd($jx2)->redIAdd($jx2)->redIAdd($this->curve->a->redMul($jz4));
 
-         $jxd4 = $jx->redAdd($jx);
 
-         $jxd4 = $jxd4->redIAdd($jxd4);
 
-         $t1 = $jxd4->redMul($jy2);
 
-         $nx = $c->redSqr()->redISub($t1->redAdd($t1));
 
-         $t2 = $t1->redISub($nx);
 
-         $jyd8 = $jy2->redSqr();
 
-         $jyd8 = $jyd8->redIAdd($jyd8);
 
-         $jyd8 = $jyd8->redIAdd($jyd8);
 
-         $jyd8 = $jyd8->redIAdd($jyd8);
 
-         $ny = $c->redMul($t2)->redISub($jyd8);
 
-         $nz = $jy->redAdd($jy)->redMul($jz);
 
-         return $this->curve->jpoint($nx, $ny, $nz);
 
-     }
 
-     public function trpl()
 
-     {
 
-         if( !$this->curve->zeroA )
 
-             return $this->dbl()->add($this);
 
-         // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
 
-         // 5M + 10S + ...
 
-         $xx = $this->x->redSqr();
 
-         $yy = $this->y->redSqr();
 
-         $zz = $this->z->redSqr();
 
-         // YYYY = YY^2
 
-         $yyyy = $yy->redSqr();
 
-         // M = 3 * XX + a * ZZ2; a = 0
 
-         $m = $xx->redAdd($xx)->redIAdd($xx);
 
-         // MM = M^2
 
-         $mm = $m->redSqr();
 
-         // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
 
-         $e = $this->x->redAdd($yy)->redSqr()->redISub($xx)->redISub($yyyy);
 
-         $e = $e->redIAdd($e);
 
-         $e = $e->redAdd($e)->redIAdd($e);
 
-         $e = $e->redISub($mm);
 
-         $ee = $e->redSqr();
 
-         // T = 16*YYYY
 
-         $t = $yyyy->redIAdd($yyyy);
 
-         $t = $t->redIAdd($t);
 
-         $t = $t->redIAdd($t);
 
-         $t = $t->redIAdd($t);
 
-         // U = (M + E)^2 - MM - EE - T
 
-         $u = $m->redAdd($e)->redSqr()->redISub($mm)->redISub($ee)->redISub($t);
 
-         $yyu4 = $yy->redMul($u);
 
-         $yyu4 = $yyu4->redIAdd($yyu4);
 
-         $yyu4 = $yyu4->redIAdd($yyu4);
 
-         // X3 = 4 * (X1 * EE - 4 * YY * U)
 
-         $nx = $this->x->redMul($ee)->redISub($yyu4);
 
-         $nx = $nx->redIAdd($nx);
 
-         $nx = $nx->redIAdd($nx);
 
-         // Y3 = 8 * Y1 * (U * (T - U) - E * EE)
 
-         $ny = $this->y->redMul($u->redMul($t->redISub($u))->redISub($e->redMul($ee)));
 
-         $ny = $ny->redIAdd($ny);
 
-         $ny = $ny->redIAdd($ny);
 
-         $ny = $ny->redIAdd($ny);
 
-         // Z3 = (Z1 + E)^2 - ZZ - EE
 
-         $nz = $this->z->redAdd($e)->redSqr()->redISub($zz)->redISub($ee);
 
-         return $this->curve->jpoint($nx, $ny, $nz);
 
-     }
 
-     public function mul($k, $kbase) {
 
-         return $this->curve->_wnafMul($this, new BN($k, $kbase));
 
-     }
 
-     public function eq($p)
 
-     {
 
-         if( $p->type == "affine" )
 
-             return $this->eq($p->toJ());
 
-         if( $this == $p )
 
-             return true;
 
-         // x1 * z2^2 == x2 * z1^2
 
-         $z2 = $this->z->redSqr();
 
-         $pz2 = $p->z->redSqr();
 
-         if( ! $this->x->redMul($pz2)->redISub($p->x->redMul($z2))->isZero() )
 
-             return false;
 
-         // y1 * z2^3 == y2 * z1^3
 
-         $z3 = $z2->redMul($this->z);
 
-         $pz3 = $pz2->redMul($p->z);
 
-         return $this->y->redMul($pz3)->redISub($p->y->redMul($z3))->isZero();
 
-     }
 
-     public function eqXToP($x)
 
-     {
 
-         $zs = $this->z->redSqr();
 
-         $rx = $x->toRed($this->curve->red)->redMul($zs);
 
-         if( $this->x->cmp($rx) == 0 )
 
-             return true;
 
-         $xc = $x->_clone();
 
-         $t = $this->curve->redN->redMul($zs);
 
-         while(true)
 
-         {
 
-             $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;
 
-         }
 
-     }
 
-     public function inspect()
 
-     {
 
-         if( $this->isInfinity() )
 
-             return "<EC JPoint Infinity>";
 
-         return "<EC JPoint x: " . $this->x->toString(16, 2) .
 
-             " y: " . $this->y->toString(16, 2) .
 
-             " z: " . $this->z->toString(16, 2) . ">";
 
-     }
 
-     public function __debugInfo() {
 
-         return [
 
-             "EC JPoint" => ($this->isInfinity() ?
 
-                 "Infinity" :
 
-                 [
 
-                     "x" => $this->x->toString(16,2),
 
-                     "y" => $this->y->toString(16,2),
 
-                     "z" => $this->z->toString(16,2)
 
-                 ]
 
-             )
 
-         ];
 
-     }
 
-     public function isInfinity() {
 
-         // XXX This code assumes that zero is always zero in red
 
-         return $this->z->isZero();
 
-     }
 
- }
 
- ?>
 
 
  |