def x_pk_mul(one_x, one_pk): result = [None] * len(one_pk) for i in range(len(one_pk)): # call ntt product = convolutions.convolution_ntt(one_x.all_coeffs(), one_pk[i].all_coeffs(), prime=16389 * 2**11 + 1) result[i] = Poly(product, x, modulus=Q, symmetric=True) return np.asarray(result)
def G_mul(g, s): result = [] for i in range(N): result.append(Poly([0], x, modulus=Q, symmetric=True)) for i in range(len(g)): for k in range(len(s)): product = convolutions.convolution_ntt(g[i][k].all_coeffs(), s[k].all_coeffs(), prime=16389 * 2**11 + 1) result[i] = result[i] + Poly(product, x, modulus=Q, symmetric=True) return np.asarray(result)
def test_convolution(): # fft a = [1, S(5)/3, sqrt(3), S(7)/5] b = [9, 5, 5, 4, 3, 2] c = [3, 5, 3, 7, 8] d = [1422, 6572, 3213, 5552] assert convolution(a, b) == convolution_fft(a, b) assert convolution(a, b, dps=9) == convolution_fft(a, b, dps=9) assert convolution(a, d, dps=7) == convolution_fft(d, a, dps=7) assert convolution(a, d[1:], dps=3) == convolution_fft(d[1:], a, dps=3) # prime moduli of the form (m*2**k + 1), sequence length # should be a divisor of 2**k p = 7*17*2**23 + 1 q = 19*2**10 + 1 # ntt assert convolution(d, b, prime=q) == convolution_ntt(b, d, prime=q) assert convolution(c, b, prime=p) == convolution_ntt(b, c, prime=p) assert convolution(d, c, prime=p) == convolution_ntt(c, d, prime=p) raises(TypeError, lambda: convolution(b, d, dps=5, prime=q)) raises(TypeError, lambda: convolution(b, d, dps=6, prime=q)) # fwht assert convolution(a, b, dyadic=True) == convolution_fwht(a, b) assert convolution(a, b, dyadic=False) == convolution(a, b) raises(TypeError, lambda: convolution(b, d, dps=2, dyadic=True)) raises(TypeError, lambda: convolution(b, d, prime=p, dyadic=True)) raises(TypeError, lambda: convolution(a, b, dps=2, dyadic=True)) raises(TypeError, lambda: convolution(b, c, prime=p, dyadic=True)) # subset assert convolution(a, b, subset=True) == convolution_subset(a, b) == \ convolution(a, b, subset=True, dyadic=False) == \ convolution(a, b, subset=True) assert convolution(a, b, subset=False) == convolution(a, b) raises(TypeError, lambda: convolution(a, b, subset=True, dyadic=True)) raises(TypeError, lambda: convolution(c, d, subset=True, dps=6)) raises(TypeError, lambda: convolution(a, c, subset=True, prime=q))
def test_convolution(): # fft a = [1, Rational(5, 3), sqrt(3), Rational(7, 5)] b = [9, 5, 5, 4, 3, 2] c = [3, 5, 3, 7, 8] d = [1422, 6572, 3213, 5552] assert convolution(a, b) == convolution_fft(a, b) assert convolution(a, b, dps=9) == convolution_fft(a, b, dps=9) assert convolution(a, d, dps=7) == convolution_fft(d, a, dps=7) assert convolution(a, d[1:], dps=3) == convolution_fft(d[1:], a, dps=3) # prime moduli of the form (m*2**k + 1), sequence length # should be a divisor of 2**k p = 7*17*2**23 + 1 q = 19*2**10 + 1 # ntt assert convolution(d, b, prime=q) == convolution_ntt(b, d, prime=q) assert convolution(c, b, prime=p) == convolution_ntt(b, c, prime=p) assert convolution(d, c, prime=p) == convolution_ntt(c, d, prime=p) raises(TypeError, lambda: convolution(b, d, dps=5, prime=q)) raises(TypeError, lambda: convolution(b, d, dps=6, prime=q)) # fwht assert convolution(a, b, dyadic=True) == convolution_fwht(a, b) assert convolution(a, b, dyadic=False) == convolution(a, b) raises(TypeError, lambda: convolution(b, d, dps=2, dyadic=True)) raises(TypeError, lambda: convolution(b, d, prime=p, dyadic=True)) raises(TypeError, lambda: convolution(a, b, dps=2, dyadic=True)) raises(TypeError, lambda: convolution(b, c, prime=p, dyadic=True)) # subset assert convolution(a, b, subset=True) == convolution_subset(a, b) == \ convolution(a, b, subset=True, dyadic=False) == \ convolution(a, b, subset=True) assert convolution(a, b, subset=False) == convolution(a, b) raises(TypeError, lambda: convolution(a, b, subset=True, dyadic=True)) raises(TypeError, lambda: convolution(c, d, subset=True, dps=6)) raises(TypeError, lambda: convolution(a, c, subset=True, prime=q))
def test_convolution_ntt(): # prime moduli of the form (m*2**k + 1), sequence length # should be a divisor of 2**k p = 7*17*2**23 + 1 q = 19*2**10 + 1 r = 2*500000003 + 1 # only for sequences of length 1 or 2 s = 2*3*5*7 # composite modulus assert all(convolution_ntt([], x, prime=y) == [] for x in ([], [1]) for y in (p, q, r)) assert convolution_ntt([2], [3], r) == [6] assert convolution_ntt([2, 3], [4], r) == [8, 12] assert convolution_ntt([32121, 42144, 4214, 4241], [32132, 3232, 87242], p) == [33867619, 459741727, 79180879, 831885249, 381344700, 369993322] assert convolution_ntt([121913, 3171831, 31888131, 12], [17882, 21292, 29921, 312], q) == \ [8158, 3065, 3682, 7090, 1239, 2232, 3744] assert convolution_ntt([12, 19, 21, 98, 67], [2, 6, 7, 8, 9], p) == \ convolution_ntt([12, 19, 21, 98, 67], [2, 6, 7, 8, 9], q) assert convolution_ntt([12, 19, 21, 98, 67], [21, 76, 17, 78, 69], p) == \ convolution_ntt([12, 19, 21, 98, 67], [21, 76, 17, 78, 69], q) raises(ValueError, lambda: convolution_ntt([2, 3], [4, 5], r)) raises(ValueError, lambda: convolution_ntt([x, y], [y, x], q)) raises(TypeError, lambda: convolution_ntt(x, y, p))
def test_convolution_ntt(): # prime moduli of the form (m*2**k + 1), sequence length # should be a divisor of 2**k p = 7*17*2**23 + 1 q = 19*2**10 + 1 r = 2*500000003 + 1 # only for sequences of length 1 or 2 # s = 2*3*5*7 # composite modulus assert all(convolution_ntt([], x, prime=y) == [] for x in ([], [1]) for y in (p, q, r)) assert convolution_ntt([2], [3], r) == [6] assert convolution_ntt([2, 3], [4], r) == [8, 12] assert convolution_ntt([32121, 42144, 4214, 4241], [32132, 3232, 87242], p) == [33867619, 459741727, 79180879, 831885249, 381344700, 369993322] assert convolution_ntt([121913, 3171831, 31888131, 12], [17882, 21292, 29921, 312], q) == \ [8158, 3065, 3682, 7090, 1239, 2232, 3744] assert convolution_ntt([12, 19, 21, 98, 67], [2, 6, 7, 8, 9], p) == \ convolution_ntt([12, 19, 21, 98, 67], [2, 6, 7, 8, 9], q) assert convolution_ntt([12, 19, 21, 98, 67], [21, 76, 17, 78, 69], p) == \ convolution_ntt([12, 19, 21, 98, 67], [21, 76, 17, 78, 69], q) raises(ValueError, lambda: convolution_ntt([2, 3], [4, 5], r)) raises(ValueError, lambda: convolution_ntt([x, y], [y, x], q)) raises(TypeError, lambda: convolution_ntt(x, y, p))
def RSign(message, pk_list, position, sk, G, time_restart): s = random_special_S(DEGREE) row = [None] * key_list_size for i in range(key_list_size): if i == position: continue row[i] = random_special_poly(DEGREE) x_list = np.asarray(row) t = G_mul(G, s) for ii in range(len(t)): foo, t[ii] = div(t[ii], modulus_poly) summation = 0 for i in range(len(x_list)): if i == position: continue summation = summation + x_pk_mul(x_list[i], pk_list[i]) t = t + summation # reduction for i in range(len(t)): foo, t[i] = div(t[i], modulus_poly) t[i] = Poly(t[i].all_coeffs(), x, modulus=Q, symmetric=True) t_hash = [] for i in range(len(t)): t_hash.append(t[i].all_coeffs()) t_hash = np.asarray(t_hash) t_hash = str(t_hash).encode() # hashing # it seems that simply hashing the list t is not going to work, try to create a list of coeffs sha = SHA256.new() sha.update(message.encode()) # converting pk_list(a ndarray to a string) sha.update(pk_list.tostring()) sha.update(t_hash) hashed_product = int(sha.hexdigest(), 16) ternaray_string = ternary(hashed_product) x_poly = ternary_poly(ternaray_string, DEGREE) # subtracting my_x = x_poly for ii in range(len(x_list)): if ii == position: continue this_poly = Poly(x_list[ii].all_coeffs(), x, modulus=3, symmetric=True) my_x = my_x - this_poly my_x = find_my_x(my_x) my_x = Poly(my_x.all_coeffs(), x, modulus=Q, symmetric=True) x_list[position] = my_x z = [None] * (M + 1) z = np.asarray(z) for i in range(len(z)): x_coef = convolutions.convolution_ntt(my_x.all_coeffs(), sk[i].all_coeffs(), prime=16389 * 2**11 + 1) z[i] = Poly(x_coef, x, modulus=Q, symmetric=True) - s[i] foo, z[i] = div(z[i], modulus_poly) z[i] = Poly(z[i].all_coeffs(), x, modulus=Q, symmetric=True) if z_check_row(z[i]) == 0: time_restart[0] += 1 return RSign(message, pk_list, position, sk, G, time_restart) return (z, x_list)