def _extract_authority_result(PP, B0, b, tally): r = tally.final_com_r T0, T1 = tally.additional_com t0 = T0[-1] t1 = T1[-1] B0r = matrix_vector(B0, r, PP.X, PP.d) zero = list(t0[i] - B0r[i] for i in range(PP.kappa)) x = list((t1[i] - scalar(b[i], r, PP.X, PP.d)) for i in range(PP.npoly)) return zero, x
def commit_with_r(PP, B0, b, m, r): t0 = matrix_vector(B0, r, PP.X, PP.d) t1 = [] for i in range(PP.npoly): t1.append(scalar(b[i], r, PP.X, PP.d) + m[i]) return t0, t1
def proof_v(PP, t0, t1, r, m, public_seed): d = PP.d l = PP.l X = PP.X k = PP.k npoly = PP.npoly m_prime = _compute_m_prime(PP) B0, b = gen_public_b_with_extra(PP, public_seed) seed = randombytes(PP.seedlen) nonce = 0 g, nonce = random_poly_with_zeros(PP, seed, nonce, d, PP.g_zeros) t2 = scalar(b[npoly], r, X, d) + g while True: Y = [0] * k W = [0] * k for i in range(PP.k): Y[i] = discrete_gaussian_vector_y(PP, PP.baselen, PP.sigma1) W[i] = matrix_vector(B0, Y[i], X, d) if k == 1: # PP.npoly should be 1 y = Y[0] gamma, ag_hash = get_alpha_gamma(PP, t0, t1, t2, W) t3 = (scalar(b[npoly + 1], r, X, d) - (2 * m[0] - m_prime[0]) * scalar(b[0], y, X, d)).mod(X**d + 1) vpp = (scalar(b[npoly + 1], y, X, d) + scalar(b[0], y, X, d)**2).mod(X**d + 1) intt_factor = gamma * l h = (g + intt_factor * m[0] - gamma).mod(X**d + 1) vulp = scalar(list((intt_factor * b[0][i] + b[npoly][i]) for i in range(PP.baselen)), y, X, d) else: alpha, gamma, ag_hash = get_alpha_gamma(PP, t0, t1, t2, W) t3 = scalar(b[npoly + 1], r, X, d) vpp = scalar(b[npoly + 1], Y[0], X, d) for i in range(k): for j in range(npoly): t3 -= (alpha[i * npoly + j] * phi(PP, ((2 * m[j] - m_prime[j]) * scalar(b[j], Y[i], X, d)).mod(X**d + 1), -i)).mod(X**d + 1) vpp += (alpha[i * npoly + j] * phi(PP, (scalar(b[j], Y[i], X, d)**2).mod(X**d + 1), -i)).mod(X**d + 1) h = g for mu in range(k): coef = X**mu / k coef_inner = 0 for nu in range(k): coef_inner += phi(PP, (d * gamma[mu] * sum(m[j] for j in range(npoly)) - gamma[mu]).mod(X**d + 1), nu) h += (coef * coef_inner).mod(X**d + 1) vulp = [0] * k for i in range(k): for mu in range(k): coef = X**mu / k coef_inner = 0 for nu in range(k): for j in range(npoly): coef_inner += phi(PP, scalar(vector_mult_by_scalar(b[j], d * gamma[mu]), Y[(i - nu) % k], X, d), nu) vulp[i] += (coef * coef_inner).mod(X**d + 1) vulp[i] += scalar(b[npoly], Y[i], X, d) c_hash = get_challenge_hash(PP, ag_hash, t3, vpp, h, vulp) c = get_challenge(PP, c_hash) Z, res_ok = _compute_z(PP, Y, c, r) if res_ok == 0 and inf_norm_matr(Z, PP.q) < PP.inf_bound1: break return (h, c_hash, Z), (t2, t3)
def sum_of_commitments(PP, S, T0, T1, public_seed): d = PP.d X = PP.X u = PP.u npoly = PP.npoly p = len(S) max_layers = ceil(log(p, u)) B0, b = gen_public_b(PP, public_seed) X_poly = list( list(T1[i][j] - scalar(b[j], S[i], X, d) for j in range(npoly)) for i in range(p)) S_amo = [] T0_amo = [] T1_amo = [] S_amo_zero = [] T0_amo_zero = [] T1_amo_zero = [] for i in range(p): S_amo.append(S[i]) T0_amo.append(T0[i]) T1_amo.append(T1[i]) r_seed = randombytes(PP.seedlen) nonce = 0 max_index = p offset = 0 for layer in range(1, max_layers + 1): blocks = ceil(p / u**layer) for block in range(blocks): start = block * u end = min((block + 1) * u, max_index) m = list( sum(X_poly[i][j] for i in range(start, end)) for j in range(npoly)) X_poly[block] = m t0, t1, r, nonce = commit(PP, B0, b, m, r_seed, nonce) t0_prime = list(t0[i] - sum(T0_amo[j + offset][i] for j in range(start, end)) for i in range(PP.kappa)) t1_prime = list(t1[i] - sum(T1_amo[j + offset][i] for j in range(start, end)) for i in range(npoly)) r_prime = list(r[i] - sum(S_amo[j + offset][i] for j in range(start, end)) for i in range(PP.baselen)) T0_amo.append(t0) T1_amo.append(t1) S_amo.append(r) T0_amo_zero.append(t0_prime) T1_amo_zero.append(t1_prime) S_amo_zero.append(r_prime) offset += max_index max_index = blocks R = PP.R amo_proof = proof_amo(PP, Matrix(R, S_amo).transpose(), Matrix(R, T0_amo).transpose(), len(T1_amo), public_seed) amo_zero_proof = proof_amo_to_zero(PP, Matrix(R, S_amo_zero).transpose(), Matrix(R, T0_amo_zero).transpose(), Matrix(R, T1_amo_zero).transpose(), len(T1_amo_zero), public_seed) return amo_proof, amo_zero_proof, (T0_amo[p:], T1_amo[p:]), S_amo[-1]
def verify_v(PP, proof, commitment, additional_com, public_seed): d = PP.d l = PP.l X = PP.X k = PP.k npoly = PP.npoly m_prime = _compute_m_prime(PP) B0, b = gen_public_b_with_extra(PP, public_seed) h, c_hash, Z = proof c = get_challenge(PP, c_hash) t0, t1 = commitment t2, t3 = additional_com if check_z_len(PP, Z): return 1 W = [0] * k f1 = [0] * k f2 = [0] * k for i in range(k): B0z = matrix_vector(B0, Z[i], X, d) w = [0] * PP.kappa for j in range(PP.kappa): w[j] = (B0z[j] - c * t0[j]).mod(X**d + 1) W[i] = w f1[i] = list((scalar(b[j], Z[i], X, d) - c * t1[j]).mod(X**d + 1) for j in range(npoly)) f2[i] = list((scalar(b[j], Z[i], X, d) - c * (t1[j] - m_prime[j])).mod(X**d + 1) for j in range(npoly)) if k != 1: c = phi(PP, c, 1) f3 = (scalar(b[npoly + 1], Z[0], X, d) - c * t3).mod(X**d + 1) hlist = h.list() for i in range(PP.g_zeros): if hlist[i] != 0: return 1 if k == 1: # PP.npoly should be 1 gamma, ag_hash = get_alpha_gamma(PP, t0, t1, t2, W) vpp = (f1[0][0] * f2[0][0] + f3).mod(X**d + 1) intt_factor = l * gamma tau = (intt_factor * sum(t1[i] for i in range(npoly)) - gamma).mod(X**d + 1) vulp = (scalar(list((intt_factor * sum(b[j][i] for j in range(npoly)) + b[npoly][i]) for i in range(PP.baselen)), Z[0], X, d) - c * (tau + t2 - h)).mod(X**d + 1) else: alpha, gamma, ag_hash = get_alpha_gamma(PP, t0, t1, t2, W) vpp = f3 for i in range(k): for j in range(npoly): vpp += (alpha[i * npoly + j] * phi(PP, (f1[i][j] * f2[i][j]).mod(X**d + 1), -i)).mod(X**d + 1) tau = 0 for mu in range(k): coef = X**mu / k coef_inner = 0 for nu in range(k): coef_inner += phi(PP, (d * gamma[mu] * sum(t1[j] for j in range(npoly)) - gamma[mu]).mod(X**d + 1), nu) tau += (coef * coef_inner).mod(X**d + 1) vulp = [0] * k for i in range(k): for mu in range(k): coef = X**mu / k coef_inner = 0 for nu in range(k): for j in range(npoly): coef_inner += phi(PP, scalar(vector_mult_by_scalar(b[j], d * gamma[mu]), Z[(i - nu) % k], X, d), nu) vulp[i] += (coef * coef_inner).mod(X**d + 1) vulp[i] += scalar(b[npoly], Z[i], X, d) vulp[i] -= (c * (tau + t2 - h)).mod(X**d + 1) c = phi(PP, c, 1) c_hash_prime = get_challenge_hash(PP, ag_hash, t3, vpp, h, vulp) if c_hash != c_hash_prime: return 1 return 0