def SDiv_ABZS12(a, b, l, kappa): theta = int(ceil(log(l, 2))) x = b y = a for i in range(theta - 1): y = y * ((2**(l + 1)) - x) y = AdvInteger.TruncPr(y, 2 * l + 1, l, kappa) x = x * ((2**(l + 1)) - x) x = AdvInteger.TruncPr(x, 2 * l + 1, l, kappa) y = y * ((2**(l + 1)) - x) y = AdvInteger.TruncPr(y, 2 * l + 1, l, kappa) return y
def SDiv_mono(a, b, l, kappa): theta = int(ceil(log(l / 3.5) / log(2))) alpha = two_power(2 * l) w = types.cint(int(2.9142 * two_power(l))) - 2 * b x = alpha - b * w y = a * w y = AdvInteger.TruncPr(y, 2 * l + 1, l + 1, kappa) for i in range(theta - 1): y = y * (alpha + x) # keep y with l bits y = AdvInteger.TruncPr(y, 3 * l, 2 * l, kappa) x = x**2 # keep x with 2l bits x = AdvInteger.TruncPr(x, 4 * l, 2 * l, kappa) y = y * (alpha + x) y = AdvInteger.TruncPr(y, 3 * l, 2 * l, kappa) return y
def Div(a, b, k, f, kappa, simplex_flag=False): theta = int(ceil(log(k / 3.5) / log(2))) alpha = AdvInteger.two_power(2 * f) w = AppRcr(b, k, f, kappa, simplex_flag) x = alpha - b * w y = a * w y = AdvInteger.TruncPr(y, 2 * k, f, kappa) for i in range(theta): y = y * (alpha + x) x = x * x y = AdvInteger.TruncPr(y, 2 * k, 2 * f, kappa) x = AdvInteger.TruncPr(x, 2 * k, 2 * f, kappa) y = y * (alpha + x) y = AdvInteger.TruncPr(y, 2 * k, 2 * f, kappa) return y
def AppRcr(b, k, f, kappa, simplex_flag=False): """ Approximate reciprocal of [b]: Given [b], compute [1/b] """ alpha = types.cint(int(2.9142 * 2**k)) c, v = Norm(b, k, f, kappa, simplex_flag) #v should be 2**{k - m} where m is the length of the bitwise repr of [b] d = alpha - 2 * c w = d * v w = AdvInteger.TruncPr(w, 2 * k, 2 * (k - f)) # now w * 2 ^ {-f} should be an initial approximation of 1/b return w
def SDiv(a, b, l, kappa): theta = int(ceil(log(l / 3.5) / log(2))) alpha = AdvInteger.two_power(2 * l) beta = 1 / types.cint(AdvInteger.two_power(l)) w = types.cint(int(2.9142 * AdvInteger.two_power(l))) - 2 * b x = alpha - b * w y = a * w y = AdvInteger.TruncPr(y, 2 * l, l, kappa) x2 = types.sint() AdvInteger.Mod2m(x2, x, 2 * l + 1, l, kappa, False) x1 = (x - x2) * beta for i in range(theta - 1): y = y * (x1 + two_power(l)) + AdvInteger.TruncPr( y * x2, 2 * l, l, kappa) y = AdvInteger.TruncPr(y, 2 * l + 1, l + 1, kappa) x = x1 * x2 + AdvInteger.TruncPr(x2**2, 2 * l + 1, l + 1, kappa) x = x1 * x1 + AdvInteger.TruncPr(x, 2 * l + 1, l - 1, kappa) x2 = types.sint() AdvInteger.Mod2m(x2, x, 2 * l, l, kappa, False) x1 = (x - x2) * beta y = y * (x1 + two_power(l)) + AdvInteger.TruncPr(y * x2, 2 * l, l, kappa) y = AdvInteger.TruncPr(y, 2 * l + 1, l - 1, kappa) return y
def block(i): A[i] = AdvInteger.TruncPr(A[i - 1] * W[i - 1], 2 * k, f, kappa) temp = (B[i - 1] * W[i - 1]) >> f # no reading and writing to the same variable in a for loop. W[i] = two - temp B[i] = temp