ECPoint ECCurve::doublePoint(ECPoint &p) { if (p.isPointAtInfinity()) { return p; } BigInteger px = p.getX(); BigInteger py = p.getY(); BigInteger rx; BigInteger ry; // 1 / 2py BigInteger yInv = (py + py) % _p; yInv = yInv.invm(_p); // 3 * px^2 + a BigInteger s = ((((px * px) * 3) + _a) * yInv) % _p; // rx = s^2 - 2px rx = (s * s - px - px) % _p; // ry = -py + s(px - rx) ry = (s * (px - rx) - py) % _p; return ECPoint(rx, ry); }
ECPoint ECCurve::toAffine(ECPointJacobian &p) { BigInteger z = p.getZ(); BigInteger zInv = z.invm(_p); BigInteger z2Inv = (zInv * zInv) % _p; BigInteger z3Inv = (z2Inv * zInv) % _p; BigInteger x = p.getX(); BigInteger y = p.getY(); return ECPoint((x * z2Inv) % _p, (y * z3Inv) % _p); }
ECPoint ECCurve::addPoint(ECPoint &p, ECPoint &q) { BigInteger rx; BigInteger ry; BigInteger px = p.getX(); BigInteger py = p.getY(); BigInteger qx = q.getX(); BigInteger qy = q.getY(); // Px == Qx && Py == Qy if (p == q) { return doublePoint(p); } // Px == Qx && Py != Qy if (px == qx) { return ECPoint(); } if (p.isPointAtInfinity()) { return q; } if (q.isPointAtInfinity()) { return p; } // s = (py - qy)/(px - qx) BigInteger rise = (py - qy) % _p; BigInteger run = (px - qx) % _p; BigInteger s = (run.invm(_p) * rise) % _p; // rx = s^2 - px - qx rx = (s*s - px - qx) % _p; // ry = -py + s(px - rx) ry = (s * (px - rx) - py) % _p; return ECPoint(rx, ry); }