Skip to content
This repository has been archived by the owner on Aug 18, 2020. It is now read-only.

Commit

Permalink
add basic operations port and python example code
Browse files Browse the repository at this point in the history
  • Loading branch information
Todd Stavish committed Oct 27, 2017
1 parent c1165c9 commit d68e83f
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 11 deletions.
64 changes: 60 additions & 4 deletions SEALPython/wrapper.cpp
@@ -1,10 +1,18 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "bigpoly.h"
#include "bigpolyarray.h"
#include "biguint.h"
#include "chooser.h"
#include "encryptionparams.h"
#include "ciphertext.h"
#include "decryptor.h"
#include "encoder.h"
#include "encryptor.h"
#include "encryptionparams.h"
#include "evaluator.h"
#include "keygenerator.h"
#include "memorypoolhandle.h"
#include "plaintext.h"

namespace py = pybind11;

Expand All @@ -16,6 +24,14 @@ using namespace std;

PYBIND11_MODULE(seal, m) {

py::class_<BigPoly>(m, "BigPoly")
.def(py::init<>())
.def("to_string", &BigPoly::to_string,
"Returns a human-readable string description of the BigPoly");

py::class_<BigPolyArray>(m, "BigPolyArray")
.def(py::init<>());

py::class_<BigUInt>(m, "BigUInt")
.def(py::init<>())
.def("to_double", &BigUInt::to_double,
Expand All @@ -25,11 +41,24 @@ PYBIND11_MODULE(seal, m) {
.def_static("default_parameter_options", &ChooserEvaluator::default_parameter_options,
"Retrieve default parameter options");

py::class_<Ciphertext>(m, "Ciphertext")
.def(py::init<const BigPolyArray &>());

py::class_<Decryptor>(m, "Decryptor")
.def(py::init<const EncryptionParameters &, const BigPoly &, const MemoryPoolHandle &>())
.def("decrypt", (BigPoly (Decryptor::*)(const BigPolyArray &)) &Decryptor::decrypt,
"Decrypts a ciphertext and returns the result")
.def("invariant_noise_budget", &Decryptor::invariant_noise_budget, "Returns noise budget");

py::class_<Encryptor>(m, "Encryptor")
.def(py::init<const EncryptionParameters &, const BigPolyArray &, const MemoryPoolHandle &>())
.def("encrypt", (BigPolyArray (Encryptor::*)(const BigPoly &)) &Encryptor::encrypt,
"Encrypts a plaintext and returns the result");

py::class_<EncryptionParameters>(m, "EncryptionParameters")
.def(py::init<>())
.def(py::init<const MemoryPoolHandle &>())
.def("plain_modulus", &EncryptionParameters::plain_modulus,
"Returns the plaintext modulus")
.def("plain_modulus", &EncryptionParameters::plain_modulus, "Returns the plaintext modulus")
.def("set_coeff_modulus",
(void (EncryptionParameters::*)(const BigUInt &)) &EncryptionParameters::set_coeff_modulus,
"Set coefficient modulus parameter")
Expand All @@ -56,11 +85,38 @@ PYBIND11_MODULE(seal, m) {

py::class_<EncryptionParameterQualifiers>(m, "EncryptionParameterQuailifers");

py::class_<Evaluator>(m, "Evaluator")
.def(py::init<const EncryptionParameters &, const MemoryPoolHandle &>())
.def("negate", (BigPolyArray (Evaluator::*)(const BigPolyArray &)) &Evaluator::negate,
"Negates a ciphertext and returns the result")
.def("add", (BigPolyArray (Evaluator::*)(const BigPolyArray &, const BigPolyArray &)) &Evaluator::add,
"Adds two ciphertexts and returns the result")
.def("sub", (BigPolyArray (Evaluator::*)(const BigPolyArray &, const BigPolyArray &)) &Evaluator::sub,
"Subtracts two ciphertexts and returns the result")
.def("multiply",
(BigPolyArray (Evaluator::*)(const BigPolyArray &, const BigPolyArray &)) &Evaluator::multiply,
"Multiplies two ciphertexts without performing relinearization, and returns the result");

py::class_<IntegerEncoder>(m, "IntegerEncoder")
.def(py::init<const BigUInt &, std::uint64_t, const MemoryPoolHandle &>());
.def(py::init<const BigUInt &, std::uint64_t, const MemoryPoolHandle &>())
.def("encode", (BigPoly (IntegerEncoder::*)(std::uint64_t)) &IntegerEncoder::encode, "Encode integer")
.def("encode", (BigPoly (IntegerEncoder::*)(std::int64_t)) &IntegerEncoder::encode, "Encode integer")
.def("decode_int32", &IntegerEncoder::decode_int32,
"Decodes a plaintext polynomial and returns the result as std::uint32_t");

py::class_<KeyGenerator>(m, "KeyGenerator")
.def(py::init<const EncryptionParameters &, const MemoryPoolHandle &>())
.def("generate", &KeyGenerator::generate, "Generates keys")
.def("public_key", &KeyGenerator::public_key, "Returns public key")
.def("secret_key", &KeyGenerator::secret_key, "Returns secret key");

py::class_<MemoryPoolHandle>(m, "MemoryPoolHandle")
.def(py::init<>())
.def_static("acquire_global", &MemoryPoolHandle::acquire_global,
"Returns a MemoryPoolHandle pointing to the global memory pool");

py::class_<Plaintext>(m, "Plaintext")
.def(py::init<>())
.def(py::init<const BigPoly &>())
.def("to_string", &Plaintext::to_string, "Returns the plaintext as a formated string");
}
92 changes: 87 additions & 5 deletions SEALPythonExamples/examples.py
@@ -1,7 +1,13 @@
from seal import ChooserEvaluator, \
EncryptionParameters, \
IntegerEncoder, \
MemoryPoolHandle
from seal import ChooserEvaluator, \
Ciphertext, \
Decryptor, \
Encryptor, \
EncryptionParameters, \
Evaluator, \
IntegerEncoder, \
KeyGenerator, \
MemoryPoolHandle, \
Plaintext

def example_basics():
"""
Expand Down Expand Up @@ -143,9 +149,85 @@ def example_basics():
# at least as large as this number.

# Here we choose to create an IntegerEncoder with base b=2.
memorypool = MemoryPoolHandle.acquire_global()
encoder = IntegerEncoder(parms.plain_modulus(),
2,
MemoryPoolHandle.acquire_global())
memorypool)

# Encode two integers as polynomials.
value1 = 5
value2 = -7
encoded1 = encoder.encode(value1)
encoded2 = encoder.encode(value2)
print("Encoded " + str(value1) + " as polynomial " + encoded1.to_string())
print("Encoded " + str(value2) + " as polynomial " + encoded2.to_string())

# Generate keys.
print("Generating keys ...")
generator = KeyGenerator(parms, memorypool);
generator.generate(0);
print("... key generation complete")
public_key = generator.public_key()
secret_key = generator.secret_key()

# Encrypt values.
print("Encrypting values...")
encryptor = Encryptor(parms, public_key, memorypool)
encrypted1 = encryptor.encrypt(encoded1)
encrypted2 = encryptor.encrypt(encoded2)

# Perform arithmetic on encrypted values.
print("Performing arithmetic on ecrypted numbers ...")
evaluator = Evaluator(parms, memorypool)
print("Performing homomorphic negation ...")
encryptednegated1 = evaluator.negate(encrypted1)
print("Performing homomorphic addition ...")
encryptedsum = evaluator.add(encrypted1, encrypted2)
print("Performing homomorphic subtraction ...")
encrypteddiff = evaluator.sub(encrypted1, encrypted2)
print("Performing homomorphic multiplication ...")
encryptedproduct = evaluator.multiply(encrypted1, encrypted2)

# Decrypt results.
print("Decrypting results ...")
decryptor = Decryptor(parms, secret_key, memorypool)
decrypted1 = decryptor.decrypt(encrypted1)
decrypted2 = decryptor.decrypt(encrypted2)
decryptednegated1 = decryptor.decrypt(encryptednegated1)
decryptedsum = decryptor.decrypt(encryptedsum)
decrypteddiff = decryptor.decrypt(encrypteddiff)
decryptedproduct = decryptor.decrypt(encryptedproduct)

# Decode results.
decoded1 = encoder.decode_int32(decrypted1)
decoded2 = encoder.decode_int32(decrypted2)
decodednegated1 = encoder.decode_int32(decryptednegated1)
decodedsum = encoder.decode_int32(decryptedsum)
decodeddiff = encoder.decode_int32(decrypteddiff)
decodedproduct = encoder.decode_int32(decryptedproduct)

# Display results.
print("Original = " + str(value1) + "; after encryption/decryption = "
+ str(decoded1))
print("Original = " + str(value2) + "; after encryption/decryption = "
+ str(decoded2))
print("Encrypted negate of " + str(value1) + " = " + str(decodednegated1))
print("Encrypted addition of " + str(value1) + " and " + str(value2) + " = "
+ str(decodedsum))
print("Encrypted subtraction of " + str(value1) + " and " + str(value2)
+ " = " + str(decodeddiff))
print("Encrypted multiplication of " + str(value1) + " and " + str(value2)
+ " = " + str(decodedproduct))

# How much noise budget did we use in these operations?
print("Noise budget in encryption of " + str(value1) + ": "
+ str(decryptor.invariant_noise_budget(encrypted1)) + " bits")
print("Noise budget in encryption of " + str(value2) + ": "
+ str(decryptor.invariant_noise_budget(encrypted2)) + " bits")
print("Noise budget in sum: "
+ str(decryptor.invariant_noise_budget(encryptedsum)) + " bits")
print("Noise budget in product: "
+ str(decryptor.invariant_noise_budget(encryptedproduct)) + " bits")

def main():
# Example: Basics
Expand Down
4 changes: 2 additions & 2 deletions run-docker.sh
@@ -1,4 +1,4 @@
#!/bin/bash
docker run -it seal bash
# docker run -it seal bash
# docker run -it seal ./bin/sealexamples
# docker run -it seal python3 SEALPythonExamples/examples.py
docker run -it seal python3 SEALPythonExamples/examples.py

0 comments on commit d68e83f

Please sign in to comment.