1 #include <cln/integer.h>
2 #include <cln/modinteger.h>
5 #include "cra_garner.hpp"
13 retract_symm(const cl_MI& x, const cl_modint_ring& R,
16 cl_I result = R->retract(x);
17 if (result > (modulus >> 1))
18 result = result - modulus;
23 compute_recips(vector<cl_MI>& dst,
24 const vector<cl_I>& moduli)
26 for (size_t k = 1; k < moduli.size(); ++k) {
27 cl_modint_ring R = find_modint_ring(moduli[k]);
28 cl_MI product = R->canonhom(moduli[0]);
29 for (size_t i = 1; i < k; ++i)
30 product = product*moduli[i];
31 dst[k-1] = recip(product);
36 compute_mix_radix_coeffs(vector<cl_I>& dst,
37 const vector<cl_I>& residues,
38 const vector<cl_I>& moduli,
39 const vector<cl_MI>& recips)
44 cl_modint_ring R = find_modint_ring(moduli[1]);
45 cl_MI tmp = R->canonhom(residues[0]);
46 cl_MI next = (R->canonhom(residues[1]) - tmp)*recips[0];
47 dst[1] = retract_symm(next, R, moduli[1]);
50 for (size_t k = 2; k < residues.size(); ++k) {
51 cl_modint_ring R = find_modint_ring(moduli[k]);
52 cl_MI tmp = R->canonhom(dst[k-1]);
54 for (size_t j = k - 1 /* NOT k - 2 */; j-- != 0; )
55 tmp = tmp*moduli[j] + R->canonhom(dst[j]);
57 cl_MI next = (R->canonhom(residues[k]) - tmp)*recips[k-1];
58 dst[k] = retract_symm(next, R, moduli[k]);
63 mixed_radix_2_ordinary(const vector<cl_I>& mixed_radix_coeffs,
64 const vector<cl_I>& moduli)
66 size_t k = mixed_radix_coeffs.size() - 1;
67 cl_I u = mixed_radix_coeffs[k];
69 u = u*moduli[k] + mixed_radix_coeffs[k];
73 cl_I integer_cra(const vector<cl_I>& residues,
74 const vector<cl_I>& moduli)
77 vector<cl_MI> recips(moduli.size() - 1);
78 compute_recips(recips, moduli);
80 vector<cl_I> coeffs(moduli.size());
81 compute_mix_radix_coeffs(coeffs, residues, moduli, recips);
82 cl_I result = mixed_radix_2_ordinary(coeffs, moduli);