def GenerateSignturesOfHashes(hashes, Gx, priv_signx): signatures = [] global kinv_rp for x in hashes: z = do_ecdsa_sign(Gx, priv_signx, x, kinv_rp=kinv_rp) signatures.append(z) return signatures
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) } }
def create_petition(inputs, reference_inputs, parameters, UUID, options, priv_owner, pub_owner, vvk): # inital score scores = [0 for _ in options] # pack vvk packed_vvk = (pack(vvk[0]), pack(vvk[1]), pack(vvk[2])) # new petition object new_petition = { 'type': 'PObject', 'UUID': pet_pack(UUID), # unique ID of the petition 'owner': pet_pack(pub_owner), # entity creating the petition 'verifier': packed_vvk, # entity delivering credentials to participate to the petition 'options': options, # the options to sign 'scores': scores # the signatures per option } # ID lists signed_list = {'type': 'PList', 'list': []} # signature pet_params = pet_setup() hasher = sha256() hasher.update(dumps(new_petition).encode('utf8')) sig = do_ecdsa_sign(pet_params[0], priv_owner, hasher.digest()) # return return { 'outputs': (inputs[0], dumps(new_petition), dumps(signed_list)), 'extra_parameters': (pet_pack(sig), ) }
def dh_encrypt(pub, message, aliceSig = None): """ Assume you know the public key of someone else (Bob), and wish to Encrypt a message for them. - Generate a fresh DH key for this message. - Derive a fresh shared key. - Use the shared key to AES_GCM encrypt the message. - Optionally: sign the message with Alice's key. """ # pub is bob's pub key, alicesig is my private sig key, # which shuold be different from enc/dec keypair # for cryptographic sec reasons # priv is an integer, pub is an ec point alice_G, alice_priv, alice_pub = dh_get_key() # shared secret = my priv x bob's pub point shared_key = alice_priv * pub # hash ec pt to derive key shared_key = sha256(shared_key.export()).digest() # aes_gcm encrypt aes = Cipher("aes-256-gcm") iv = urandom(len(shared_key)) ciphertext, tag = aes.quick_gcm_enc(shared_key, iv, message.encode("utf-8")) # sign message (assume using common curve) # hash ciphertext sig = do_ecdsa_sign(EcGroup(), aliceSig, sha256(ciphertext).digest()) if aliceSig else None # return alice_pub for dh_decrypt on bob side # (because bob needs alice's pub to gen shared secret) return (iv, ciphertext, tag, alice_pub, sig)
def ecdsa_sign(G, priv_sign, message): """ Sign the SHA256 digest of the message using ECDSA and return a signature """ plaintext = message.encode("utf8") sig = do_ecdsa_sign(G, priv_sign, plaintext) return sig
def transfer(inputs, reference_inputs, parameters, *args): # 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 if loads(inputs[0])['callback'] == None: hasher = sha256() hasher.update(dumps(inputs).encode('utf8')) hasher.update(dumps(parameters[0]).encode('utf8')) G = setup()[0] priv = args[0] sig = do_ecdsa_sign(G, priv, hasher.digest()) else: # create dependency # @Mustafa: we need to modify the framework to make possible to pass a callback here; # i.e., make possible to execute callback_function(args) for any function passed as argument hello_contract.init() sig = setup()[0].order().random() # dump # return return { 'outputs': (dumps(new_from_account), dumps(new_to_account)), 'extra_parameters': (pack(sig), ) }
def ecdsa_sign(G, priv_sign, message): """ Sign the SHA256 digest of the message using ECDSA and return a signature """ plaintext = message.encode("utf8") digest = sha256(plaintext).digest() sig = do_ecdsa_sign(G,priv_sign,digest) return sig
def sign(message): pp = PublicParams.get_default() params = LocalParams.get_default() G = pp.ec_group digest = pp.hash_func(message).digest() kinv_rp = do_ecdsa_setup(G, params.sig.sk) sig = do_ecdsa_sign(G, params.sig.sk, digest, kinv_rp=kinv_rp) return sig
def ecdsa_sign(G, priv_sign, message): """ Sign the SHA256 digest of the message using ECDSA and return a signature """ plaintext = message.encode("utf8") ## YOUR CODE HERE digest = sha1(plaintext).digest() sig = do_ecdsa_sign(G, priv_sign, digest) return sig
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)
def ecdsa_sign(G, priv_sign, message): """ Sign the SHA256 digest of the message using ECDSA and return a signature """ plaintext = message.encode("utf8") ##digest/hash digest = sha256(plaintext).digest() ##sign sig = do_ecdsa_sign(G, priv_sign, digest) return sig
def ecdsa_sign(G, priv_sign, message): """ Sign the SHA256 digest of the message using ECDSA and return a signature """ plaintext = message.encode("utf8") ## YOUR CODE HERE digest = sha256(plaintext).digest() ## implementng a signature scheme ## hash the message and get the digest code(hash function as binary string) sig = do_ecdsa_sign(G, priv_sign, digest) ## sign the message return sig
def sign(body, params, secret, public): digest = sha256(body).digest() sig = ecdsa.do_ecdsa_sign(params.group.G, secret, digest) sig = tuple(map(bn_encode, sig)) signature = { "r": sig[0], "s": sig[1], "public": public, } return canonical.to_canonical(signature)
def sign(self, message): """ Sign a 32-byte message using the key pair """ assert len(message) == 32 assert self.sec is not None r, s = do_ecdsa_sign(self.G, self.sec, message, self.optim) r0, s0 = r.binary(), s.binary() assert len(r0) <= 32 and len(s0) <= 32 sig = pack("H32sH32s", len(r0), r0, len(s0), s0) return sig
def ecdsa_sign(G, priv_sign, message): """ Sign the SHA256 digest of the message using ECDSA and return a signature """ plaintext = message.encode("utf8") ## YOUR CODE HERE G = EcGroup() ver_key = priv_sign * G.generator() digest = sha256(plaintext).digest() kinv_rp = do_ecdsa_setup(G, priv_sign) sig = do_ecdsa_sign(G, priv_sign, digest, kinv_rp=kinv_rp) return sig
def sign(message): """Sign a message. :param bytes message: Message :return: Tuple of bignums (``petlib.bn.Bn``) """ pp = PublicParams.get_default() params = LocalParams.get_default() G = pp.ec_group digest = pp.hash_func(message).digest() kinv_rp = do_ecdsa_setup(G, params.sig.sk) sig = do_ecdsa_sign(G, params.sig.sk, digest, kinv_rp=kinv_rp) return sig
def castVote(voter_id, candidate): DC = {} R = order.random() for non_vote in filter(lambda l: l != candidate, candidates): DC[non_vote] = ' '.join([getRandomWord() for i in range(4)]) rc, masks, rb = genRealCommitments(candidate, K, R) commitments, randoms = genFakeCommitments(DC, K, candidate, R) randoms[candidate] = rb commitments[candidate] = masks cmt_list = [] for sk in sorted(commitments): cmt_list.append(commitments[sk]) everything = challengeHash(''.join(map(str, [rc] + list(chain(cmt_list)))), K) #alphabetize this rx = order.random() x = commit(Bn.from_hex(everything), rx) DC[candidate] = ' '.join([getRandomWord() for i in range(4)]) #random challenge real vote answers = answerChallenges(DC, randoms, K, R) verifyCommitment(x, rc, cmt_list, rx) challenge_dict = { candidate: { 'challenge': DC[candidate], 'answer': list(map(str, answers[candidate])), 'proof': commitments[candidate] } for candidate in DC } receipt = serializeEcPts({ 'voter_id': voter_id, 'challenges': challenge_dict, 'vote_commitment': rc, 'rx': str(rx), 'commitment_to_everything': x }) sig = do_ecdsa_sign(G, sig_key, EcPtToStr(x).encode('utf-8'), kinv_rp) signed_cmt = '_'.join((EcPtToStr(x), hex(sig[0])[2:], hex(sig[1])[2:])) qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=4, border=4, ) qr.add_data(signed_cmt) qr.make() img = qr.make_image() img.save('qrcodes/to_print.png') return (candidate, rc, R, everything, str(x), answers, receipt)
def steady_encrypt(self, plaintext): assert len(self.Ks) > 0 encode = CryptoEnc().encode gcm_enc = self.aes.quick_gcm_enc ## Sign using ephemeral signature md = sha1(self.Ks[-1] + plaintext).digest() # Note: include the key here to bing the signature # to the encrypted channel defined by this key. r, s = do_ecdsa_sign(self.G, self.priv_sign, md) inner_message = [B(self.name.encode("utf8")), B(plaintext), r, s] plain_inner = encode(inner_message).encode("utf8") ## Encrypt using AEC-GCM iv = bytes(urandom(16)) ciphertext, tag = gcm_enc(self.Ks[-1], iv, plain_inner) return encode([B(iv), B(ciphertext), B(tag)])
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) } }
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),) }
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': ( dumps(enc_added_votes), pack(sig), voter_pub, # already packed dumps(proof_bin), pack(proof_sum)) }
The first thing we are going to do is sign a peice of text. Signing is an important foundational part of our contract design. Before signing we create a digest of the text as it might be very long. """ digest = sha1(b"Something I wish to sign").digest() print hexlify(digest) """Next we can sign it. We need the elliptic curve parameter `G` which we can get from the params we created in the setup. We pass it the public key we generated earlier""" (G, _, _, _) = params kinv_rp = do_ecdsa_setup(G, private_key) """Now we can sign our digest""" sig = do_ecdsa_sign(G, private_key, digest, kinv_rp=kinv_rp) print pack(sig) """Finally we can verify it using the public key from our keypair""" do_ecdsa_verify(G, public_key, sig, digest) """Here is a bunch of crypto functions for [homomorphic encryption](https://en.wikipedia.org/wiki/Homomorphic_encryption) See [here](https://crypto.stackexchange.com/questions/45040/can-elliptic-curve-cryptography-encrypt-with-public-key-and-decrypt-with-private) for an answer about doing encryption with elliptic curve cryptography. In order to do [asymetric encryption](https://en.wikipedia.org/wiki/Public-key_cryptography) using ECC you first have to turn your message into a point on the curve,you can then encrypt using a public key which can be decrypted with the private key. There is a scheme for more general encrpytion, the https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme which allows two parties to generate a symetric key that they can use to encrypt a message between them """
def stage5(): # super annoying that I have to do this for some reason reset_dict_keys() session["challenges"][session["chosen"]] = request.form["chosen_challenge"] R, rc, masks, rb, commitments, randoms, cmt_list, everything, rx, x, answers, receipt = desist_tricky_objects( ) answers = genvote.answerChallenges(session["challenges"], randoms, genvote.K, R) # genvote.verifyCommitment(x, rc, cmt_list, rx) challenge_dict = { candidate: { 'challenge': session["challenges"][candidate], 'answer': list(map(str, answers[candidate])), 'proof': commitments[candidate] } for candidate in session["challenges"] } receipt = genvote.serializeEcPts({ 'voter_id': session["voter_id"], 'challenges': challenge_dict, 'vote_commitment': rc, 'rx': str(rx), 'commitment_to_everything': x }) # print challenges print_text('CHALLENGES') for i in session["candidates"]: print_text( str(i) + ' | ' + session["rev_d"][i] + ' | ' + session["challenges"][i]) # random beacon r = requests.get("https://beacon.nist.gov/rest/record/last") timestamp = re.search(r"<timeStamp>(.*)<\/timeStamp>", r.text).group(1) outputvalue = re.search(r"<outputValue>(.*)<\/outputValue>", r.text).group(1) # timestamp and outputvalue need to be printed to receipt in some way # print(timestamp, outputvalue) print_text('RANDOM BEACON') print_text('Timestamp: ' + timestamp) print_text('Beacon Value: ' + outputvalue) cmt_ev = genvote.EcPtToStr(x) all_qr_data_dict = { "ID": session["voter_id"], "B_T": timestamp, "B_V": outputvalue, "CMT": cmt_ev, "CHAL": session["challenges"] } all_qr_data_ser = json.dumps(all_qr_data_dict) qr_path = 'qrcodes/' + session["voter_id"] sig = do_ecdsa_sign(genvote.G, genvote.sig_key, all_qr_data_ser.encode('utf-8'), genvote.kinv_rp) sign_dict = {'r': hex(sig[0])[2:], 's': hex(sig[1])[2:]} signed_data = json.dumps(sign_dict) plain_qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=4, border=4, ) plain_qr.add_data(all_qr_data_ser) plain_qr.make() plain_img = plain_qr.make_image() plain_img.save(qr_path + '-plain' + '.png') sig_qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=4, border=4, ) sig_qr.add_data(signed_data) sig_qr.make() sig_img = sig_qr.make_image() sig_img.save(qr_path + '-sig' + '.png') # REALLY, WE NEED TO PRINT THE QR CODE HERE, NOT SAVE IT print_text('PLAINTEXT QR CODE') print_image(qr_path + '-plain' + '.png') print_text('SIGNED QR CODE') print_image(qr_path + '-sig' + '.png') # print voter_id #os.system('echo "Voter ID: ' + session["voter_id"] + '" | lpr') print_text('Voter ID: ' + session["voter_id"]) # print Receipt Certified #os.system('echo "--RECEIPT CERTIFIED--" | lpr') print_text('-RECEIPT CERTIFIED-') # blank space at the bottom for i in range(5): print_text('') persist_tricky_objects(R, rc, masks, rb, commitments, randoms, cmt_list, everything, rx, x, answers, receipt) return render_template("stage5.html", candidates=session["candidates"], cand_dict=session["rev_d"], chosen=session["chosen"], challenges=session["challenges"], voter_id=session["voter_id"])