Files
MP-SPDZ/Math/gfp.hpp
Marcel Keller 6cc3fccef0 Maintenance.
2023-05-09 14:50:53 +10:00

203 lines
3.9 KiB
C++

#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<int X, int L>
const true_type gfp_<X, L>::invertible;
template<int X, int L>
const true_type gfp_<X, L>::prime_field;
template<int X, int L>
const int gfp_<X, L>::MAX_N_BITS;
template<int X, int L>
inline void gfp_<X, L>::read_or_generate_setup(string dir,
const OnlineOptions& opts)
{
if (opts.prime == 0)
read_setup<gfp_<X, L>>(dir, opts.lgp);
else
init_field(opts.prime);
}
template<int X, int L>
void gfp_<X, L>::check_setup(string dir)
{
::check_setup(dir, pr());
}
template<int X, int L>
void gfp_<X, L>::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 <int X, int L>
void gfp_<X, L>::init_default(int lgp, bool mont)
{
init_field(SPDZ_Data_Setup_Primes(lgp), mont);
}
template<int X, int L>
gfp_<X, L>::gfp_(const gfpvar& other)
{
assert(ZpD.pr == other.get_ZpD().pr);
a = other.get();
}
template <int X, int L>
void gfp_<X, L>::check()
{
assert(mpn_cmp(a.x, ZpD.get_prA(), t()) < 0);
}
template <int X, int L>
void gfp_<X, L>::almost_randomize(PRNG& G)
{
G.get_octets((octet*)a.x,t()*sizeof(mp_limb_t));
a.x[t()-1]&=ZpD.mask;
}
template <int X, int L>
gfp_<X, L> gfp_<X, L>::operator<<(int n) const
{
if (!is_zero())
{
if (n != 0)
{
return *this * power_of_two(1, n);
}
else
return *this;
}
else
{
return {};
}
}
template <int X, int L>
gfp_<X, L> gfp_<X, L>::operator>>(int n) const
{
if (!is_zero())
{
if (n != 0)
{
return (bigint::tmp = *this) >>= n;
}
else
return *this;
}
else
{
return {};
}
}
template <int X, int L>
gfp_<X, L> gfp_<X, L>::operator<<(const gfp_& i) const
{
return *this << (bigint::tmp = i).get_ui();
}
template <int X, int L>
gfp_<X, L> gfp_<X, L>::operator>>(const gfp_& i) const
{
return *this >> (bigint::tmp = i).get_ui();
}
template<int X, int L>
gfp_<X, L> gfp_<X, L>::invert() const
{
gfp_ res;
Inv(res.a, a, ZpD);
return res;
}
template<int X, int L>
gfp_<X, L> gfp_<X, L>::sqrRoot()
{
// Temp move to bigint so as to call sqrRootMod
bigint ti;
ti = sqrRootMod(*this);
if (!isOdd(ti))
ti = ZpD.pr - ti;
gfp_<X, L> temp;
to_gfp(temp, ti);
return temp;
}
template <int X, int L>
void gfp_<X, L>::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<int X, int L>
bool gfp_<X, L>::allows(Dtype type)
{
return type <= DATA_INVERSE;
}
template<int X, int L>
void gfp_<X, L>::specification(octetStream& os)
{
os.store(pr());
}
template <int X, int L>
gfp_<X, L> gfp_<X, L>::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