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

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
Kind of slow, but works.
  • Loading branch information
fjarri committed Apr 2, 2018
0 parents commit 17f3b62
Show file tree
Hide file tree
Showing 13 changed files with 1,606 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__pycache__
*.egg-info
69 changes: 69 additions & 0 deletions examples/test_mux.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import numpy
import time

from tfhe import *


def int_to_bitarray(x):
return numpy.array([((x >> i) & 1 != 0) for i in range(16)])


def bitarray_to_int(x):
int_answer = 0
for i in range(16):
int_answer = int_answer | (x[i] << i)
return int_answer


def reference_mux(bits1, bits2, bits3):
numpy.array([b if a else c for a, b, c in zip(bits1, bits2, bits3)])


def encrypt():

rng = numpy.random.RandomState(123)

print("Key generation:")
t = time.time()
secret_key, cloud_key = tfhe_key_pair(rng)
print(time.time() - t)

bits1 = int_to_bitarray(2017)
bits2 = int_to_bitarray(42)
bits3 = int_to_bitarray(12345)

print("Encryption:")
t = time.time()
ciphertext1 = tfhe_encrypt(rng, secret_key, bits1)
ciphertext2 = tfhe_encrypt(rng, secret_key, bits2)
ciphertext3 = tfhe_encrypt(rng, secret_key, bits3)
print(time.time() - t)

return secret_key, cloud_key, ciphertext1, ciphertext2, ciphertext3


def process(cloud_key, ciphertext1, ciphertext2, ciphertext3):
params = tfhe_parameters(cloud_key)
result = empty_ciphertext(params, ciphertext1.shape)

print("Processing:")
t = time.time()
tfhe_gate_MUX_(cloud_key, result, ciphertext1, ciphertext2, ciphertext3)
print(time.time() - t)

return result


def verify(secret_key, answer):
print("Decryption:")
t = time.time()
answer_bits = tfhe_decrypt(secret_key, answer)
print(time.time() - t)

int_answer = bitarray_to_int(answer_bits)
print("Answer:", int_answer)


secret_key, cloud_key, ciphertext1, ciphertext2, ciphertext3 = encrypt()
answer = process(cloud_key, ciphertext1, ciphertext2, ciphertext3)
verify(secret_key, answer)
90 changes: 90 additions & 0 deletions examples/tutorial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import numpy
import time

from tfhe import *


def int_to_bitarray(x):
return numpy.array([((x >> i) & 1 != 0) for i in range(16)])


def bitarray_to_int(x):
int_answer = 0
for i in range(16):
int_answer = int_answer | (x[i] << i)
return int_answer


def reference_mux(bits1, bits2, bits3):
numpy.array([b if a else c for a, b, c in zip(bits1, bits2, bits3)])


def encrypt():

rng = numpy.random.RandomState(123)

secret_key, cloud_key = tfhe_key_pair(rng)

bits1 = int_to_bitarray(2017)
bits2 = int_to_bitarray(42)

ciphertext1 = tfhe_encrypt(rng, secret_key, bits1)
ciphertext2 = tfhe_encrypt(rng, secret_key, bits2)

return secret_key, cloud_key, ciphertext1, ciphertext2


# elementary full comparator gate that is used to compare the i-th bit:
# input: ai and bi the i-th bit of a and b
# lsb_carry: the result of the comparison on the lowest bits
# algo: if (a==b) return lsb_carry else return b
def encrypted_compare_bit_(cloud_key, result, a, b, lsb_carry, tmp):
tfhe_gate_XNOR_(cloud_key, tmp, a, b)
tfhe_gate_MUX_(cloud_key, result, tmp, lsb_carry, a)


# this function compares two multibit words, and puts the max in result
def encrypted_minimum_(cloud_key, result, a, b):

nb_bits = result.shape[0]

params = tfhe_parameters(cloud_key)

tmp1 = empty_ciphertext(params, (1,))
tmp2 = empty_ciphertext(params, (1,))

# initialize the carry to 0
tfhe_gate_CONSTANT_(cloud_key, tmp1, False)

# run the elementary comparator gate n times
for i in range(nb_bits):
encrypted_compare_bit_(cloud_key, tmp1, a[i:i+1], b[i:i+1], tmp1, tmp2)

# tmp1 is the result of the comparaison: 0 if a is larger, 1 if b is larger
# select the max and copy it to the result
tfhe_gate_MUX_(cloud_key, result, tmp1, b, a)



def process(cloud_key, ciphertext1, ciphertext2):

# if necessary, the params are inside the key
params = tfhe_parameters(cloud_key)

# do some operations on the ciphertexts: here, we will compute the
# minimum of the two
result = empty_ciphertext(params, ciphertext1.shape)
encrypted_minimum_(cloud_key, result, ciphertext1, ciphertext2)

return result


def verify(secret_key, answer):
answer_bits = tfhe_decrypt(secret_key, answer)
int_answer = bitarray_to_int(answer_bits)
print("Answer:", int_answer)


secret_key, cloud_key, ciphertext1, ciphertext2 = encrypt()
answer = process(cloud_key, ciphertext1, ciphertext2)
verify(secret_key, answer)
13 changes: 13 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from setuptools import setup

setup(
name='tfhe',
version='0.0.1',
description='TFHE port in Python',
url='http://github.com/nucypher/tfhe.py',
author='Bogdan Opanchuk',
author_email='bogdan@nucypher.com',
license='MIT',
packages=['tfhe'],
install_requires=['numpy'],
zip_safe=True)
9 changes: 9 additions & 0 deletions tfhe/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .keys import (
tfhe_key_pair,
tfhe_parameters,
tfhe_encrypt,
tfhe_decrypt,
empty_ciphertext
)

from .boot_gates import tfhe_gate_MUX_, tfhe_gate_CONSTANT_, tfhe_gate_XNOR_

0 comments on commit 17f3b62

Please sign in to comment.