Skip to content
This repository was archived by the owner on Nov 21, 2023. It is now read-only.

Commit 17f3b62

Browse files
committed
Initial version
Kind of slow, but works.
0 parents  commit 17f3b62

File tree

13 files changed

+1606
-0
lines changed

13 files changed

+1606
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__pycache__
2+
*.egg-info

examples/test_mux.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import numpy
2+
import time
3+
4+
from tfhe import *
5+
6+
7+
def int_to_bitarray(x):
8+
return numpy.array([((x >> i) & 1 != 0) for i in range(16)])
9+
10+
11+
def bitarray_to_int(x):
12+
int_answer = 0
13+
for i in range(16):
14+
int_answer = int_answer | (x[i] << i)
15+
return int_answer
16+
17+
18+
def reference_mux(bits1, bits2, bits3):
19+
numpy.array([b if a else c for a, b, c in zip(bits1, bits2, bits3)])
20+
21+
22+
def encrypt():
23+
24+
rng = numpy.random.RandomState(123)
25+
26+
print("Key generation:")
27+
t = time.time()
28+
secret_key, cloud_key = tfhe_key_pair(rng)
29+
print(time.time() - t)
30+
31+
bits1 = int_to_bitarray(2017)
32+
bits2 = int_to_bitarray(42)
33+
bits3 = int_to_bitarray(12345)
34+
35+
print("Encryption:")
36+
t = time.time()
37+
ciphertext1 = tfhe_encrypt(rng, secret_key, bits1)
38+
ciphertext2 = tfhe_encrypt(rng, secret_key, bits2)
39+
ciphertext3 = tfhe_encrypt(rng, secret_key, bits3)
40+
print(time.time() - t)
41+
42+
return secret_key, cloud_key, ciphertext1, ciphertext2, ciphertext3
43+
44+
45+
def process(cloud_key, ciphertext1, ciphertext2, ciphertext3):
46+
params = tfhe_parameters(cloud_key)
47+
result = empty_ciphertext(params, ciphertext1.shape)
48+
49+
print("Processing:")
50+
t = time.time()
51+
tfhe_gate_MUX_(cloud_key, result, ciphertext1, ciphertext2, ciphertext3)
52+
print(time.time() - t)
53+
54+
return result
55+
56+
57+
def verify(secret_key, answer):
58+
print("Decryption:")
59+
t = time.time()
60+
answer_bits = tfhe_decrypt(secret_key, answer)
61+
print(time.time() - t)
62+
63+
int_answer = bitarray_to_int(answer_bits)
64+
print("Answer:", int_answer)
65+
66+
67+
secret_key, cloud_key, ciphertext1, ciphertext2, ciphertext3 = encrypt()
68+
answer = process(cloud_key, ciphertext1, ciphertext2, ciphertext3)
69+
verify(secret_key, answer)

examples/tutorial.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import numpy
2+
import time
3+
4+
from tfhe import *
5+
6+
7+
def int_to_bitarray(x):
8+
return numpy.array([((x >> i) & 1 != 0) for i in range(16)])
9+
10+
11+
def bitarray_to_int(x):
12+
int_answer = 0
13+
for i in range(16):
14+
int_answer = int_answer | (x[i] << i)
15+
return int_answer
16+
17+
18+
def reference_mux(bits1, bits2, bits3):
19+
numpy.array([b if a else c for a, b, c in zip(bits1, bits2, bits3)])
20+
21+
22+
def encrypt():
23+
24+
rng = numpy.random.RandomState(123)
25+
26+
secret_key, cloud_key = tfhe_key_pair(rng)
27+
28+
bits1 = int_to_bitarray(2017)
29+
bits2 = int_to_bitarray(42)
30+
31+
ciphertext1 = tfhe_encrypt(rng, secret_key, bits1)
32+
ciphertext2 = tfhe_encrypt(rng, secret_key, bits2)
33+
34+
return secret_key, cloud_key, ciphertext1, ciphertext2
35+
36+
37+
# elementary full comparator gate that is used to compare the i-th bit:
38+
# input: ai and bi the i-th bit of a and b
39+
# lsb_carry: the result of the comparison on the lowest bits
40+
# algo: if (a==b) return lsb_carry else return b
41+
def encrypted_compare_bit_(cloud_key, result, a, b, lsb_carry, tmp):
42+
tfhe_gate_XNOR_(cloud_key, tmp, a, b)
43+
tfhe_gate_MUX_(cloud_key, result, tmp, lsb_carry, a)
44+
45+
46+
# this function compares two multibit words, and puts the max in result
47+
def encrypted_minimum_(cloud_key, result, a, b):
48+
49+
nb_bits = result.shape[0]
50+
51+
params = tfhe_parameters(cloud_key)
52+
53+
tmp1 = empty_ciphertext(params, (1,))
54+
tmp2 = empty_ciphertext(params, (1,))
55+
56+
# initialize the carry to 0
57+
tfhe_gate_CONSTANT_(cloud_key, tmp1, False)
58+
59+
# run the elementary comparator gate n times
60+
for i in range(nb_bits):
61+
encrypted_compare_bit_(cloud_key, tmp1, a[i:i+1], b[i:i+1], tmp1, tmp2)
62+
63+
# tmp1 is the result of the comparaison: 0 if a is larger, 1 if b is larger
64+
# select the max and copy it to the result
65+
tfhe_gate_MUX_(cloud_key, result, tmp1, b, a)
66+
67+
68+
69+
def process(cloud_key, ciphertext1, ciphertext2):
70+
71+
# if necessary, the params are inside the key
72+
params = tfhe_parameters(cloud_key)
73+
74+
# do some operations on the ciphertexts: here, we will compute the
75+
# minimum of the two
76+
result = empty_ciphertext(params, ciphertext1.shape)
77+
encrypted_minimum_(cloud_key, result, ciphertext1, ciphertext2)
78+
79+
return result
80+
81+
82+
def verify(secret_key, answer):
83+
answer_bits = tfhe_decrypt(secret_key, answer)
84+
int_answer = bitarray_to_int(answer_bits)
85+
print("Answer:", int_answer)
86+
87+
88+
secret_key, cloud_key, ciphertext1, ciphertext2 = encrypt()
89+
answer = process(cloud_key, ciphertext1, ciphertext2)
90+
verify(secret_key, answer)

setup.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name='tfhe',
5+
version='0.0.1',
6+
description='TFHE port in Python',
7+
url='http://github.com/nucypher/tfhe.py',
8+
author='Bogdan Opanchuk',
9+
author_email='[email protected]',
10+
license='MIT',
11+
packages=['tfhe'],
12+
install_requires=['numpy'],
13+
zip_safe=True)

tfhe/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from .keys import (
2+
tfhe_key_pair,
3+
tfhe_parameters,
4+
tfhe_encrypt,
5+
tfhe_decrypt,
6+
empty_ciphertext
7+
)
8+
9+
from .boot_gates import tfhe_gate_MUX_, tfhe_gate_CONSTANT_, tfhe_gate_XNOR_

0 commit comments

Comments
 (0)