示例#1
0
def add_reading(inputs, reference_inputs, parameters, meter_priv, reading,
                opening):

    # compute output
    old_meter = loads(inputs[0])
    new_meter = loads(inputs[0])

    # create commitement to the reading
    (G, g, (h0, _, _, _), _) = setup()
    commitment = loads(reading) * g + unpack(opening) * h0

    # update readings
    new_meter['readings'].append(pack(commitment))

    # hash message to sign
    hasher = sha256()
    hasher.update(dumps(old_meter).encode('utf8'))
    hasher.update(dumps(pack(commitment)).encode('utf8'))

    # sign message
    sig = do_ecdsa_sign(G, unpack(meter_priv), hasher.digest())

    # return
    return {
        'outputs': (dumps(new_meter), ),
        'extra_parameters': {
            'reading': pack(commitment),
            'signature': pack(sig)
        }
    }
示例#2
0
def create_petition_checker(inputs, reference_inputs, parameters, outputs,
                            returns, dependencies):
    try:

        # retrieve petition
        petition = loads(outputs[1])
        num_options = len(petition['options'])

        print "CHECKING (create) - check format"
        if len(inputs) != 1 or len(reference_inputs) != 0 or len(
                outputs) != 2 or len(returns) != 0:
            return False
        if num_options < 1 or num_options != len(petition['scores']):
            return False

        print "CHECKING (create) - check tokens"
        if loads(inputs[0])['type'] != 'PetitionEncToken' or loads(
                outputs[0])['type'] != 'PetitionEncToken':
            return False
        if petition['type'] != 'PetitionEncObject':
            return False

        print "CHECKING (create) - check proof"
        params = setup()
        proof_init = unpack(parameters[0])
        tally_pub = unpack(petition['tally_pub'])
        for value in petition['scores']:
            if not verifyzero(params, tally_pub, unpack(value), proof_init):
                return False

        # otherwise
        return True

    except (KeyError, Exception):
        return False
示例#3
0
文件: vote.py 项目: alxd112/byzcuit
def create_vote(inputs, reference_inputs, parameters, options, participants,
                tally_priv, tally_pub):

    # genrate param
    params = setup()
    pub = unpack(tally_pub)

    # encrypt initial score
    (a, b, k) = binencrypt(params, pub, 0)  # encryption of a zero
    c = (a, b)
    scores = [pack(c) for _ in loads(options)]

    # new vote object
    new_vote = {
        'type': 'VoteObject',
        'options': loads(options),
        'scores': scores,
        'participants': loads(participants),
        'tally_pub': tally_pub
    }

    # proof that all init values are zero
    proof_init = provezero(params, pub, c, unpack(tally_priv))

    # return
    return {
        'outputs': (inputs[0], dumps(new_vote)),
        'extra_parameters': {
            'proof_init': pack(proof_init)
        }
    }
示例#4
0
def validate_sig(sig, pub, msg="proof"):
    # check that the signature on the proof is correct
    hasher = sha256()
    hasher.update(msg)
    # verify signature
    (G, _, _, _) = setup()
    if not do_ecdsa_verify(G, unpack(pub), unpack(sig), hasher.digest()):
        raise Exception("Invalid signature")
示例#5
0
def transfer_checker(inputs, reference_inputs, parameters, outputs, returns, dependencies):
    try:
        amount = loads(parameters[0])
        input_from_account = loads(inputs[0])
        input_to_account = loads(inputs[1])
        output_from_account = loads(outputs[0])
        output_to_account = loads(outputs[1])
        
        # check format
        if len(inputs) != 2 or len(reference_inputs) != 0 or len(outputs) != 2 or len(returns) != 0:
            return False

        if input_from_account['pub'] != output_from_account['pub'] or input_to_account['pub'] != output_to_account['pub']:
            return False

        # check tokens
        if input_from_account['type'] != 'BankAccount' or input_to_account['type'] != 'BankAccount':
            return False
        if output_from_account['type'] != 'BankAccount' or output_to_account['type'] != 'BankAccount':
            return False

        # amount transfered should be non-negative
        if amount < 0:
            return False

        # amount transfered should not exceed balance
        if input_from_account['balance'] < amount:
            return False

        # consistency between inputs and outputs
        if input_from_account['balance'] != output_from_account['balance'] + amount:
            return False
        if input_to_account['balance'] != output_to_account['balance'] - amount:
            return False

        # verify transaction
        if input_from_account['callback'] == None:
            sig = unpack(parameters[1])
            pub = unpack(input_from_account['pub'])
            hasher = sha256()
            hasher.update(dumps(inputs).encode('utf8'))
            hasher.update(dumps(parameters[0]).encode('utf8'))
            G = setup()[0]
            if not do_ecdsa_verify(G, pub, sig, hasher.digest()): return False
        else:
            # verify depend transaction -- specified by 'callback'
            # NOTE: the checker of the dependency is automatcally called
            callback = dependencies[0]
            if callback['contractID']+'.'+callback['methodID'] != input_from_account['callback']: return False
            # NOTE: this is not enough -- this only verifes that a particular process has been called,
            # we also need to verify the inputs of that process: e.g., verifying that a bank transfer has been done
            # is useless if you don't verify the beneficiary. Any idea ?

        # otherwise
        return True

    except (KeyError, Exception):
        return False
示例#6
0
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 auth_transfer_checker(inputs, reference_inputs, parameters, outputs, returns, dependencies):
    try:
        amount = loads(parameters[0])
        input_from_account = loads(inputs[0])
        input_to_account = loads(inputs[1])
        output_from_account = loads(outputs[0])
        output_to_account = loads(outputs[1])
        sig = unpack(parameters[1])

        # check format
        if len(inputs) != 2 or len(reference_inputs) != 0 or len(outputs) != 2 or len(returns) != 0:
            return False
        if input_from_account['pub'] != output_from_account['pub'] or input_to_account['pub'] != output_to_account['pub']:
            return False

        # check tokens
        if input_from_account['type'] != 'BankAccount' or input_to_account['type'] != 'BankAccount':
            return False
        if output_from_account['type'] != 'BankAccount' or output_to_account['type'] != 'BankAccount':
            return False

        # amount transfered should be non-negative
        if amount < 0:
            return False

        # amount transfered should not exceed balance
        if input_from_account['balance'] < amount:
            return False

        # consistency between inputs and outputs
        if input_from_account['balance'] != output_from_account['balance'] + amount:
            return False
        if input_to_account['balance'] != output_to_account['balance'] - amount:
            return False


        # hash message to verify signature
        hasher = sha256()
        hasher.update(dumps(inputs).encode('utf8'))
        hasher.update(dumps(reference_inputs).encode('utf8'))
        hasher.update(dumps(parameters[0]).encode('utf8'))

        # recompose signed digest
        pub = unpack(input_from_account['pub'])

        # verify signature
        (G, _, _, _) = setup()
        return do_ecdsa_verify(G, pub, sig, hasher.digest())

        return True

    except (KeyError, Exception):
        return False
示例#8
0
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
示例#9
0
def compute_bill(inputs, reference_inputs, parameters, readings, openings,
                 tariffs):

    # get meter
    meter = loads(inputs[0])

    # compute total bill
    G = setup()[0]
    total_bill = sum(r * t for r, t in zip(loads(readings), loads(tariffs)))
    sum_openings = sum(
        o * t for o, t in zip(unpack(openings), loads(tariffs))) % G.order()

    # new bill
    bill = {
        'type': 'SMBill',
        'info': meter['info'],
        'total_bill': total_bill,
        'billing_period': meter['billing_period'],
        'tariffs': meter['tariffs']
    }

    # return
    return {
        'outputs': (dumps(bill), ),
        'extra_parameters': {
            'total_bill': dumps(total_bill),
            'sum_openings': pack(sum_openings),
        }
    }
示例#10
0
文件: vote.py 项目: alxd112/byzcuit
def tally_checker(inputs, reference_inputs, parameters, outputs, returns,
                  dependencies):
    try:

        # retrieve vote
        vote = loads(inputs[0])
        result = loads(outputs[0])

        # check format
        if len(inputs) != 1 or len(reference_inputs) != 0 or len(
                outputs) != 1 or len(returns) != 0:
            return False
        if len(vote['options']) != len(result['outcome']):
            return False

        # check tokens
        if result['type'] != 'VoteResult':
            return False

        # generate params, retrieve tally's public key and the parameters
        params = setup()
        (G, _, (h0, _, _, _), _) = params
        tally_pub = unpack(vote['tally_pub'])
        sig = unpack(parameters['signature'])
        proof_dec = loads(parameters['proof_dec'])
        outcome = result['outcome']

        # verify proof of correct decryption
        for i in range(0, len(vote['scores'])):
            a, b = unpack(vote['scores'][i])
            ciphertext = (a, b - outcome[i] * h0)
            if not verifyzero(params, tally_pub, ciphertext,
                              unpack(proof_dec[i])):
                return False

        # verify signature
        hasher = sha256()
        hasher.update(dumps(vote).encode('utf8'))
        hasher.update(dumps(result['outcome']).encode('utf8'))
        if not do_ecdsa_verify(G, tally_pub, sig, hasher.digest()):
            return False

        # otherwise
        return True

    except (KeyError, Exception):
        return False
示例#11
0
def add_reading_checker(inputs, reference_inputs, parameters, outputs, returns,
                        dependencies):
    try:

        # get objects
        old_meter = loads(inputs[0])
        new_meter = loads(outputs[0])

        # check format
        if len(inputs) != 1 or len(reference_inputs) != 0 or len(
                outputs) != 1 or len(returns) != 0:
            return False
        if old_meter['pub'] != new_meter['pub'] or old_meter[
                'info'] != new_meter['info']:
            return False
        if old_meter['tariffs'] != new_meter['tariffs'] or old_meter[
                'billing_period'] != new_meter['billing_period']:
            return False

        # check tokens
        if old_meter['type'] != new_meter['type']:
            return False

        # check readings' consistency
        if new_meter['readings'] != old_meter['readings'] + [
                parameters['reading']
        ]:
            return False

        # hash message to sign
        hasher = sha256()
        hasher.update(dumps(old_meter).encode('utf8'))
        hasher.update(dumps(parameters['reading']).encode('utf8'))

        # verify signature
        G = setup()[0]
        pub = unpack(old_meter['pub'])
        sig = unpack(parameters['signature'])
        if not do_ecdsa_verify(G, pub, sig, hasher.digest()):
            return False

        # otherwise
        return True

    except (KeyError, Exception):
        return False
示例#12
0
def generate_sig(priv, msg="proof"):
    hasher = sha256()
    hasher.update(msg)

    # sign message
    G = setup()[0]
    sig = do_ecdsa_sign(G, unpack(priv), hasher.digest())
    return pack(sig)
示例#13
0
def compute_bill_checker(inputs, reference_inputs, parameters, outputs,
                         returns, dependencies):
    try:

        # get objects
        meter = loads(inputs[0])
        bill = loads(outputs[0])

        # check format
        if len(inputs) != 1 or len(reference_inputs) != 0 or len(
                outputs) != 1 or len(returns) != 0:
            return False
        if meter['billing_period'] != bill['billing_period'] or meter[
                'info'] != bill['info']:
            return False
        if meter['tariffs'] != bill['tariffs']:
            return False
        if bill['total_bill'] != loads(parameters['total_bill']):
            return False

        # check tokens
        if bill['type'] != 'SMBill':
            return False

        # get objects
        tariffs = bill['tariffs']
        commitements = meter['readings']
        sum_openings = unpack(parameters['sum_openings'])
        total_bill = loads(parameters['total_bill'])

        # verify bill
        (G, g, (h0, _, _, _), _) = setup()
        bill_commitment = G.infinite()
        for i in range(0, len(commitements)):
            bill_commitment = bill_commitment + tariffs[i] * unpack(
                commitements[i])

        if bill_commitment - sum_openings * h0 != total_bill * g:
            return False

        # otherwise
        return True

    except (KeyError, Exception):
        return False
示例#14
0
def submit_bid_checker(inputs, reference_inputs, parameters, outputs, returns, dependencies):
    try:
        input_token = loads(inputs[0])
        output_token = loads(outputs[0])
        output_bid = loads(outputs[1])
        smart_meter = loads(reference_inputs[0])
        # check format
        if len(inputs) != 1 or len(reference_inputs) != 1 or len(outputs) != 2 or len(parameters) != 2 or len(returns) != 0:
            return False

        # check tokens
        if input_token['type'] != 'EBToken' or output_token['type'] != 'EBToken':
            return False
        if output_bid['type'] != 'EBBuy' and output_bid['type'] != 'EBSell':
            return False
        if smart_meter['type'] != 'SMMeter':
            return False
        if output_bid['pub'] != smart_meter['pub']:
            return False
        # hash message to verify signature
        hasher = sha256()
        hasher.update(dumps(input_token).encode('utf8'))
        hasher.update(dumps(smart_meter).encode('utf8'))
        hasher.update(dumps(output_bid).encode('utf8'))

        # recompose signed digest
        pub = unpack(smart_meter['pub'])
        sig = unpack(parameters[1])

        # verify signature
        (G, _, _, _) = setup()
        if not do_ecdsa_verify(G, pub, sig, hasher.digest()):
            return False

        # otherwise
        return True

    except (KeyError, Exception):
        return False
示例#15
0
文件: vote.py 项目: alxd112/byzcuit
def create_vote_checker(inputs, reference_inputs, parameters, outputs, returns,
                        dependencies):
    try:

        # retrieve vote
        vote = loads(outputs[1])
        num_votes = len(vote['options'])

        # check format
        if len(inputs) != 1 or len(reference_inputs) != 0 or len(
                outputs) != 2 or len(returns) != 0:
            return False
        if num_votes < 1 or num_votes != len(vote['scores']):
            return False
        if vote['participants'] == None:
            return False

        # check tokens
        if loads(inputs[0])['type'] != 'VoteToken' or loads(
                outputs[0])['type'] != 'VoteToken':
            return False
        if vote['type'] != 'VoteObject':
            return False

        # check proof
        params = setup()
        proof_init = unpack(parameters['proof_init'])
        tally_pub = unpack(vote['tally_pub'])
        for value in vote['scores']:
            if not verifyzero(params, tally_pub, unpack(value), proof_init):
                return False

        # otherwise
        return True

    except (KeyError, Exception):
        return False
示例#16
0
def submit_bid(inputs, reference_inputs, parameters, meter_priv):

    # Extract bid object from paramters
    bid = loads(parameters[0])
    smart_meter = loads(reference_inputs[0])
    token = loads(inputs[0])
    bid['pub'] = smart_meter['pub']
    # Create a hash digest of inputs and parameters
    hasher = sha256()
    hasher.update(dumps(token).encode('utf8'))
    hasher.update(dumps(smart_meter).encode('utf8'))
    hasher.update(dumps(bid).encode('utf8'))

    # sign message
    G = setup()[0]
    sig = do_ecdsa_sign(G, unpack(meter_priv), hasher.digest())
    # return
    return {
        'outputs': (inputs[0],dumps(bid)),
        'extra_parameters' : (
            pack(sig),
        )
    }
def auth_transfer(inputs, reference_inputs, parameters, priv):

    # compute outputs
    amount = loads(parameters[0])
    new_from_account = loads(inputs[0])
    new_to_account   = loads(inputs[1])
    new_from_account["balance"] -= amount
    new_to_account["balance"]   += amount

    # hash message to sign
    hasher = sha256()
    hasher.update(dumps(inputs).encode('utf8'))
    hasher.update(dumps(reference_inputs).encode('utf8'))
    hasher.update(dumps(parameters[0]).encode('utf8'))

    # sign message
    G = setup()[0]
    sig = do_ecdsa_sign(G, unpack(priv), hasher.digest())

    # return
    return {
        'outputs': (dumps(new_from_account), dumps(new_to_account)),
        'extra_parameters' : (pack(sig),)
    }
示例#18
0
文件: vote.py 项目: alxd112/byzcuit
def tally(inputs, reference_inputs, parameters, tally_priv, tally_pub):

    # retrieve last vote
    vote = loads(inputs[0])

    # generate params & retrieve tally's public key
    params = setup()
    table = make_table(params)
    (G, _, (h0, _, _, _), _) = params

    # decrypt aggregated results
    outcome = []
    for item in vote['scores']:
        outcome.append(dec(params, table, unpack(tally_priv), unpack(item)))

    # proof of decryption
    proof_dec = []
    for i in range(0, len(vote['scores'])):
        a, b = unpack(vote['scores'][i])
        ciphertext = (a, b - outcome[i] * h0)
        tmp = provezero(params, unpack(tally_pub), ciphertext,
                        unpack(tally_priv))
        proof_dec.append(pack(tmp))

    # signature
    hasher = sha256()
    hasher.update(dumps(vote).encode('utf8'))
    hasher.update(dumps(outcome).encode('utf8'))
    sig = do_ecdsa_sign(G, unpack(tally_priv), hasher.digest())

    # pack result
    result = {'type': 'VoteResult', 'outcome': outcome}

    # return
    return {
        'outputs': (dumps(result), ),
        'extra_parameters': {
            'proof_dec': dumps(proof_dec),
            'signature': pack(sig)
        }
    }
示例#19
0
文件: vote.py 项目: alxd112/byzcuit
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)
        }
    }
示例#20
0
文件: vote.py 项目: alxd112/byzcuit
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