Function: zncoppersmith
Section: number_theoretical
C-Name: zncoppersmith
Prototype: GGGDG
Help: zncoppersmith(P, N, X, {B=N}): finds all integers x
 with |x| <= X such that  gcd(N, P(x)) >= B. The parameter X should be smaller
 than exp((log B)^2 / (deg(P) log N)) and the leading coefficient of P should be
 coprime to N.
Doc: \idx{Coppersmith}'s algorithm. $N$ being an integer and $P\in \Z[t]$,
 finds in polynomial time in $\log(N)$ and $d = \text{deg}(P)$ all integers $x$
 with $|x| \leq X$ such that
 $$\gcd(N, P(x)) \geq B.$$
 This is a famous application of the \idx{LLL} algorithm meant to help in the
 factorization of $N$. Notice that $P$ may be reduced modulo $N\Z[t]$ without
 affecting the situation. The parameter $X$ must not be too large: assume for
 now that the leading coefficient of $P$ is coprime to $N$, then we must have
 $$d \log X \log N < \log^2 B,$$ i.e., $X < N^{1/d}$ when $B = N$. Let now
 $P_0$ be the gcd of the leading coefficient of $P$ and $N$. In applications to
 factorization, we should have $P_0 = 1$; otherwise, either $P_0 = N$ and we can
 reduce the degree of $P$, or $P_0$ is a non trivial factor of $N$. For
 completeness, we nevertheless document the exact conditions that $X$ must
 satisfy in this case: let $p := \log_N P_0$, $b := \log_N B$, $x := \log_N
 X$, then

 \item either $p \geq d / (2d-1)$ is large and we must have $x d < 2b - 1$;

 \item or $p < d / (2d-1)$ and we must have both $p < b < 1 - p + p/d$
 and $x(d + p(1-2d)) < (b - p)^2$. Note that this reduces to
 $x d < b^2$ when $p = 0$, i.e., the condition described above.

 Some $x$ larger than $X$ may be returned if you are
 very lucky. The routine runs in polynomial time in $\log N$ and $d$
 but the smaller $B$, or the larger $X$, the slower.
 The strength of Coppersmith method is the ability to find roots modulo a
 general \emph{composite} $N$: if $N$ is a prime or a prime power,
 \tet{polrootsmod} or \tet{polrootspadic} will be much faster.

 We shall now present two simple applications. The first one is
 finding nontrivial factors of $N$, given some partial information on the
 factors; in that case $B$ must obviously be smaller than the largest
 nontrivial divisor of $N$.
 \bprog
 setrand(1); \\ to make the example reproducible
 [a,b] = [10^30, 10^31]; D = 20;
 p = randomprime([a,b]);
 q = randomprime([a,b]); N = p*q;
 \\ assume we know 0) p | N; 1) p in [a,b]; 2) the last D digits of p
 p0 = p % 10^D;

 ? L = zncoppersmith(10^D*x + p0, N, b \ 10^D, a)
 time = 1ms.
 %6 = [738281386540]
 ? gcd(L[1] * 10^D + p0, N) == p
 %7 = 1
 @eprog\noindent and we recovered $p$, faster than by trying all
 possibilities $ x < 10^{11}$.

 The second application is an attack on RSA with low exponent, when the
 message $x$ is short and the padding $P$ is known to the attacker. We use
 the same RSA modulus $N$ as in the first example:
 \bprog
 setrand(1);
 P = random(N);    \\ known padding
 e = 3;            \\ small public encryption exponent
 X = floor(N^0.3); \\ N^(1/e - epsilon)
 x0 = random(X);   \\ unknown short message
 C = lift( (Mod(x0,N) + P)^e ); \\ known ciphertext, with padding P
 zncoppersmith((P + x)^3 - C, N, X)

 \\ result in 244ms.
 %14 = [2679982004001230401]

 ? %[1] == x0
 %15 = 1
 @eprog\noindent
 We guessed an integer of the order of $10^{18}$, almost instantly.
