def step3(gammas, alphas, alpha_randomness, As, Bs, ai, bi, r, s, dijs): """3) Every party ``P_i`` does: (a) compute ``c_i = SUM_j Dec_sk_i(gamma_ij) - SUM_j d_ji mod p`` (b) pick random ``t_i in (Z_p)^2``, compute and broadcast ``C_i = Com_ck(c_i, t_i)`` """ # c_i = SUM_j Dec_sk_i(gamma_ij) - SUM_j d_ji mod p. ls = [list(x) for x in zip(gammas, dijs)] ci = field(tripple_3a(ls, self.players[self.id].seckey)) # (b) pick random t_i in (Z_p)^2. t1 = random_number(field.modulus) t2 = random_number(field.modulus) t = (t1, t2) # C_i = Com_ck(c_i, t_i). Ci = commitment.commit(ci.value, t1.value, t2.value) # Broadcast Ci. Cs = self.broadcast(self.players.keys(), self.players.keys(), repr(Ci)) result = gatherResults(Cs) result.addCallbacks(step45, self.error_handler, callbackArgs=(alphas, gammas, alpha_randomness, As, Bs, ai, bi, ci, r, s, t, dijs)) return result
def __check_commitment(cls, commitment_str, row_id, permutation, salt, constant): """ check the reveal of a commitment to a permutation, """ # prepare the string that we are committing to message = str(row_id) message += ''.join([chr(el) for el in permutation]) # reperform commitment and check equality return commitment_str == commitment.commit(message, salt, constant)
def recombine_value(shares, Ca, Cb): a, b = 0, 0 rhoa1, rhob1 = 0, 0 rhoa2, rhob2 = 0, 0 for ai, rhoai1, rhoai2, bi, rhobi1, rhobi2 in shares: a += ai b += bi rhoa1 += rhoai1 rhob1 += rhobi1 rhoa2 += rhoai2 rhob2 += rhobi2 Ca1 = commitment.commit(a.value, rhoa1.value, rhoa2.value) Cb1 = commitment.commit(b.value, rhob1.value, rhob2.value) if Ca1 == Ca and Cb1 == Cb: return a, b else: #return x raise OrlandiException("Wrong commitment for value %s, %s, %s, %s, %s, %s, found %s, %s expected %s, %s." % (a, rhoa1, rhoa2, b, rhob1, rhob2, Ca1, Cb1, Ca, Cb))
def __check_commitment(cls, commitment_str, partition_id, instance_id, row_id, external_id, permutation, salt, constant): """ check the reveal of a commitment to a permutation, the "external_id" is the reference to the other table, either pid or rid """ # prepare the string that we are committing to message = chr(partition_id) + chr(instance_id) + str(row_id) + str(external_id) message += ''.join([chr(el) for el in permutation]) # reperform commitment and check equality return commitment_str == commitment.commit(message, salt, constant)
def _additive_constant(self, zero, field_element): """Greate an additive constant. Any additive constant can be interpreted as: ``[c]_1 = (c, 0, Com_ck(c,0))`` and ``[c]_i = (0, 0, Com_ck(c,0)) for i != 1``. """ v = zero if self.id == 1: v = field_element Cx = commitment.commit(field_element.value, zero.value, zero.value) return (v, (zero, zero), Cx)
def verify_code_openings(self, open_ballot, constant, code_callback_func = None): """ this ballot is the commitment, the other ballot is the opening. The code_callback_func, if present, is a function to call back: code_callback_func(web_serial_num, pid, question_id, symbol_id, confirmation_code) This is called only when a code is successfully verified, and enables bookkeeping of codes to show the voters in a verification interface. """ # pid match if self.pid != open_ballot.pid: return False # check opening of barcode serial number if it's there if hasattr(open_ballot, 'barcodeSerial') and open_ballot.barcodeSerial != None: if self.barcodeSerialCommitment != commitment.commit(str(self.pid) + " " + open_ballot.barcodeSerial, open_ballot.barcodeSerialSalt, constant): return false # check opening of web serial number if self.webSerialCommitment != commitment.commit(str(self.pid) + " " + open_ballot.webSerial, open_ballot.webSerialSalt, constant): return False # check opening of all marked codes for q_id, q in open_ballot.questions.iteritems(): # the symbols for this ballot committed_symbols = self.questions[q_id] # go through the open symbols for s_id, s in q.iteritems(): if committed_symbols[s_id]['c'] != commitment.commit(" ".join([str(self.pid), q_id, str(s_id), s['code']]), s['salt'], constant): return False # record the code for this ballot if code_callback_func: code_callback_func(open_ballot.webSerial, self.pid, q_id, s_id, s['code']) # only if all tests pass, then succeed return True
def recombine_value((shares, Cx)): x = 0 rho1 = 0 rho2 = 0 for xi, rhoi1, rhoi2 in shares: x += xi rho1 += rhoi1 rho2 += rhoi2 Cx1 = commitment.commit(x.value, rho1.value, rho2.value) if Cx1 == Cx: return x else: #return x raise OrlandiException("Wrong commitment for value %s, %s, %s, found %s expected %s." % (x, rho1, rho2, Cx1, Cx))
def random_share(self, field): """Generate a random share in the field, field. To generate a share of a random element ``r in Z_p``, party ``P_i`` chooses at random ``r_i, rho_ri in Z_p X (Z_p)^2`` and broadcast ``C_r^i = Com_ck(r_i, rho_ri)``. Every party computes ``C_r = PRODUCT_i=1^n C_r^i = Com_ck(r, rho_r)``, where ``r_i = SUM_i=1^n r_i and rho_r = SUM_i=1^n rho_ri``. Party ``P_i sets [r]_i = (r_i, rho_ri, C_r)``. """ self.increment_pc() # P_i chooses at random r_i, rho_ri in Z_p x (Z_p)^2 ri = field(rand.randint(0, field.modulus - 1)) rhoi1 = field(rand.randint(0, field.modulus - 1)) rhoi2 = field(rand.randint(0, field.modulus - 1)) # compute C_r^i = Com_ck(r_i, rho_ri). Cri = commitment.commit(ri.value, rhoi1, rhoi2) # Broadcast C_r^i. sls = gatherResults( self.broadcast(self.players.keys(), self.players.keys(), repr(Cri))) def compute_commitment(ls): Cr = reduce(operator.mul, ls) return OrlandiShare(self, field, ri, (rhoi1, rhoi2), Cr) def deserialize(ls): return [commitment.deserialize(x) for x in ls] sls.addCallbacks(deserialize, self.error_handler) sls.addCallbacks(compute_commitment, self.error_handler) s = Share(self, field) # We add the result to the chains in triple. sls.chainDeferred(s) # do actual communication self.activate_reactor() return s
def random_share(self, field): """Generate a random share in the field, field. To generate a share of a random element ``r in Z_p``, party ``P_i`` chooses at random ``r_i, rho_ri in Z_p X (Z_p)^2`` and broadcast ``C_r^i = Com_ck(r_i, rho_ri)``. Every party computes ``C_r = PRODUCT_i=1^n C_r^i = Com_ck(r, rho_r)``, where ``r_i = SUM_i=1^n r_i and rho_r = SUM_i=1^n rho_ri``. Party ``P_i sets [r]_i = (r_i, rho_ri, C_r)``. """ self.increment_pc() # P_i chooses at random r_i, rho_ri in Z_p x (Z_p)^2 ri = field(rand.randint(0, field.modulus - 1)) rhoi1 = field(rand.randint(0, field.modulus - 1)) rhoi2 = field(rand.randint(0, field.modulus - 1)) # compute C_r^i = Com_ck(r_i, rho_ri). Cri = commitment.commit(ri.value, rhoi1, rhoi2) # Broadcast C_r^i. sls = gatherResults(self.broadcast(self.players.keys(), self.players.keys(), repr(Cri))) def compute_commitment(ls): Cr = reduce(operator.mul, ls) return OrlandiShare(self, field, ri, (rhoi1, rhoi2), Cr) def deserialize(ls): return [ commitment.deserialize(x) for x in ls ] sls.addCallbacks(deserialize, self.error_handler) sls.addCallbacks(compute_commitment, self.error_handler) s = Share(self, field) # We add the result to the chains in triple. sls.chainDeferred(s) # do actual communication self.activate_reactor() return s
def _get_share(self, field, value): Cc = commitment.commit(value * 3, 0, 0) c = OrlandiShare(self, field, field(value), (field(0), field(0)), Cc) return c
def _constant(self, xi, x, field): """Greate a share *xi* with commitment to value *x*.""" zero = field(0) Cx = commitment.commit(x.value, 0, 0) return (xi, (zero, zero), Cx)
def secret_share(self, inputters, field, number=None): """Share the value *number* among all the parties using additive sharing. To share an element ``x in Z_p``, choose random ``x_1, ..., x_n-1 in Z_p``, define ``x_n = x - SUM_i=1^n-1 x_i mod p``. Choose random values ``rho_x1, ..., rho_xn in (Z_p)^2``, define ``rho_x = SUM_i=1^n rho_x,i`` and ``C_x = Com_ck(x, p_x)``. Send ``[x]_i = (x_i, rho_xi, C_x)`` to party ``P_i``. """ assert number is None or self.id in inputters self.increment_pc() def additive_shares_with_rho(x): """Returns a tuple of a list of tuples (player id, share, rho) and rho. Chooses random elements ``x_1, ..., x_n-1`` in field and ``x_n`` st. ``x_n = x - Sum_i=1^n-1 x_i``. Chooses random pair of elements ``rho_1, ..., rho_n in Z_p^2`` and define ``rho_n = Sum_i=1^n rho_i``. Returns a pair of ``((player id, x_i, rho_i), rho)``. """ shares = [] rhos = [] sum = 0 rho1 = 0 rho2 = 0 for i in xrange(1, self.num_players): xi = field(rand.randint(0, field.modulus - 1)) rhoi1 = field(rand.randint(0, field.modulus - 1)) rhoi2 = field(rand.randint(0, field.modulus - 1)) sum += xi rho1 += rhoi1 rho2 += rhoi2 shares.append((i, xi, (rhoi1, rhoi2))) xn = field(x) - sum rhon1 = field(rand.randint(0, field.modulus - 1)) rhon2 = field(rand.randint(0, field.modulus - 1)) shares.append((self.num_players, xn, (rhon1, rhon2))) rho1 += rhon1 rho2 += rhon2 return shares, (rho1, rho2) # Send ``[x]_i = (x_i, rho_x,i, C_x)`` to party ``P_i``. results = [] for peer_id in inputters: if peer_id == self.id: pc = tuple(self.program_counter) shares, rho = additive_shares_with_rho(number) Cx = commitment.commit(number, rho[0].value, rho[1].value) # Distribute the shares for other_id, xi, rhoi in shares: # Send ``xi``, ``rhoi``, and commitment self._send_orlandi_share(other_id, pc, xi, rhoi, Cx) # Expect ``xi``, ``rhoi``, and commitment results.append(self._expect_orlandi_share(peer_id, field)) # do actual communication self.activate_reactor() # Unpack a singleton list. if len(results) == 1: return results[0] return results
def step45(lists): """For all i in test_set the parties reveal the randomness used for TripleTest() and checks that the randomness is consistent with the actual values.""" M_without_test_set = lists[0] T = lists[1] def get_share(x, ls): share = ls[x * 4] rho1 = ls[x * 4 + 1] rho2 = ls[x * 4 + 2] commitment = ls[x * 4 + 3] return (share, rho1, rho2, commitment) def send_share(player_id, pc, a): self._send_orlandi_share(player_id, pc, a.share, a.rho, a.commitment) def receive_shares(player_id): Cx = Deferred() xi = self._expect_share(player_id, field) rho1 = self._expect_share(player_id, field) rho2 = self._expect_share(player_id, field) self._expect_data(player_id, TEXT, Cx) Cx.addCallbacks(commitment.deserialize, self.error_handler) return gatherResults([xi, rho1, rho2, Cx]) def send_long(player_id, pc, l): self.protocols[player_id].sendData(pc, TEXT, str(l)) def receive_long(player_id): l = Deferred() self._expect_data(player_id, TEXT, l) l.addCallbacks(long, self.error_handler) return l def check((ais, bis, cis, alpha_randomness, dijs), alphas, gammas): """So if B receives ai, bi, dij, ri, si, and the randomness used in the computation of alpha, he then checks that: 1) the alpha_i he received is equals to the encryption of ai and the commitment he received, Ai, is equal to the commitment of ai and ri 2) the commitment he received, Bj, is equal to the commitment of bj and sj 3) the gammaij he received is equal to the gammaij he now computes based on the values he reveives 4) a, b, c is a triple, a * b = c 5) ai, bi < p and dij < p^3 """ a = 0 a_rho1 = 0 a_rho2 = 0 b = 0 b_rho1 = 0 b_rho2 = 0 c = 0 c_rho1 = 0 c_rho2 = 0 for x in xrange(len(ais)): (ai, a_rhoi1, a_rhoi2, A) = ais[x] (bi, b_rhoi1, b_rhoi2, B) = bis[x] (ci, c_rhoi1, c_rhoi2, C) = cis[x] # 5) ai, bi < p... if ai >= field.modulus: raise OrlandiException( "Inconsistent share ai, ai >= p: %i" % ai) if bi >= field.modulus: raise OrlandiException( "Inconsistent share bi, bi >= p: %i" % bi) a += ai a_rho1 += a_rhoi1 a_rho2 += a_rhoi2 b += bi b_rho1 += b_rhoi1 b_rho2 += b_rhoi2 c += ci c_rho1 += c_rhoi1 c_rho2 += c_rhoi2 # 1) the alpha_i he received is equals to the encryption of ai... alphai = encrypt_r(ai.value, alpha_randomness[x], self.players[x + 1].pubkey) if not (alphas[x] == alphai): raise OrlandiException( "Inconsistent alpha from player %i, %i, %i" % (x + 1, alphas[x], alphai)) A1 = commitment.commit(a.value, a_rho1.value, a_rho2.value) B1 = commitment.commit(b.value, b_rho1.value, b_rho2.value) C1 = commitment.commit(c.value, c_rho1.value, c_rho2.value) # 1) ... and the commitment he received, Ai, is equal # to the commitment of ai and ri. if A1 != A: raise OrlandiException( "Inconsistent commitment for value %s, found %s expected %s." % (a, A1, A)) # 2) the commitment he received, Bj, is equal to the # commitment of bj and sj. if B1 != B: raise OrlandiException( "Inconsistent commitment for value %s, found %s expected %s." % (b, B1, B)) if C1 != C: raise OrlandiException( "Inconsistent commitment for value %s, found %s expected %s." % (c, C1, C)) # 4) a, b, c is a triple, a * b = c if a * b != c: raise OrlandiException( "Inconsistent triple, %i * %i does not equals %i." % (a, b, c)) # 3) the gammaij he received is equal to the gammaij # he now computes based on the values he reveives player = self.players[self.id] fixed_base = player.pubkey['fixed_base'] alpha = alphas[self.id - 1] modulus_3 = field.modulus**3 for j in xrange(len(ais)): dij = dijs[j] # 5) ... and dij < p^3. if dij >= (modulus_3): raise OrlandiException( "Inconsistent random value dij %i from player %i" % (dij, j + 1)) # gamma_ij = alpha_i^b_j Enc_ek_i(1;1)^d_ij # gammaij = tripple_2c(alphas[self.id - 1], bis[j][0].value, # dij, self.players[self.id].pubkey) gammaij = fixed_base.calc(dij, alpha, bis[j][0].value) if gammaij != gammas[j]: raise OrlandiException("Inconsistent gammaij, %i, %i" % (gammaij, gammas[j])) return True
# 1) Every party P_i chooses random values a_i, r_i in Z_p X (Z_p)^2, # compute alpha_i = Enc_eki(a_i) and Ai = Com_ck(a_i, r_i), and # broadcast them. # Every party P_i chooses random values a_i, r_i in Z_p X (Z_p)^2 ai = random_number(field.modulus) r1 = random_number(field.modulus) r2 = random_number(field.modulus) # compute alpha_i = Enc_eki(a_i) pubkey = self.players[self.id].pubkey alpha_randomness = rand.randint(1, long(pubkey['n'])) alphai = encrypt_r(ai.value, alpha_randomness, pubkey) # and A_i = Com_ck(a_i, r_i). Ai = commitment.commit(ai.value, r1.value, r2.value) # choose random b_j, s_j in Z_p X (Z_p)^2. bj = random_number(field.modulus) s1 = random_number(field.modulus) s2 = random_number(field.modulus) # compute B_j = Com_ck(b_j, s_j). Bj = commitment.commit(bj.value, s1.value, s2.value) # broadcast alpha_i, A_i, B_j. ds = self.broadcast(sorted(self.players.keys()), sorted(self.players.keys()), str(alphai) + ":" + repr(Ai) + ":" + repr(Bj)) alphas_As_Bs = gatherResults(ds)
# 1) Every party P_i chooses random values a_i, r_i in Z_p X (Z_p)^2, # compute alpha_i = Enc_eki(a_i) and Ai = Com_ck(a_i, r_i), and # broadcast them. # Every party P_i chooses random values a_i, r_i in Z_p X (Z_p)^2 ai = random_number(field.modulus) r1 = random_number(field.modulus) r2 = random_number(field.modulus) # compute alpha_i = Enc_eki(a_i) pubkey = self.players[self.id].pubkey alpha_randomness = rand.randint(1, long(pubkey['n'])) alphai = encrypt_r(ai.value, alpha_randomness, pubkey) # and A_i = Com_ck(a_i, r_i). Ai = commitment.commit(ai.value, r1.value, r2.value) # choose random b_j, s_j in Z_p X (Z_p)^2. bj = random_number(field.modulus) s1 = random_number(field.modulus) s2 = random_number(field.modulus) # compute B_j = Com_ck(b_j, s_j). Bj = commitment.commit(bj.value, s1.value, s2.value) # broadcast alpha_i, A_i, B_j. ds = self.broadcast(sorted(self.players.keys()), sorted(self.players.keys()), str(alphai) + ":" + repr(Ai) + ":" + repr(Bj)) alphas_As_Bs = gatherResults(ds) def split_alphas_As_Bs(ls):
def step45(lists): """For all i in test_set the parties reveal the randomness used for TripleTest() and checks that the randomness is consistent with the actual values.""" M_without_test_set = lists[0] T = lists[1] def get_share(x, ls): share = ls[x * 4] rho1 = ls[x * 4 + 1] rho2 = ls[x * 4 + 2] commitment = ls[x * 4 + 3] return (share, rho1, rho2, commitment) def send_share(player_id, pc, a): self._send_orlandi_share(player_id, pc, a.share, a.rho, a.commitment) def receive_shares(player_id): Cx = Deferred() xi = self._expect_share(player_id, field) rho1 = self._expect_share(player_id, field) rho2 = self._expect_share(player_id, field) self._expect_data(player_id, TEXT, Cx) Cx.addCallbacks(commitment.deserialize, self.error_handler) return gatherResults([xi, rho1, rho2, Cx]) def send_long(player_id, pc, l): self.protocols[player_id].sendData(pc, TEXT, str(l)) def receive_long(player_id): l = Deferred() self._expect_data(player_id, TEXT, l) l.addCallbacks(long, self.error_handler) return l def check((ais, bis, cis, alpha_randomness, dijs), alphas, gammas): """So if B receives ai, bi, dij, ri, si, and the randomness used in the computation of alpha, he then checks that: 1) the alpha_i he received is equals to the encryption of ai and the commitment he received, Ai, is equal to the commitment of ai and ri 2) the commitment he received, Bj, is equal to the commitment of bj and sj 3) the gammaij he received is equal to the gammaij he now computes based on the values he reveives 4) a, b, c is a triple, a * b = c 5) ai, bi < p and dij < p^3 """ a = 0 a_rho1 = 0 a_rho2 = 0 b = 0 b_rho1 = 0 b_rho2 = 0 c = 0 c_rho1 = 0 c_rho2 = 0 for x in xrange(len(ais)): (ai, a_rhoi1, a_rhoi2, A) = ais[x] (bi, b_rhoi1, b_rhoi2, B) = bis[x] (ci, c_rhoi1, c_rhoi2, C) = cis[x] # 5) ai, bi < p... if ai >= field.modulus: raise OrlandiException("Inconsistent share ai, ai >= p: %i" % ai) if bi >= field.modulus: raise OrlandiException("Inconsistent share bi, bi >= p: %i" % bi) a += ai a_rho1 += a_rhoi1 a_rho2 += a_rhoi2 b += bi b_rho1 += b_rhoi1 b_rho2 += b_rhoi2 c += ci c_rho1 += c_rhoi1 c_rho2 += c_rhoi2 # 1) the alpha_i he received is equals to the encryption of ai... alphai = encrypt_r(ai.value, alpha_randomness[x], self.players[x + 1].pubkey) if not(alphas[x] == alphai): raise OrlandiException("Inconsistent alpha from player %i, %i, %i" % (x + 1, alphas[x], alphai)) A1 = commitment.commit(a.value, a_rho1.value, a_rho2.value) B1 = commitment.commit(b.value, b_rho1.value, b_rho2.value) C1 = commitment.commit(c.value, c_rho1.value, c_rho2.value) # 1) ... and the commitment he received, Ai, is equal # to the commitment of ai and ri. if A1 != A: raise OrlandiException("Inconsistent commitment for value %s, found %s expected %s." % (a, A1, A)) # 2) the commitment he received, Bj, is equal to the # commitment of bj and sj. if B1 != B: raise OrlandiException("Inconsistent commitment for value %s, found %s expected %s." % (b, B1, B)) if C1 != C: raise OrlandiException("Inconsistent commitment for value %s, found %s expected %s." % (c, C1, C)) # 4) a, b, c is a triple, a * b = c if a * b != c: raise OrlandiException("Inconsistent triple, %i * %i does not equals %i." % (a, b, c)) # 3) the gammaij he received is equal to the gammaij # he now computes based on the values he reveives player = self.players[self.id] fixed_base = player.pubkey['fixed_base'] alpha = alphas[self.id - 1] modulus_3 = field.modulus**3 for j in xrange(len(ais)): dij = dijs[j] # 5) ... and dij < p^3. if dij >= (modulus_3): raise OrlandiException("Inconsistent random value dij %i from player %i" % (dij, j + 1)) # gamma_ij = alpha_i^b_j Enc_ek_i(1;1)^d_ij # gammaij = tripple_2c(alphas[self.id - 1], bis[j][0].value, # dij, self.players[self.id].pubkey) gammaij = fixed_base.calc(dij, alpha, bis[j][0].value) if gammaij != gammas[j]: raise OrlandiException("Inconsistent gammaij, %i, %i" % (gammaij, gammas[j])) return True