/* Copyright (C) 2015 Kushagra Singh This file is part of FLINT. FLINT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "flint.h" #include "ulong_extras.h" /* P (x : z) = P1 (x1 : z1) + P2 (x2 : z2) where P0 (x0 : zo) is P - Q */ /* Coordinates of P : x = 4 * z0 * (x1 * x2 - z1 * z2)^2 mod n z = 4 * x0 * (x2 * z1 - x1 * z2)^2 mod n */ void n_factor_ecm_add(mp_limb_t *x, mp_limb_t *z, mp_limb_t x1, mp_limb_t z1, mp_limb_t x2, mp_limb_t z2, mp_limb_t x0, mp_limb_t z0, mp_limb_t n, n_ecm_t n_ecm_inf) { mp_limb_t u, v, w; if (z1 == 0) { *x = x2; *z = z2; return; } if (z2 == 0) { *x = x1; *z = z1; return; } if (z0 == 0) { n_factor_ecm_double(x, z, x1, z1, n, n_ecm_inf); return; } u = n_submod(x2, z2, n); /* u = (x2 - z2) */ v = n_addmod(x1, z1, n); /* v = (x1 + z1) */ /* u = (x2 - z2) * (x1 + z1) */ u = n_mulmod_preinv(u, v, n, n_ecm_inf->ninv, n_ecm_inf->normbits); v = n_submod(x1, z1, n); /* v = (x1 - z1) */ w = n_addmod(x2, z2, n); /* w = (x2 + z2) */ /* v = (x1 - z1) * (x2 + z2) */ v = n_mulmod_preinv(v, w, n, n_ecm_inf->ninv, n_ecm_inf->normbits); w = n_addmod(u, v, n); /* w = 2 * (x1 * x2 - z1 * z2) */ v = n_submod(v, u, n); /* v = 2 * (x2 * z1 - x1 * z2) */ /* w = 4 * (x1 * x2 - z1 * z2)^2 */ w = n_mulmod_preinv(w, w, n, n_ecm_inf->ninv, n_ecm_inf->normbits); /* v = 4 * (x2 * z1 - x1 * z2)^2 */ v = n_mulmod_preinv(v, v, n, n_ecm_inf->ninv, n_ecm_inf->normbits); /* x = 4 * z0 * (x1 * x2 - z1 * z2)^2 */ *x = n_mulmod_preinv(z0, w, n, n_ecm_inf->ninv, n_ecm_inf->normbits); /* z = 4 * x0 * (x2 * z1 - x1 * z2)^2 */ *z = n_mulmod_preinv(x0, v, n, n_ecm_inf->ninv, n_ecm_inf->normbits); }