FunctionEvaluator#

class FunctionEvaluator#

This class is used to evaluate different available functions on CTiles, such as approximate inverse function.

abs(self: pyhelayers.FunctionEvaluator, a: pyhelayers.CTile, g_rep: int, f_rep: int, max_possible_abs_value: float) pyhelayers.CTile#
Calculates absolute value.

This method return the absolute value of a cipher text. :param a: Cipher to calculate absolute for. :param g_rep: How many repetitions of g(x). :param f_rep: How many repetitions of f(x). :param max_possible_abs_value: The maximum absolute value possible for a.

compare(self: pyhelayers.FunctionEvaluator, a: pyhelayers.CTile, b: pyhelayers.Tile, g_rep: int, f_rep: int, max_possible_abs_of_diff: float) pyhelayers.CTile#

Comparison of two numbers. This method compares two numbers a and b and return 1 if a>b, 0 if b<a and 0.5 if a==b by calculating sign(a-b).

Parameters:
  • a (CTile) – First ciphertext to compare

  • b (CTile) – Second ciphertext to compare

  • g_rep (int) – How many repetitions of g(x) See further explanation in sign()

  • f_rep (int) – How many repetitions of f(x) See further explanation in sign()

  • max_possible_abs_of_diff (double) – An upper upper bound on |a-b|. The tighter this bound is, the more accurate the result will be.

compareInPlace(self: pyhelayers.FunctionEvaluator, a: pyhelayers.CTile, b: pyhelayers.Tile, g_rep: int, f_rep: int, max_possible_abs_of_diff: float) None#

Comparison of two numbers. This method compares two numbers a and b and return 1 if a>b, 0 if b<a and 0.5 if a==b by calculating sign(a-b).

Parameters:
  • a – First CTile to compare

  • b – Second Tile to compare

  • g_rep (int) – How many repetitions of g(x) See further explanation in sign()

  • f_rep (int) – How many repetitions of f(x) See further explanation in sign()

  • max_possible_abs_of_diff (double) – An upper upper bound on |a-b|. The tighter this bound is, the more accurate the result will be.

composite_polynomial_evaluation(self: pyhelayers.FunctionEvaluator, res: pyhelayers.CTile, src: pyhelayers.CTile, polys: std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, type: pyhelayers.EvalType = <EvalType.MIN_DEPTH: 2>) None#

Composite polynomial evaluation. Evaluates the composition of the given polynomials on the given “src”, and stores the result in “res”.

Parameters:
  • res – Where to store the result.

  • src – The input of the composite polynomial.

  • polys

    The coefficients of the composition polynomials.

    polys[0] is evaluated first, and polys[i][0] is the free coefficient of the i-th polynomial.

    param type:

    The type of the evaluation algorithm. See also the documentation of “EvalType”.

composite_polynomial_evaluation_in_place(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, polys: std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, type: pyhelayers.EvalType = <EvalType.MIN_DEPTH: 2>) None#

Composite polynomial evaluation, in place. Evaluates the composition of the given polynomials on the given “src”, and stores the result in “src”.

param src:

The input of the composite polynomial. This will contain the result of the evaluation at the end of the function execution.

param polys:

The coefficients of the composition polynomials. polys[0] is evaluated first, and polys[i][0] is the free coefficient of the i-th polynomial.

param type:

The type of the evaluation algorithm. See also the documentation of “EvalType”.

composite_remez_depth12_sign(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, max_abs_val: float, binary_res: bool = False) pyhelayers.CTile#

Computes the (approximated) sign of src. The sign is computed as a composition of three remez polynomials, and it consumes a total multiplication depth of 12. The error remains below 0.1 if |src|/max_abs_val >= 2^-9, and it remains in order of 1e-4 (or less) if |src|/max_abs_val >= 2^-8.

Parameters:
  • src (CTile) – Ciphertext to calculate its inverse.

  • max_abs_val – Ciphertext to calculate its inverse.

  • binary_res – If true the result will be close to 0 when src < 0 and close to 1 when src > 0. If false, the result will be close to -1 when src < 0 and close to 1 when src > 0. Defaults to false.

composite_remez_depth12_sign_in_place(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, max_abs_val: float, binary_res: bool = False) pyhelayers.CTile#

Computes the (approximated) sign of src, in place. The sign is computed as a composition of three remez polynomials, and it consumes a total multiplication depth of 12. The error remains below 0.1 if |src|/max_abs_val >= 2^-9, and it remains in order of 1e-4 (or less) if |src|/max_abs_val >= 2^-8.

Parameters:
  • src (CTile) – Ciphertext to calculate its inverse.

  • max_abs_val – Ciphertext to calculate its inverse.

  • binary_res – If true the result will be close to 0 when src < 0 and close to 1 when src > 0. If false, the result will be close to -1 when src < 0 and close to 1 when src > 0. Defaults to false.

gelu_by_sigmoid(self: pyhelayers.FunctionEvaluator, x: pyhelayers.CTile, scale: float) None#

Calculates (an approximation of) GELU(x) in place.

Parameters:
  • x – CTile. The values to calculate GELU on. The output will be stored in place.

  • scale – double. scale to divide x by in order to compute sigmoid from sign.

static get_poly_eval_mul_depth(*args, **kwargs)#

Overloaded function.

  1. get_poly_eval_mul_depth(num_encrypted_coefs: int, normalized: bool) -> int

    Returns the required multiplication depth to evaluate the described polynomial.

    param num_encrypted_coefs:

    The number of encrypted coefficients of the polynomial

    param normalized:

    If false, the polynomial to evaluate will be composed from the coefficients in “coeffs” vector only. Otherwise, an extra term, whose coefficient is 1 and whose power is coefs.size(), will be added.

  2. get_poly_eval_mul_depth(coefs: std::vector<double, std::allocator<double> >, type: pyhelayers.EvalType) -> int

    Returns the required multiplication depth to evaluate the given polynomial, using the given evaluation method.

    param coefs:

    The polynomial’s coefficients.

    param type:

    The polynomial evaluation method.

inverse_positive(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, lower_bound: float, upper_bound: float, bit_resolution: int = 5) pyhelayers.CTile#

Calculates (an approximation of) 1/src. src must be between lower_bound and upper_bound, and lower_bound must be non-negative. The tighter the given bounds are, the more accurate the result will be. For more details, see “Homomorphic Encryption for Arithmetic of Approximate Numbers” paper, p. 15: https://eprint.iacr.org/2016/421.pdf.

Parameters:
  • src (CTile) – Ciphertext to calculate its inverse.

  • lower_bound (double) – a lower bound on src. The tighter this bound is, the more accurate the result will be. This lower bound must be non-negative.

  • upper_bound (double) – an upper upper bound on src. The tighter this bound is, the more accurate the result will be.

  • bit_resolution – Controls the accuracy of the result. A higher bit_resolution value will increase the accuracy of the result at the account of consuming more multiplication depth. Defaults to 5.

inverse_positive_without_scaling(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, bit_resolution: int = 5) pyhelayers.CTile#

Calculates (an approximation of) 1/src. src must be in the range(0, 2), and the approximation becomes less accurate near the boundaries.

Parameters:
  • src (CTile) – Ciphertext to calculate its inverse.

  • bit_resolution – Controls the accuracy of the result. A higher bit_resolution value will increase the accuracy of the result at the account of consuming more multiplication depth. Defaults to 5.

inverse_without_scaling(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, bit_resolution: int = 5) pyhelayers.CTile#

Calculates (an approximation of) 1/src. src must be in the range(-sqrt(2), sqrt(2)), and the approximation becomes less accurate near the boundaries.

Parameters:
  • src (CTile) – Ciphertext to calculate its inverse.

  • bit_resolution – Controls the accuracy of the result. A higher bit_resolution value will increase the accuracy of the result at the account of consuming more multiplication depth. Defaults to 5.

min(*args, **kwargs)#

Overloaded function.

  1. min(self: pyhelayers.FunctionEvaluator, min_res: pyhelayers.CTile, min_indicators: pyhelayers.CTileVector, cs: pyhelayers.CTileVector, g_rep: int, f_rep: int, max_diff: float = 1) -> None

Stores the minimum of “cs” CTiles in “min_res” and stores in

minIndicators[i] a CTile containing 1 if cs[i] is the minimum and 0 otherwise

param min_res:

CTile containg minimum.

param min_indicators:

stores in minIndicators[i] a CTile containing 1 if cs[i] is the minimum and 0 otherwise.

param cs:

array of CTile

param g_rep:

Determine the accuracy of the result. Greater g_rep will result with a greater accuracy on the account of slower runtime and more multiplication depth.

param f_rep:

Determine the accuracy of the result. Greater f_rep will result with a greater accuracy on the account of slower runtime and more multiplication depth.

param max_diff:

The maximum possible absolute difference between two values in cs[i].

  1. min(self: pyhelayers.FunctionEvaluator, min_res: pyhelayers.CTile, min_indicators: pyhelayers.CTile, a: pyhelayers.CTile, b: pyhelayers.CTile, g_rep: int, f_rep: int, max_diff: float = 1, delay_mul_by_half: bool = False) -> None

Computes min(a,b), stores it in min_res and stores the minimum

indicator in “minIndicator” (1 if a < b and 0 otherwise).

param min_res:

min(a,b) will be stored here.

param min_indicators:

The resulting minimum indicator. This will contain an encryption of 1 if a < b and 0 otherwise.

param a:

The first CTile for the minimum computation.

param b:

The second CTile for the minimum computation.

param g_rep:

Determine the accuracy of the result. Greater gRep will result with a greater accuracy on the account of slower runtime and more multiplication depth.

param f_rep:

Determine the accuracy of the result. Greater fRep will result with a greater accuracy on the account of slower runtime and more multiplication depth.

param max_diff:

The maximum possible absolute difference between a and b.

param delay_mul_by_half:

If true, min_res will contain two times min(a,b) and the function will consume one less chain index in “min_res”.

multiply_many(self: pyhelayers.FunctionEvaluator, cts: std::vector<helayers::CTileTensor, std::allocator<helayers::CTileTensor> >) pyhelayers.CTileTensor#

Returns the product of the given CTileTensors. The multiplication depth consumed by this function is ceil(log(cst.size()))

param cts:

The vector of CTileTensors to multiply.

return:

CTileTensor.

rtype:

CTileTensor

one_hot(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, possible_values: numpy.ndarray[numpy.float64]) pyhelayers.CTileVector#

Given ciphertext src and a list possible_values of the possible values inside src, calculates possible_values indicator ciphertexts that indicates which slots in src contain the corresponding value. Formally, the i’th indicator ciphertext contains 1 in slot j only if src[j]=possible_values[i], and 0 otherwise.

Parameters:
  • src (CTile) – The source ciphertext

  • possible_values (list) – A list of doubles contain the possible values inside src

poly_eval(self: pyhelayers.FunctionEvaluator, res: pyhelayers.CTile, src: pyhelayers.CTile, coefs: std::vector<double, std::allocator<double> >, type: pyhelayers.EvalType = <EvalType.MIN_DEPTH: 2>) None#

Polynomial evaluation. Evaluates the given polynomial on input

“src”, and stores the result in “res”.

Parameters:
  • res – Where to store the result.

  • src – The input of the polynomial.

  • coefs – The coefficients of the polynomial. coefs[0] is the free coefficient.

  • type – The type of the evaluation algorithm. See also the documentation of “EvalType”.

poly_eval_by_roots(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, roots: std::vector<std::complex<double>, std::allocator<std::complex<double> > >, coef: float, block_size: int = -1) pyhelayers.CTile#

Polynomial evaluation using a polynomial’s roots. If the roots vector is (r1, …, rn), then the evaluated polynomial is: coef * (x - r1) * … * (x - rn).

Parameters:
  • src – The input of the polynomial.

  • roots – The roots of the polynomial..

  • coef – The evaluated polynomial is coef * prod(x-r_i) (where r_i are the roots).

  • block_size – Before evaluation, each blockSize roots are expanded into one polynomial of degree block_size. If -1, a blockSize of min(sqrt(n), 16) is used (where n is the number of roots). Defaults to -1. If a positive value is given, it must not be greater than 30.

Returns:

The CTile.

Return type:

CTile

poly_eval_by_roots_in_place(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, roots: std::vector<std::complex<double>, std::allocator<std::complex<double> > >, coef: float, block_size: int = -1) None#

Polynomial evaluation using a polynomial’s roots, in place. Refer to polyEvalByRoots() documentation for more details.

param src:

The input of the polynomial. This will contain the result of the evaluation at the end of the function execution

param roots:

The roots of the polynomial..

param coef:

The evaluated polynomial is coef * prod(x-r_i) (where r_i are the roots).

param block_size:

Before evaluation, each blockSize roots are expanded into one polynomial of degree block_size. If -1, a block_size of min(sqrt(n), 16) is used (where n is the number of roots). Defaults to -1. If a positive value is given, it must not be greater than 30.

poly_eval_in_place(*args, **kwargs)#

Overloaded function.

  1. poly_eval_in_place(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, coefs: pyhelayers.CTileVector, normalized: bool = False, ignore_free_coef: bool = False) -> None

    Polynomial evaluation, in place. Evaluates the given polynomial on input “src”, and stores the result in “src”.

    param src:

    The input of the polynomial. This will contain the result of the evaluation at the end of the function

    execution.

    param coefs:

    The (encrypted) coefficients of the polynomial. coefs[0] is the free coefficient.

    param normalized:

    If false, the polynomial to evaluate will be composed from the coefficients in “coeffs” vector only. Otherwise, an extra term, whose coefficient is 1 and whose power is coefs.size(), will be added. coefs[0] is the free coefficient.

    param ignore_free_coef:

    If true, the first coefficient in “coefs” array is not added to the final result.

  2. poly_eval_in_place(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, coefs: pyhelayers.CTileVector, required_ci_for_coefs: std::vector<int, std::allocator<int> >, normalized: bool = False, ignore_free_coef: bool = False) -> None

    Polynomial evaluation, in place. Evaluates the given polynomial on input “src”, and stores the result in “src”.

    param src:

    The input of the polynomial. This will contain the result of the evaluation at the end of the function

    execution.

    param coefs:

    The (encrypted) coefficients of the polynomial. coefs[0] is the free coefficient.

    :param required_ci_for_coefs :After the end of the computation, the i-th

    element of this vector will contain the chain index of the ciphertext

    which was multiplied by coefs[i]

    param normalized:

    If false, the polynomial to evaluate will be composed from the coefficients in “coeffs” vector only. Otherwise, an extra term, whose coefficient is 1 and whose power is coefs.size(), will be added. coefs[0] is the free coefficient.

    param ignore_free_coef:

    If true, the first coefficient in “coefs” array is not added to the final result.

  3. poly_eval_in_place(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, coefs: std::vector<double, std::allocator<double> >, type: pyhelayers.EvalType = <EvalType.MIN_DEPTH: 2>) -> None

    Polynomial evaluation, in place. Evaluates the given polynomial on input “src”, and stores the result in “src”.

    param src:

    The input of the polynomial. This will contain the result of the evaluation at the end of the function

    execution.

    param coefs:

    The (encrypted) coefficients of the polynomial. coefs[0] is the free coefficient.

    param type:

    The type of the evaluation algorithm. See also the documentation of “EvalType”.

poly_eval_needs_bs(*args, **kwargs)#

Overloaded function.

  1. poly_eval_needs_bs(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, num_encrypted_coefs: int, normalized: bool) -> bool

    Checks whether bootstrapping will be required to complete the specified polynomial evaluation. If bootstrapping is required to evaluate the given polynomial on the given p src ciphertext and using the given evaluation method, returns true. Otherwise, returns false.

    param src:

    The ciphertext to evaluate the polynomial on.

    param num_encrypted_coefs:

    The number of encrypted coefficients of the polynomial.

    param normalized:

    If false, the polynomial to evaluate will be composed from the coefficients in “coeffs” vector only. Otherwise, an extra term, whose coefficient is 1 and whose power is coefs.size(), will be added.

  2. poly_eval_needs_bs(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, coeffs: numpy.ndarray[numpy.float64], type: pyhelayers.EvalType) -> bool

    Checks whether bootstrapping will be required to complete the specified polynomial evaluation. If bootstrapping is required to evaluate the given polynomial on the given p src ciphertext and using the given evaluation method, returns true. Otherwise, returns false.

    param src:

    The ciphertext to evaluate the polynomial on.

    param coeffs:

    The polynomial’s coefficients.

    param type:

    The polynomial evaluation method.

pow(self: pyhelayers.FunctionEvaluator, res: pyhelayers.CTile, src: pyhelayers.CTile, degree: int) None#

Computes src^degree, and stores the result into res. :param res: Where the result should be stored. :param src: To compute its power. :param degree: The required exponent.

pow_in_place(self: pyhelayers.FunctionEvaluator, c: pyhelayers.CTile, degree: int, non_linearized_monomials: bool = False, non_scaled_monomials: bool = False, ci: int = 0) None#

Computes c^degree, in place. :param c: Cipher to compute its power. The result will be stored here. :param degree: The required exponent. :param non_linearized_monomials: If true the result is not linearized. :param non_scaled_monomials: If true the result is not scaled. :param ci: If not 0 the result’s chain index set to ci

relu_by_sign15(self: pyhelayers.FunctionEvaluator, x: pyhelayers.CTile, max_abs_val: float) None#

Calculates (an approximation of) ReLU(x) in place assuming that x is in [-max_abs_val, max_abs_val].

Parameters:
  • x – CTile. The values to calculate ReLU on. The output will be stored in place.

  • max_abs_val – double. Maximal expected absolute value of value in the slots of x

sigmoid(self: pyhelayers.FunctionEvaluator, res: pyhelayers.CTile, src: pyhelayers.CTile, type: pyhelayers.SigmoidType) None#

A polynomial approximation of sigmoid.

Parameters:
  • res – Where to store the result.

  • src – Ciphertext to calculate its sigmoid.

  • type – Specifies the degree of the approximating polynomial. See also SigmoidType documentation.

sigmoid_in_place(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, type: pyhelayers.SigmoidType) None#

A polynomial approximation of sigmoid in place.

Parameters:
  • src – Ciphertext to calculate its sigmoid. The result will be stored here.

  • type – Specifies the degree of the approximating polynomial. See also SigmoidType documentation.

sign(self: pyhelayers.FunctionEvaluator, a: pyhelayers.CTile, g_rep: int, f_rep: int, max_abs_val: float = 1, binary_res: bool = False) pyhelayers.CTile#

Returns the (approximated) sign of a. The sign is computed as the g(g(…g(f(f(…f(x)))))), where g(x) and f(x) are two degree 7 polynomials. The number of times g(x) and f(x) appear in the composition can be controlled by g_rep and f_rep arguments, respectively. a must be in the range [-max_abs_val, max_abs_val].

Parameters:
  • a (CTile) – Ciphertext we want to find its sign. a must be in the range [-max_abs_val, max_abs_val].

  • g_rep (int) – How many repetitions of g(x)

  • f_rep (int) – How many repetitions of f(x)

  • max_abs_val (double) – An upper bound on the absolute value of a. Defaults to 1.

  • binary_res (boolean) – If true the result will be close to 0 when a < 0 and close to 1 when a > 0. If false, the result will be close to -1 when a < 0 and close to 1 when a > 0. Defaults to false.

sign_in_place(self: pyhelayers.FunctionEvaluator, a: pyhelayers.CTile, g_rep: int, f_rep: int, max_abs_val: float = 1, binary_res: bool = False) None#

Returns the (approximated) sign of a, in place. src must be in the range [-maxAbsVal, maxAbsVal]. The sign is computed as f(f(…f(g(g(…g(x)))))), where g(x) and f(x) are two degree 7 polynomials. The number of times g(x) and f(x) appear in the composition can be controlled by p gRep and p fRep arguments, respectively. g(x) is a “giant-step” polynomial, which takes an input in the range (-1, 1) and pushes it to be close to -1 or 1, while f(x) is a “baby-step” polynomial, which takes an input already close to -1 or 1, and brings it closer to one of them. The sign approximation starts by applying g(x) gRep times to bring the input to be close to -1 or 1, and then applying f(x) fRep times to tune the output so the error gets reduced. It is recommended to set fRep to a small value (1, 2 or 3), and then increase gRep until reaching the desired accuracy. The multiplication depth consumed by the sign function is 3*(gRep+fRep), and higher values of gRep, fRep increase accuracy at the expense of increasing latency of the sign function. Possible values for gRep, fRep are: * gRep=3, fRep=2: maximum error of 1.9e-05 when |x| in [2^(-7), 1]. * gRep=4, fRep=2: maximum error of 1.4e-06 when |x| in [2^(-9), 1]. * gRep=5, fRep=2: maximum error of 1.1e-07 when |x| in [2^(-11), 1]. See also SignOptimizer class and SignOptimizerTest.cpp for automatic choise of gRep, fRep that achieve a desired error and helper functions that compute the errors achieved by a specific pair of gRep, fRep.

Parameters:
  • a (CTile) – Ciphertext we want to find its sign. a must be in the range [-max_abs_val, max_abs_val].

  • g_rep (int) – How many repetitions of g(x)

  • f_rep (int) – How many repetitions of f(x)

  • max_abs_val (double) – An upper bound on the absolute value of a. Defaults to 1.

  • binary_res (boolean) – If true the result will be close to 0 when a < 0 and close to 1 when a > 0. If false, the result will be close to -1 when a < 0 and close to 1 when a > 0. Defaults to false.

sqrt(self: pyhelayers.FunctionEvaluator, src: pyhelayers.CTile, bit_resolution: int) None#
Calculates (an approximation of) sqrt(src). src must be in the range

[0,1].

Parameters:
  • src – To compute its square root.

  • bit_resolution – Controls the accuracy of the result. A higher value results with a better accuracy at the account of higher multiplication depth and higher latency.