def validate_token_record(token_record, parent_public_key, signing_algorithm = 'ES256'): """ A function for validating an individual token record and extracting the decoded token. """ if not ("token" in token_record and "publicKey" in token_record and \ "parentPublicKey" in token_record): raise ValueError("Invalid token record") token = token_record["token"] public_key = BitcoinPublicKey(parent_public_key) decoded_token = jwt.decode( token, public_key.to_pem(), algorithms=[signing_algorithm]) decoded_token = json.loads(json.dumps(decoded_token)) if "subject" not in decoded_token and "publicKey" not in decoded_token["subject"]: raise ValueError("Invalid decoded token") if "claim" not in decoded_token: raise ValueError("Invalid decoded token") if token_record["publicKey"] == token_record["parentPublicKey"]: if token_record["publicKey"] != decoded_token["subject"]["publicKey"]: raise ValueError("Token's public key doesn't match") else: raise ValueError("Verification of tokens signed with keychains is not yet supported") return decoded_token
def get_address_from_pubkey(hex_pubkey): """ get bitcoin address from pub key """ pubkey = BitcoinPublicKey(hex_pubkey) return pubkey.address()
def setUp(self): self.private_key_hex = str(PRIVATE_KEY) self.public_key_hex = str(PUBLIC_KEY) self.domain_name = 'localhost:3000' self.private_key = BitcoinPrivateKey(self.private_key_hex) self.public_key = BitcoinPublicKey(self.public_key_hex) self.sample_encoded_token = REQUEST_SAMPLE_ENCODED_TOKEN self.sample_decoded_token = REQUEST_SAMPLE_DECODED_TOKEN self.maxDiff = None
def setUp(self): self.private_key_hex = str(PRIVATE_KEY) self.public_key_hex = str(PUBLIC_KEY) self.private_key = BitcoinPrivateKey(self.private_key_hex) self.public_key = BitcoinPublicKey(self.public_key_hex) self.profile = RYAN_PROFILE self.username = '******' self.sample_encoded_token = RESPONSE_SAMPLE_ENCODED_TOKEN self.sample_decoded_token = RESPONSE_SAMPLE_DECODED_TOKEN
def broadcast(name, data_hash, consensus_hash, private_key, blockchain_client, blockchain_broadcaster=None, tx_only=False, user_public_key=None, testset=False): """ Write a name update into the blockchain. Returns a JSON object with 'data' set to the nulldata and 'transaction_hash' set to the transaction hash on success. """ # sanity check pay_fee = True if user_public_key is not None: pay_fee = False tx_only = True if user_public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if user_public_key is not None: # subsidizing pubk = BitcoinPublicKey( user_public_key ) from_address = pubk.address() # get inputs from utxo provider inputs = get_unspents( from_address, blockchain_client ) elif private_key is not None: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) nulldata = build(name, consensus_hash, data_hash=data_hash, testset=testset) outputs = make_outputs( nulldata, inputs, from_address, pay_fee=pay_fee ) if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {'unsigned_tx': unsigned_tx} else: signed_tx = tx_serialize_and_sign( inputs, outputs, private_key_obj ) response = broadcast_transaction( signed_tx, blockchain_broadcaster ) response.update({'data': nulldata}) return response
def broadcast(name_list, private_key, register_addr_list, consensus_hash, blockchain_client, fee, \ blockchain_broadcaster=None, subsidy_public_key=None, tx_only=False, testset=False): """ Builds and broadcasts a preorder transaction. @subsidy_public_key: if given, the public part of the subsidy key """ if subsidy_public_key is not None: # subsidizing, and only want the tx tx_only = True # sanity check if subsidy_public_key is None and private_key is None: raise Exception("Missing both client public and private key") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None # change address inputs = None private_key_obj = None script_pubkey = None # to be mixed into preorder hash if subsidy_public_key is not None: # subsidizing pubk = BitcoinPublicKey( subsidy_public_key ) from_address = BitcoinPublicKey( subsidy_public_key ).address() inputs = get_unspents( from_address, blockchain_client ) script_pubkey = get_script_pubkey( subsidy_public_key ) else: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() script_pubkey = get_script_pubkey( public_key ) # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) nulldata = build( name_list, script_pubkey, register_addr_list, consensus_hash, testset=testset) outputs = make_outputs(nulldata, inputs, from_address, fee, format='hex') if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(inputs, outputs, private_key_obj, blockchain_client) response.update({'data': nulldata}) return response
def broadcast(name, destination_address, keepdata, consensus_hash, private_key, blockchain_client, blockchain_broadcaster=None, tx_only=False, user_public_key=None, testset=False): # sanity check pay_fee = True if user_public_key is not None: pay_fee = False tx_only = True if user_public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if user_public_key is not None: # subsidizing pubk = BitcoinPublicKey( user_public_key ) from_address = pubk.address() inputs = get_unspents( from_address, blockchain_client ) elif private_key is not None: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) nulldata = build(name, keepdata, consensus_hash, testset=testset) outputs = make_outputs(nulldata, inputs, destination_address, from_address, pay_fee=pay_fee, format='hex') if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(inputs, outputs, private_key_obj, blockchain_broadcaster) response.update({'data': nulldata}) return response
def do_signatures_match_public_keys(token, tokenizer, decoded_token): # extract the public key from the token try: payload = decoded_token['payload'] if not payload['public_keys']: return True if len(payload['public_keys']) != 1: raise NotImplementedError('Multiple public keys are not supported') public_key = BitcoinPublicKey(str(payload['public_keys'][0])) except KeyError: traceback.print_exc() return False # return whether the token is verified/valid return tokenizer.verify(token, public_key.to_pem())
def __init__(self, signing_key, verifying_key, challenge, blockchain_id=None, public_keychain=None, chain_path=None, crypto_backend=default_backend()): """ signing_key should be provided in PEM format verifying_key should be provided in compressed hex format blockchainid should be a string master_public_key should be an extended public key chain_path should be a string """ self.bitcoin_private_key = BitcoinPrivateKey(signing_key, compressed=True) self.bitcoin_public_key = BitcoinPublicKey(verifying_key) self.tokenizer = Tokenizer(crypto_backend=crypto_backend) self.signing_key = signing_key self.verifying_key = verifying_key self.challenge = challenge self.blockchain_id = blockchain_id self.public_keychain = public_keychain self.chain_path = chain_path
class AuthResponseTest(unittest.TestCase): def setUp(self): self.private_key_hex = str(PRIVATE_KEY) self.public_key_hex = str(PUBLIC_KEY) self.private_key = BitcoinPrivateKey(self.private_key_hex) self.public_key = BitcoinPublicKey(self.public_key_hex) self.profile = RYAN_PROFILE self.username = '******' self.sample_encoded_token = RESPONSE_SAMPLE_ENCODED_TOKEN self.sample_decoded_token = RESPONSE_SAMPLE_DECODED_TOKEN def tearDown(self): pass def test_auth_response_token_encoding(self): # without username, testing basics auth_response = AuthResponse(self.private_key_hex, RYAN_PROFILE) auth_response_token = auth_response.token() decoded_token = AuthResponse.decode(auth_response_token) payload = decoded_token['payload'] self.assertEqual(payload['public_keys'][0], self.public_key_hex) self.assertEqual(get_address_from_did(payload['iss']), self.public_key.address()) self.assertEqual(payload['profile'], self.profile) self.assertEqual(payload['username'], None) self.assertTrue(AuthResponse.verify(auth_response_token)) # with username with requests_mock.mock() as m: m.get(LOCALHOST_CORE_API + NAME_LOOKUP_URL + self.username, text=json.dumps({'address': self.public_key.address()})) auth_response = AuthResponse(self.private_key_hex, RYAN_PROFILE, self.username) auth_response_token = auth_response.token() self.assertTrue( do_public_keys_match_username( auth_response_token, Tokenizer(), AuthResponse.decode(auth_response_token))) self.assertTrue(AuthResponse.verify(auth_response_token)) def test_auth_response_token_decoding(self): decoded_token = AuthResponse.decode(self.sample_encoded_token) self.assertEqual(decoded_token, self.sample_decoded_token)
def is_valid_jwt(cls, token, tokenizer): # decode the token try: decoded_token = cls.decode(token) except DecodeError: traceback.print_exc() return False # extract the public key from the token try: payload = decoded_token['payload'] public_key_str = payload['issuer']['publicKey'] public_key = BitcoinPublicKey(str(public_key_str)) except KeyError: traceback.print_exc() return False # return whether the token is verified/valid return tokenizer.verify(token, public_key.to_pem())
def is_valid_jwt(cls, token): # decode the token try: decoded_token = cls.decode(token) except DecodeError: traceback.print_exc() return False # extract the public key from the token try: payload = decoded_token['payload'] public_key_str = payload['issuer']['publicKey'] public_key = BitcoinPublicKey(str(public_key_str)) except KeyError: traceback.print_exc() return False # return whether the token is verified/valid return cls.tokenizer.verify(token, public_key.to_pem())
def do_public_keys_match_issuer(token, tokenizer, decoded_token): # extract the public key from the token try: payload = decoded_token['payload'] if not payload['public_keys']: return not payload.get('iss', None) if len(payload['public_keys']) != 1: raise NotImplementedError('Multiple public keys are not supported') address_from_pub_key = BitcoinPublicKey(str(payload['public_keys'][0])).address() address_from_iss = get_address_from_did(payload['iss']) return address_from_pub_key == address_from_iss except (KeyError, ValueError): traceback.print_exc() return False
def validate_token_record(token_record, parent_public_key, signing_algorithm='ES256'): """ A function for validating an individual token record and extracting the decoded token. """ if not ("token" in token_record and "publicKey" in token_record and \ "parentPublicKey" in token_record): raise ValueError("Invalid token record") token = token_record["token"] public_key = BitcoinPublicKey(parent_public_key) decoded_token = jwt.decode(token, public_key.to_pem(), algorithms=[signing_algorithm]) decoded_token = json.loads(json.dumps(decoded_token)) if "subject" not in decoded_token and "publicKey" not in decoded_token[ "subject"]: raise ValueError("Invalid decoded token") if "claim" not in decoded_token: raise ValueError("Invalid decoded token") if token_record["publicKey"] == token_record["parentPublicKey"]: if token_record["publicKey"] != decoded_token["subject"]["publicKey"]: raise ValueError("Token's public key doesn't match") else: raise ValueError( "Verification of tokens signed with keychains is not yet supported" ) return decoded_token
def __init__(self, signing_key, verifying_key, issuing_domain, permissions=[], crypto_backend=default_backend()): """ signing_key should be provided in PEM format verifying_key should be provided in compressed hex format issuing_domain should be a valid domain permissions should be a list """ validate_permissions(permissions) self.bitcoin_private_key = BitcoinPrivateKey(signing_key, compressed=True) self.bitcoin_public_key = BitcoinPublicKey(verifying_key) self.tokenizer = Tokenizer(crypto_backend=crypto_backend) self.issuing_domain = issuing_domain self.permissions = permissions self.signing_key = signing_key self.verifying_key = verifying_key
class AuthRequestTest(unittest.TestCase): def setUp(self): self.private_key_hex = str(PRIVATE_KEY) self.public_key_hex = str(PUBLIC_KEY) self.domain_name = 'localhost:3000' self.private_key = BitcoinPrivateKey(self.private_key_hex) self.public_key = BitcoinPublicKey(self.public_key_hex) self.sample_encoded_token = REQUEST_SAMPLE_ENCODED_TOKEN self.sample_decoded_token = REQUEST_SAMPLE_DECODED_TOKEN self.maxDiff = None def tearDown(self): pass def test_auth_request_token_encoding(self): # valid AuthRequest auth_request = AuthRequest(self.private_key_hex, self.domain_name) auth_request_token = auth_request.token() decoded_token = AuthRequest.decode(auth_request_token) payload = decoded_token['payload'] self.assertEqual(payload['public_keys'][0], self.public_key_hex) self.assertEqual(get_address_from_did(payload['iss']), self.public_key.address()) self.assertEqual(payload['scopes'], []) self.assertEqual(payload['manifest_uri'], self.domain_name + '/manifest.json') self.assertTrue(AuthRequest.verify(auth_request_token)) # invalid AuthRequest auth_request = AuthRequest(self.private_key_hex, self.domain_name) auth_request_token = auth_request.token()[:-1] self.assertFalse(AuthRequest.verify(auth_request_token)) def test_auth_request_token_decoding(self): decoded_token = AuthRequest.decode(self.sample_encoded_token) self.assertEqual(decoded_token, self.sample_decoded_token) def test_custom_openssl_backend(self): auth_request = AuthRequest(self.private_key_hex, self.domain_name, crypto_backend=openssl_backend) auth_request_token = auth_request.token() self.assertTrue(AuthRequest.verify(auth_request_token))
balmap = pickle.load(output) # 'obj_dict' is a dict object output = open('pickled_tmpmap.dat', 'rb') tmpmap = pickle.load(output) # 'obj_dict' is a dict object else: if os.path.isfile("genesis.json") == False: print "Downloading Genesis Block" download_file() save_file() json_file = "genesis.json" json_data = open(json_file) data = json.load(json_data) for x in data: try: addy = "" pub = str(x["owner_pubkey"]) pbl = BitcoinPublicKey(pub) tmpmap[pub] = pbl.address() addy = tmpmap[pub] if addy not in balmap: balmap[addy] = 0 balmap[addy] += float(x["mir_amount"]) except Exception as e: print e output = open('pickled_tmpmap.dat', 'wb+') pickle.dump(tmpmap, output) output.close() output = open('pickled_balmap.dat', 'wb+') pickle.dump(balmap, output)
public_key = private_key.public_key() public_key.to_hex() #Test 2 #private key from pybitcoin import BitcoinPrivateKey from pybitcoin import BitcoinPublicKey private_key = BitcoinPrivateKey() private_key.to_hex() private_key.to_wif() #public key public_key = private_key.public_key() public_key.to_hex() public_key_2 = BitcoinPublicKey(str(public_key.to_hex(), "utf-8")[1:]) print(public_key.to_hex() == public_key_2.to_hex()) #Test 3 #private key from pybitcoin import BitcoinPrivateKey from pybitcoin import BitcoinPublicKey from pybitcoin import BlockcypherClient private_key = BitcoinPrivateKey() private_key.to_hex() private_key.to_wif() #insert from to hex below private_key_2 = BitcoinPrivateKey('') #public key public_key = private_key.public_key()
def broadcast(name, data_hash, consensus_hash, private_key, blockchain_client, blockchain_broadcaster=None, tx_only=False, user_public_key=None, testset=False): """ Write a name update into the blockchain. Returns a JSON object with 'data' set to the nulldata and 'transaction_hash' set to the transaction hash on success. """ # sanity check pay_fee = True if user_public_key is not None: pay_fee = False tx_only = True if user_public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if user_public_key is not None: # subsidizing pubk = BitcoinPublicKey(user_public_key) from_address = pubk.address() # get inputs from utxo provider inputs = get_unspents(from_address, blockchain_client) elif private_key is not None: # ordering directly pubk = BitcoinPrivateKey(private_key).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key( private_key, blockchain_client) nulldata = build(name, consensus_hash, data_hash=data_hash, testset=testset) outputs = make_outputs(nulldata, inputs, from_address, pay_fee=pay_fee) if tx_only: unsigned_tx = serialize_transaction(inputs, outputs) return {'unsigned_tx': unsigned_tx} else: signed_tx = tx_serialize_and_sign(inputs, outputs, private_key_obj) response = broadcast_transaction(signed_tx, blockchain_broadcaster) response.update({'data': nulldata}) return response
def get_script_pubkey(public_key): hash160 = BitcoinPublicKey(public_key).hash160() script_pubkey = script_to_hex( 'OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG' % hash160) return script_pubkey
def broadcast(name, destination_address, keepdata, consensus_hash, private_key, blockchain_client, blockchain_broadcaster=None, tx_only=False, user_public_key=None, testset=False): # sanity check pay_fee = True if user_public_key is not None: pay_fee = False tx_only = True if user_public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if user_public_key is not None: # subsidizing pubk = BitcoinPublicKey(user_public_key) from_address = pubk.address() inputs = get_unspents(from_address, blockchain_client) elif private_key is not None: # ordering directly pubk = BitcoinPrivateKey(private_key).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key( private_key, blockchain_client) nulldata = build(name, keepdata, consensus_hash, testset=testset) outputs = make_outputs(nulldata, inputs, destination_address, from_address, pay_fee=pay_fee, format='hex') if tx_only: unsigned_tx = serialize_transaction(inputs, outputs) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(inputs, outputs, private_key_obj, blockchain_broadcaster) response.update({'data': nulldata}) return response