#ifndef MATH_GFP_HPP_ #define MATH_GFP_HPP_ #include "Math/gfp.h" #include "Math/gfpvar.h" #include "Math/Setup.h" #include "Tools/Exceptions.h" #include "Math/bigint.hpp" #include "Math/Setup.hpp" template const true_type gfp_::invertible; template const true_type gfp_::prime_field; template const int gfp_::MAX_N_BITS; template inline void gfp_::read_or_generate_setup(string dir, const OnlineOptions& opts) { if (opts.prime == 0) read_setup>(dir, opts.lgp); else init_field(opts.prime); } template void gfp_::check_setup(string dir) { ::check_setup(dir, pr()); } template void gfp_::init_field(const bigint& p, bool mont) { ZpD.init(p, mont); char name[100]; snprintf(name, 100, "gfp_<%d, %d>", X, L); if (ZpD.get_t() > L) { throw wrong_gfp_size(name, p, "GFP_MOD_SZ", ZpD.get_t()); } if (ZpD.get_t() < L) { if (mont) throw wrong_gfp_size(name, p, "GFP_MOD_SZ", ZpD.get_t()); else cerr << name << " larger than necessary for modulus " << p << endl; } } template void gfp_::init_default(int lgp, bool mont) { init_field(SPDZ_Data_Setup_Primes(lgp), mont); } template gfp_::gfp_(const gfpvar& other) { assert(ZpD.pr == other.get_ZpD().pr); a = other.get(); } template void gfp_::check() { assert(mpn_cmp(a.x, ZpD.get_prA(), t()) < 0); } template void gfp_::almost_randomize(PRNG& G) { G.get_octets((octet*)a.x,t()*sizeof(mp_limb_t)); a.x[t()-1]&=ZpD.mask; } template gfp_ gfp_::operator<<(int n) const { if (!is_zero()) { if (n != 0) { return *this * power_of_two(1, n); } else return *this; } else { return {}; } } template gfp_ gfp_::operator>>(int n) const { if (!is_zero()) { if (n != 0) { return (bigint::tmp = *this) >>= n; } else return *this; } else { return {}; } } template gfp_ gfp_::operator<<(const gfp_& i) const { return *this << (bigint::tmp = i).get_ui(); } template gfp_ gfp_::operator>>(const gfp_& i) const { return *this >> (bigint::tmp = i).get_ui(); } template gfp_ gfp_::invert() const { gfp_ res; Inv(res.a, a, ZpD); return res; } template gfp_ gfp_::sqrRoot() { // Temp move to bigint so as to call sqrRootMod bigint ti; to_bigint(ti, *this); ti = sqrRootMod(ti, ZpD.pr); if (!isOdd(ti)) ti = ZpD.pr - ti; gfp_ temp; to_gfp(temp, ti); return temp; } template void gfp_::reqbl(int n) { if ((int)n > 0 && pr() < bigint(1) << (n-1)) { cerr << "Tape requires prime of bit length " << n << endl; cerr << "Run with '-lgp " << n << "'" << endl; throw invalid_params(); } else if ((int)n < 0) { throw Processor_Error("Program compiled for rings not fields, " "run compile.py without -R"); } } template bool gfp_::allows(Dtype) { return true; } template void gfp_::specification(octetStream& os) { os.store(pr()); } template gfp_ gfp_::power_of_two(bool bit, int exp) { if (bit) { while (exp >= int(powers.size())) { bigint::tmp = 1; bigint::tmp <<= powers.size(); powers.push_back(bigint::tmp); } return powers.at(exp); } else return 0; } #endif