-
Notifications
You must be signed in to change notification settings - Fork 1
/
qseive.c
120 lines (104 loc) · 2.81 KB
/
qseive.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h>
#include <gmp.h>
#include "bw.h"
#include "fmpz.h"
#include "ulong_extras.h"
void
_qseive(const mp_limb_t n, const mp_limb_t B)
{
nmod_sparse_mat_t M;
mp_limb_t quad, *quads, *xs, x, i = 0, j, piB = n_prime_pi(B);
const mp_limb_t * ps = n_primes_arr_readonly(piB + 2);
const double * pinvs = n_prime_inverses_arr_readonly(piB + 2);
mzd_t *K;
/* init */
quads = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *));
xs = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *));
K = mzd_init(piB + 1, 1);
nmod_sparse_mat_init(M, piB + 1, piB + 1, 2);
printf("init done\n");
printf("using %ld primes\n", piB);
/* seive */
for (x = n_sqrt(n), i = 0; i <= piB; x++)
{
quad = x*x - n;
if (quad == 0)
continue;
for (j = 0; j < piB; j++)
n_remove2_precomp(&quad, ps[j], pinvs[j]);
if (quad == 1) /* was B-smooth */
{
quads[i] = x*x - n;
quad = x*x - n;
for (j = 0; j < piB; j++)
{
if (n_remove2_precomp(&quad, ps[j], pinvs[j]) % 2)
_nmod_sparse_mat_set_entry(M, j, i, M->row_supports[j], 1);
}
xs[i] = x;
i++;
}
}
printf("data collection done\n");
n_cleanup_primes();
_bw(K, M, 1, 2, 7, 7);
printf("procesing complete\n");
mzd_print(K);
int done = 0;
for (j = 0; !done; j++)
{
fmpz_t a, b, diff, N;
fmpz_init_set_ui(a, 1);
fmpz_init_set_ui(b, 1);
fmpz_init_set_ui(N, n);
fmpz_init(diff);
for (i = 0; i < piB; i++)
{
if (mzd_read_bit(K, i, j))
{
fmpz_mul_ui(a, a, xs[i]);
fmpz_mul_ui(b, b, quads[i]);
}
}
assert(fmpz_is_square(b));
fmpz_sqrt(b, b);
if (fmpz_mod_ui(a, a, n) != fmpz_mod_ui(b, b, n) && fmpz_mod_ui(a, a, n) != n - fmpz_mod_ui(b, b, n))
{
done = 1;
fmpz_print(a);
printf("\n");
fmpz_print(b);
printf("\n");
fmpz_sub(diff, a, b);
fmpz_gcd(a, diff, N);
fmpz_divexact(b, N, a);
fmpz_print(a);
printf("\n");
fmpz_print(b);
}
fmpz_clear(a);
fmpz_clear(b);
fmpz_clear(N);
fmpz_clear(diff);
}
/* cleanup */
free(quads);
free(xs);
mzd_free(K);
nmod_sparse_mat_clear(M);
return;
}
void
qseive(mp_limb_t n)
{
double logn = log(n), loglogn = log(logn);
mp_limb_t B = (mp_limb_t)(exp((0.5f + 0.38f)*sqrt(logn*loglogn)));
_qseive(n, B);
}
int
main(int argc, char * argv[])
{
mp_limb_t n = 10142789312725007;
n = n_nextprime(1000000000,0)*n_nextprime(1200000000,0);
qseive(n);
}