Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ build/
.vscode/
.idea
.png
.json
.txt
*.json
*.txt
.cproject
.project
.html
*.pyc
.settings/
docs/
demoData/
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
cmake_minimum_required (VERSION 3.5.1)

project(openfhe)
project (OpenFHE-Python)

set(OPENFHE_PYTHON_VERSION_MAJOR 0)
set(OPENFHE_PYTHON_VERSION_MINOR 8)
set(OPENFHE_PYTHON_VERSION_PATCH 1)
set(OPENFHE_PYTHON_VERSION ${OPENFHE_PYTHON_VERSION_MAJOR}.${OPENFHE_PYTHON_VERSION_MINOR}.${OPENFHE_PYTHON_VERSION_PATCH})

set(CMAKE_CXX_STANDARD 17)
option( BUILD_STATIC "Set to ON to include static versions of the library" OFF)

Expand Down Expand Up @@ -66,4 +72,4 @@ execute_process(
)

message(STATUS "Python site packages directory: ${PYTHON_SITE_PACKAGES}")
install(TARGETS openfhe LIBRARY DESTINATION ${PYTHON_SITE_PACKAGES})
install(TARGETS openfhe LIBRARY DESTINATION ${PYTHON_SITE_PACKAGES})
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
- [Building](#building)
- [Prerequisites](#requirements)
- [Linux Install](#linux)
- [Installing the .so: Conda](#conda)
- [Installing the .so: System](#system-install)
- [Using Conda environments](#conda)
- [Running Examples](#code-examples)
- [OpenFHE Python Wrapper Documentation](#openfhe-python-wrapper-documentation)

Expand Down
19 changes: 12 additions & 7 deletions examples/pke/iterative-ckks-bootstrapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ def iterative_bootstrap_example():
parameters.SetSecurityLevel(SecurityLevel.HEStd_NotSet)
parameters.SetRingDim(1 << 12)

rescale_tech = ScalingTechnique.FLEXIBLEAUTO
dcrt_bits = 59
first_mod = 60
if get_native_int()==128:
rescale_tech = ScalingTechnique.FIXEDAUTO
dcrt_bits = 78
first_mod = 89
else:
rescale_tech = ScalingTechnique.FLEXIBLEAUTO
dcrt_bits = 59
first_mod = 60

parameters.SetScalingModSize(dcrt_bits)
parameters.SetScalingTechnique(rescale_tech)
Expand All @@ -35,12 +40,10 @@ def iterative_bootstrap_example():
num_iterations = 2

level_budget = [3, 3]
# Each extra iteration on top of 1 requires an extra level to be consumed.
approx_bootstrapp_depth = 8 + (num_iterations - 1)
bsgs_dim = [0,0]

levels_used_before_bootstrap = 10
depth = levels_used_before_bootstrap + FHECKKSRNS.GetBootstrapDepth(approx_bootstrapp_depth, level_budget, secret_key_dist)
levels_available_after_bootstrap = 10
depth = levels_available_after_bootstrap = 10 + FHECKKSRNS.GetBootstrapDepth(level_budget, secret_key_dist) + (num_iterations - 1)
parameters.SetMultiplicativeDepth(depth)

# Generate crypto context
Expand Down Expand Up @@ -80,6 +83,8 @@ def iterative_bootstrap_example():
Here, we assume all ciphertexts in the cryptoContext will have num_slots slots.
We start with a depleted ciphertext that has used up all of its levels."""
ptxt = cryptocontext.MakeCKKSPackedPlaintext(x, 1, depth -1,None,num_slots)
ptxt.SetLength(num_slots)
print(f"Input: {ptxt}")

# Encrypt the encoded vectors
ciph = cryptocontext.Encrypt(key_pair.publicKey, ptxt)
Expand Down
24 changes: 14 additions & 10 deletions examples/pke/simple-ckks-bootstrapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@ def simple_bootstrap_example():
parameters.SetSecurityLevel(SecurityLevel.HEStd_NotSet)
parameters.SetRingDim(1<<12)

rescale_tech = ScalingTechnique.FLEXIBLEAUTO
dcrt_bits = 59
first_mod = 60
if get_native_int()==128:
rescale_tech = ScalingTechnique.FIXEDAUTO
dcrt_bits = 78
first_mod = 89
else:
rescale_tech = ScalingTechnique.FLEXIBLEAUTO
dcrt_bits = 59
first_mod = 60

parameters.SetScalingModSize(dcrt_bits)
parameters.SetScalingTechnique(rescale_tech)
parameters.SetFirstModSize(first_mod)

level_budget = [4, 4]
approx_bootstrapp_depth = 8

levels_used_before_bootstrap = 10
levels_available_after_bootstrap = 10

depth = levels_used_before_bootstrap + FHECKKSRNS.GetBootstrapDepth(approx_bootstrapp_depth, level_budget, secret_key_dist)
depth = levels_available_after_bootstrap + FHECKKSRNS.GetBootstrapDepth(level_budget, secret_key_dist)

parameters.SetMultiplicativeDepth(depth)

Expand All @@ -51,18 +55,18 @@ def simple_bootstrap_example():
x = [0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0, 5.0]
encoded_length = len(x)

ptxt = cryptocontext.MakeCKKSPackedPlaintext(x)
ptxt = cryptocontext.MakeCKKSPackedPlaintext(x,1,depth-1)
ptxt.SetLength(encoded_length)

print(f"Input: {x}")
print(f"Input: {ptxt}")

ciph = cryptocontext.Encrypt(key_pair.publicKey, ptxt)

print(f"Initial number of levels remaining: {ciph.GetLevel()}")
print(f"Initial number of levels remaining: {depth - ciph.GetLevel()}")

ciphertext_after = cryptocontext.EvalBootstrap(ciph)

print(f"Number of levels remaining after bootstrapping: {ciphertext_after.GetLevel()}")
print(f"Number of levels remaining after bootstrapping: {depth - ciphertext_after.GetLevel()}")

result = cryptocontext.Decrypt(ciphertext_after,key_pair.secretKey)
result.SetLength(encoded_length)
Expand Down
97 changes: 61 additions & 36 deletions examples/pke/simple-integers-serial-bgvrns.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# import openfhe.PKESchemeFeature as Feature

datafolder = 'demoData'

serType = BINARY # BINARY or JSON
print("This program requres the subdirectory `" + datafolder + "' to exist, otherwise you will get an error writing serializations.")

# Sample Program: Step 1: Set CryptoContext
Expand All @@ -18,7 +18,7 @@
cryptoContext.Enable(PKESchemeFeature.LEVELEDSHE)

# Serialize cryptocontext
if not SerializeToFile(datafolder + "/cryptocontext.txt", cryptoContext, BINARY):
if not SerializeToFile(datafolder + "/cryptocontext.txt", cryptoContext, serType):
raise Exception("Error writing serialization of the crypto context to cryptocontext.txt")
print("The cryptocontext has been serialized.")

Expand All @@ -29,21 +29,21 @@
print("The keypair has been generated.")

# Serialize the public key
if not SerializeToFile(datafolder + "/key-public.txt", keypair.publicKey, BINARY):
if not SerializeToFile(datafolder + "/key-public.txt", keypair.publicKey, serType):
raise Exception("Error writing serialization of the public key to key-public.txt")
print("The public key has been serialized.")

# Serialize the secret key
if not SerializeToFile(datafolder + "/key-secret.txt", keypair.secretKey, BINARY):
raise Exception("Error writing serialization of the secret key to key-secret.txt")
if not SerializeToFile(datafolder + "/key-private.txt", keypair.secretKey, serType):
raise Exception("Error writing serialization of the secret key to key-private.txt")
print("The secret key has been serialized.")

# Generate the relinearization key
cryptoContext.EvalMultKeyGen(keypair.secretKey)
print("The relinearization key has been generated.")

# Serialize the relinearization key
if not cryptoContext.SerializeEvalMultKey(datafolder + "/key-eval-mult.txt",BINARY):
if not cryptoContext.SerializeEvalMultKey(datafolder + "/key-eval-mult.txt",serType):
raise Exception("Error writing serialization of the eval mult keys to \"key-eval-mult.txt\"")
print("The relinearization key has been serialized.")

Expand All @@ -52,7 +52,7 @@
print("The rotation evaluation keys have been generated.")

# Serialize the rotation evaluation keys
if not cryptoContext.SerializeEvalAutomorphismKey(datafolder + "/key-eval-rot.txt",BINARY):
if not cryptoContext.SerializeEvalAutomorphismKey(datafolder + "/key-eval-rot.txt",serType):
raise Exception("Error writing serialization of the eval rotate keys to \"key-eval-rot.txt\"")
print("The rotation evaluation keys have been serialized.")

Expand All @@ -77,15 +77,15 @@
ciphertext3 = cryptoContext.Encrypt(keypair.publicKey, plaintext3)
print("The plaintexts have been encrypted.")

if not SerializeToFile(datafolder + "/ciphertext1.txt", ciphertext1, BINARY):
if not SerializeToFile(datafolder + "/ciphertext1.txt", ciphertext1, serType):
raise Exception("Error writing serialization of ciphertext 1 to ciphertext1.txt")
print("The first ciphertext has been serialized.")

if not SerializeToFile(datafolder + "/ciphertext2.txt", ciphertext2, BINARY):
if not SerializeToFile(datafolder + "/ciphertext2.txt", ciphertext2, serType):
raise Exception("Error writing serialization of ciphertext2 to ciphertext2.txt")
print("The second ciphertext has been serialized.")

if not SerializeToFile(datafolder + "/ciphertext3.txt", ciphertext3, BINARY):
if not SerializeToFile(datafolder + "/ciphertext3.txt", ciphertext3, serType):
raise Exception("Error writing serialization of ciphertext3 to ciphertext3.txt")
print("The third ciphertext has been serialized.")

Expand All @@ -101,49 +101,45 @@
ReleaseAllContexts()

# Deserialize the crypto context
cc = CryptoContext()

if not DeserializeFromFile(datafolder + "/cryptocontext.txt", cc, BINARY):
cc, res = DeserializeCryptoContext(datafolder + "/cryptocontext.txt", serType)
if not res:
raise Exception("Error reading serialization of the crypto context from cryptocontext.txt")
print("The cryptocontext has been deserialized.")

# Deserialize the public key
pk = PublicKey()
pk, res = DeserializePublicKey(datafolder + "/key-public.txt", serType)

if not DeserializeFromFile(datafolder + "/key-public.txt", pk, BINARY):
if not res:
raise Exception("Error reading serialization of the public key from key-public.txt")

print("The public key has been deserialized.")

# if cryptoContext.DeserializeEvalMultKey(datafolder + "/key-eval-mult.txt",BINARY):
# raise Exception("Could not deserialize the eval mult key file")
if not cc.DeserializeEvalMultKey(datafolder + "/key-eval-mult.txt",serType):
raise Exception("Could not deserialize the eval mult key file")

# print("The relinearization key has been deserialized.")
print("The relinearization key has been deserialized.")

# if cryptoContext.DeserializeEvalAutomorphismKey(datafolder + "/key-eval-rot.txt",BINARY):
# raise Exception("Could not deserialize the eval rotation key file")
if not cc.DeserializeEvalAutomorphismKey(datafolder + "/key-eval-rot.txt",serType):
raise Exception("Could not deserialize the eval rotation key file")

# print("Deserialized the eval rotation keys.")
print("Deserialized the eval rotation keys.")

# Deserialize the ciphertexts
ct1, res = DeserializeCiphertext(datafolder + "/ciphertext1.txt", serType)

ct1 = Ciphertext()
ct2 = Ciphertext()
ct3 = Ciphertext()

if not DeserializeFromFile(datafolder + "/ciphertext1.txt", ct1, BINARY):
if not res:
raise Exception("Could not read the ciphertext")

print("The first ciphertext has been deserialized.")

if not DeserializeFromFile(datafolder + "/ciphertext2.txt", ct2, BINARY):
raise Exception("Could not read the ciphertext")
ct2, res = DeserializeCiphertext(datafolder + "/ciphertext2.txt", serType)

if not res:
raise Exception("Could not read the ciphertext")
print("The second ciphertext has been deserialized.")

if not DeserializeFromFile(datafolder + "/ciphertext3.txt", ct3, BINARY):
ct3, res = DeserializeCiphertext(datafolder + "/ciphertext3.txt", serType)
if not res:
raise Exception("Could not read the ciphertext")

print("The third ciphertext has been deserialized.")

# Homomorphic addition
Expand All @@ -161,8 +157,37 @@
ciphertextRot3 = cc.EvalRotate(ct3, -1)
ciphertextRot4 = cc.EvalRotate(ct3, -2)






# Sample Program: Step 5: Decryption

sk, res = DeserializePrivateKey(datafolder + "/key-private.txt", serType)
if not res:
raise Exception("Could not read secret key")
print("The secret key has been deserialized.")

# Decrypt the result of additions
plaintextAddResult = cc.Decrypt(sk, ciphertextAddResult)

# Decrypt the result of multiplications
plaintextMultResult = cc.Decrypt(sk, ciphertextMultResult)

# Decrypt the result of rotations
plaintextRot1 = cc.Decrypt(sk, ciphertextRot1)
plaintextRot2 = cc.Decrypt(sk, ciphertextRot2)
plaintextRot3 = cc.Decrypt(sk, ciphertextRot3)
plaintextRot4 = cc.Decrypt(sk, ciphertextRot4)

# Shows only the same number of elements as in the original plaintext vector
# By default it will show all coefficients in the BFV-encoded polynomial
plaintextRot1.SetLength(len(vectorOfInts1))
plaintextRot2.SetLength(len(vectorOfInts1))
plaintextRot3.SetLength(len(vectorOfInts1))
plaintextRot4.SetLength(len(vectorOfInts1))

# Output results
print("\nResults of homomorphic computations")
print("#1 + #2 + #3: " + str(plaintextAddResult))
print("#1 * #2 * #3: " + str(plaintextMultResult))
print("Left rotation of #1 by 1: " + str(plaintextRot1))
print("Left rotation of #1 by 2: " + str(plaintextRot2))
print("Right rotation of #1 by 1: " + str(plaintextRot3))
print("Right rotation of #1 by 2: " + str(plaintextRot4))
Loading