def ProveOneOfN(ck, cis, el, r, message=""): """ NIZK Proof that Com(0; r) is within Cis. The fact that it is the el'th commitmtnet is not revealed. + Ring signature on "message". """ n = int(math.ceil(math.log(len(cis)) / math.log(2))) assert Com(ck, 0, r) == cis[el] (G, g, h, o) = ck ## Commit to the bits of the index el = Bn(el) eli = [Bn(int(el.is_bit_set(i))) for i in range(n)] ri = [o.random() for i in range(n)] ai = [o.random() for i in range(n)] si = [o.random() for i in range(n)] ti = [o.random() for i in range(n)] Celi = [Com(ck, elix, rix) for elix, rix in zip(eli, ri)] Cai = [Com(ck, a, s) for a, s in zip(ai, si)] Cbi = [Com(ck, l * a, s) for l, a, s in zip(eli, ai, ti)] # Compute p_idxi(x) p_idx_i = [] for idx in range(len(cis)): idx = Bn(idx) idxi = [Bn(int(idx.is_bit_set(i))) for i in range(n)] p = [Bn(1)] for j, idxi_j in enumerate(idxi): if idxi_j == 0: p = poly_mul(o, p, [-ai[j], -eli[j] + 1]) else: p = poly_mul(o, p, [ai[j], eli[j]]) p_idx_i += [p] # Compute all Cdi's roi = [] cdi = [] for i in range(n): roi_i = o.random() roi += [roi_i] # cdi_i = Com(ck, 0, roi_i) wis = [] for idx, cidx in enumerate(cis): wis += [p_idx_i[idx][i]] # cdi_i += p_idx_i[idx][i] * cidx # assert G.wsum(wis, cis) + Com(ck, 0, roi_i) == cdi_i cdi_i = G.wsum(wis, cis) + Com(ck, 0, roi_i) cdi += [cdi_i] ## The challenge x = challenge(list(ck) + cis + Celi + Cai + Cbi + cdi + [message]) ## The responses fi = [(elj * x + aj) % o for elj, aj in zip(eli, ai)] zai = [(rj * x + sj) % o for rj, sj in zip(ri, si)] zbi = [(rj * (x - fj) + tj) % o for rj, fj, tj in zip(ri, fi, ti)] zd = r * pow(x, n, o) % o for k in range(n): zd = (zd - roi[k] * pow(x, k, o)) % o proof = (Celi, Cai, Cbi, cdi, fi, zai, zbi, zd) return proof
def ProveOneOfN(ck, cis, el, r, message = ""): """ NIZK Proof that Com(0; r) is within Cis. The fact that it is the el'th commitmtnet is not revealed. + Ring signature on "message". """ n = int(math.ceil(math.log(len(cis)) / math.log(2))) assert Com(ck, 0, r) == cis[el] (G, g, h, o) = ck ## Commit to the bits of the index el = Bn(el) eli = [Bn(int(el.is_bit_set(i))) for i in range(n)] ri = [o.random() for i in range(n)] ai = [o.random() for i in range(n)] si = [o.random() for i in range(n)] ti = [o.random() for i in range(n)] Celi = [Com(ck, elix, rix) for elix, rix in zip(eli, ri)] Cai = [Com(ck, a, s) for a, s in zip(ai, si)] Cbi = [Com(ck, l * a , s) for l, a, s in zip(eli, ai, ti)] # Compute p_idxi(x) p_idx_i = [] for idx in range(len(cis)): idx = Bn(idx) idxi = [Bn(int(idx.is_bit_set(i))) for i in range(n)] p = [Bn(1)] for j, idxi_j in enumerate(idxi): if idxi_j == 0: p = poly_mul(o, p, [ -ai[j] , - eli[j] + 1] ) else: p = poly_mul(o, p, [ ai[j] , eli[j] ]) p_idx_i += [p] # Compute all Cdi's roi = [] cdi = [] for i in range(n): roi_i = o.random() roi += [ roi_i ] # cdi_i = Com(ck, 0, roi_i) wis = [] for idx, cidx in enumerate(cis): wis += [ p_idx_i[idx][i] ] # cdi_i += p_idx_i[idx][i] * cidx # assert G.wsum(wis, cis) + Com(ck, 0, roi_i) == cdi_i cdi_i = G.wsum(wis, cis) + Com(ck, 0, roi_i) cdi += [ cdi_i ] ## The challenge x = challenge(list(ck) + cis + Celi + Cai + Cbi + cdi + [ message ]) ## The responses fi = [(elj * x + aj) % o for elj, aj in zip(eli, ai)] zai = [(rj * x + sj) % o for rj, sj in zip(ri, si)] zbi = [(rj * (x - fj) + tj) % o for rj, fj, tj in zip(ri, fi, ti)] zd = r * pow(x, n, o) % o for k in range(n): zd = (zd - roi[k] * pow(x, k, o)) % o proof = (Celi, Cai, Cbi, cdi, fi, zai, zbi, zd) return proof
def VerifyOneOfN(ck, cis, proof, message=""): """ Verify the ring signature on message """ n = int(math.ceil(math.log(len(cis)) / math.log(2))) (G, g, h, o) = ck (Celi, Cai, Cbi, cdi, fi, zai, zbi, zd) = proof ## Check all parts of the proof are in the right groups assert 0 <= zd < o for k in range(n): assert 0 <= fi[k] < o assert 0 <= zai[k] < o assert 0 <= zbi[k] < o assert G.check_point(Celi[k]) assert G.check_point(Cai[k]) assert G.check_point(Cbi[k]) assert G.check_point(cdi[k]) # Recompute the challenge x = challenge(list(ck) + cis + Celi + Cai + Cbi + cdi + [message]) ret = True for i in range(n): ret &= x * Celi[i] + Cai[i] == Com(ck, fi[i], zai[i]) ret &= (x - fi[i]) * Celi[i] + Cbi[i] == Com(ck, Bn(0), zbi[i]) # acc = G.infinite() bases = [] expons = [] for idx, ci in enumerate(cis): idx = Bn(idx) idxi = [Bn(int(idx.is_bit_set(i))) for i in range(n)] acc_exp = Bn(1) for k, ij in enumerate(idxi): if ij == 0: acc_exp = acc_exp.mod_mul(x - fi[k], o) else: acc_exp = acc_exp.mod_mul(fi[k], o) bases += [ci] expons += [acc_exp] # acc = acc + acc_exp * ci for k in range(n): expi = (-pow(x, k, o)) # acc = acc + expi * cdi[k] bases += [cdi[k]] expons += [expi] # assert G.wsum(expons, bases) == acc acc = G.wsum(expons, bases) ret &= acc == Com(ck, 0, zd) return ret
def VerifyOneOfN(ck, cis, proof, message = ""): """ Verify the ring signature on message """ n = int(math.ceil(math.log(len(cis)) / math.log(2))) (G, g, h, o) = ck (Celi, Cai, Cbi, cdi, fi, zai, zbi, zd) = proof ## Check all parts of the proof are in the right groups assert 0 <= zd < o for k in range(n): assert 0 <= fi[k] < o assert 0 <= zai[k] < o assert 0 <= zbi[k] < o assert G.check_point(Celi[k]) assert G.check_point(Cai[k]) assert G.check_point(Cbi[k]) assert G.check_point(cdi[k]) # Recompute the challenge x = challenge(list(ck) + cis + Celi + Cai + Cbi + cdi + [ message ]) ret = True for i in range(n): ret &= x * Celi[i] + Cai[i] == Com(ck, fi[i], zai[i]) ret &= (x - fi[i]) * Celi[i] + Cbi[i] == Com(ck, Bn(0), zbi[i]) # acc = G.infinite() bases = [] expons = [] for idx, ci in enumerate(cis): idx = Bn(idx) idxi = [Bn(int(idx.is_bit_set(i))) for i in range(n)] acc_exp = Bn(1) for k, ij in enumerate(idxi): if ij == 0: acc_exp = acc_exp.mod_mul(x - fi[k], o) else: acc_exp = acc_exp.mod_mul(fi[k], o) bases += [ ci ] expons += [ acc_exp ] # acc = acc + acc_exp * ci for k in range(n): expi = (- pow(x,k,o)) # acc = acc + expi * cdi[k] bases += [ cdi[k] ] expons += [ expi ] # assert G.wsum(expons, bases) == acc acc = G.wsum(expons, bases) ret &= acc == Com(ck, 0, zd) return ret