/* * FixedVec.h * */ #ifndef MATH_FIXEDVEC_H_ #define MATH_FIXEDVEC_H_ #include #include using namespace std; #include "Tools/octetStream.h" #include "Tools/random.h" #include "field_types.h" template class ReplicatedMC; template class ReplicatedInput; template class ReplicatedPrivateOutput; template class Replicated; template class FixedVec { array v; public: typedef T value_type; static const int length = L; static int size() { return L * T::size(); } static string type_string() { return T::type_string() + "^" + to_string(L); } static string type_short() { return string(1, T::type_char()); } static DataFieldType field_type() { return T::field_type(); } template static FixedVec Mul(const FixedVec& a, const V& b) { FixedVec res; for (int i = 0; i < L; i++) res[i] = T::Mul(a[i], b); return res; } FixedVec(const T& other = 0) { for (auto& x : v) x = other; } FixedVec(long other) : FixedVec(T(other)) { } template FixedVec(const FixedVec& other) { for (int i = 0; i < L; i++) v[i] = other[i]; } FixedVec(const array& other) { v = other; } const array& get() const { return v; } T& operator[](int i) { return v[i]; } const T& operator[](int i) const { return v[i]; } void assign(const T& other) { for (auto& x : v) x = other; } void assign(const char* buffer) { for (int i = 0; i < L; i++) v[i].assign(buffer + i * T::size()); } void assign_zero() { for (auto& x : v) x = 0; } void assign_one() { assign(1); } void add(const FixedVec& x, const FixedVec& y) { for (int i = 0; i < L; i++) v[i] = x.v[i] + y.v[i]; } void sub(const FixedVec& x, const FixedVec& y) { for (int i = 0; i < L; i++) v[i] = x.v[i] - y.v[i]; } void mul(const FixedVec& x, const FixedVec& y) { for (int i = 0; i < L; i++) v[i].mul(x.v[i], y.v[i]); } void add(const FixedVec& x) { add(*this, x); } void negate() { for (auto& x : v) x = -x; } bool equal(const FixedVec& x) const { for (int i = 0; i < L; i++) if (v[i] != x[i]) return false; return true; } bool is_zero() { return equal(0); } bool is_one() { return equal(1); } FixedVecoperator+(const FixedVec& other) const { FixedVec res; res.add(*this, other); return res; } FixedVecoperator-(const FixedVec& other) const { FixedVec res; res.sub(*this, other); return res; } FixedVecoperator*(const FixedVec& other) const { FixedVec res; res.mul(*this, other); return res; } FixedVecoperator/(const FixedVec& other) const { FixedVec res; for (int i = 0; i < L; i++) res[i] = v[i] / other[i]; return res; } FixedVecoperator^(const FixedVec& other) const { FixedVec res; for (int i = 0; i < L; i++) res[i] = v[i] ^ other[i]; return res; } FixedVecoperator&(const FixedVec& other) const { FixedVec res; for (int i = 0; i < L; i++) res[i] = v[i] & other[i]; return res; } FixedVec& operator+=(const FixedVec& other) { add(other); return *this; } FixedVec& operator*=(const FixedVec& other) { *this = *this * other; return *this; } FixedVec& operator/=(const FixedVec& other) { *this = *this / other; return *this; } FixedVec& operator^=(const FixedVec& other) { for (int i = 0; i < L; i++) v[i] ^= other[i]; return *this; } FixedVec& operator&=(const FixedVec& other) { for (int i = 0; i < L; i++) v[i] &= other[i]; return *this; } FixedVec operator<<(int i) const { FixedVec res; for (int j = 0; j < L; j++) res[j] = v[j] << i; return res; } FixedVec operator>>(int i) const { FixedVec res; for (int j = 0; j < L; j++) res[j] = v[j] >> i; return res; } FixedVec& operator>>=(int i) { *this = *this >> i; return *this; } T sum() const { T res = 0; for (auto& x : v) res += x; return res; } FixedVec extend_bit() const { FixedVec res; for (int i = 0; i < L; i++) res[i] = v[i].extend_bit(); return res; } FixedVec mask(int n_bits) const { FixedVec res; for (int i = 0; i < L; i++) res[i] = v[i].mask(n_bits); return res; } void randomize(PRNG& G) { for (auto& x : v) x.randomize(G); } void randomize_to_sum(const T& sum, PRNG& G) { T s = 0; for (int i = 1; i < L; i++) { v[i].randomize(G); s += v[i]; } v[0] = sum - s; } void force_to_bit() { for (auto& x : v) x.force_to_bit(); } void output(ostream& s, bool human) const { for (auto& x : v) x.output(s, human); } void input(istream& s, bool human) { for (auto& x : v) x.input(s, human); } void pack(octetStream& os) const { for (auto& x : v) x.pack(os); } void unpack(octetStream& os) { for (auto& x : v) x.unpack(os); } }; template FixedVec operator*(const U& a, const FixedVec& b) { return b * a; } template ostream& operator<<(ostream& os, const FixedVec& v) { for (int i = 0; i < L; i++) { os << v[i]; if (i < L - 1) os << ","; } return os; } #endif /* MATH_FIXEDVEC_H_ */