Skip to content

Commit

Permalink
Merge branch 'main' of github.com:OpenMined/TenSEAL
Browse files Browse the repository at this point in the history
  • Loading branch information
bcebere committed Nov 7, 2022
2 parents ce399df + ca54c3b commit 5c1e9c1
Show file tree
Hide file tree
Showing 39 changed files with 331 additions and 150 deletions.
7 changes: 0 additions & 7 deletions .github/codeql/codeql-config.yml

This file was deleted.

46 changes: 0 additions & 46 deletions .github/workflows/codeql-analysis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 3.14)

project(tenseal)

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ TenSEAL is a library for doing homomorphic encryption operations on tensors, bui

- :key: Encryption/Decryption of vectors of integers using BFV
- :old_key: Encryption/Decryption of vectors of real numbers using CKKS
- :fire: Element-wise addition, substraction and multiplication of encrypted-encrypted vectors and encrypted-plain vectors
- :fire: Element-wise addition, subtraction and multiplication of encrypted-encrypted vectors and encrypted-plain vectors
- :cyclone: Dot product and vector-matrix multiplication
- :zap: Complete SEAL API under `tenseal.sealapi`

Expand Down Expand Up @@ -95,7 +95,7 @@ Supported platforms and their requirements are listed below: (this are only requ
- **MacOS:** Xcode toolchain (>= 9.3)
- **Windows:** Microsoft Visual Studio (>= 10.0.40219.1, Visual Studio 2010 SP1 or later).

If you want to install tenseal from the repository, you should first make sure to have the requirements for your platform (listed above) and [CMake (3.12 or higher)](https://cmake.org/install/) installed, then get the third party libraries (if you didn't already) by running the following command from the root directory of the project
If you want to install tenseal from the repository, you should first make sure to have the requirements for your platform (listed above) and [CMake (3.14 or higher)](https://cmake.org/install/) installed, then get the third party libraries (if you didn't already) by running the following command from the root directory of the project

```bash
$ git submodule init
Expand Down
8 changes: 4 additions & 4 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
black==19.10b0
bumpversion>=0.5.3
black==22.3.0
bumpversion
flake8
numpy
pytest>=5.4.1
pytest
pytest-benchmark
pytest-cov
pytest-benchmark[histogram]
setuptools>=41.0.0
setuptools
pygal
pygaljs
scikit-image
Expand Down
8 changes: 5 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,18 @@ def build_extension(self, ext):
cfg = "Debug" if self.debug else "Release"
build_args = ["--config", cfg]

env = os.environ.copy()

if platform.system() == "Windows":
cmake_args += [f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{cfg.upper()}={extdir}"]
if sys.maxsize > 2 ** 32:
if sys.maxsize > 2**32:
cmake_args += ["-A", "x64"]
build_args += ["--", "/m", "/p:TrackFileAccess=false"]
else:
cmake_args += ["-DCMAKE_BUILD_TYPE=" + cfg]
build_args += ["--", "-j"]
if "MAKEFLAGS" not in env:
build_args += ["--", "-j"]

env = os.environ.copy()
env["CXXFLAGS"] = '{} -DVERSION_INFO=\\"{}\\"'.format(
env.get("CXXFLAGS", ""), self.distribution.get_version()
)
Expand Down
2 changes: 2 additions & 0 deletions tenseal/binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ void bind_bfv_vector(py::module &m) {
})
.def("mul_plain_",
py::overload_cast<const int64_t &>(&BFVVector::mul_plain_inplace))
.def("polyval", &BFVVector::polyval)
.def("polyval_", &BFVVector::polyval_inplace)
.def("dot", &BFVVector::dot)
.def("dot", &BFVVector::dot_plain)
.def("dot_", &BFVVector::dot_inplace)
Expand Down
6 changes: 3 additions & 3 deletions tenseal/cpp/tensors/bfvtensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,15 @@ shared_ptr<BFVTensor> BFVTensor::sum_batch_inplace() {
}

shared_ptr<BFVTensor> BFVTensor::polyval_inplace(
const vector<double>& coefficients) {
const vector<int64_t>& coefficients) {
if (coefficients.size() == 0) {
throw invalid_argument(
"the coefficients vector need to have at least one element");
}

int degree = static_cast<int>(coefficients.size()) - 1;
while (degree >= 0) {
if (coefficients[degree] == 0.0)
if (coefficients[degree] == 0)
degree--;
else
break;
Expand Down Expand Up @@ -413,7 +413,7 @@ shared_ptr<BFVTensor> BFVTensor::polyval_inplace(

// coefficients[1] * x + ... + coefficients[degree] * x^(degree)
for (int i = 1; i <= degree; i++) {
if (coefficients[i] == 0.0) continue;
if (coefficients[i] == 0) continue;
x = compute_polynomial_term(i, coefficients[i], x_squares);
result->add_inplace(x);
}
Expand Down
2 changes: 1 addition & 1 deletion tenseal/cpp/tensors/bfvtensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class BFVTensor : public EncryptedTensor<int64_t, shared_ptr<BFVTensor>>,
shared_ptr<BFVTensor> sum_batch_inplace();

shared_ptr<BFVTensor> polyval_inplace(
const vector<double>& coefficients) override;
const vector<int64_t>& coefficients) override;

shared_ptr<BFVTensor> dot_inplace(
const shared_ptr<BFVTensor>& to_mul) override;
Expand Down
73 changes: 65 additions & 8 deletions tenseal/cpp/tensors/bfvvector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,20 @@ shared_ptr<BFVVector> BFVVector::dot_plain_inplace(

shared_ptr<BFVVector> BFVVector::sum_inplace(size_t /*axis=0*/) {
vector<Ciphertext> interm_sum;
// TODO use multithreading for sum
for (size_t idx = 0; idx < this->_ciphertexts.size(); ++idx) {
Ciphertext out = this->_ciphertexts[idx];
sum_vector(this->tenseal_context(), out, this->_sizes[idx]);
interm_sum.push_back(out);
}
size_t size = this->_ciphertexts.size();
interm_sum.resize(size);

task_t worker_func = [&](size_t start, size_t end) -> bool {
for (size_t idx = start; idx < end; ++idx) {
Ciphertext out = this->_ciphertexts[idx];
sum_vector(this->tenseal_context(), out, this->_sizes[idx]);
interm_sum[idx] = out;
}
return true;
};

this->dispatch_jobs(worker_func, size);

Ciphertext result;
tenseal_context()->evaluator->add_many(interm_sum, result);

Expand Down Expand Up @@ -343,8 +351,57 @@ shared_ptr<BFVVector> BFVVector::matmul_plain_inplace(
}

shared_ptr<BFVVector> BFVVector::polyval_inplace(
const vector<double>& coefficients) {
throw std::logic_error("not implemented");
const vector<int64_t>& coefficients) {
if (coefficients.size() == 0) {
throw invalid_argument(
"the coefficients vector need to have at least one element");
}

int degree = static_cast<int>(coefficients.size()) - 1;
while (degree >= 0) {
if (coefficients[degree] == 0)
degree--;
else
break;
}

// null polynomial: output should be an encrypted 0
// we can multiply by 0, or return the encryption of zero
if (degree == -1) {
// we set the vector to the encryption of zero
for (auto& ct : this->_ciphertexts) {
this->tenseal_context()->encrypt_zero(ct);
}
return shared_from_this();
}

// set result accumulator to the constant coefficient
vector<int64_t> cst_coeff(this->size(), coefficients[0]);
auto result = BFVVector::Create(this->tenseal_context(), cst_coeff);

// pre-compute squares of x
auto x = this->copy();

int max_square = static_cast<int>(floor(log2(degree)));
vector<shared_ptr<BFVVector>> x_squares;
x_squares.reserve(max_square + 1);
x_squares.push_back(x->copy()); // x
for (int i = 1; i <= max_square; i++) {
x->square_inplace();
x_squares.push_back(x->copy()); // x^(2^i)
}

// coefficients[1] * x + ... + coefficients[degree] * x^(degree)
for (int i = 1; i <= degree; i++) {
if (coefficients[i] == 0) continue;
x = compute_polynomial_term(
i, coefficients[i],
x_squares); // currently takes a double, allow int64
result->add_inplace(x);
}

this->_ciphertexts = result->ciphertext();
return shared_from_this();
}

shared_ptr<BFVVector> BFVVector::conv2d_im2col_inplace(
Expand Down
2 changes: 1 addition & 1 deletion tenseal/cpp/tensors/bfvvector.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class BFVVector
* p(x) = coefficients[0] + coefficients[1] * x + ... + coefficients[i] *
*x^i
**/
encrypted_t polyval_inplace(const vector<double>& coefficients) override;
encrypted_t polyval_inplace(const vector<int64_t>& coefficients) override;

/*
* Image Block to Columns.
Expand Down
20 changes: 14 additions & 6 deletions tenseal/cpp/tensors/ckksvector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,20 @@ shared_ptr<CKKSVector> CKKSVector::dot_plain_inplace(const plain_t& to_mul) {

shared_ptr<CKKSVector> CKKSVector::sum_inplace(size_t /*axis = 0*/) {
vector<Ciphertext> interm_sum;
// TODO use multithreading for the sum
for (size_t idx = 0; idx < this->_ciphertexts.size(); ++idx) {
Ciphertext out = this->_ciphertexts[idx];
sum_vector(this->tenseal_context(), out, this->_sizes[idx]);
interm_sum.push_back(out);
}
size_t size = this->_ciphertexts.size();
interm_sum.resize(size);

task_t worker_func = [&](size_t start, size_t end) -> bool {
for (size_t idx = start; idx < end; ++idx) {
Ciphertext out = this->_ciphertexts[idx];
sum_vector(this->tenseal_context(), out, this->_sizes[idx]);
interm_sum[idx] = out;
}
return true;
};

this->dispatch_jobs(worker_func, size);

Ciphertext result;
tenseal_context()->evaluator->add_many(interm_sum, result);

Expand Down
5 changes: 3 additions & 2 deletions tenseal/cpp/tensors/encrypted_tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,11 @@ class EncryptedTensor {
* p(x) = coefficients[0] + coefficients[1] * x + ... + coefficients[i] *
*x^i
**/
encrypted_t polyval(const vector<double>& coefficients) const {
encrypted_t polyval(const vector<plain_data_t>& coefficients) const {
return this->copy()->polyval_inplace(coefficients);
};
virtual encrypted_t polyval_inplace(const vector<double>& coefficients) = 0;
virtual encrypted_t polyval_inplace(
const vector<plain_data_t>& coefficients) = 0;
/**
* Load/Save the Tensor from/to a serialized protobuffer.
**/
Expand Down
Loading

0 comments on commit 5c1e9c1

Please sign in to comment.