// sqrt_mod_p().
// General includes.
-#include "cl_sysdep.h"
+#include "base/cl_sysdep.h"
// Specification.
-#include "cl_numtheory.h"
+#include "cln/numtheory.h"
// Implementation.
-#include "cl_I.h"
-#include "cl_abort.h"
+#include "integer/cl_I.h"
+#include "cln/exception.h"
#undef floor
-#include <math.h>
+#include <cmath>
#define floor cln_floor
+// MacOS X does "#define _R 0x00040000L". Grr...
+#undef _R
+
+namespace cln {
+
// Algorithm 1 (for very small p only):
// Try different values.
// Assume p is prime and a nonzero square in Z/pZ.
}
const pol2 square (const pol2& u)
{
- return pol2(::square(u.c0) + ::square(u.c1)*a, (u.c0*u.c1)<<1);
+ return pol2(cln::square(u.c0) + cln::square(u.c1)*a, (u.c0*u.c1)<<1);
}
const pol2 expt_pos (const pol2& x, const cl_I& y)
{
if (c1inv.condition)
return c1inv.condition;
var cl_MI z = -u.c0*c1inv;
- if (::square(z) == a)
+ if (cln::square(z) == a)
return gcd_result(1,z);
else
return gcd_result(0);
}
}
+#if defined(__GNUC__) && defined(__s390__) && (__GNUC__ == 2) // Workaround GCC-bug (see below)
+ struct cl_sylow2gen_property : public cl_property {
+ SUBCLASS_cl_property();
+ public:
+ cl_I h_rep;
+ // Constructor.
+ cl_sylow2gen_property (const cl_symbol& k, const cl_MI& h) : cl_property (k), h_rep (h.rep) {}
+ };
+#endif
+
// Algorithm 3 (for p > 2 only):
// Tonelli-Shanks.
// [Cohen, A Course in Computational Algebraic Number Theory,
// take h in G_(j+1) \ G_j, so that h^2 in G_j \ G_(j-1), and
// a^-1*b^2*h^2 is in G_(j-1). So multiply b with h.
var cl_I& p = R->modulus;
- var uintL e = ord2(p-1);
+ var uintC e = ord2(p-1);
var cl_I m = (p-1) >> e;
// p-1 = 2^e*m, m odd.
// We will have the invariant c = a^-1*b^2 in G/G_j.
- var uintL j = e;
+ var uintC j = e;
// Initialize b = a^((m+1)/2), c = a^m, but avoid to divide by a.
var cl_MI c = R->expt_pos(a,(m-1)>>1);
var cl_MI b = R->mul(a,c);
// Since this computation is a bit costly, we cache its result
// on the ring's property list.
static const cl_symbol key = (cl_symbol)(cl_string)"generator of 2-Sylow subgroup of (Z/pZ)^*";
+#if !(defined(__GNUC__) && defined(__s390__) && (__GNUC__ == 2)) // Workaround GCC-bug (see above)
struct cl_sylow2gen_property : public cl_property {
SUBCLASS_cl_property();
public:
// Constructor.
cl_sylow2gen_property (const cl_symbol& k, const cl_MI& h) : cl_property (k), h_rep (h.rep) {}
};
+#endif
var cl_sylow2gen_property* prop = (cl_sylow2gen_property*) R->get_property(key);
if (prop)
h = cl_MI(R,prop->h_rep);
do {
// Now c = a^-1*b^2 in G_j, h in G_j \ G_(j-1).
// Determine the smallest i such that c in G_i.
- var uintL i = 0;
+ var uintC i = 0;
var cl_MI ci = c; // c_i = c^(2^i)
for ( ; i < j; i++, ci = R->square(ci))
if (ci == R->one())
// Indicates that p is not prime.
return new cl_composite_condition(p);
// OK, i < j.
- for (var uintL count = j-i-1; count > 0; count--)
+ for (var uintC count = j-i-1; count > 0; count--)
h = R->square(h);
// Now h in G_(i+1) \ G_i.
b = R->mul(b,h);
const sqrt_mod_p_t sqrt_mod_p (const cl_modint_ring& R, const cl_MI& a)
{
- if (!(a.ring() == R)) cl_abort();
+ if (!(a.ring() == R)) throw runtime_exception();
var cl_I& p = R->modulus;
var cl_I aa = R->retract(a);
switch (jacobi(aa,p)) {
else
return sqrt_mod_p_t(2,R->canonhom(x1),R->canonhom(x2));
}
- var uintL l = integer_length(p);
- var uintL e = ord2(p-1);
- //if (e > 30 && e > l/(log((double)l)*0.72-1))
- if (e > 30 && e > l/(log((double)l)*0.92-2.41))
+ var uintC l = integer_length(p);
+ var uintC e = ord2(p-1);
+ //if (e > 30 && e > l/(::log((double)l)*0.72-1))
+ if (e > 30 && e > l/(::log((double)l)*0.92-2.41))
// Algorithm 2.
return cantor_zassenhaus_sqrt(R,a);
else
// Algorithm 3.
return tonelli_shanks_sqrt(R,a);
}
+
+} // namespace cln