Example #1
0
    def clean_settings( backup_json ):
        clean_settings = {}
        new_settings = json.loads( backup_json, object_hook=lambda x: Settings.Instance().fix_account_keys(x) )
        if 'bip32master' not in new_settings:
            raise ValueError( "Given JSON doesn't have master key" )
        vbytes, depth, fingerprint, i, chaincode, key = bitcoin.bip32_deserialize( new_settings['bip32master'] )
        if vbytes != bitcoin.PRIVATE or depth != 0 or i != 0 or fingerprint != '\x00'*4:
            raise ValueError( "Master key is not at top of tree and private" )

        clean_settings['bip32master'] = new_settings['bip32master']
        clean_settings['accountNumber'] = new_settings.get( "accountNumber", 1 )
        clean_settings['accounts'] = { }
        
        for account, account_info in new_settings.get( 'accounts', { } ).items():
            if 'accountKey' not in account_info:
                raise ValueError( "Account %i has no master key" % account )
            vbytes, depth, fingerprint, i, chaincode, key = bitcoin.bip32_deserialize( account_info["accountKey"]  )
            if depth != 2 or vbytes != bitcoin.PRIVATE or i != 0:
                raise ValueError( "Account %i has invalid master key" % account )

            if account_info.get( "numKeys", 0 ) < 0:
                raise ValueError( "Account %i has invalid key count " % account )
            clean_settings['accounts'][account] = { }
            clean_settings['accounts'][account]['accountKey'] = account_info['accountKey']
            clean_settings['accounts'][account]['numKeys'] = account_info.get( "numKeys", 0 )
            clean_settings['accounts'][account]['keys'] = []
            KeyHelper.regenerate_keys( account_info['accountKey'], range( account_info.get("numKeys", 0 )), clean_settings['accounts'][account]['keys'] )

            #FIXME: actually check validity of imported redeemscripts
            clean_settings['redeemScripts'] = new_settings.get( 'redeemScripts', [] )

        return clean_settings
Example #2
0
def test_invalid_bip32_key():
    #keys with invalid checksum
    bad_keys = (
    'xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8BrrngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7',
    'xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQQKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw'
    )
    for x in bad_keys:
        with pytest.raises(Exception) as e_info:
            fake_tuple = btc.bip32_deserialize(x)
Example #3
0
    def clean_settings(backup_json):
        clean_settings = {}
        new_settings = json.loads(
            backup_json,
            object_hook=lambda x: Settings.Instance().fix_account_keys(x))
        if 'bip32master' not in new_settings:
            raise ValueError("Given JSON doesn't have master key")
        vbytes, depth, fingerprint, i, chaincode, key = bitcoin.bip32_deserialize(
            new_settings['bip32master'])
        if vbytes != bitcoin.PRIVATE or depth != 0 or i != 0 or fingerprint != '\x00' * 4:
            raise ValueError("Master key is not at top of tree and private")

        clean_settings['bip32master'] = new_settings['bip32master']
        clean_settings['accountNumber'] = new_settings.get("accountNumber", 1)
        clean_settings['accounts'] = {}

        for account, account_info in new_settings.get('accounts', {}).items():
            if 'accountKey' not in account_info:
                raise ValueError("Account %i has no master key" % account)
            vbytes, depth, fingerprint, i, chaincode, key = bitcoin.bip32_deserialize(
                account_info["accountKey"])
            if depth != 2 or vbytes != bitcoin.PRIVATE or i != 0:
                raise ValueError("Account %i has invalid master key" % account)

            if account_info.get("numKeys", 0) < 0:
                raise ValueError("Account %i has invalid key count " % account)
            clean_settings['accounts'][account] = {}
            clean_settings['accounts'][account]['accountKey'] = account_info[
                'accountKey']
            clean_settings['accounts'][account]['numKeys'] = account_info.get(
                "numKeys", 0)
            clean_settings['accounts'][account]['keys'] = []
            KeyHelper.regenerate_keys(
                account_info['accountKey'],
                range(account_info.get("numKeys", 0)),
                clean_settings['accounts'][account]['keys'])

            #FIXME: actually check validity of imported redeemscripts
            clean_settings['redeemScripts'] = new_settings.get(
                'redeemScripts', [])

        return clean_settings
Example #4
0
def key_address(masterkey, path):
    """Compute address and private key (hex) for path"""

    derived_key = descend(masterkey, path)
    priv_key = btc.bip32_deserialize(derived_key)[-1]
    pub_key = btc.bip32_extract_key(btc.bip32_privtopub(derived_key))
    priv_key_hex = btc.encode_privkey(
        btc.decode_privkey(priv_key, 'bin_compressed'), 'hex')
    address = btc.pubkey_to_address(pub_key)

    return priv_key_hex, address
Example #5
0
    def make_moderator(self):
        """
        Set self as a moderator in the DHT.
        """

        u = objects.Profile()
        k = u.PublicKey()
        k.public_key = bitcoin.bip32_deserialize(KeyChain().bitcoin_master_pubkey)[5]
        k.signature = self.signing_key.sign(k.public_key)[:64]
        u.bitcoin_key.MergeFrom(k)
        u.moderator = True
        Profile().update(u)
        proto = self.kserver.node.getProto().SerializeToString()
        self.kserver.set(digest("moderators"), digest(proto), proto)
Example #6
0
    def make_moderator(self):
        """
        Set self as a moderator in the DHT.
        """

        u = objects.Profile()
        k = u.PublicKey()
        k.public_key = bitcoin.bip32_deserialize(KeyChain(self.db).bitcoin_master_pubkey)[5]
        k.signature = self.signing_key.sign(k.public_key)[:64]
        u.bitcoin_key.MergeFrom(k)
        u.moderator = True
        Profile(self.db).update(u)
        proto = self.kserver.node.getProto().SerializeToString()
        self.kserver.set(digest("moderators"), digest(proto), proto)
 def test_child_generation(self):
     public_keychain = PublicKeychain.from_public_key(self.public_key_hex)
     public_keychain_child = public_keychain.child(0)
     keychain_parts = bip32_deserialize(str(public_keychain_child))
     self.assertEqual(keychain_parts[4], self.reference_child_0_chaincode)
Example #8
0
 def test_child_generation(self):
     public_keychain = PublicKeychain.from_public_key(self.public_key_hex)
     public_keychain_child = public_keychain.child(0)
     keychain_parts = bip32_deserialize(str(public_keychain_child))
     self.assertEqual(keychain_parts[4], self.reference_child_0_chaincode)
Example #9
0
def is_bip32_pubkey(s):
    try:
        key = btc.bip32_deserialize(s)
        return key[0] in btc.PUBLIC
    except Exception:
        return False
Example #10
0
    def create(self,
               expiration_date,
               metadata_category,
               title,
               description,
               currency_code,
               price,
               process_time,
               nsfw,
               shipping_origin,
               shipping_regions,
               est_delivery_domestic=None,
               est_delivery_international=None,
               terms_conditions=None,
               returns=None,
               keywords=None,
               category=None,
               condition=None,
               sku=None,
               images=None,
               free_shipping=None,
               shipping_currency_code=None,
               shipping_domestic=None,
               shipping_international=None,
               options=None,
               moderators=None):
        """
        All parameters are strings except:

        :param expiration_date: `string` (must be formatted UTC datetime)
        :param keywords: `list`
        :param nsfw: `boolean`
        :param images: a `list` of image files
        :param free_shipping: `boolean`
        :param shipping_origin: a 'string' formatted `CountryCode`
        :param shipping_regions: a 'list' of 'string' formatted `CountryCode`s
        :param options: a 'dict' containing options as keys and 'list' as option values.
        :param moderators: a 'list' of 'string' guids (hex encoded).
        """

        # TODO: import keys into the contract, import moderator information from db, sign contract.
        profile = Profile().get()
        keychain = KeyChain()
        self.contract = OrderedDict(
            {
                "vendor_offer": {
                    "listing": {
                        "metadata": {
                            "version": "0.1",
                            "expiry": expiration_date + " UTC",
                            "category": metadata_category,
                            "category_sub": "fixed price"
                        },
                        "id": {
                            "guid": keychain.guid.encode("hex"),
                            "pubkeys": {
                                "guid": keychain.guid_signed_pubkey[64:].encode("hex"),
                                "bitcoin": bitcoin.bip32_deserialize(
                                    KeyChain().bitcoin_master_pubkey)[5].encode("hex")
                            }
                        },
                        "item": {
                            "title": title,
                            "description": description,
                            "process_time": process_time,
                            "price_per_unit": {},
                            "nsfw": nsfw
                        }
                    }
                }
            }
        )
        if metadata_category == "physical good" and condition is not None:
            self.contract["vendor_offer"]["listing"]["item"]["condition"] = condition
        if currency_code.upper() == "BTC":
            item = self.contract["vendor_offer"]["listing"]["item"]
            item["price_per_unit"]["bitcoin"] = price
        else:
            item = self.contract["vendor_offer"]["listing"]["item"]
            item["price_per_unit"]["fiat"] = {}
            item["price_per_unit"]["fiat"]["price"] = price
            item["price_per_unit"]["fiat"]["currency_code"] = currency_code
        if keywords is not None:
            self.contract["vendor_offer"]["listing"]["item"]["keywords"] = []
            self.contract["vendor_offer"]["listing"]["item"]["keywords"].extend(keywords)
        if category is not None:
            self.contract["vendor_offer"]["listing"]["item"]["category"] = category
        if sku is not None:
            self.contract["vendor_offer"]["listing"]["item"]["sku"] = sku
        if options is not None:
            self.contract["vendor_offer"]["listing"]["item"]["options"] = options
        if metadata_category == "physical good":
            self.contract["vendor_offer"]["listing"]["shipping"] = {}
            shipping = self.contract["vendor_offer"]["listing"]["shipping"]
            shipping["shipping_origin"] = shipping_origin
            if free_shipping is False:
                self.contract["vendor_offer"]["listing"]["shipping"]["free"] = False
                self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"] = {}
                if shipping_currency_code == "BTC":
                    self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"]["bitcoin"] = {}
                    self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"]["bitcoin"][
                        "domestic"] = shipping_domestic
                    self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"]["bitcoin"][
                        "international"] = shipping_international
                else:
                    shipping = self.contract["vendor_offer"]["listing"]["shipping"]
                    shipping["flat_fee"]["fiat"] = {}
                    shipping["flat_fee"]["fiat"]["price"] = {}
                    shipping["flat_fee"]["fiat"]["price"][
                        "domestic"] = shipping_domestic
                    shipping["flat_fee"]["fiat"]["price"][
                        "international"] = shipping_international
                    shipping["flat_fee"]["fiat"][
                        "currency_code"] = shipping_currency_code
            else:
                self.contract["vendor_offer"]["listing"]["shipping"]["free"] = True
            self.contract["vendor_offer"]["listing"]["shipping"]["shipping_regions"] = []
            for region in shipping_regions:
                shipping = self.contract["vendor_offer"]["listing"]["shipping"]
                shipping["shipping_regions"].append(region)
            listing = self.contract["vendor_offer"]["listing"]
            listing["shipping"]["est_delivery"] = {}
            listing["shipping"]["est_delivery"]["domestic"] = est_delivery_domestic
            listing["shipping"]["est_delivery"][
                "international"] = est_delivery_international
        if profile.HasField("handle"):
            self.contract["vendor_offer"]["listing"]["id"]["blockchain_id"] = profile.handle
        if images is not None:
            self.contract["vendor_offer"]["listing"]["item"]["image_hashes"] = []
            for image in images:
                hash_value = digest(image).encode("hex")
                self.contract["vendor_offer"]["listing"]["item"]["image_hashes"].append(hash_value)
                with open(DATA_FOLDER + "store/media/" + hash_value, 'w') as outfile:
                    outfile.write(image)
                HashMap().insert(digest(image), DATA_FOLDER + "store/media/" + hash_value)
        if terms_conditions is not None or returns is not None:
            self.contract["vendor_offer"]["listing"]["policy"] = {}
            if terms_conditions is not None:
                self.contract["vendor_offer"]["listing"]["policy"]["terms_conditions"] = terms_conditions
            if returns is not None:
                self.contract["vendor_offer"]["listing"]["policy"]["returns"] = returns
        if moderators is not None:
            self.contract["vendor_offer"]["listing"]["moderators"] = []
            for mod in moderators:
                mod_info = ModeratorStore().get_moderator(unhexlify(mod))
                print mod_info
                if mod_info is not None:
                    moderator = {
                        "guid": mod,
                        "blockchain_id": mod_info[6],
                        "pubkeys": {
                            "signing": {
                                "key": mod_info[1][64:].encode("hex"),
                                "signature": mod_info[1][:64].encode("hex")
                            },
                            "encryption": {
                                "key": mod_info[2].encode("hex"),
                                "signature": mod_info[3].encode("hex")
                            },
                            "bitcoin": {
                                "key": mod_info[4].encode("hex"),
                                "signature": mod_info[5].encode("hex")
                            }
                        }
                    }
                    self.contract["vendor_offer"]["listing"]["moderators"].append(moderator)

        listing = json.dumps(self.contract["vendor_offer"]["listing"], indent=4)
        self.contract["vendor_offer"]["signature"] = \
            keychain.signing_key.sign(listing, encoder=nacl.encoding.HexEncoder)[:128]
        self.save()