def add_signature_checker(inputs, reference_inputs, parameters, outputs, returns, dependencies): try: print "CHECKING - parameters " + str(parameters) # retrieve petition old_signature = loads(inputs[0]) new_signature = loads(outputs[0]) num_options = len(old_signature['options']) # check format if len(inputs) != 1 or len(reference_inputs) != 0 or len( outputs) != 1 or len(returns) != 0: return False if num_options != len(new_signature['scores']) or num_options != len( new_signature['scores']): return False if old_signature['tally_pub'] != new_signature['tally_pub']: return False print "CHECKING - tokens" if new_signature['type'] != 'PetitionEncObject': return False print "CHECKING - Generate params" # generate params, retrieve tally's public key and the parameters params = setup() tally_pub = unpack(old_signature['tally_pub']) added_signature = loads(parameters[0]) proof_bin = loads(parameters[1]) proof_sum = unpack(parameters[2]) print "CHECKING - verify proofs of binary (Signatures have to be bin values)" for i in range(0, num_options): if not verifybin(params, tally_pub, unpack(added_signature[i]), unpack(proof_bin[i])): return False print "CHECKING - verify proof of sum of signatures (sum of signatures has to be 1)" sum_a, sum_b = unpack(added_signature[-1]) sum_c = (sum_a, sum_b) for i in range(0, num_options - 1): sum_c = add(sum_c, unpack(added_signature[i])) if not verifyone(params, tally_pub, sum_c, proof_sum): return False print "CHECKING - verify that output == input + signature" for i in range(0, num_options): tmp_c = add(unpack(old_signature['scores'][i]), unpack(added_signature[i])) if not new_signature['scores'][i] == pack(tmp_c): return False # otherwise return True except (KeyError, Exception): return False
def add_signature(inputs, reference_inputs, parameters, added_signature): old_signature = loads(inputs[0]) new_signature = loads(inputs[0]) added_signature = loads(added_signature) params = setup() tally_pub = unpack(old_signature['tally_pub']) # encrypt signatures & proofs to build enc_added_signatures = [] # encrypted signatures proof_bin = [ ] # signatures are binary, well-formed, and the prover know the signature's value sum_a, sum_b, sum_k = (0, 0, 0) # sum of signatures equals 1 # loop over signatures for i in range(0, len(added_signature)): # encrypt added signature (a, b, k) = binencrypt(params, tally_pub, added_signature[i]) c = (a, b) enc_added_signatures.append(pack(c)) # update new scores new_c = add(unpack(old_signature['scores'][i]), c) new_signature['scores'][i] = pack(new_c) # construct proof of binary tmp1 = provebin(params, tally_pub, (a, b), k, added_signature[i]) proof_bin.append(pack(tmp1)) # update sum of signature if i == 0: sum_a, sum_b, sum_k = (a, b, k) else: sum_c = (sum_a, sum_b) sum_a, sum_b, sum_k = add_side(sum_c, c, sum_k, k) # build proof that sum of signatures equals 1 sum_c = (sum_a, sum_b) proof_sum = proveone(params, tally_pub, sum_c, sum_k) # compute signature (G, _, _, _) = params hasher = sha256() hasher.update(dumps(old_signature).encode('utf8')) hasher.update(dumps(enc_added_signatures).encode('utf8')) # return return { 'outputs': (dumps(new_signature), ), 'extra_parameters': (dumps(enc_added_signatures), dumps(proof_bin), pack(proof_sum)) }
def add_vote(inputs, reference_inputs, parameters, added_vote, voter_priv, voter_pub): # retrieve old vote & init new vote object old_vote = loads(inputs[0]) new_vote = loads(inputs[0]) added_vote = loads(added_vote) # generate params & retrieve tally's public key params = setup() tally_pub = unpack(old_vote['tally_pub']) # encrypt votes & proofs to build enc_added_votes = [] # encrypted votes proof_bin = [ ] # votes are binary, well-formed, and the prover know the vote's value sum_a, sum_b, sum_k = (0, 0, 0) # sum of votes equals 1 # loop over votes for i in range(0, len(added_vote)): # encrypt added vote (a, b, k) = binencrypt(params, tally_pub, added_vote[i]) c = (a, b) enc_added_votes.append(pack(c)) # update new scores new_c = add(unpack(old_vote['scores'][i]), c) new_vote['scores'][i] = pack(new_c) # construct proof of binary tmp1 = provebin(params, tally_pub, (a, b), k, added_vote[i]) proof_bin.append(pack(tmp1)) # update sum of votes if i == 0: sum_a, sum_b, sum_k = (a, b, k) else: sum_c = (sum_a, sum_b) sum_a, sum_b, sum_k = add_side(sum_c, c, sum_k, k) # build proof that sum of votes equals 1 sum_c = (sum_a, sum_b) proof_sum = proveone(params, tally_pub, sum_c, sum_k) # remove voter from participants new_vote['participants'].remove(voter_pub) # compute signature (G, _, _, _) = params hasher = sha256() hasher.update(dumps(old_vote).encode('utf8')) hasher.update(dumps(enc_added_votes).encode('utf8')) sig = do_ecdsa_sign(G, unpack(voter_priv), hasher.digest()) # return return { 'outputs': (dumps(new_vote), ), 'extra_parameters': { 'votes': dumps(enc_added_votes), 'signature': pack(sig), 'voter_pub': voter_pub, # already packed 'proof_bin': dumps(proof_bin), 'proof_sum': pack(proof_sum) } }
def add_vote_checker(inputs, reference_inputs, parameters, outputs, returns, dependencies): try: # retrieve vote old_vote = loads(inputs[0]) new_vote = loads(outputs[0]) num_votes = len(old_vote['options']) # check format if len(inputs) != 1 or len(reference_inputs) != 0 or len( outputs) != 1 or len(returns) != 0: return False if num_votes != len(new_vote['scores']) or num_votes != len( new_vote['scores']): return False if new_vote['participants'] == None: return False if old_vote['tally_pub'] != new_vote['tally_pub']: return False # check tokens if new_vote['type'] != 'VoteObject': return False # check that voter has been removed from participants if not parameters['voter_pub'] in old_vote['participants']: return False if parameters['voter_pub'] in new_vote['participants']: return False if len(old_vote['participants']) != len(new_vote['participants']) + 1: return False # generate params, retrieve tally's public key and the parameters params = setup() tally_pub = unpack(old_vote['tally_pub']) added_vote = loads(parameters['votes']) sig = unpack(parameters['signature']) voter_pub = unpack(parameters['voter_pub']) proof_bin = loads(parameters['proof_bin']) proof_sum = unpack(parameters['proof_sum']) # verify signature (G, _, _, _) = params hasher = sha256() hasher.update(dumps(old_vote).encode('utf8')) hasher.update(dumps(added_vote).encode('utf8')) if not do_ecdsa_verify(G, voter_pub, sig, hasher.digest()): return False # verify proofs of binary (votes have to be bin values) for i in range(0, num_votes): if not verifybin(params, tally_pub, unpack(added_vote[i]), unpack(proof_bin[i])): return False # verify proof of sum of votes (sum of votes has to be 1) sum_a, sum_b = unpack(added_vote[-1]) sum_c = (sum_a, sum_b) for i in range(0, num_votes - 1): sum_c = add(sum_c, unpack(added_vote[i])) if not verifyone(params, tally_pub, sum_c, proof_sum): return False # verify that output == input + vote for i in range(0, num_votes): tmp_c = add(unpack(old_vote['scores'][i]), unpack(added_vote[i])) if not new_vote['scores'][i] == pack(tmp_c): return False # otherwise return True except (KeyError, Exception): return False