def validate_sig(sig, msg, address, type="transaction"): try: pubkey = ecdsa_recover(msg, sig) except: raise InvalidSignature("Can't recover pubkey from %s signature" % type) valid_sig = ecdsa_verify(msg, sig, pubkey) valid_address = pubtoaddr(pubkey) == address if not valid_sig or not valid_address: raise InvalidSignature("%s signature not valid" % type.title()) return True
def validate_peer_registration(reg, now=None): ts = dateutil.parser.parse(reg['timestamp']) validate_timestamp(ts, now=now) to_sign = "{domain}{payout_address}{timestamp}".format(**reg) try: pubkey = ecdsa_recover(to_sign, reg['signature']) except: raise InvalidSignature("Can't recover pubkey from signature") valid_address = pubtoaddr(pubkey) == reg['payout_address'] valid_sig = ecdsa_verify(to_sign, reg['signature'], pubkey) if not valid_sig or not valid_address: raise InvalidSignature("Invalid Signature") return True
def validate_transaction(tx, ledger=None, min_fee=0.01, now=None): """ Validates that the passed in transaction object is valid in terms of cryptography. UTXO validation does not happen here. `ledger` is a callable that returns the address's balance and last spend timestamp. """ ts = dateutil.parser.parse(tx['timestamp']) out_total, out_msg = _process_outputs(tx['outputs'], ts) validate_timestamp(ts, now=now) in_total = 0 for i, input in enumerate(tx['inputs']): address, amount, sig = input amount = _cut_to_8(amount) if amount <= 0: raise InvalidAmounts("Input %s can't be zero or negative" % i) message = "%s%s%s" % (address, amount, out_msg) in_total += amount try: pubkey = ecdsa_recover(message, sig) except: raise InvalidSignature("Signature %s not valid" % i) if ledger: address_balance, last_spend = ledger(address) delt = datetime.timedelta(seconds=PROPAGATION_WINDOW_SECONDS) if last_spend + delt > ts: raise InvalidTransaction("Input too young") if address_balance < amount: raise InvalidAmounts("Not enough balance in %s" % address) valid_sig = ecdsa_verify(message, sig, pubkey) valid_address = pubtoaddr(pubkey) == address if not valid_sig or not valid_address: raise InvalidSignature("Signature %s not valid" % i) if in_total < out_total: raise InvalidAmounts("Input amount does not exceed output amount") fee = in_total - out_total if fee < min_fee: raise InvalidFee("Fee of %.8f below min fee of %.8f" % (fee, min_fee)) return True
def checkSigBitcoin(message, signature, authorname): try: # FIXME: is base64.b64decode(...) safe? pub = bitcoin.ecdsa_recover(message, signature) except: raise jvalidate.ValidationError( "Bitcoin signature or message invalid.") author = Member.by_name(authorname) if author is None: raise jvalidate.ValidationError( "Member '%s' not found for PGP signature check." % authorname) addr = author.address addr_from_pub = bitcoin.pubkey_to_address(pub) # is this enough? FIXME: review! # FIXME: check type(?) bug in bitcoin.ecsda_verify_addr if addr != addr_from_pub: raise jvalidate.ValidationError( "Bitcoin signature validation failed (%s, %s, %s)." % (repr(message), signature, addr))
def __init__(self, token_addr, mints, outputs, privs=None, linked_onchain_txn=None, signatures=[]): self.token_addr = token_addr self.mints = mints self.outputs = outputs self.privs = privs self.linked_onchain_txn = linked_onchain_txn self.signatures = signatures msg = self.txn_part() log.info("Token transaction part hash: %s", hexlify(bitcoin.electrum_sig_hash(msg))) if self.privs is None: assert (len(self.signatures)) self.signed_addresses = [] for sig in self.signatures: addr_reconstructed = bitcoin.pubtoaddr( bitcoin.ecdsa_recover(msg, sig)) self.signed_addresses.append(addr_reconstructed) else: self.signed_addresses = [ bitcoin.privkey_to_address(priv) for priv in privs ] import io b = io.BytesIO() self.write(b) self.hsh = bitcoin.sha256( bytes(b.getbuffer())[:-1] ) # TOTAL hash, including signatures, but excluding final \n byte self.handle = "TOK_" + self.hsh log.info("Token transaction overall hash: %s", self.hsh)
def verify_sign(msg, sig, address): public_key = bitcoin.ecdsa_recover(msg, sig) return address == bitcoin.pubkey_to_address(public_key)
u_shared = user_pk for i in range(NB_RELAY_NODES): u_shared = bitcoin.multiply(u_shared, relayNodes[i]['secret']) # Then exitNode calculate and sign the global shared secret global_shared = bitcoin.multiply(u_shared, exitNode_sk) global_shared_signature = bitcoin.ecdsa_sign(global_shared, exitNode_sk) # Then, the exitNode accept the connection by sending back the signature # The relayNodes now calculate new shared with exitNode e_shared = exitNode_pk for i in range(NB_RELAY_NODES)[::-1]: e_shared = bitcoin.multiply(e_shared, relayNodes[i]['secret']) # User can now calculate global shared key and test if exitNode has the same assert exitNode_pk == bitcoin.ecdsa_recover(bitcoin.multiply(e_shared, user_sk), global_shared_signature) ################################################################################ ########################## Communication Process ########################### ################################################################################ # The user have some data that he can encrypt with global shared key user_msg = 'A random user message.' encrypted_msg = AES_encrypt(user_msg, global_shared) # The user send it to relayNodes, wich will relay it to exitNode # Now, the exitNode can read the data without knowing the user exit_msg = AES_decrypt(encrypted_msg, global_shared) assert exit_msg == user_msg