algorithm for reciprocal
Two numbers are reciprocals of each other, which means that the multiplication of these two numbers equals 1. For example, a and b are reciprocals of each other, then ab=1.
The reciprocal of 5 is 0.2, we can find it very simply, but how to find the reciprocal of a number in the ciphertext field?
An algorithm is given in the article "An investigation of complex operations with word-size homomorphic encryption".
We assume that y=1-x, and the modulus of y is less than (for real numbers, the absolute value) 0.5, then the following formula holds
Substitute x=1-y, and use the square difference formula to prove it quickly.
When r is large enough, obviously, the above formula is 1, and the reciprocal of x we require can be found through the formula on the left
In this way, we have an iterative method to calculate the reciprocal of a number using only addition and multiplication.
However, the above method may have a problem, that is, the x at this time can only be in the range of [0.5,1], and the y involved in the calculation is a decimal.
We multiply the left and right sides of the above formula by one at the same time , let z=xp, y=pz then have
In this way, it can be calculated when the modulus of y is less than p/2.
However, obviously, when p=1, the amount of calculation will be much smaller
TenSEAL uses CKKS code example
import tenseal as ts
ctx=ts.context(ts.SCHEME_TYPE.CKKS, poly_modulus_degree=8192, coeff_mod_bit_sizes=[44,30,30,30,30,44])
ctx.global_scale=2**30
import numpy as np
m1=np.array([1.2,0.6,0.4])
c0=ts.ckks_vector(ctx,m1)
p1=1
p=p1
r=4
t=p-c0
c=t
v=p+c
for i in range(r-1):
c=c*c
p=p*p
v=v*(p+c)
m=v.decrypt()
m=np.array(m)/(p1**(2**(r)))
print(m)
print(m*m1)
When r=2 or 3, the result is more accurate