def ecdsa_verify(G, pub_verify, message, sig): """ Verify the ECDSA signature on the message """ plaintext = message.encode("utf8") digest = sha256(plaintext).digest() ## YOUR CODE HERE res = do_ecdsa_verify(G, pub_verify, sig, digest) return res
def verify(self, message, sig): """ Verify the message and the signature """ assert len(message) == 32 lr, r, ls, s = unpack("H32sH32s", sig) sig = Bn.from_binary(r[:lr]), Bn.from_binary(s[:ls]) return do_ecdsa_verify(self.G, self.pub, sig, message)
def ecdsa_verify(G, pub_verify, message, sig): """ Verify the ECDSA signature on the message """ plaintext = message.encode("utf8") digest = sha256(plaintext).digest() res = do_ecdsa_verify(G,pub_verify,sig,digest) return res
def dh_decrypt(priv, ciphertext, aliceVer = None): """ Decrypt a received message encrypted using your public key, of which the private key is provided. Optionally verify the message came from Alice using her verification key.""" # ciphertext be (iv, ciphertext, tag, sender_pub, sig) # bob decrypting: check sig using alice's pub ver key, # then decrypt using shared key derived from priv (bob's private key) # check input parameter format if (not isinstance(ciphertext, tuple)) or (isinstance(ciphertext, tuple) and len(ciphertext) != 5): raise Exception("Expecting tuple (iv, ciphertext, tag, sender public key, signature).") iv, encmsg, tag, sender_pub, sig = ciphertext # verify signature if aliceVer: if not sig: raise Exception("Signature required before decyption.") elif not do_ecdsa_verify(EcGroup(), aliceVer, sig, sha256(encmsg).digest()): raise Exception("Signature verification failed.") # shared key = bob priv x alice's pub point shared_key = priv * sender_pub # hash shared_key = sha256(shared_key.export()).digest() # decrypt aes = Cipher("aes-256-gcm") plaintext = aes.quick_gcm_dec(shared_key, iv, encmsg, tag) return plaintext.encode("utf-8")
def steady_decrypt(self, ciphertext): assert len(self.Ks) > 0 decode = CryptoDec().decode gcm_dec = self.aes.quick_gcm_dec [iv, ciphertext, tag] = decode(ciphertext) assert isinstance(ciphertext, bytes) assert isinstance(iv, bytes) assert isinstance(tag, bytes) ## Decrypt and check integrity plaintext = gcm_dec(self.Ks[-1], iv, ciphertext, tag) assert isinstance(plaintext, bytes) ## Check signature [xname, xplain, r, s] = decode(plaintext.decode("utf8")) md = sha1(self.Ks[-1] + bytes(xplain)).digest() sig = (r,s) pub = self.current_dict[xname.decode("utf8")] if not do_ecdsa_verify(self.G, pub, sig, bytes(md)): return None return (xname, xplain)
def steady_decrypt(self, ciphertext): assert len(self.Ks) > 0 decode = CryptoDec().decode gcm_dec = self.aes.quick_gcm_dec [iv, ciphertext, tag] = decode(ciphertext) assert isinstance(ciphertext, bytes) assert isinstance(iv, bytes) assert isinstance(tag, bytes) ## Decrypt and check integrity plaintext = gcm_dec(self.Ks[-1], iv, ciphertext, tag) assert isinstance(plaintext, bytes) ## Check signature [xname, xplain, r, s] = decode(plaintext.decode("utf8")) md = sha1(self.Ks[-1] + bytes(xplain)).digest() sig = (r, s) pub = self.current_dict[xname.decode("utf8")] if not do_ecdsa_verify(self.G, pub, sig, bytes(md)): return None return (xname, xplain)
def ecdsa_verify(G, pub_verify, message, sig): """ Verify the ECDSA signature on the message """ plaintext = message.encode("utf8") res = do_ecdsa_verify(G, pub_verify, sig, plaintext) return res
def CompareHashesOfTwoArr(hashes, sigs, Gx, pub_verifyx): failed = 0 result = True for a, b in zip(hashes, sigs): res = do_ecdsa_verify(Gx, pub_verifyx, b, a) if (res == False): result = False return result
def verify(mixnet_data, signature, params): signature = canonical.from_unicode_canonical(signature) digest = sha256(mixnet_data).digest() sig = tuple(map(bn_decode, (signature["r"], signature["s"]))) ver_key = mk_EcPt(signature["public"], params) valid = ecdsa.do_ecdsa_verify(params.group.G, ver_key, sig, digest) key_id = get_key_id_from_key_data(ver_key) return valid, key_id
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")
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
def verify_signature(sig_pk, sig, message): """Verify a signature. :param petlib.EcPt sig_pk: Signature verification key :param sig: Signature :type sig: tuple of bignums (``petlib.bn.Bn``) :param bytes message: Message """ pp = PublicParams.get_default() G = pp.ec_group digest = pp.hash_func(message).digest() return do_ecdsa_verify(G, sig_pk, sig, digest)
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
def ecdsa_verify(G, pub_verify, message, sig): """ Verify the ECDSA signature on the message """ plaintext = message.encode("utf8") ## YOUR CODE HERE digest = sha256( plaintext).digest() #prdouce hash function as binary string res = do_ecdsa_verify( G, pub_verify, sig, digest) # verify by applying the verification function return res
def create_petition_checker(inputs, reference_inputs, parameters, outputs, returns, dependencies): try: # retrieve petition petition = loads(outputs[1]) # retrieve ID list spent_list = loads(outputs[2]) # retrieve parameters sig = pet_unpack(parameters[0]) # check format if len(inputs) != 1 or len(reference_inputs) != 0 or len( outputs) != 3 or len(returns) != 0: return False # check types if loads(inputs[0])['type'] != 'PToken' or loads( outputs[0])['type'] != 'PToken': return False if petition['type'] != 'PObject' or spent_list['type'] != 'PList': return False # check fields petition['UUID'] # check presence of UUID petition['verifier'] # check presence of verifier options = petition['options'] scores = petition['scores'] pub_owner = pet_unpack(petition['owner']) if len(options) < 1 or len(options) != len(scores): return False # check initalised scores if not all(init_score == 0 for init_score in scores): return False # verify signature pet_params = pet_setup() hasher = sha256() hasher.update(outputs[1].encode('utf8')) if not do_ecdsa_verify(pet_params[0], pub_owner, sig, hasher.digest()): return False # verify that the spent list is empty if spent_list['list']: return False # otherwise return True except (KeyError, Exception): return False
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']) proof_dec = loads(parameters[0]) sig = unpack(parameters[1]) 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
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
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
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 enc_side(params, pub, counter): """ encrypts the values of a small counter """ assert -2**8 < counter < 2**8 (_, g, (h0, _, _, _), o) = params
def verify_signature(sig_pk, sig, message): pp = PublicParams.get_default() G = pp.ec_group digest = pp.hash_func(message).digest() return do_ecdsa_verify(G, sig_pk, sig, digest)
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[2] in old_vote['participants']: return False if parameters[2] 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[0]) sig = unpack(parameters[1]) voter_pub = unpack(parameters[2]) proof_bin = loads(parameters[3]) proof_sum = unpack(parameters[4]) # 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