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

Commit d68e83f

Browse files
author
Todd Stavish
committed
add basic operations port and python example code
1 parent c1165c9 commit d68e83f

File tree

3 files changed

+149
-11
lines changed

3 files changed

+149
-11
lines changed

SEALPython/wrapper.cpp

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
#include <pybind11/pybind11.h>
22
#include <pybind11/stl.h>
3+
#include "bigpoly.h"
4+
#include "bigpolyarray.h"
35
#include "biguint.h"
46
#include "chooser.h"
5-
#include "encryptionparams.h"
7+
#include "ciphertext.h"
8+
#include "decryptor.h"
69
#include "encoder.h"
10+
#include "encryptor.h"
11+
#include "encryptionparams.h"
12+
#include "evaluator.h"
13+
#include "keygenerator.h"
714
#include "memorypoolhandle.h"
15+
#include "plaintext.h"
816

917
namespace py = pybind11;
1018

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

1725
PYBIND11_MODULE(seal, m) {
1826

27+
py::class_<BigPoly>(m, "BigPoly")
28+
.def(py::init<>())
29+
.def("to_string", &BigPoly::to_string,
30+
"Returns a human-readable string description of the BigPoly");
31+
32+
py::class_<BigPolyArray>(m, "BigPolyArray")
33+
.def(py::init<>());
34+
1935
py::class_<BigUInt>(m, "BigUInt")
2036
.def(py::init<>())
2137
.def("to_double", &BigUInt::to_double,
@@ -25,11 +41,24 @@ PYBIND11_MODULE(seal, m) {
2541
.def_static("default_parameter_options", &ChooserEvaluator::default_parameter_options,
2642
"Retrieve default parameter options");
2743

44+
py::class_<Ciphertext>(m, "Ciphertext")
45+
.def(py::init<const BigPolyArray &>());
46+
47+
py::class_<Decryptor>(m, "Decryptor")
48+
.def(py::init<const EncryptionParameters &, const BigPoly &, const MemoryPoolHandle &>())
49+
.def("decrypt", (BigPoly (Decryptor::*)(const BigPolyArray &)) &Decryptor::decrypt,
50+
"Decrypts a ciphertext and returns the result")
51+
.def("invariant_noise_budget", &Decryptor::invariant_noise_budget, "Returns noise budget");
52+
53+
py::class_<Encryptor>(m, "Encryptor")
54+
.def(py::init<const EncryptionParameters &, const BigPolyArray &, const MemoryPoolHandle &>())
55+
.def("encrypt", (BigPolyArray (Encryptor::*)(const BigPoly &)) &Encryptor::encrypt,
56+
"Encrypts a plaintext and returns the result");
57+
2858
py::class_<EncryptionParameters>(m, "EncryptionParameters")
2959
.def(py::init<>())
3060
.def(py::init<const MemoryPoolHandle &>())
31-
.def("plain_modulus", &EncryptionParameters::plain_modulus,
32-
"Returns the plaintext modulus")
61+
.def("plain_modulus", &EncryptionParameters::plain_modulus, "Returns the plaintext modulus")
3362
.def("set_coeff_modulus",
3463
(void (EncryptionParameters::*)(const BigUInt &)) &EncryptionParameters::set_coeff_modulus,
3564
"Set coefficient modulus parameter")
@@ -56,11 +85,38 @@ PYBIND11_MODULE(seal, m) {
5685

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

88+
py::class_<Evaluator>(m, "Evaluator")
89+
.def(py::init<const EncryptionParameters &, const MemoryPoolHandle &>())
90+
.def("negate", (BigPolyArray (Evaluator::*)(const BigPolyArray &)) &Evaluator::negate,
91+
"Negates a ciphertext and returns the result")
92+
.def("add", (BigPolyArray (Evaluator::*)(const BigPolyArray &, const BigPolyArray &)) &Evaluator::add,
93+
"Adds two ciphertexts and returns the result")
94+
.def("sub", (BigPolyArray (Evaluator::*)(const BigPolyArray &, const BigPolyArray &)) &Evaluator::sub,
95+
"Subtracts two ciphertexts and returns the result")
96+
.def("multiply",
97+
(BigPolyArray (Evaluator::*)(const BigPolyArray &, const BigPolyArray &)) &Evaluator::multiply,
98+
"Multiplies two ciphertexts without performing relinearization, and returns the result");
99+
59100
py::class_<IntegerEncoder>(m, "IntegerEncoder")
60-
.def(py::init<const BigUInt &, std::uint64_t, const MemoryPoolHandle &>());
101+
.def(py::init<const BigUInt &, std::uint64_t, const MemoryPoolHandle &>())
102+
.def("encode", (BigPoly (IntegerEncoder::*)(std::uint64_t)) &IntegerEncoder::encode, "Encode integer")
103+
.def("encode", (BigPoly (IntegerEncoder::*)(std::int64_t)) &IntegerEncoder::encode, "Encode integer")
104+
.def("decode_int32", &IntegerEncoder::decode_int32,
105+
"Decodes a plaintext polynomial and returns the result as std::uint32_t");
106+
107+
py::class_<KeyGenerator>(m, "KeyGenerator")
108+
.def(py::init<const EncryptionParameters &, const MemoryPoolHandle &>())
109+
.def("generate", &KeyGenerator::generate, "Generates keys")
110+
.def("public_key", &KeyGenerator::public_key, "Returns public key")
111+
.def("secret_key", &KeyGenerator::secret_key, "Returns secret key");
61112

62113
py::class_<MemoryPoolHandle>(m, "MemoryPoolHandle")
63114
.def(py::init<>())
64115
.def_static("acquire_global", &MemoryPoolHandle::acquire_global,
65116
"Returns a MemoryPoolHandle pointing to the global memory pool");
117+
118+
py::class_<Plaintext>(m, "Plaintext")
119+
.def(py::init<>())
120+
.def(py::init<const BigPoly &>())
121+
.def("to_string", &Plaintext::to_string, "Returns the plaintext as a formated string");
66122
}

SEALPythonExamples/examples.py

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
from seal import ChooserEvaluator, \
2-
EncryptionParameters, \
3-
IntegerEncoder, \
4-
MemoryPoolHandle
1+
from seal import ChooserEvaluator, \
2+
Ciphertext, \
3+
Decryptor, \
4+
Encryptor, \
5+
EncryptionParameters, \
6+
Evaluator, \
7+
IntegerEncoder, \
8+
KeyGenerator, \
9+
MemoryPoolHandle, \
10+
Plaintext
511

612
def example_basics():
713
"""
@@ -143,9 +149,85 @@ def example_basics():
143149
# at least as large as this number.
144150

145151
# Here we choose to create an IntegerEncoder with base b=2.
152+
memorypool = MemoryPoolHandle.acquire_global()
146153
encoder = IntegerEncoder(parms.plain_modulus(),
147154
2,
148-
MemoryPoolHandle.acquire_global())
155+
memorypool)
156+
157+
# Encode two integers as polynomials.
158+
value1 = 5
159+
value2 = -7
160+
encoded1 = encoder.encode(value1)
161+
encoded2 = encoder.encode(value2)
162+
print("Encoded " + str(value1) + " as polynomial " + encoded1.to_string())
163+
print("Encoded " + str(value2) + " as polynomial " + encoded2.to_string())
164+
165+
# Generate keys.
166+
print("Generating keys ...")
167+
generator = KeyGenerator(parms, memorypool);
168+
generator.generate(0);
169+
print("... key generation complete")
170+
public_key = generator.public_key()
171+
secret_key = generator.secret_key()
172+
173+
# Encrypt values.
174+
print("Encrypting values...")
175+
encryptor = Encryptor(parms, public_key, memorypool)
176+
encrypted1 = encryptor.encrypt(encoded1)
177+
encrypted2 = encryptor.encrypt(encoded2)
178+
179+
# Perform arithmetic on encrypted values.
180+
print("Performing arithmetic on ecrypted numbers ...")
181+
evaluator = Evaluator(parms, memorypool)
182+
print("Performing homomorphic negation ...")
183+
encryptednegated1 = evaluator.negate(encrypted1)
184+
print("Performing homomorphic addition ...")
185+
encryptedsum = evaluator.add(encrypted1, encrypted2)
186+
print("Performing homomorphic subtraction ...")
187+
encrypteddiff = evaluator.sub(encrypted1, encrypted2)
188+
print("Performing homomorphic multiplication ...")
189+
encryptedproduct = evaluator.multiply(encrypted1, encrypted2)
190+
191+
# Decrypt results.
192+
print("Decrypting results ...")
193+
decryptor = Decryptor(parms, secret_key, memorypool)
194+
decrypted1 = decryptor.decrypt(encrypted1)
195+
decrypted2 = decryptor.decrypt(encrypted2)
196+
decryptednegated1 = decryptor.decrypt(encryptednegated1)
197+
decryptedsum = decryptor.decrypt(encryptedsum)
198+
decrypteddiff = decryptor.decrypt(encrypteddiff)
199+
decryptedproduct = decryptor.decrypt(encryptedproduct)
200+
201+
# Decode results.
202+
decoded1 = encoder.decode_int32(decrypted1)
203+
decoded2 = encoder.decode_int32(decrypted2)
204+
decodednegated1 = encoder.decode_int32(decryptednegated1)
205+
decodedsum = encoder.decode_int32(decryptedsum)
206+
decodeddiff = encoder.decode_int32(decrypteddiff)
207+
decodedproduct = encoder.decode_int32(decryptedproduct)
208+
209+
# Display results.
210+
print("Original = " + str(value1) + "; after encryption/decryption = "
211+
+ str(decoded1))
212+
print("Original = " + str(value2) + "; after encryption/decryption = "
213+
+ str(decoded2))
214+
print("Encrypted negate of " + str(value1) + " = " + str(decodednegated1))
215+
print("Encrypted addition of " + str(value1) + " and " + str(value2) + " = "
216+
+ str(decodedsum))
217+
print("Encrypted subtraction of " + str(value1) + " and " + str(value2)
218+
+ " = " + str(decodeddiff))
219+
print("Encrypted multiplication of " + str(value1) + " and " + str(value2)
220+
+ " = " + str(decodedproduct))
221+
222+
# How much noise budget did we use in these operations?
223+
print("Noise budget in encryption of " + str(value1) + ": "
224+
+ str(decryptor.invariant_noise_budget(encrypted1)) + " bits")
225+
print("Noise budget in encryption of " + str(value2) + ": "
226+
+ str(decryptor.invariant_noise_budget(encrypted2)) + " bits")
227+
print("Noise budget in sum: "
228+
+ str(decryptor.invariant_noise_budget(encryptedsum)) + " bits")
229+
print("Noise budget in product: "
230+
+ str(decryptor.invariant_noise_budget(encryptedproduct)) + " bits")
149231

150232
def main():
151233
# Example: Basics

run-docker.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/bash
2-
docker run -it seal bash
2+
# docker run -it seal bash
33
# docker run -it seal ./bin/sealexamples
4-
# docker run -it seal python3 SEALPythonExamples/examples.py
4+
docker run -it seal python3 SEALPythonExamples/examples.py

0 commit comments

Comments
 (0)