def __init__(self, context): """ Class providing decryption operation :param context: Context initialising HE parameters """ self.context = context.context self.secret_key = context.secret_key self.decryptor = Decryptor(self.context, self.secret_key) self.encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) self.evaluator = context.evaluator
def __init__(self, context: FracContext): """ Class providing encoding and encryption operations, operations over encrypted data :param context: Context initialising HE parameters """ self.context = context.context self.public_key = context.public_key self.encryptor = Encryptor(self.context, self.public_key) self.encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) self.evaluator = context.evaluator self.ev_keys = EvaluationKeys() context.keygen.generate_evaluation_keys(seal.dbc_max(), self.ev_keys)
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 decrypt(self, raw_data): if not self.initialized: self.log("Not initialized") return False # Setup the encoder encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) # Unpickle, base64 decode, and decrypt each ciphertext result decrypted_data = [] for d in raw_data: encrypted_data = pickle.loads( base64.b64decode(d) ) plain_data = Plaintext() self.decryptor.decrypt(encrypted_data, plain_data) decrypted_data.append( str(encoder.decode(plain_data)) ) return decrypted_data
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 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 encrypt(self, data): if not self.initialized: self.log("Not initialized") return False # Setup the encoder encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) # Create the array of encrypted data objects encrypted_data = [] for raw_data in data: encrypted_data.append(Ciphertext(self.encrypt_params)) self.encryptor.encrypt( encoder.encode(raw_data), encrypted_data[-1] ) # Pickle each Ciphertext, base64 encode it, and store it in the array for i in range(0, len(encrypted_data)): encrypted_data[i].save("fhe_enc.bin") encrypted_data[i] = base64.b64encode( pickle.dumps(encrypted_data[i]) ) return encrypted_data
def evaluate(self, encrypted_data, lower_idx=0, higher_idx=-1): result = Ciphertext() # Setup the encoder encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) # Unpack the data first unpacked_data = [] for d in encrypted_data[lower_idx:higher_idx]: unpacked_data.append(pickle.loads(base64.b64decode(d))) # Perform operations self.evaluator.add_many(unpacked_data, result) div = encoder.encode(1/len(unpacked_data)) self.evaluator.multiply_plain(result, div) # Pack the result result = base64.b64encode( pickle.dumps(result) ) return result
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)
class FractionalDecryptorUtils: def __init__(self, context): """ Class providing decryption operation :param context: Context initialising HE parameters """ self.context = context.context self.secret_key = context.secret_key self.decryptor = Decryptor(self.context, self.secret_key) self.encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) self.evaluator = context.evaluator def decrypt(self, encrypted_res): plain_result = Plaintext() self.decryptor.decrypt(encrypted_res, plain_result) result = self.encoder.decode(plain_result) return result
def set_encoder( self, fractional_encoder=True, whole_sign_digits=32, decimal_sign_digits=32, base=3, ): if fractional_encoder: self.__enco = FractionalEncoder( self._cont.plain_modulus(), self._cont.poly_modulus(), whole_sign_digits, decimal_sign_digits, base, ) else: self.__enco = IntegerEncoder( self._cont.plain_modulus(), base, )
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 __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)
class FractionalEncoderUtils: def __init__(self, context: FracContext): """ Class providing encoding and encryption operations, operations over encrypted data :param context: Context initialising HE parameters """ self.context = context.context self.public_key = context.public_key self.encryptor = Encryptor(self.context, self.public_key) self.encoder = FractionalEncoder(self.context.plain_modulus(), self.context.poly_modulus(), 64, 32, 3) self.evaluator = context.evaluator self.ev_keys = EvaluationKeys() context.keygen.generate_evaluation_keys(seal.dbc_max(), self.ev_keys) def encode_rationals(self, numbers) -> List[Plaintext]: # encoding without encryption encoded_coefficients = [] for i in range(len(numbers)): encoded_coefficients.append(self.encoder.encode(numbers[i])) return encoded_coefficients def encode_num(self, num) -> Plaintext: if type(num) == Plaintext or num is None: return num else: # encoding without encryption return self.encoder.encode(num) def sum_enc_array(self, array: List[Ciphertext]) -> Ciphertext: # can applied for 1D array only encrypted_result = Ciphertext() self.evaluator.add_many(array, encrypted_result) return encrypted_result def encrypt_rationals(self, rational_numbers: List) -> List[Ciphertext]: """ :param rational_numbers: array of rational numbers :return: encrypted result """ encrypted_rationals = [] for i in range(len(rational_numbers)): encrypted_rationals.append(Ciphertext(self.context.params)) self.encryptor.encrypt(self.encoder.encode(rational_numbers[i]), encrypted_rationals[i]) return encrypted_rationals def weighted_average(self, encrypted_rationals, encoded_coefficients, encoded_divide_by) -> Ciphertext: """ Weighted average, where weights encoded, not encrypted numbers :param encoded_divide_by: fixed point fractional, e.g 0.1 to perform division by 10 :return: encrypted result """ for i in range(len(encrypted_rationals)): self.evaluator.multiply_plain(encrypted_rationals[i], encoded_coefficients[i]) encrypted_result = Ciphertext() self.evaluator.add_many(encrypted_rationals, encrypted_result) self.evaluator.multiply_plain(encrypted_result, encoded_divide_by) return encrypted_result def subtract(self, a: Ciphertext, b: Ciphertext) -> Ciphertext: """ Substruction operation of 2 fractional numbers :param a: encrypted fractional value :param b: encrypted fractional value :return: substracted result """ a = deepcopy(a) minus_sign = self.encoder.encode(-1) self.evaluator.multiply_plain(b, minus_sign) self.evaluator.add(a, b) return a def encrypt_num(self, value) -> Ciphertext: if type(value) == Ciphertext or value is None: return value else: encrypted = Ciphertext() if type(value) == Plaintext: self.encryptor.encrypt(value, encrypted) else: plain = self.encoder.encode(value) self.encryptor.encrypt(plain, encrypted) return encrypted def add(self, a: Ciphertext, b: Ciphertext) -> Ciphertext: """ :param a: encrypted fractional value :param b: encrypted fractional value :return: encrypted sum of a and b """ a = deepcopy(a) self.evaluator.add(a, b) return a def add_plain(self, a: Ciphertext, b: Plaintext) -> Ciphertext: """ :param a: encrypted fractional value :param b: encoded fractional value :return: encrypted sum of a and b """ a = deepcopy(a) self.evaluator.add_plain(a, b) return a def multiply(self, a: Ciphertext, b: Ciphertext) -> Ciphertext: """ :param a: encrypted fractional value :param b: encrypted fractional value :return: encrypted product of a and b """ a = deepcopy(a) self.evaluator.multiply(a, b) return a def multiply_plain(self, a: Ciphertext, b: Plaintext) -> Ciphertext: """ :param a: encrypted fractional value :param b: encrypted fractional value :return: encrypted product of a and b """ a = deepcopy(a) self.evaluator.multiply_plain(a, b) return a def relinearize(self, a: Ciphertext) -> Ciphertext: """ :param a: encrypted fractional value, supposedly result of multiplication :return: relinearized a """ a = deepcopy(a) self.evaluator.relinearize(a, self.ev_keys) return a
p = Plaintext() decryptor.decrypt(y, p) m.append(encoderF.decode(p)) M.append(m) return (M) ########################## paramaters required ################################# parms = EncryptionParameters() parms.set_poly_modulus("1x^8192 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(8192)) parms.set_plain_modulus(1 << 21) context = SEALContext(parms) encoderF = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 30, 34, 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) ########################## encoding main matrix ################################ A = [Ciphertext(), Ciphertext(), Ciphertext(), Ciphertext()] for i in range(len(A)): encryptor.encrypt(encoderF.encode(i), A[i])
class CipherMatrix: """ """ 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 __repr__(self): """ :return: """ print("Encrypted:", self._encrypted) if not self._encrypted: print(self.matrix) return "" else: return '[]' def __str__(self): """ :return: """ print("| Encryption parameters:") print("| poly_modulus: " + self.context.poly_modulus().to_string()) # Print the size of the true (product) coefficient modulus print("| coeff_modulus_size: " + ( str)(self.context.total_coeff_modulus().significant_bit_count()) + " bits") print("| plain_modulus: " + (str)(self.context.plain_modulus().value())) print("| noise_standard_deviation: " + (str)(self.context.noise_standard_deviation())) if self.matrix is not None: print(self.matrix.shape) return str(type(self)) def __add__(self, other): """ :param other: :return: """ assert isinstance( other, CipherMatrix), "Can only be added with a CipherMatrix" A_enc = self._encrypted B_enc = other._encrypted if A_enc: A = self.encrypted_matrix else: A = self.matrix if B_enc: B = other.encrypted_matrix else: B = other.matrix assert A.shape == B.shape, "Dimension mismatch, Matrices must be of same shape. Got {} and {}".format( A.shape, B.shape) shape = A.shape result = CipherMatrix(np.zeros(shape, dtype=np.int32)) result._update_cryptors(self.get_keygen()) if A_enc: if B_enc: res_mat = result.encrypted_matrix for i in range(shape[0]): for j in range(shape[1]): self.evaluator.add(A[i, j], B[i, j], res_mat[i, j]) result._encrypted = True else: res_mat = result.encrypted_matrix for i in range(shape[0]): for j in range(shape[1]): self.evaluator.add_plain(A[i, j], self.encoder.encode(B[i, j]), res_mat[i, j]) result._encrypted = True else: if B_enc: res_mat = result.encrypted_matrix for i in range(shape[0]): for j in range(shape[1]): self.evaluator.add_plain(B[i, j], self.encoder.encode(A[i, j]), res_mat[i, j]) result._encrypted = True else: result.matrix = A + B result._encrypted = False return result def __sub__(self, other): """ :param other: :return: """ assert isinstance(other, CipherMatrix) if other._encrypted: shape = other.encrypted_matrix.shape for i in range(shape[0]): for j in range(shape[1]): self.evaluator.negate(other.encrypted_matrix[i, j]) else: other.matrix = -1 * other.matrix return self + other def __mul__(self, other): """ :param other: :return: """ assert isinstance( other, CipherMatrix), "Can only be multiplied with a CipherMatrix" # print("LHS", self._id, "RHS", other._id) A_enc = self._encrypted B_enc = other._encrypted if A_enc: A = self.encrypted_matrix else: A = self.matrix if B_enc: B = other.encrypted_matrix else: B = other.matrix Ashape = A.shape Bshape = B.shape assert Ashape[1] == Bshape[0], "Dimensionality mismatch" result_shape = [Ashape[0], Bshape[1]] result = CipherMatrix(np.zeros(shape=result_shape)) if A_enc: if B_enc: for i in range(Ashape[0]): for j in range(Bshape[1]): result_array = [] for k in range(Ashape[1]): res = Ciphertext() self.evaluator.multiply(A[i, k], B[k, j], res) result_array.append(res) self.evaluator.add_many(result_array, result.encrypted_matrix[i, j]) result._encrypted = True else: for i in range(Ashape[0]): for j in range(Bshape[1]): result_array = [] for k in range(Ashape[1]): res = Ciphertext() self.evaluator.multiply_plain( A[i, k], self.encoder.encode(B[k, j]), res) result_array.append(res) self.evaluator.add_many(result_array, result.encrypted_matrix[i, j]) result._encrypted = True else: if B_enc: for i in range(Ashape[0]): for j in range(Bshape[1]): result_array = [] for k in range(Ashape[1]): res = Ciphertext() self.evaluator.multiply_plain( B[i, k], self.encoder.encode(A[k, j]), res) result_array.append(res) self.evaluator.add_many(result_array, result.encrypted_matrix[i, j]) result._encrypted = True else: result.matrix = np.matmul(A, B) result._encrypted = False return result def save(self, path): """ :param path: :return: """ save_dir = os.path.join(path, self._id) if self._saved: print("CipherMatrix already saved") else: assert not os.path.isdir(save_dir), "Directory already exists" os.mkdir(save_dir) if not self._encrypted: self.encrypt() shape = self.encrypted_matrix.shape for i in range(shape[0]): for j in range(shape[1]): element_name = str(i) + '-' + str(j) + '.ahem' self.encrypted_matrix[i, j].save( os.path.join(save_dir, element_name)) self.secret_key.save("/keys/" + "." + self._id + '.wheskey') self._saved = True return save_dir def load(self, path, load_secret_key=False): """ :param path: :param load_secret_key: :return: """ self._id = path.split('/')[-1] print("Loading Matrix:", self._id) file_list = os.listdir(path) index_list = [[file.split('.')[0].split('-'), file] for file in file_list] M = int(max([int(ind[0][0]) for ind in index_list])) + 1 N = int(max([int(ind[0][1]) for ind in index_list])) + 1 del self.encrypted_matrix self.encrypted_matrix = np.empty([M, N], dtype=object) for index in index_list: i = int(index[0][0]) j = int(index[0][1]) self.encrypted_matrix[i, j] = Ciphertext() self.encrypted_matrix[i, j].load(os.path.join(path, index[1])) if load_secret_key: self.secret_key.load("/keys/" + "." + self._id + '.wheskey') self.matrix = np.empty(self.encrypted_matrix.shape) self._encrypted = True def encrypt(self, matrix=None, keygen=None): """ :param matrix: :return: """ assert not self._encrypted, "Matrix already encrypted" if matrix is not None: assert self.matrix is None, "matrix already exists" self.matrix = np.copy(matrix) shape = self.matrix.shape self.encrypted_matrix = np.empty(shape, dtype=object) if keygen is not None: self._update_cryptors(keygen) for i in range(shape[0]): for j in range(shape[1]): val = self.encoder.encode(self.matrix[i, j]) self.encrypted_matrix[i, j] = Ciphertext() self.encryptor.encrypt(val, self.encrypted_matrix[i, j]) self._encrypted = True def decrypt(self, encrypted_matrix=None, keygen=None): """ :return: """ if encrypted_matrix is not None: self.encrypted_matrix = encrypted_matrix assert self._encrypted, "No encrypted matrix" del self.matrix shape = self.encrypted_matrix.shape self.matrix = np.empty(shape) if keygen is not None: self._update_cryptors(keygen) for i in range(shape[0]): for j in range(shape[1]): plain_text = Plaintext() self.decryptor.decrypt(self.encrypted_matrix[i, j], plain_text) self.matrix[i, j] = self.encoder.decode(plain_text) self._encrypted = False return np.copy(self.matrix) def get_keygen(self): """ :return: """ return self.keygen def _update_cryptors(self, keygen): """ :param keygen: :return: """ self.keygen = keygen self.public_key = keygen.public_key() self.secret_key = keygen.secret_key() self.encryptor = Encryptor(self.context, self.public_key) self.decryptor = Decryptor(self.context, self.secret_key) return
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))
encryptor.encrypt(plain_matrix, cm) # cm = [[0] * len(m[0]) for i in range(len(m))] # for i in range(len(m)): # for j in range(len(m[0])): # cm[i][j] = Ciphertext(parms) # encryptor.encrypt(encoder.encode(m[i][j]), cm[i][j]) print(cm) np.reshape(cm, (r, c)) return cm # v1 = [3.1, 4.159, 2.65, 3.5897, 9.3, 2.3, 8.46, 2.64, 3.383, 2.795] # v2 = [0.1, 0.05, 0.05, 0.2, 0.05, 0.3, 0.1, 0.025, 0.075, 0.05] encryptor = Encryptor(context, public_key) encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3) def decryptMatrix(cm): r, c = len(cm), len(cm[0]) m = [[0] * c for i in range(r)] decryptor = Decryptor(context, secret_key) plain_result = Plaintext() for i in range(r): for j in range(c): decryptor.decrypt(cm[i][j], plain_result) m[i][j] = encoder.decode(plain_result) return m # m1 = [[1,3,2],[4,3,1]]
tM = [list(tup) for tup in zip(*M)] del (M) ncol = len(tM) for i in range(ncol): encrypt_matrix_row(tM[i], i) print("outside the loop") return (tM) parms = EncryptionParameters() parms.set_poly_modulus("1x^8192 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(8192)) parms.set_plain_modulus(1 << 21) context = SEALContext(parms) encoderF = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 30, 34, 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) dir_path = os.path.dirname(os.path.realpath(__file__)) snp = open(dir_path + "/snpMat.txt", "r+") S = [] for row in snp.readlines(): S.append(row.strip().split()) S = S[1:]
p=Plaintext() decryptor.decrypt(y, p) m.append(encoderF.decode(p)) M.append(m) return(M) parms = EncryptionParameters() parms.set_poly_modulus("1x^8192 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(8192)) parms.set_plain_modulus(1 << 21) context = SEALContext(parms) #encoder = IntegerEncoder(context.plain_modulus()) encoderF = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 30, 34, 3) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() #ev_keys40 = EvaluationKeys #ev_keys20 = EvaluationKeys() #keygen.generate_evaluation_keys(40,5,ev_keys40) #keygen.generate_evaluation_keys(20,3,ev_keys20) encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) plain_A = [] A=[] n=int(input("Enter dimension: "))
if __name__ == '__main__': multiprocessing.freeze_support() ########################## 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)
for i in range(16): A.append(random.randint(0,64)) A+=[0]*(100-16) print(A) for i in range(16,32,5): A[i]=1 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) encoder = IntegerEncoder(context.plain_modulus()) encoderF =FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 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) for i in range(len(A)): A_plain.append(encoder.encode(A[i])) A_cipherObject.append(Ciphertext()) encryptor.encrypt(A_plain[i],A_cipherObject[i]) print("Noise budget of "+ str(i)+" "+str((decryptor.invariant_noise_budget(A_cipherObject[i]))) + " bits") A_cipherObject=chunk(A_cipherObject) C=A_cipherObject
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)
SEALContext, \ EvaluationKeys, \ GaloisKeys, \ PolyCRTBuilder, \ ChooserEncoder, \ ChooserEvaluator, \ ChooserPoly parms = EncryptionParameters() parms.set_poly_modulus("1x^8192 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(8192)) parms.set_plain_modulus(1 << 21) context = SEALContext(parms) #encoder = IntegerEncoder(context.plain_modulus()) encoderF = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 30, 34, 3) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_key() #ev_keys40 = EvaluationKeys #ev_keys20 = EvaluationKeys() #keygen.generate_evaluation_keys(40,5,ev_keys40) #keygen.generate_evaluation_keys(20,3,ev_keys20) encryptor = Encryptor(context, public_key) evaluator = Evaluator(context) decryptor = Decryptor(context, secret_key) def print_plain(D): # function to print out all elements in a matrix for row in D:
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))))
def unit_test(): parms = EncryptionParameters() parms.set_poly_modulus("1x^8192 + 1") parms.set_coeff_modulus(seal.coeff_modulus_128(8192)) parms.set_plain_modulus(1 << 10) context = SEALContext(parms) # Print the parameters that we have chosen print_parameters(context) encoder = FractionalEncoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3) keygen = KeyGenerator(context) public_key = keygen.public_key() secret_key = keygen.secret_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) learningRate = 0.1 learningRate_data = encoder.encode(learningRate) learningRate_e = Ciphertext() encryptor.encrypt(learningRate_data, learningRate_e) updatedVals = [] updatedVals.append(50) updatedVals.append(50) updatedVals_unenc = [] updatedVals_unenc.append(updatedVals[0]) updatedVals_unenc.append(updatedVals[1]) for i in range(15): x = 1 y = 1 updatedVals = learn(x, y, evaluator, updatedVals[0], updatedVals[1], encoder, encryptor, learningRate_e, decryptor) ypred = updatedVals_unenc[0] * x + updatedVals_unenc[1] error = ypred - y updatedVals_unenc[0] = updatedVals_unenc[0] - x * error * learningRate updatedVals_unenc[1] = updatedVals_unenc[1] - error * learningRate print((str)(updatedVals[1]) + ":" + (str)(updatedVals[0]) + ":" + (str)(updatedVals_unenc[1]) + ":" + (str)(updatedVals_unenc[0])) x = 2 y = 3 updatedVals = learn(x, y, evaluator, updatedVals[0], updatedVals[1], encoder, encryptor, learningRate_e, decryptor) ypred = updatedVals_unenc[0] * x + updatedVals_unenc[1] error = ypred - y updatedVals_unenc[0] = updatedVals_unenc[0] - x * error * learningRate updatedVals_unenc[1] = updatedVals_unenc[1] - error * learningRate print((str)(updatedVals[1]) + ":" + (str)(updatedVals[0]) + ":" + (str)(updatedVals_unenc[1]) + ":" + (str)(updatedVals_unenc[0])) x = 4 y = 3 updatedVals = learn(x, y, evaluator, updatedVals[0], updatedVals[1], encoder, encryptor, learningRate_e, decryptor) ypred = updatedVals_unenc[0] * x + updatedVals_unenc[1] error = ypred - y updatedVals_unenc[0] = updatedVals_unenc[0] - x * error * learningRate updatedVals_unenc[1] = updatedVals_unenc[1] - error * learningRate print((str)(updatedVals[1]) + ":" + (str)(updatedVals[0]) + ":" + (str)(updatedVals_unenc[1]) + ":" + (str)(updatedVals_unenc[0])) x = 3 y = 2 updatedVals = learn(x, y, evaluator, updatedVals[0], updatedVals[1], encoder, encryptor, learningRate_e, decryptor) ypred = updatedVals_unenc[0] * x + updatedVals_unenc[1] error = ypred - y updatedVals_unenc[0] = updatedVals_unenc[0] - x * error * learningRate updatedVals_unenc[1] = updatedVals_unenc[1] - error * learningRate print((str)(updatedVals[1]) + ":" + (str)(updatedVals[0]) + ":" + (str)(updatedVals_unenc[1]) + ":" + (str)(updatedVals_unenc[0])) x = 5 y = 5 updatedVals = learn(x, y, evaluator, updatedVals[0], updatedVals[1], encoder, encryptor, learningRate_e, decryptor) ypred = updatedVals_unenc[0] * x + updatedVals_unenc[1] error = ypred - y updatedVals_unenc[0] = updatedVals_unenc[0] - x * error * learningRate updatedVals_unenc[1] = updatedVals_unenc[1] - error * learningRate print((str)(updatedVals[1]) + ":" + (str)(updatedVals[0]) + ":" + (str)(updatedVals_unenc[1]) + ":" + (str)(updatedVals_unenc[0]))