/* * AddableVector.h * */ #ifndef FHEOFFLINE_ADDABLEVECTOR_H_ #define FHEOFFLINE_ADDABLEVECTOR_H_ #include using namespace std; #include "FHE/Plaintext.h" #include "Rq_Element.h" template class AddableVector: public vector { public: AddableVector() {} AddableVector(size_t n, const T& x = T()) : vector(n, x) {} template AddableVector(const Plaintext& other) : AddableVector(other.get_poly()) {} template AddableVector(const vector& other) { this->assign(other.begin(), other.end()); } AddableVector(const Rq_Element& other) : AddableVector(other.to_vec_bigint()) { } void allocate_slots(const bigint& init) { for (auto& x: *this) x.allocate_slots(init); } int get_min_alloc() { int res = 1 << 30; for (auto& x: *this) res = min(res, x.get_min_alloc()); return res; } template AddableVector& operator=(const vector& v) { this->assign(v.begin(), v.end()); return *this; } AddableVector& operator+=(const AddableVector& y) { if (this->size() != y.size()) throw out_of_range("vector length mismatch"); size_t n = this->size(); for (unsigned int i = 0; i < n; i++) (*this)[i] += y[i]; return *this; } AddableVector operator-(const AddableVector& y) const { if (this->size() != y.size()) throw out_of_range("vector length mismatch"); AddableVector res; res.reserve(y.size()); size_t n = this->size(); for (unsigned int i = 0; i < n; i++) res.push_back((*this)[i] - y[i]); return res; } void mul(const AddableVector& x, const AddableVector& y) { if (x.size() != y.size()) throw length_error("vector length mismatch"); for (size_t i = 0; i < y.size(); i++) (*this)[i].mul(x[i], y[i]); } AddableVector mul_by_X_i(int i, const FHE_PK& pk) const; void generateUniform(PRNG& G, int n_bits) { for (unsigned int i = 0; i < this->size(); i++) (*this)[i].generateUniform(G, n_bits); } void randomize(PRNG& G) { for (auto& x : *this) x.randomize(G); } void randomize(PRNG& G, int n_bits, PT_Type type = Evaluation) { for (auto& x : *this) x.randomize(G, n_bits, false, false, type); } void assign_zero() { for (auto& x : *this) x.assign_zero(); } void assign_one() { for (auto& x : *this) x.assign_one(); } void from(const Generator& generator) { for (auto& x: *this) generator.get(x); } void pack(octetStream& os) const { os.store((unsigned int)this->size()); for (unsigned int i = 0; i < this->size(); i++) (*this)[i].pack(os); } size_t unpack_size(octetStream& os) { unsigned int size; os.get(size); this->reserve(size); return size; } void unpack(octetStream& os, const T& init = T()) { size_t new_size = unpack_size(os); this->clear(); for (unsigned int i = 0; i < new_size; i++) { this->push_back(init); this->back().unpack(os); } } void add(octetStream& os, T& tmp) { size_t new_size = unpack_size(os); T init = tmp; T& item = tmp; for (unsigned int i = 0; i < this->size(); i++) { item.unpack(os); (*this)[i] += item; } for (size_t i = this->size(); i < new_size; i++) { item.unpack(os); this->push_back(init); this->back() += item; } } T infinity_norm() const { T res = 0; for (auto& x: *this) res = min(res, x); return res; } size_t report_size(ReportType type) { size_t res = 4; for (unsigned int i = 0; i < this->size(); i++) res += (*this)[i].report_size(type); return res; } }; template class AddableMatrix: public AddableVector > { public: void resize(int n) { this->vector< AddableVector >::resize(n); } void resize(int n, int m) { resize(n); for (int i = 0; i < n; i++) (*this)[i].resize(m); } AddableMatrix mul_by_X_i(int i, const FHE_PK& pk) const; }; template AddableMatrix AddableMatrix::mul_by_X_i(int i, const FHE_PK& pk) const { AddableMatrix res; res.resize(this->size()); for (size_t j = 0; j < this->size(); j++) res[j] = (*this)[j].mul_by_X_i(i, pk); return res; } #endif /* FHEOFFLINE_ADDABLEVECTOR_H_ */