Skip to content

Commit 696d9e2

Browse files
committed
add more examples
1 parent 23e9434 commit 696d9e2

6 files changed

Lines changed: 409 additions & 0 deletions

File tree

examples/1_bfv_basics.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from seal import *
2+
from seal_helper import print_example_banner, print_parameters
3+
4+
5+
def bfv_basics():
6+
print_example_banner("Example: BFV Basics")
7+
8+
parms = EncryptionParameters(scheme_type.bfv)
9+
poly_modulus_degree = 8192
10+
parms.set_poly_modulus_degree(poly_modulus_degree)
11+
parms.set_coeff_modulus(CoeffModulus.BFVDefault(poly_modulus_degree))
12+
parms.set_plain_modulus(1024)
13+
14+
context = SEALContext(parms)
15+
print_parameters(context)
16+
print(f"parameter validation: {context.parameter_error_message()}")
17+
18+
keygen = KeyGenerator(context)
19+
secret_key = keygen.secret_key()
20+
public_key = keygen.create_public_key()
21+
relin_keys = keygen.create_relin_keys()
22+
23+
encryptor = Encryptor(context, public_key)
24+
evaluator = Evaluator(context)
25+
decryptor = Decryptor(context, secret_key)
26+
27+
x = 6
28+
x_plain = Plaintext(str(x))
29+
x_encrypted = encryptor.encrypt(x_plain)
30+
print(f"fresh ciphertext size: {x_encrypted.size()}")
31+
print(f"fresh noise budget: {decryptor.invariant_noise_budget(x_encrypted)} bits")
32+
33+
x_squared = evaluator.square(x_encrypted)
34+
evaluator.relinearize_inplace(x_squared, relin_keys)
35+
36+
one = Plaintext("1")
37+
x_sq_plus_one = evaluator.add_plain(x_squared, one)
38+
39+
x_plus_one = evaluator.add_plain(x_encrypted, one)
40+
x_plus_one_sq = evaluator.square(x_plus_one)
41+
evaluator.relinearize_inplace(x_plus_one_sq, relin_keys)
42+
43+
four = Plaintext("4")
44+
evaluator.multiply_plain_inplace(x_sq_plus_one, four)
45+
encrypted_result = evaluator.multiply(x_sq_plus_one, x_plus_one_sq)
46+
evaluator.relinearize_inplace(encrypted_result, relin_keys)
47+
48+
plain_result = decryptor.decrypt(encrypted_result)
49+
print("decrypted 4(x^2+1)(x+1)^2 (hex):", plain_result.to_string())
50+
print(f"result noise budget: {decryptor.invariant_noise_budget(encrypted_result)} bits")
51+
52+
53+
if __name__ == "__main__":
54+
bfv_basics()

examples/2_encoders.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import numpy as np
2+
from seal import *
3+
from seal_helper import print_example_banner, print_parameters, print_vector
4+
5+
6+
def bfv_batch_encoder_example():
7+
print_example_banner("Example: Encoders / BFV Batching")
8+
9+
parms = EncryptionParameters(scheme_type.bfv)
10+
poly_modulus_degree = 8192
11+
parms.set_poly_modulus_degree(poly_modulus_degree)
12+
parms.set_coeff_modulus(CoeffModulus.BFVDefault(poly_modulus_degree))
13+
parms.set_plain_modulus(PlainModulus.Batching(poly_modulus_degree, 20))
14+
15+
context = SEALContext(parms)
16+
print_parameters(context)
17+
18+
keygen = KeyGenerator(context)
19+
encryptor = Encryptor(context, keygen.create_public_key())
20+
evaluator = Evaluator(context)
21+
decryptor = Decryptor(context, keygen.secret_key())
22+
batch_encoder = BatchEncoder(context)
23+
24+
slot_count = batch_encoder.slot_count()
25+
pod_matrix = [0] * slot_count
26+
pod_matrix[0:8] = [0, 1, 2, 3, 4, 5, 6, 7]
27+
28+
plain_matrix = batch_encoder.encode(pod_matrix)
29+
encrypted_matrix = encryptor.encrypt(plain_matrix)
30+
31+
pod_matrix2 = [((i & 1) + 1) for i in range(slot_count)]
32+
plain_matrix2 = batch_encoder.encode(pod_matrix2)
33+
34+
encrypted_matrix = evaluator.add_plain(encrypted_matrix, plain_matrix2)
35+
evaluator.square_inplace(encrypted_matrix)
36+
evaluator.relinearize_inplace(encrypted_matrix, keygen.create_relin_keys())
37+
38+
plain_result = decryptor.decrypt(encrypted_matrix)
39+
pod_result = batch_encoder.decode(plain_result)
40+
print_vector(pod_result.astype(np.float64), 8, 0)
41+
42+
43+
def ckks_encoder_example():
44+
print_example_banner("Example: Encoders / CKKS")
45+
46+
parms = EncryptionParameters(scheme_type.ckks)
47+
poly_modulus_degree = 8192
48+
parms.set_poly_modulus_degree(poly_modulus_degree)
49+
parms.set_coeff_modulus(CoeffModulus.Create(poly_modulus_degree, [40, 40, 40, 40, 40]))
50+
context = SEALContext(parms)
51+
52+
encoder = CKKSEncoder(context)
53+
keygen = KeyGenerator(context)
54+
encryptor = Encryptor(context, keygen.create_public_key())
55+
evaluator = Evaluator(context)
56+
decryptor = Decryptor(context, keygen.secret_key())
57+
relin_keys = keygen.create_relin_keys()
58+
59+
input_vec = [0.0, 1.1, 2.2, 3.3]
60+
scale = 2.0 ** 30
61+
plain = encoder.encode(input_vec, scale)
62+
encrypted = encryptor.encrypt(plain)
63+
64+
evaluator.square_inplace(encrypted)
65+
evaluator.relinearize_inplace(encrypted, relin_keys)
66+
67+
output_plain = decryptor.decrypt(encrypted)
68+
output = encoder.decode(output_plain)
69+
print_vector(output, 4, 4)
70+
71+
72+
if __name__ == "__main__":
73+
bfv_batch_encoder_example()
74+
ckks_encoder_example()

examples/3_levels.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from seal import *
2+
from seal_helper import print_example_banner, print_parameters
3+
4+
5+
def levels_example():
6+
print_example_banner("Example: Levels")
7+
8+
parms = EncryptionParameters(scheme_type.bfv)
9+
poly_modulus_degree = 8192
10+
parms.set_poly_modulus_degree(poly_modulus_degree)
11+
parms.set_coeff_modulus(CoeffModulus.Create(poly_modulus_degree, [50, 30, 30, 50, 50]))
12+
parms.set_plain_modulus(PlainModulus.Batching(poly_modulus_degree, 20))
13+
14+
context = SEALContext(parms)
15+
print_parameters(context)
16+
17+
context_data = context.key_context_data()
18+
print("modulus switching chain:")
19+
while context_data is not None:
20+
print(f" chain index: {context_data.chain_index()}, coeff modulus count: {len(context_data.parms().coeff_modulus())}")
21+
context_data = context_data.next_context_data()
22+
23+
keygen = KeyGenerator(context)
24+
encryptor = Encryptor(context, keygen.create_public_key())
25+
evaluator = Evaluator(context)
26+
decryptor = Decryptor(context, keygen.secret_key())
27+
28+
plain = Plaintext("1x^3 + 2x^2 + 3x^1 + 4")
29+
encrypted = encryptor.encrypt(plain)
30+
31+
print("noise budget while switching levels:")
32+
while True:
33+
print(f" {decryptor.invariant_noise_budget(encrypted)} bits")
34+
try:
35+
evaluator.mod_switch_to_next_inplace(encrypted)
36+
except ValueError:
37+
break
38+
39+
decrypted = decryptor.decrypt(encrypted)
40+
print("decrypted after switching:", decrypted.to_string())
41+
42+
43+
if __name__ == "__main__":
44+
levels_example()

examples/5_ckks_basics.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import math
2+
from seal import *
3+
from seal_helper import print_example_banner, print_parameters, print_vector
4+
5+
6+
def ckks_basics():
7+
print_example_banner("Example: CKKS Basics")
8+
9+
parms = EncryptionParameters(scheme_type.ckks)
10+
poly_modulus_degree = 8192
11+
parms.set_poly_modulus_degree(poly_modulus_degree)
12+
parms.set_coeff_modulus(CoeffModulus.Create(poly_modulus_degree, [60, 40, 40, 60]))
13+
14+
context = SEALContext(parms)
15+
print_parameters(context)
16+
17+
encoder = CKKSEncoder(context)
18+
keygen = KeyGenerator(context)
19+
encryptor = Encryptor(context, keygen.create_public_key())
20+
evaluator = Evaluator(context)
21+
decryptor = Decryptor(context, keygen.secret_key())
22+
relin_keys = keygen.create_relin_keys()
23+
24+
scale = 2.0 ** 40
25+
input_vec = [0.0, 0.4, 0.8, 1.2]
26+
x_plain = encoder.encode(input_vec, scale)
27+
x1_encrypted = encryptor.encrypt(x_plain)
28+
x2_encrypted = evaluator.square(x1_encrypted)
29+
evaluator.relinearize_inplace(x2_encrypted, relin_keys)
30+
evaluator.rescale_to_next_inplace(x2_encrypted)
31+
32+
plain_coeff3 = encoder.encode(3.14159265, scale)
33+
plain_coeff1 = encoder.encode(0.4, scale)
34+
plain_coeff0 = encoder.encode(1.0, scale)
35+
36+
evaluator.mod_switch_to_inplace(plain_coeff3, x2_encrypted.parms_id())
37+
x3_encrypted = evaluator.multiply_plain(x2_encrypted, plain_coeff3)
38+
evaluator.rescale_to_next_inplace(x3_encrypted)
39+
40+
x1_encrypted_linear = evaluator.multiply_plain(x1_encrypted, plain_coeff1)
41+
evaluator.rescale_to_next_inplace(x1_encrypted_linear)
42+
evaluator.mod_switch_to_inplace(x1_encrypted_linear, x3_encrypted.parms_id())
43+
44+
evaluator.mod_switch_to_inplace(plain_coeff0, x3_encrypted.parms_id())
45+
46+
x3_encrypted.scale(scale)
47+
x1_encrypted_linear.scale(scale)
48+
encrypted_result = evaluator.add(x3_encrypted, x1_encrypted_linear)
49+
encrypted_result = evaluator.add_plain(encrypted_result, plain_coeff0)
50+
51+
plain_result = decryptor.decrypt(encrypted_result)
52+
result = encoder.decode(plain_result)
53+
54+
expected = [3.14159265 * (x * x) + 0.4 * x + 1.0 for x in input_vec]
55+
print("expected:")
56+
print_vector(expected, 4, 6)
57+
print("computed:")
58+
print_vector(result, 4, 6)
59+
60+
61+
if __name__ == "__main__":
62+
ckks_basics()

examples/6_rotation.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from seal import *
2+
from seal_helper import print_example_banner, print_parameters, print_vector
3+
4+
5+
def bfv_rotation():
6+
print_example_banner("Example: Rotation / BFV")
7+
8+
parms = EncryptionParameters(scheme_type.bfv)
9+
poly_modulus_degree = 8192
10+
parms.set_poly_modulus_degree(poly_modulus_degree)
11+
parms.set_coeff_modulus(CoeffModulus.BFVDefault(poly_modulus_degree))
12+
parms.set_plain_modulus(PlainModulus.Batching(poly_modulus_degree, 20))
13+
14+
context = SEALContext(parms)
15+
print_parameters(context)
16+
17+
keygen = KeyGenerator(context)
18+
encryptor = Encryptor(context, keygen.create_public_key())
19+
evaluator = Evaluator(context)
20+
decryptor = Decryptor(context, keygen.secret_key())
21+
batch_encoder = BatchEncoder(context)
22+
galois_keys = keygen.create_galois_keys()
23+
24+
slot_count = batch_encoder.slot_count()
25+
pod_matrix = [0] * slot_count
26+
pod_matrix[0:8] = [0, 1, 2, 3, 4, 5, 6, 7]
27+
28+
plain_matrix = batch_encoder.encode(pod_matrix)
29+
encrypted_matrix = encryptor.encrypt(plain_matrix)
30+
31+
evaluator.rotate_rows_inplace(encrypted_matrix, 3, galois_keys)
32+
print_vector(batch_encoder.decode(decryptor.decrypt(encrypted_matrix)).astype(float), 8, 0)
33+
34+
evaluator.rotate_columns_inplace(encrypted_matrix, galois_keys)
35+
print_vector(batch_encoder.decode(decryptor.decrypt(encrypted_matrix)).astype(float), 8, 0)
36+
37+
38+
def ckks_rotation():
39+
print_example_banner("Example: Rotation / CKKS")
40+
41+
parms = EncryptionParameters(scheme_type.ckks)
42+
poly_modulus_degree = 8192
43+
parms.set_poly_modulus_degree(poly_modulus_degree)
44+
parms.set_coeff_modulus(CoeffModulus.Create(poly_modulus_degree, [60, 40, 40, 60]))
45+
46+
context = SEALContext(parms)
47+
encoder = CKKSEncoder(context)
48+
keygen = KeyGenerator(context)
49+
encryptor = Encryptor(context, keygen.create_public_key())
50+
evaluator = Evaluator(context)
51+
decryptor = Decryptor(context, keygen.secret_key())
52+
galois_keys = keygen.create_galois_keys()
53+
54+
input_vec = [float(i) for i in range(8)]
55+
plain = encoder.encode(input_vec, 2.0 ** 40)
56+
encrypted = encryptor.encrypt(plain)
57+
58+
rotated = evaluator.rotate_vector(encrypted, 2, galois_keys)
59+
result = encoder.decode(decryptor.decrypt(rotated))
60+
print_vector(result, 8, 3)
61+
62+
63+
if __name__ == "__main__":
64+
bfv_rotation()
65+
ckks_rotation()

0 commit comments

Comments
 (0)