def processMessage(self): ''' Fetches a message from the queue and computes encrypted operations to get the generation / new grid state and pushes new encrypted grid state in the queue to the client :return: ''' print("[SERVER SIMULATION] Start fetching message") # fetch Message from queue, message is a dictionary with structure # {"encrypted_old_grid": encrypted_old_grid, "encrypted_live_neighbours_grid": encrypted_live_neighbours_grid} message_from_client = self.client_to_server_queue.get(0) print("[SERVER SIMULATION] In Queue", message_from_client) encrypted_old_grid = message_from_client["encrypted_old_grid"] encrypted_live_neighbours_grid = message_from_client[ "encrypted_live_neighbours_grid"] # Pyseal Evaluator evaluator = Evaluator(self.encryptionContext) # Computation of new grid encrypted_new_grid = [] for i in range(self.N * self.N): encrypted_result = Ciphertext() evaluator.add(encrypted_old_grid[i], encrypted_live_neighbours_grid[i], encrypted_result) encrypted_new_grid.append(encrypted_result) print("[SERVER SIMULATION] New Grid Computed") print("[SERVER SIMULATION] Message to client ", encrypted_new_grid) self.server_to_client_queue.put(encrypted_new_grid) print( "[SERVER SIMULATION] Put computed grid into server to client queue" )
def initialize(self, use_old_keys=False): # Initialize encryption params self.init_encrypt_params() # Check if the public & private key files exist if os.path.isfile(defs.FN_FHE_PUBLIC_KEY) and \ os.path.isfile(defs.FN_FHE_PRIVATE_KEY) and \ use_old_keys == True: self.log("Keys already exist. Reusing them instead.") if not self.load_keys(): self.log("Failed to load keys") return False else: # If not, then attempt to generate new ones if not self.generate_keys(): self.log("Failed to generate keys") return False # Setup the rest of the crypto engine self.encryptor = Encryptor(self.context, self.public_key) self.evaluator = Evaluator(self.context) self.decryptor = Decryptor(self.context, self.private_key) # Set the initialized flag self.initialized = True return True
def test2(): img_path = '00001.jpg' img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) print("Original image dimensions {}".format(img.shape)) sift = cv2.xfeatures2d.SIFT_create() (kps, desc) = sift.detectAndCompute(img, None) desc = preprocessing.normalize(np.array( desc.flatten()[:DESC_SIZE]).reshape(1, DESC_SIZE), norm='l2') descriptor_vec1 = desc descriptor_vec2 = descriptor_vec1 context = config() public_key, secret_key = keygen(context) encoder = IntegerEncoder(context.plain_modulus()) encryptor = Encryptor(context, public_key) crtbuilder = PolyCRTBuilder(context) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) slot_count = (int)(crtbuilder.slot_count()) print("slot count {}".format(slot_count)) print("Plaintext shape", descriptor_vec1.shape) plain_matrix = decompose_plain(slot_count, descriptor_vec1, crtbuilder) for i in range(10000): encrypted_matrix = Ciphertext() print("Encrypting: ") time_start = time.time() encryptor.encrypt(plain_matrix, encrypted_matrix) time_end = time.time() print("Done in time {}".format((str)(1000 * (time_end - time_start)))) print("Square:") time_start = time.time() evaluator.square(encrypted_matrix) time_end = time.time() print("Square is done in {} miliseconds".format( (str)(1000 * (time_end - time_start)))) plain_result = Plaintext() print("Decryption plain: ") time_start = time.time() decryptor.decrypt(encrypted_matrix, plain_result) time_end = time.time() print("Decryption is done in {} miliseconds".format( (str)(1000 * (time_end - time_start)))) # print("Plaintext polynomial: {}".format(plain_result.to_string())) # print("Decoded integer: {}".format(encoder.decode_int32(plain_result))) print("Noise budget {} bits".format( decryptor.invariant_noise_budget(encrypted_matrix)))
def example_rotation_ckks(): print("Example: Rotation / Rotation in CKKS"); #Rotations in the CKKS scheme work very similarly to rotations in BFV. parms = EncryptionParameters(scheme_type.CKKS) poly_modulus_degree = 8192 parms.set_poly_modulus_degree(poly_modulus_degree) parms.set_coeff_modulus(CoeffModulus.Create( poly_modulus_degree, IntVector([40, 40, 40, 40, 40]))) context = SEALContext.Create(parms) print_parameters(context) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() relin_keys = keygen.relin_keys() gal_keys = keygen.galois_keys() encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) ckks_encoder = CKKSEncoder(context) slot_count = ckks_encoder.slot_count() print("Number of slots: {}".format(slot_count)) step_size = 1.0 / (slot_count - 1) input = DoubleVector(list(map(lambda x: x*step_size, range(0, slot_count)))) print_vector(input) scale = 2.0**50 print("Encode and encrypt.") plain = Plaintext() ckks_encoder.encode(input, scale, plain) encrypted = Ciphertext() encryptor.encrypt(plain, encrypted) rotated = Ciphertext() print("Rotate 2 steps left.") evaluator.rotate_vector(encrypted, 2, gal_keys, rotated) print(" + Decrypt and decode ...... Correct.") decryptor.decrypt(rotated, plain) result = DoubleVector() ckks_encoder.decode(plain, result) print_vector(result)
def __init__(self, poly_modulus="1x^1024 + 1", coef_modulus_n_primes=20, plain_modulus=1 << 32): """ Set up encryption context for encoder and decoder :param poly_modulus: :param coef_modulus_n_primes: :param plain_modulus: """ self.params = EncryptionParameters() self.params.set_poly_modulus(poly_modulus) self.params.set_coeff_modulus([ seal.SmallModulus(p) for p in FracContext.primes[:coef_modulus_n_primes] ]) self.params.set_plain_modulus(plain_modulus) self.context = SEALContext(self.params) self.print_parameters(self.context) self.keygen = KeyGenerator(self.context) self.public_key = self.keygen.public_key() self.secret_key = self.keygen.secret_key() self.evaluator = Evaluator(self.context)
class vec_plain_multiply(object): """Multiply componentwise cipher and plain along cipher's last dimension cipher.shape[-1]= plain.shape """ def __init__(self, context): self.evaluator = Evaluator(context) def __call__(self, cipher, plain): """In order to not affect cipher for other calculations, make copy""" cipher = dc(cipher) if cipher.shape[-1] != plain.shape[0]: raise ValueError("The cipher shape and plain shape don't match.") for indices in np.ndindex(cipher.shape[:-1]): for i in range(plain.shape[0]): self.evaluator.multiply_plain(cipher[indices][i], plain[i]) return cipher
def seal_obj(): # params obj params = EncryptionParameters() # set params params.set_poly_modulus("1x^4096 + 1") params.set_coeff_modulus(seal.coeff_modulus_128(4096)) params.set_plain_modulus(1 << 16) # get context context = SEALContext(params) # get evaluator evaluator = Evaluator(context) # gen keys keygen = KeyGenerator(context) public_key = keygen.public_key() private_key = keygen.secret_key() # evaluator keys ev_keys = EvaluationKeys() keygen.generate_evaluation_keys(30, ev_keys) # get encryptor and decryptor encryptor = Encryptor(context, public_key) decryptor = Decryptor(context, private_key) # float number encoder encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3) return evaluator, encoder.encode, encoder.decode, encryptor.encrypt, decryptor.decrypt, ev_keys
def __init__(self, context: SEALContext, scale: float, poly_modulus_degree: int, public_key: PublicKey = None, secret_key: SecretKey = None, relin_keys: RelinKeys = None, galois_keys: GaloisKeys = None): self.scale = scale self.context = context self.encoder = CKKSEncoder(context) self.evaluator = Evaluator(context) self.encryptor = Encryptor(context, public_key) self.decryptor = Decryptor(context, secret_key) self.relin_keys = relin_keys self.galois_keys = galois_keys self.poly_modulus_degree_log = np.log2(poly_modulus_degree)
def set_parms(self, parms: EncryptionParameters, print_parms=False): self._parms = parms self._context = SEALContext.Create(self._parms) self._encoder = IntegerEncoder(self._context) self._evaluator = Evaluator(self._context) if print_parms: self.print_parameters(self._context)
def __init__(self, matrix=None): """ :param matrix: numpy.ndarray to be encrypted. """ self.parms = EncryptionParameters() self.parms.set_poly_modulus("1x^2048 + 1") self.parms.set_coeff_modulus(seal.coeff_modulus_128(2048)) self.parms.set_plain_modulus(1 << 8) self.context = SEALContext(self.parms) # self.encoder = IntegerEncoder(self.context.plain_modulus()) self.encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) self.keygen = KeyGenerator(self.context) self.public_key = self.keygen.public_key() self.secret_key = self.keygen.secret_key() self.encryptor = Encryptor(self.context, self.public_key) self.decryptor = Decryptor(self.context, self.secret_key) self.evaluator = Evaluator(self.context) self._saved = False self._encrypted = False self._id = '{0:04d}'.format(np.random.randint(1000)) if matrix is not None: assert len( matrix.shape) == 2, "Only 2D numpy matrices accepted currently" self.matrix = np.copy(matrix) self.encrypted_matrix = np.empty(self.matrix.shape, dtype=object) for i in range(self.matrix.shape[0]): for j in range(self.matrix.shape[1]): self.encrypted_matrix[i, j] = Ciphertext() else: self.matrix = None self.encrypted_matrix = None print(self._id, "Created")
def initialize_fractional( poly_modulus_degree=4096, security_level_bits=128, plain_modulus_power_of_two=10, plain_modulus=None, encoder_integral_coefficients=1024, encoder_fractional_coefficients=3072, encoder_base=2 ): parameters = EncryptionParameters() poly_modulus = "1x^" + str(poly_modulus_degree) + " + 1" parameters.set_poly_modulus(poly_modulus) if security_level_bits == 128: parameters.set_coeff_modulus(seal.coeff_modulus_128(poly_modulus_degree)) elif security_level_bits == 192: parameters.set_coeff_modulus(seal.coeff_modulus_192(poly_modulus_degree)) else: parameters.set_coeff_modulus(seal.coeff_modulus_128(poly_modulus_degree)) print("Info: security_level_bits unknown - using default security_level_bits = 128") if plain_modulus is None: plain_modulus = 1 << plain_modulus_power_of_two parameters.set_plain_modulus(plain_modulus) context = SEALContext(parameters) print_parameters(context) global encoder encoder = FractionalEncoder( context.plain_modulus(), context.poly_modulus(), encoder_integral_coefficients, encoder_fractional_coefficients, encoder_base ) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() global encryptor encryptor = Encryptor(context, public_key) global evaluator evaluator = Evaluator(context) global decryptor decryptor = Decryptor(context, secret_key) global evaluation_keys evaluation_keys = EvaluationKeys() keygen.generate_evaluation_keys(16, evaluation_keys)
def _setup_members(self, context, config): self._encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), config['int_coeff'], config['fract_coeff'], config['base']) self._evaluator = Evaluator(context) pk, sk, self._ev_key = self._create_keys(context) self._encryptor = Encryptor(context, pk) self._decryptor = Decryptor(context, sk)
def __init__(self, seal_server_params, cipher_save_path): self.parms = EncryptionParameters(scheme_type.CKKS) self.cipher_save_path = cipher_save_path # Set Coeff modulus coeff_modulus = [ SmallModulus(i) for i in seal_server_params["coeff_modulus"] ] self.parms.set_coeff_modulus(coeff_modulus) # Set Plain modulus self.parms.set_plain_modulus(seal_server_params["plain_modulus"]) # Set Poly modulus degree self.parms.set_poly_modulus_degree( seal_server_params["poly_modulus_degree"]) self.context = SEALContext.Create(self.parms) self.evaluator = Evaluator(self.context) # Store the encrypted here self._encrypts = []
def __init__(self, modulus, degree): self.modulus = modulus self.degree = degree self.acceptable_degree = [1024, 2048, 4096, 8192, 16384] if self.degree not in self.acceptable_degree: raise Exception(f"Get {self.degree}, but expect degree {self.acceptable_degree}") self.parms = EncryptionParameters(scheme_type.BFV) self.parms.set_poly_modulus_degree(self.degree) self.parms.set_coeff_modulus(CoeffModulus.BFVDefault(self.degree)) # self.parms.set_coeff_modulus(CoeffModulus.Create(self.degree, [60])) self.parms.set_plain_modulus(self.modulus) # print(self.parms.coeff_modulus()[0].value()) self.context = SEALContext.Create(self.parms) self.keygen = KeyGenerator(self.context) self.evaluator = Evaluator(self.context) self.batch_encoder = BatchEncoder(self.context)
def inner_product(cypher1, cypher2): # We also set up an Encryptor, Evaluator, and Decryptor here. evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) for i in range(len(cypher1)): evaluator.multiply(cypher1[i], cypher2[i]) encrypted_result = Ciphertext() evaluator.add_many(cypher1, encrypted_result) return encrypted_result
def initialize_encryption(): print_example_banner("Example: Basics I"); parms = EncryptionParameters() parms.set_poly_modulus("1x^2048 + 1") # factor: 0xfffffffff00001. parms.set_coeff_modulus(seal.coeff_modulus_128(2048)) parms.set_plain_modulus(1 << 8) context = SEALContext(parms) print_parameters(context); # Here we choose to create an IntegerEncoder with base b=2. encoder = IntegerEncoder(context.plain_modulus()) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) return encryptor, evaluator, decryptor, encoder, context
def do_per_amount(amount, subtract_from=15): """ Called on every message in the stream """ print("Transaction amount ", amount) parms = EncryptionParameters() parms.set_poly_modulus("1x^2048 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(2048)) parms.set_plain_modulus(1 << 8) context = SEALContext(parms) # Encode encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3) # To create a fresh pair of keys one can call KeyGenerator::generate() at any time. keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() encryptor = Encryptor(context, public_key) plain1 = encoder.encode(amount) encoded2 = encoder.encode(subtract_from) # Encrypt encrypted1 = Ciphertext(parms) encryptor.encrypt(plain1, encrypted1) # Evaluate evaluator = Evaluator(context) evaluated = evaluate_subtraction_from_plain(evaluator, encrypted1, encoded2) # Decrypt and decode decryptor = Decryptor(context, secret_key) plain_result = Plaintext() decryptor.decrypt(evaluated, plain_result) result = encoder.decode(plain_result) str_result = "Amount left = " + str(result) print(str_result) return str_result
def configure_params(self): with yaspin( text= 'Initializing Encryptor, Eavaluator, Decryptor with generated parameters.....', spinner='dots') as sp2: self.frac_encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) self.encryptor = Encryptor(self.context, self.public_key) self.evaluator = Evaluator(self.context) self.decryptor = Decryptor(self.context, self.secret_key) if self.batching: self.crtbuilder = PolyCRTBuilder(self.context) sp2.hide() print(HTML( u'<b>></b> <msg> The system is ready to start encryption.</msg>' ), style=style) sp2.show() sp2.ok("✔")
def encryption(value): # IntegerEncoder with base 2 encoder = IntegerEncoder(context.plain_modulus()) # generate public/private keys keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() # encrypts public key encryptor = Encryptor(context, public_key) # perform computations on ciphertexts evaluator = Evaluator(context) # decrypts secret key decryptor = Decryptor(context, secret_key) # perform encryptions plaintext = encoder.encode(value) # convert into encrypted ciphertext encrypt = Ciphertext() encryptor.encrypt(plaintext, encrypt) print("Encryption successful!") print("Encrypted ciphertext: " + (str)(value) + " as " + plaintext.to_string()) # noise budget of fresh encryptions print("Noise budget: " + (str)(decryptor.invariant_noise_budget(encrypt)) + " bits") # decrypts result result = Plaintext() decryptor.decrypt(encrypt, result) print("Decryption successful!") print("Plaintext: " + result.to_string()) # decode for original integer print("Original node: " + (str)(encoder.decode_int32(result)) + "\n")
def __init__(self, poly_modulus = 2048 ,bit_strength = 128 ,plain_modulus = 1<<8, integral_coeffs = 64, fractional_coeffs = 32, fractional_base = 3): parms = EncryptionParameters() parms.set_poly_modulus("1x^{} + 1".format(poly_modulus)) if (bit_strength == 128): parms.set_coeff_modulus(seal.coeff_modulus_128(poly_modulus)) else: parms.set_coeff_modulus(seal.coeff_modulus_192(poly_modulus)) parms.set_plain_modulus(plain_modulus) self.parms = parms context = SEALContext(parms) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() self.encryptor = Encryptor(context, public_key) self.evaluator = Evaluator(context) self.decryptor = Decryptor(context, secret_key) self.encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), integral_coeffs, fractional_coeffs, fractional_base)
def test1(): #TODO make the function taking dir name, iterating through all the descriptors, encrypting #TODO add progress bar - the videos are decrypted #TODO make a function taking a query and passing it to the sklearn function KNN with custom similarity funtion #TODO add progress bar - the search is performed (calculate distance between encrypted vectors) #TODO return results #TODO Vlad Display. The results are true. The same as we would compute similarity between ncrypted vectors. # In the same time we did not have to decrypt vectors stored in 3rd parity service to perform a search. #TODO get the metrics #TODO how to opimize a = np.ones((1, DESC_SIZE)) b = np.ones((1, DESC_SIZE)) for i in range(a.shape[1]): a[0, i] = random.uniform(0.0, 1.0) b[0, i] = random.uniform(0.0, 1.0) print("Descriptors for images a and b are: ") print("a ", a) print("b ", b) context, params = config() public_key, secret_key = keygen(context) frac_encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3) encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) e1 = encrypt_vec(params, encryptor, frac_encoder, a) e3 = encrypt_vec(params, encryptor, frac_encoder, b) print("Calculate distance between plain a and b:") sim = euclidean_dist(a, b) print("Similarity between a and b: {}".format(sim)) print("Calculating distance between encrypted a and b:") time_start = time.time() enc_res = euclidean_dist_enc(evaluator, e1, e3) time_end = time.time() print("Done. Time: {} miliseconds".format( (str)(1000 * (time_end - time_start)))) plain_result = Plaintext() print("Decrypting result: ") time_start = time.time() decryptor.decrypt(enc_res, plain_result) res = frac_encoder.encode(plain_result) time_end = time.time() print("Done. Time: {} miliseconds".format( (str)(1000 * (time_end - time_start)))) print( "........................................................................" ) print("Noise budget {} bits".format( decryptor.invariant_noise_budget(enc_res))) print("Decrypted result {}, original result {}".format(res, sim)) print("Calculate distance between plain a and a:") sim = euclidean_dist(a, a.copy()) print("Similarity between a and b: {}".format(sim)) print("Calculating distance between encrypted a and a:") time_start = time.time() enc_res = euclidean_dist_enc(evaluator, e1, e1) time_end = time.time() print("Done. Time: {} miliseconds".format( (str)(1000 * (time_end - time_start)))) plain_result = Plaintext() print("Decrypting result: ") time_start = time.time() decryptor.decrypt(enc_res, plain_result) res = frac_encoder.encode(plain_result) time_end = time.time() print("Done. Time: {} miliseconds".format( (str)(1000 * (time_end - time_start)))) print( "........................................................................." ) print("Noise budget {} bits".format( decryptor.invariant_noise_budget(enc_res))) print("Decrypted result {}, original result {}".format(res, sim))
def dot_product(): print("Example: Weighted Average") # In this example we demonstrate the FractionalEncoder, and use it to compute # a weighted average of 10 encrypted rational numbers. In this computation we # perform homomorphic multiplications of ciphertexts by plaintexts, which is # much faster than regular multiplications of ciphertexts by ciphertexts. # Moreover, such `plain multiplications' never increase the ciphertext size, # which is why we have no need for evaluation keys in this example. # We start by creating encryption parameters, setting up the SEALContext, keys, # and other relevant objects. Since our computation has multiplicative depth of # only two, it suffices to use a small poly_modulus. parms = EncryptionParameters() parms.set_poly_modulus("1x^2048 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(2048)) parms.set_plain_modulus(1 << 8) context = SEALContext(parms) print_parameters(context) keygen = KeyGenerator(context) keygen2 = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() secret_key2 = keygen.secret_key() # We also set up an Encryptor, Evaluator, and Decryptor here. encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key2) # Create a vector of 10 rational numbers (as doubles). # rational_numbers = [3.1, 4.159, 2.65, 3.5897, 9.3, 2.3, 8.46, 2.64, 3.383, 2.795] rational_numbers = np.random.rand(10) # Create a vector of weights. # coefficients = [0.1, 0.05, 0.05, 0.2, 0.05, 0.3, 0.1, 0.025, 0.075, 0.05] coefficients = np.random.rand(10) my_result = np.dot(rational_numbers, coefficients) # We need a FractionalEncoder to encode the rational numbers into plaintext # polynomials. In this case we decide to reserve 64 coefficients of the # polynomial for the integral part (low-degree terms) and expand the fractional # part to 32 digits of precision (in base 3) (high-degree terms). These numbers # can be changed according to the precision that is needed; note that these # choices leave a lot of unused space in the 2048-coefficient polynomials. encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3) # We create a vector of ciphertexts for encrypting the rational numbers. encrypted_rationals = [] rational_numbers_string = "Encoding and encrypting: " for i in range(10): # We create our Ciphertext objects into the vector by passing the # encryption parameters as an argument to the constructor. This ensures # that enough memory is allocated for a size 2 ciphertext. In this example # our ciphertexts never grow in size (plain multiplication does not cause # ciphertext growth), so we can expect the ciphertexts to remain in the same # location in memory throughout the computation. In more complicated examples # one might want to call a constructor that reserves enough memory for the # ciphertext to grow to a specified size to avoid costly memory moves when # multiplications and relinearizations are performed. encrypted_rationals.append(Ciphertext(parms)) encryptor.encrypt(encoder.encode(rational_numbers[i]), encrypted_rationals[i]) rational_numbers_string += (str)(rational_numbers[i])[:6] if i < 9: rational_numbers_string += ", " print(rational_numbers_string) # Next we encode the coefficients. There is no reason to encrypt these since they # are not private data. encoded_coefficients = [] encoded_coefficients_string = "Encoding plaintext coefficients: " encrypted_coefficients =[] for i in range(10): encoded_coefficients.append(encoder.encode(coefficients[i])) encrypted_coefficients.append(Ciphertext(parms)) encryptor.encrypt(encoded_coefficients[i], encrypted_coefficients[i]) encoded_coefficients_string += (str)(coefficients[i])[:6] if i < 9: encoded_coefficients_string += ", " print(encoded_coefficients_string) # We also need to encode 0.1. Multiplication by this plaintext will have the # effect of dividing by 10. Note that in SEAL it is impossible to divide # ciphertext by another ciphertext, but in this way division by a plaintext is # possible. div_by_ten = encoder.encode(0.1) # Now compute each multiplication. prod_result = [Ciphertext() for i in range(10)] prod_result2 = [Ciphertext() for i in range(10)] print("Computing products: ") for i in range(10): # Note how we use plain multiplication instead of usual multiplication. The # result overwrites the first argument in the function call. evaluator.multiply_plain(encrypted_rationals[i], encoded_coefficients[i], prod_result[i]) evaluator.multiply(encrypted_rationals[i], encrypted_coefficients[i], prod_result2[i]) print("Done") # To obtain the linear sum we need to still compute the sum of the ciphertexts # in encrypted_rationals. There is an easy way to add together a vector of # Ciphertexts. encrypted_result = Ciphertext() encrypted_result2 = Ciphertext() print("Adding up all 10 ciphertexts: ") evaluator.add_many(prod_result, encrypted_result) evaluator.add_many(prod_result2, encrypted_result2) print("Done") # Perform division by 10 by plain multiplication with div_by_ten. # print("Dividing by 10: ") # evaluator.multiply_plain(encrypted_result, div_by_ten) # print("Done") # How much noise budget do we have left? print("Noise budget in result: " + (str)(decryptor.invariant_noise_budget(encrypted_result)) + " bits") # Decrypt, decode, and print result. plain_result = Plaintext() plain_result2 = Plaintext() print("Decrypting result: ") decryptor.decrypt(encrypted_result, plain_result) decryptor.decrypt(encrypted_result2, plain_result2) print("Done") result = encoder.decode(plain_result) print("Weighted average: " + (str)(result)[:8]) result2 = encoder.decode(plain_result2) print("Weighted average: " + (str)(result2)[:8]) print('\n\n', my_result)
def pickle_ciphertext(): parms = EncryptionParameters() parms.set_poly_modulus("1x^2048 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(2048)) parms.set_plain_modulus(1 << 8) context = SEALContext(parms) # Print the parameters that we have chosen print_parameters(context); encoder = IntegerEncoder(context.plain_modulus()) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() # To be able to encrypt, we need to construct an instance of Encryptor. Note that # the Encryptor only requires the public key. encryptor = Encryptor(context, public_key) # Computations on the ciphertexts are performed with the Evaluator class. evaluator = Evaluator(context) # We will of course want to decrypt our results to verify that everything worked, # so we need to also construct an instance of Decryptor. Note that the Decryptor # requires the secret key. decryptor = Decryptor(context, secret_key) # We start by encoding two integers as plaintext polynomials. value1 = 5; plain1 = encoder.encode(value1); print("Encoded " + (str)(value1) + " as polynomial " + plain1.to_string() + " (plain1)") value2 = -7; plain2 = encoder.encode(value2); print("Encoded " + (str)(value2) + " as polynomial " + plain2.to_string() + " (plain2)") # Encrypting the values is easy. encrypted1 = Ciphertext() encrypted2 = Ciphertext() print("Encrypting plain1: ", encrypted1) encryptor.encrypt(plain1, encrypted1) print("Done (encrypted1)", encrypted1) print("Encrypting plain2: ") encryptor.encrypt(plain2, encrypted2) print("Done (encrypted2)") # output = open('ciphertest.pkl', 'wb') # dill.dumps(encrypted_save, output) # output.close() # encrypted1 = dill.load(open('ciphertest.pkl', 'rb')) output = open('session.pkl', 'wb') dill.dump_session('session.pkl') del encrypted1 sill.load_session('session.pkl') # To illustrate the concept of noise budget, we print the budgets in the fresh # encryptions. print("Noise budget in encrypted1: " + (str)(decryptor.invariant_noise_budget(encrypted1)) + " bits") print("Noise budget in encrypted2: " + (str)(decryptor.invariant_noise_budget(encrypted2)) + " bits") # As a simple example, we compute (-encrypted1 + encrypted2) * encrypted2. # Negation is a unary operation. evaluator.negate(encrypted1) # Negation does not consume any noise budget. print("Noise budget in -encrypted1: " + (str)(decryptor.invariant_noise_budget(encrypted1)) + " bits") # Addition can be done in-place (overwriting the first argument with the result, # or alternatively a three-argument overload with a separate destination variable # can be used. The in-place variants are always more efficient. Here we overwrite # encrypted1 with the sum. evaluator.add(encrypted1, encrypted2) # It is instructive to think that addition sets the noise budget to the minimum # of the input noise budgets. In this case both inputs had roughly the same # budget going on, and the output (in encrypted1) has just slightly lower budget. # Depending on probabilistic effects, the noise growth consumption may or may # not be visible when measured in whole bits. print("Noise budget in -encrypted1 + encrypted2: " + (str)(decryptor.invariant_noise_budget(encrypted1)) + " bits") # Finally multiply with encrypted2. Again, we use the in-place version of the # function, overwriting encrypted1 with the product. evaluator.multiply(encrypted1, encrypted2) # Multiplication consumes a lot of noise budget. This is clearly seen in the # print-out. The user can change the plain_modulus to see its effect on the # rate of noise budget consumption. print("Noise budget in (-encrypted1 + encrypted2) * encrypted2: " + (str)( decryptor.invariant_noise_budget(encrypted1)) + " bits") # Now we decrypt and decode our result. plain_result = Plaintext() print("Decrypting result: ") decryptor.decrypt(encrypted1, plain_result) print("Done") # Print the result plaintext polynomial. print("Plaintext polynomial: " + plain_result.to_string()) # Decode to obtain an integer result. print("Decoded integer: " + (str)(encoder.decode_int32(plain_result)))
########################## paramaters required ################################# parms = EncryptionParameters() parms.set_poly_modulus("1x^16384 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(8192)) parms.set_plain_modulus(1 << 25) context = SEALContext(parms) encoderF = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 34, 30, 3) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) num_cores = multiprocessing.cpu_count() -1 N=4 b = numpy.random.random_integers(1,10,size=(N,N)) X = (b + b.T)/2 print("\nX:") print(X) print(numpy.linalg.det(X)) print("Inverse by Numpy:") print(numpy.linalg.inv(X)) print("\nMain program: \n") X= encrypting_Matrix(X) X_inv=inverseMatrix(X)
def example_rotation_bfv(): print("Example: Rotation / Rotation in BFV") parms = EncryptionParameters(scheme_type.BFV) poly_modulus_degree = 8192 parms.set_poly_modulus_degree(poly_modulus_degree) parms.set_coeff_modulus(CoeffModulus.BFVDefault(poly_modulus_degree)) parms.set_plain_modulus(PlainModulus.Batching(poly_modulus_degree, 20)) context = SEALContext.Create(parms) print_parameters(context) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() relin_keys = keygen.relin_keys() encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) batch_encoder = BatchEncoder(context) slot_count = batch_encoder.slot_count() row_size = int(slot_count / 2) print("Plaintext matrix row size: {}".format(row_size)) pod_matrix = UInt64Vector([0]*slot_count) pod_matrix[0] = 0 pod_matrix[1] = 1 pod_matrix[2] = 2 pod_matrix[3] = 3 pod_matrix[row_size] = 4 pod_matrix[row_size + 1] = 5 pod_matrix[row_size + 2] = 6 pod_matrix[row_size + 3] = 7 print("Input plaintext matrix:") print_matrix(pod_matrix, row_size) #First we use BatchEncoder to encode the matrix into a plaintext. We encrypt #the plaintext as usual. plain_matrix = Plaintext() print("Encode and encrypt.") batch_encoder.encode(pod_matrix, plain_matrix) encrypted_matrix = Ciphertext() encryptor.encrypt(plain_matrix, encrypted_matrix) print(" + Noise budget in fresh encryption: {} bits".format( decryptor.invariant_noise_budget(encrypted_matrix))) #Rotations require yet another type of special key called `Galois keys'. These #are easily obtained from the KeyGenerator. gal_keys = keygen.galois_keys() #Now rotate both matrix rows 3 steps to the left, decrypt, decode, and print. print("Rotate rows 3 steps left.") evaluator.rotate_rows_inplace(encrypted_matrix, 3, gal_keys) plain_result = Plaintext() print(" + Noise budget after rotation: {} bits".format( decryptor.invariant_noise_budget(encrypted_matrix))) print(" + Decrypt and decode ...... Correct.") decryptor.decrypt(encrypted_matrix, plain_result) batch_encoder.decode(plain_result, pod_matrix) print_matrix(pod_matrix, row_size) #We can also rotate the columns, i.e., swap the rows. print("Rotate columns.") evaluator.rotate_columns_inplace(encrypted_matrix, gal_keys) print(" + Noise budget after rotation: {} bits".format( decryptor.invariant_noise_budget(encrypted_matrix))) print(" + Decrypt and decode ...... Correct.") decryptor.decrypt(encrypted_matrix, plain_result) batch_encoder.decode(plain_result, pod_matrix) print_matrix(pod_matrix, row_size) #Finally, we rotate the rows 4 steps to the right, decrypt, decode, and print. print("Rotate rows 4 steps right.") evaluator.rotate_rows_inplace(encrypted_matrix, -4, gal_keys) print(" + Noise budget after rotation: {} bits".format( decryptor.invariant_noise_budget(encrypted_matrix))) print(" + Decrypt and decode ...... Correct.") decryptor.decrypt(encrypted_matrix, plain_result) batch_encoder.decode(plain_result, pod_matrix) print_matrix(pod_matrix, row_size)
def __init__(self, context): self.evaluator = Evaluator(context)
def __init__(self, context, keygen): self.relinear = Evaluator(context).relinearize self.ev_keys = EvaluationKeys() keygen.generate_evaluation_keys(10, self.ev_keys)
def encrypt(input_file): X = np.load(input_file) print("Starting the system....\n") y, people_descriptors = search_for_centroids(X) X, y = unison_shuffled_copies(X, y) np.save(input_file, X) np.save('./class_lables.npy', np.array(y)) np.save('./centroids.npy', np.array(people_descriptors)) print( "All necessary dependencies are installed. Everything is up-to-date!") print("The encryption mode is entered!") time_start = time.time() print('Configuring the encryption parameters') context, params = config() time_end = time.time() #TODO time for the report. Put to the slides #TODO Remove from logs print("Parameters are configured. Time: {}\n".format( (str)(1000 * (time_end - time_start)))) #print("Key generation .....") time_start = time.time() with yaspin(text='Generating public/private key pair', spinner='dots') as sp1: public_key, secret_key = keygen(context) time.sleep(1) sp1.hide() print(HTML( u'<b>></b> <msg>public/private key pair </msg> <sub-msg>is generated</sub-msg>' ), style=style) sp1.show() sp1.ok("✔") time_end = time.time() print("Keys are generated! Time: {}".format( (str)(1000 * (time_end - time_start)))) with yaspin( text= 'Initializing Encryptor, Eavaluator, Decryptor with generated parameters.....', spinner='dots') as sp2: frac_encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3) encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) p = [] p.append(params) p.append(context) p.append(frac_encoder) p.append(encryptor) p.append(evaluator) p.append(decryptor) ENC_CONF = p sp2.hide() print(HTML( u'<b>></b> <msg> The system is ready to start encryption.</msg>'), style=style) sp2.show() sp2.ok("✔") #enc_X = np.empty(X.shape, dtype=object) with yaspin(text='Subscribing to the online-video stream.', spinner='clock') as sp3: time.sleep(5) sp3.hide() print(HTML(u'<b>></b> <msg> Success</msg>'), style=style) sp3.show() sp3.ok("✔") print("Detecting people") time_start = time.time() with yaspin( text='Encrypting the descriptor').white.bold.shark.on_blue as sp4: for i, x in enumerate(X): sp4.write("Got descriptor of 1x{} dimension for a person".format( x.shape[0])) time.sleep(1) #enc_X[i, :] = encrypt_vec(params, encryptor, frac_encoder, x) encrypt_vec(params, encryptor, frac_encoder, x) dists = [] for j in range(people_descriptors.shape[0]): dist1 = euclidean_dist(people_descriptors[j], x) dists.append(dist1) sp4.write( "Distance between 'Current' person and Person #{}: {:.2f} - Person #{}: {:.2f} - Person #{}: {:.2f} - Person #{}: {:.2f}" .format(0, dists[0], 1, dists[1], 2, dists[2], 3, dists[3])) time.sleep(1) dists = np.array(dists) if (dists[dists < 0.6] is not None): d = np.sort(dists)[0] sp4.write( "🔦FOUND descriptor similar to Person #{}".format(d)) time.sleep(1) sp4.hide() print(HTML( u'<b>�</b> <msg>descriptor {}</msg> <sub-msg>encryption complete</sub-msg>' .format(i)), style=style) sp4.show() #sp.ok("All stream is encrypted") sp4.ok("✔") time_end = time.time() print("Encryption is complete.") print( "ALL {} descriptors are successfully encrypted and sent to the CLOUD.". format(X.shape[0])) print("Time: {}".format((str)(1000 * (time_end - time_start))))
# coeff_modulus_128bit(int) # coeff_modulus_192bit(int) parms.set_coeff_modulus(seal.coeff_modulus_128(2048)) # The plaintext modulus can be any positive integer, even though here we take # it to be a power of two. parms.set_plain_modulus(1 << 8) # 1 << 8 is bitwise operation which means 1 shifted eight times ie 2^8=256 context = SEALContext(parms) encoder = IntegerEncoder(context.plain_modulus()) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) value=7 plain1 = encoder.encode(value1) print("Encoded " + (str)(value) + " as polynomial " + plain1.to_string() + " (plain1)") encrypted _data= Ciphertext() encryptor.encrypt(plain, encrypted_data) print("Noise budget in encrypted1: " + (str)(decryptor.invariant_noise_budget(encrypted_data)) + " bits") # operations that can be performed ---> # result stored in encrypted1 data evaluator.negate(encrypted1_data)
def __init__(self, context, keygen): self.mult = Evaluator(context).multiply self.keygen = keygen if keygen: self.relinear = vec_relinearize(context, keygen)