/src/gmp-6.2.1/mpn/trialdiv.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* mpn_trialdiv -- find small factors of an mpn number using trial division. |
2 | | |
3 | | Contributed to the GNU project by Torbjorn Granlund. |
4 | | |
5 | | THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY |
6 | | SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST |
7 | | GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE. |
8 | | |
9 | | Copyright 2009, 2010, 2012, 2013 Free Software Foundation, Inc. |
10 | | |
11 | | This file is part of the GNU MP Library. |
12 | | |
13 | | The GNU MP Library is free software; you can redistribute it and/or modify |
14 | | it under the terms of either: |
15 | | |
16 | | * the GNU Lesser General Public License as published by the Free |
17 | | Software Foundation; either version 3 of the License, or (at your |
18 | | option) any later version. |
19 | | |
20 | | or |
21 | | |
22 | | * the GNU General Public License as published by the Free Software |
23 | | Foundation; either version 2 of the License, or (at your option) any |
24 | | later version. |
25 | | |
26 | | or both in parallel, as here. |
27 | | |
28 | | The GNU MP Library is distributed in the hope that it will be useful, but |
29 | | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
30 | | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
31 | | for more details. |
32 | | |
33 | | You should have received copies of the GNU General Public License and the |
34 | | GNU Lesser General Public License along with the GNU MP Library. If not, |
35 | | see https://www.gnu.org/licenses/. */ |
36 | | |
37 | | /* |
38 | | This function finds the first (smallest) factor represented in |
39 | | trialdivtab.h. It does not stop the factoring effort just because it has |
40 | | reached some sensible limit, such as the square root of the input number. |
41 | | |
42 | | The caller can limit the factoring effort by passing NPRIMES. The function |
43 | | will then divide until that limit, or perhaps a few primes more. A position |
44 | | which only mpn_trialdiv can make sense of is returned in the WHERE |
45 | | parameter. It can be used for restarting the factoring effort; the first |
46 | | call should pass 0 here. |
47 | | |
48 | | Input: 1. A non-negative number T = {tp,tn} |
49 | | 2. NPRIMES as described above, |
50 | | 3. *WHERE as described above. |
51 | | Output: 1. *WHERE updated as described above. |
52 | | 2. Return value is non-zero if we found a factor, else zero |
53 | | To get the actual prime factor, compute the mod B inverse |
54 | | of the return value. |
55 | | */ |
56 | | |
57 | | #include "gmp-impl.h" |
58 | | |
59 | | struct gmp_primes_dtab { |
60 | | mp_limb_t binv; |
61 | | mp_limb_t lim; |
62 | | }; |
63 | | |
64 | | struct gmp_primes_ptab { |
65 | | mp_limb_t ppp; /* primes, multiplied together */ |
66 | | mp_limb_t cps[7]; /* ppp values pre-computed for mpn_mod_1s_4p */ |
67 | | gmp_uint_least32_t idx:24; /* index of first primes in dtab */ |
68 | | gmp_uint_least32_t np :8; /* number of primes related to this entry */ |
69 | | }; |
70 | | |
71 | | |
72 | | static const struct gmp_primes_dtab gmp_primes_dtab[] = |
73 | | { |
74 | | #define WANT_dtab |
75 | | #define P(p,inv,lim) {inv,lim} |
76 | | #include "trialdivtab.h" |
77 | | #undef WANT_dtab |
78 | | #undef P |
79 | | {0,0} |
80 | | }; |
81 | | |
82 | | static const struct gmp_primes_ptab gmp_primes_ptab[] = |
83 | | { |
84 | | #define WANT_ptab |
85 | | #include "trialdivtab.h" |
86 | | #undef WANT_ptab |
87 | | }; |
88 | | |
89 | 0 | #define PTAB_LINES (sizeof (gmp_primes_ptab) / sizeof (gmp_primes_ptab[0])) |
90 | | |
91 | | /* FIXME: We could optimize out one of the outer loop conditions if we |
92 | | had a final ptab entry with a huge np field. */ |
93 | | mp_limb_t |
94 | | mpn_trialdiv (mp_srcptr tp, mp_size_t tn, mp_size_t nprimes, int *where) |
95 | 0 | { |
96 | 0 | mp_limb_t ppp; |
97 | 0 | const mp_limb_t *cps; |
98 | 0 | const struct gmp_primes_dtab *dp; |
99 | 0 | long i, j, idx, np; |
100 | 0 | mp_limb_t r, q; |
101 | |
|
102 | 0 | ASSERT (tn >= 1); |
103 | | |
104 | 0 | for (i = *where; i < PTAB_LINES; i++) |
105 | 0 | { |
106 | 0 | ppp = gmp_primes_ptab[i].ppp; |
107 | 0 | cps = gmp_primes_ptab[i].cps; |
108 | |
|
109 | 0 | r = mpn_mod_1s_4p (tp, tn, ppp << cps[1], cps); |
110 | |
|
111 | 0 | idx = gmp_primes_ptab[i].idx; |
112 | 0 | np = gmp_primes_ptab[i].np; |
113 | | |
114 | | /* Check divisibility by individual primes. */ |
115 | 0 | dp = &gmp_primes_dtab[idx] + np; |
116 | 0 | for (j = -np; j < 0; j++) |
117 | 0 | { |
118 | 0 | q = r * dp[j].binv; |
119 | 0 | if (q <= dp[j].lim) |
120 | 0 | { |
121 | 0 | *where = i; |
122 | 0 | return dp[j].binv; |
123 | 0 | } |
124 | 0 | } |
125 | | |
126 | 0 | nprimes -= np; |
127 | 0 | if (nprimes <= 0) |
128 | 0 | return 0; |
129 | 0 | } |
130 | 0 | return 0; |
131 | 0 | } |