def can_spent(self): for input in self.inputs: print(input) print(input.hash) if not bitcoin.ecdsa_verify(bitcoin.sha256(str(input)), input.sign, input.pubk): raise Exception()
def auth_counterparty(self, nick, btc_sig, cj_pub): '''Validate the counterpartys claim to own the btc address/pubkey that will be used for coinjoining with an ecdsa verification.''' if not btc.ecdsa_verify(self.crypto_boxes[nick][0], btc_sig, cj_pub): print 'signature didnt match pubkey and message' return False return True
def verify(challenge_hidden, challenge_visual, pubkey, signature, version): if version == 1: message = binascii.unhexlify(challenge_hidden + binascii.hexlify(challenge_visual)) elif version == 2: h1 = hashlib.sha256(binascii.unhexlify(challenge_hidden)).digest() h2 = hashlib.sha256(challenge_visual).digest() message = h1 + h2 else: raise Exception('Unknown version') signature_b64 = base64.b64encode(binascii.unhexlify(signature)) return bitcoin.ecdsa_verify(message, signature_b64, pubkey)
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 auth_counterparty(self, nick, btc_sig, auth_pub): """Validate the counterpartys claim to own the btc address/pubkey that will be used for coinjoining with an ecdsa verification. Note that this is only a first-step authorisation; it checks the btc signature, but the authorising pubkey is checked to be part of the transactoin in recv_txio. """ if not btc.ecdsa_verify(self.crypto_boxes[nick][0], btc_sig, auth_pub): log.debug('signature didnt match pubkey and message') return False return True
def save_memo(request): encrypted_text = request.POST['encrypted_text'] pubkey = request.POST['pubkey'] sig = request.POST['signature'] txid = request.POST['txid'].lower() crypto = request.POST.get('currency', 'btc').lower() if len(encrypted_text) > settings.MAX_MEMO_SIZE_BYTES: return http.JsonResponse( { 'error': "Memo exceeds maximum size of: %s bytes" % settings.MAX_MEMO_SIZE_BYTES }, status=400) data = dict(pubkey=pubkey, crypto=crypto, txid=txid, encrypted_text=encrypted_text) if Memo.objects.filter(**data).exists(): return http.HttpResponse("OK") data['signature'] = sig try: version_byte = crypto_data[crypto]['address_version_byte'] except IndexError: return http.HttpResponse("Currency not supported", status=400) address = pubkey_to_address(pubkey, version_byte) tx = CachedTransaction.fetch_full_tx(crypto, txid=txid) for item in tx['inputs'] + tx['outputs']: if item['address'] == address: break else: return http.HttpResponse("Pubkey not in TXID", status=400) if ecdsa_verify(encrypted_text, sig, pubkey): memo, c = Memo.objects.get_or_create(crypto=crypto, txid=txid, pubkey=pubkey) memo.encrypted_text = encrypted_text memo.signature = sig memo.save() else: return http.HttpResponse("Invalid signature", status=400) return http.HttpResponse("OK")
def auth_counterparty(self, nick, i_utxo_pubkey, btc_sig): self.i_utxo_pubkey = i_utxo_pubkey if not btc.ecdsa_verify(self.taker_pk, btc_sig, self.i_utxo_pubkey): print 'signature didnt match pubkey and message' return False #authorisation of taker passed #(but input utxo pubkey is checked in verify_unsigned_tx). #Send auth request to taker #TODO the next 2 lines are a little inefficient. btc_key = self.maker.wallet.get_key_from_addr(self.cj_addr) btc_pub = btc.privtopub(btc_key) btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), btc_key) self.maker.msgchan.send_ioauth(nick, self.utxos.keys(), btc_pub, self.change_addr, btc_sig) return True
def verify_nick(self, nick, sig, message): if not btc.ecdsa_verify(message + str(self.hostid), sig[1], sig[0]): log.debug("nick signature verification failed, ignoring.") return False #check that nick matches hash of pubkey nick_pkh_raw = hashlib.sha256(sig[0]).digest()[:NICK_HASH_LENGTH] nick_stripped = nick[2:2+NICK_MAX_ENCODED] #strip right padding nick_unpadded = ''.join([x for x in nick_stripped if x != 'O']) if not nick_unpadded == btc.changebase(nick_pkh_raw, 256, 58): log.debug("Nick hash check failed, expected: " + str( nick_unpadded) + ", got: " + str( btc.changebase(nick_pkh_raw, 256, 58))) return False 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 save_memo(request): encrypted_text = request.POST['encrypted_text'] pubkey = request.POST['pubkey'] sig = request.POST['signature'] txid = request.POST['txid'].lower() crypto = request.POST.get('currency', 'btc').lower() if len(encrypted_text) > settings.MAX_MEMO_SIZE_BYTES: return http.JsonResponse( {'error': "Memo exceeds maximum size of: %s bytes" % settings.MAX_MEMO_SIZE_BYTES}, status=400 ) data = dict(pubkey=pubkey, crypto=crypto, txid=txid, encrypted_text=encrypted_text) if Memo.objects.filter(**data).exists(): return http.HttpResponse("OK") data['signature'] = sig try: version_byte = crypto_data[crypto]['address_version_byte'] except IndexError: return http.HttpResponse("Currency not supported", status=400) address = pubkey_to_address(pubkey, version_byte) tx = CachedTransaction.fetch_full_tx(crypto, txid=txid) for item in tx['inputs'] + tx['outputs']: if item['address'] == address: break else: return http.HttpResponse("Pubkey not in TXID", status=400) if ecdsa_verify(encrypted_text, sig, pubkey): memo, c = Memo.objects.get_or_create( crypto=crypto, txid=txid, pubkey=pubkey ) memo.encrypted_text = encrypted_text memo.signature = sig memo.save() else: return http.HttpResponse("Invalid signature", status=400) return http.HttpResponse("OK")
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 verify_multisig(self, controller_pubkeys): #function to verify the signatures of the object against the policy #and supplied public key list: returns validity nsig = len(self.map["sigs"]) if nsig < self.map["n"]: print("Error: insufficient signatures") return False #the signature is generated over the asset list json object concatinated with the policy and time jsonstring = json.dumps(self.map["assets"], sort_keys=True) jsonstring += str(self.map["n"]) + str(self.map["m"]) + str( self.map["time"]) + str(self.map["height"]) nvalid = 0 #check all possible combinations of public keys and signatures for key in controller_pubkeys: for i, j in self.map["sigs"].items(): if bc.ecdsa_verify(jsonstring, j, key): nvalid += 1 if nvalid >= self.map["n"]: return True else: return False