public static function add($p1, $p2) { if (self::cmp($p2, self::$infinity) == 0 && $p1 instanceof Point) { return $p1; } if (self::cmp($p1, self::$infinity) == 0 && $p2 instanceof Point) { return $p2; } if (self::cmp($p1, self::$infinity) == 0 && self::cmp($p2, self::$infinity) == 0) { return self::$infinity; } if (extension_loaded('gmp') && USE_EXT == 'GMP') { if (CurveFp::cmp($p1->curve, $p2->curve) == 0) { if (gmp_cmp(gmp_Utils::gmp_mod2(gmp_sub($p1->x, $p2->x), $p1->curve->getPrime()), '0') === 0) { if (gmp_cmp(gmp_Utils::gmp_mod2(gmp_add($p1->y, $p2->y), $p1->curve->getPrime()), '0') === 0) { return self::$infinity; } else { if (gmp_cmp(gmp_Utils::gmp_mod2(gmp_sub($p1->y, $p2->y), $p1->curve->getPrime()), '0') === 0) { return self::double($p1); } } } $p = $p1->curve->getPrime(); // $l = gmp_strval(gmp_mul(gmp_sub($p2->y, $p1->y), NumberTheory::inverse_mod(gmp_sub($p2->x, $p1->x), $p))); $l = gmp_strval(gmp_mul(gmp_sub($p2->y, $p1->y), gmp_strval(gmp_invert(gmp_sub($p2->x, $p1->x), $p)))); $x3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_sub(gmp_pow($l, 2), $p1->x), $p2->x), $p)); $y3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_mul($l, gmp_sub($p1->x, $x3)), $p1->y), $p)); $p3 = new Point($p1->curve, $x3, $y3); return $p3; } else { throw new ErrorException("The Elliptic Curves do not match."); } } else { throw new ErrorException("Please install GMP"); } }
public static function add($p1, $p2) { if (self::cmp($p2, self::$infinity) == 0 && $p1 instanceof Point) { return $p1; } if (self::cmp($p1, self::$infinity) == 0 && $p2 instanceof Point) { return $p2; } if (self::cmp($p1, self::$infinity) == 0 && self::cmp($p2, self::$infinity) == 0) { return self::$infinity; } if (extension_loaded('gmp') && USE_EXT == 'GMP') { if (CurveFp::cmp($p1->curve, $p2->curve) == 0) { if (gmp_Utils::gmp_mod2(gmp_cmp($p1->x, $p2->x), $p1->curve->getPrime()) == 0) { if (gmp_Utils::gmp_mod2(gmp_add($p1->y, $p2->y), $p1->curve->getPrime()) == 0) { return self::$infinity; } else { return self::double($p1); } } $p = $p1->curve->getPrime(); $l = gmp_strval(gmp_mul(gmp_sub($p2->y, $p1->y), NumberTheory::inverse_mod(gmp_sub($p2->x, $p1->x), $p))); $x3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_sub(gmp_pow($l, 2), $p1->x), $p2->x), $p)); $y3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_mul($l, gmp_sub($p1->x, $x3)), $p1->y), $p)); $p3 = new Point($p1->curve, $x3, $y3); return $p3; } else { throw new ErrorException("The Elliptic Curves do not match."); } } elseif (extension_loaded('bcmath') && USE_EXT == 'BCMATH') { if (CurveFp::cmp($p1->curve, $p2->curve) == 0) { if (bcmod(bccomp($p1->x, $p2->x), $p1->curve->getPrime()) == 0) { if (bcmod(bcadd($p1->y, $p2->y), $p1->curve->getPrime()) == 0) { return self::$infinity; } else { return self::double($p1); } } $p = $p1->curve->getPrime(); $l = bcmod(bcmul(bcsub($p2->y, $p1->y), NumberTheory::inverse_mod(bcsub($p2->x, $p1->x), $p)), $p); $x3 = bcmod(bcsub(bcsub(bcpow($l, 2), $p1->x), $p2->x), $p); $step0 = bcsub($p1->x, $x3); $step1 = bcmul($l, $step0); $step2 = bcsub($step1, $p1->y); $step3 = bcmod($step2, $p); $y3 = bcmod(bcsub(bcmul($l, bcsub($p1->x, $x3)), $p1->y), $p); if (bccomp(0, $y3) == 1) { $y3 = bcadd($p, $y3); } $p3 = new Point($p1->curve, $x3, $y3); return $p3; } else { throw new ErrorException("The Elliptic Curves do not match."); } } else { throw new ErrorException("Please install BCMATH or GMP"); } }