OpenMined/TenSEAL#

image1

[1]:
!pip install tenseal
Requirement already satisfied: tenseal in /home/hsiangjenli/miniconda3/lib/python3.12/site-packages (0.3.15)

HE consist of four primary algorithms :cite:xu2021privacy#

  1. Key Generation - Generates a public key ( \(\textbf{pk}\) ) and a secret key ( \(\textbf{sk}\) ).

  2. Encryption - Encrypts a plaintext tensor ( \(\text{num}\) ) into a ciphertext tensor ( \(\textbf{Enc}(\text{pk}, \text{num}) = C_{\text{num}}\) ).

  3. Evaluation - Performs operations on ciphertext tensors.

  4. Decryption - Decrypts a ciphertext tensor ( \(C_{\text{num}}\) ) into a plaintext tensor ( \(\textbf{Dec}(\text{sk}, C_{\text{num}}) = \text{num}\) ).

Import Lib#

[2]:
import tenseal as ts

# Show available schemes
for scheme in ts.SCHEME_TYPE:
    print(scheme)
SCHEME_TYPE.NONE
SCHEME_TYPE.BFV
SCHEME_TYPE.CKKS

Key Generation#

In tenseal library, the key generation is done by calling the tenseal.enc_context.Context() function. The parameters of this function are:

[3]:
?Context
Object `Context` not found.
[4]:
from tenseal.enc_context import Context

context = Context(scheme=ts.SCHEME_TYPE.BFV, poly_modulus_degree=4096, plain_modulus=1032193)
[5]:
# Get Secret Key
sk = context.secret_key().data

# Get Public Key
pk = context.public_key().data

Encryption & Decryption#

[6]:
from tenseal.tensors import BFVVector

vector = [1, 2, 3, 4, 5]

# Encryption
encrypted_vector = BFVVector(context, vector).data

# Get the size of the encrypted vector
encrypted_vector.size()

# Decryption
encrypted_vector.decrypt(sk)
[6]:
[1, 2, 3, 4, 5]

Evaluation#

Evaluation key is used to perform homomorphic operations (usually, homomorphic product or, the somehow equivalent operation, a logic AND gate).

Add#

[7]:
encrypted_vector.add(encrypted_vector).decrypt(sk)
[7]:
[2, 4, 6, 8, 10]
[8]:
(encrypted_vector + [1, 1, 1, 1, 1]).decrypt(sk)
[8]:
[2, 3, 4, 5, 6]
[9]:
(encrypted_vector + encrypted_vector).decrypt(sk)
[9]:
[2, 4, 6, 8, 10]

subtract#

[10]:
(encrypted_vector - [1, 1, 1, 1, 1]).decrypt(sk)
[10]:
[0, 1, 2, 3, 4]
[11]:
(encrypted_vector - encrypted_vector).decrypt(sk) # Error
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[11], line 1
----> 1 (encrypted_vector - encrypted_vector).decrypt(sk) # Error

RuntimeError: result ciphertext is transparent

Mul#

[12]:
(encrypted_vector * 5).decrypt(sk)
[12]:
[5, 10, 15, 20, 25]
[13]:
(encrypted_vector * 0).decrypt(sk) # Error
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[13], line 1
----> 1 (encrypted_vector * 0).decrypt(sk) # Error

RuntimeError: result ciphertext is transparent
[14]:
(encrypted_vector * -1).decrypt(sk)
[14]:
[-1, -2, -3, -4, -5]