Exemple #1
0
def generate(passphrase, trees=['primary']):
    """Generate a seed for the primary tree of a Gem wallet.

    You may choose to store the passphrase for a user so the user doesn't have
    to type it in every time. This is okay (although the security risks should
    be obvious) but Gem strongly discourages storing even the encrypted private
    seed, and storing both the passphrase and the private seed is completely
    insane. Don't do it.

    Args:
      passphrase (str): The passphrase that will be used to encrypt the seed
        before it's send to Gem. Key-stretching is done with PBDKF2 and
        encryption is done with nacl's SecretBox.
      trees (list of str): A list of names to generate trees for. For User
        Wallets this will be ['primary'], for Application Wallets it will be
       ['primary', 'backup'].

    Returns:
      A dict of dicts containing the serialized public master node, and
       a sub-dict with the encrypted private seed for each tree in `trees`.
    """
    seeds, multi_wallet = MultiWallet.generate(trees, entropy=True)

    result = {}
    for tree in trees:
        result[tree] = dict(private_seed=seeds[tree],
                            public_seed=multi_wallet.public_wif(tree),
                            encrypted_seed=PassphraseBox.encrypt(passphrase,
                                                                 seeds[tree]))
    return result
Exemple #2
0
def generate(passphrase, trees=['primary']):
    """Generate a seed for the primary tree of a Gem wallet.

    You may choose to store the passphrase for a user so the user doesn't have
    to type it in every time. This is okay (although the security risks should
    be obvious) but Gem strongly discourages storing even the encrypted private
    seed, and storing both the passphrase and the private seed is completely
    insane. Don't do it.

    Args:
      passphrase (str): The passphrase that will be used to encrypt the seed
        before it's send to Gem. Key-stretching is done with PBDKF2 and
        encryption is done with nacl's SecretBox.
      trees (list of str): A list of names to generate trees for. For User
        Wallets this will be ['primary'], for Application Wallets it will be
       ['primary', 'backup'].

    Returns:
      A dict of dicts containing the serialized public master node, and
       a sub-dict with the encrypted private seed for each tree in `trees`.
    """
    seeds, multi_wallet = MultiWallet.generate(trees, entropy=True)

    result = {}
    for tree in trees:
        result[tree] = dict(private_seed=seeds[tree],
                            public_seed=multi_wallet.public_wif(tree),
                            encrypted_seed=PassphraseBox.encrypt(
                                passphrase, seeds[tree]))
    return result
Exemple #3
0
    def unlock(self, passphrase):
        """Unlock the Wallet by decrypting the primary_private_seed with the
        supplied passphrase. Once unlocked, the private seed is accessible in
        memory and calls to `account.pay` will succeed. This is a necessary step
        for creating transactions.

        Args:
          passphrase (str): The passphrase the User used to encrypt this wallet.
        Returns:
          self
        """
        wallet = self.resource
        try:
            if wallet.primary_private_seed['nonce']:
                primary_seed = NaclPassphraseBox.decrypt(
                    passphrase, wallet.primary_private_seed)
            else:
                primary_seed = PassphraseBox.decrypt(
                    passphrase, wallet.primary_private_seed)
        except:
            raise InvalidPassphraseError()

        self.multi_wallet = MultiWallet(
            private_seeds={'primary': primary_seed},
            public={'cosigner': wallet.cosigner_public_seed,
                    'backup': wallet.backup_public_seed})
        return self
Exemple #4
0
    def unlock(self, passphrase, encrypted_seed=None):
        """Unlock the Wallet by decrypting the primary_private_seed with the
        supplied passphrase. Once unlocked, the private seed is accessible in
        memory and calls to `account.pay` will succeed. This is a necessary step
        for creating transactions.

        Args:
          passphrase (str): The passphrase the User used to encrypt this wallet.
          encrypted_seed (dict): A dictionary of the form
            {'ciphertext': longhexvalue,
             'iterations': integer of pbkdf2 derivations,
             'nonce': 24-byte hex value
             'salt': 16-byte hex value}
            this dict represents an private seed (not a master key) encrypted
            with the `passphrase` using pbkdf2. You can obtain this value with
            wallet.generate. If this value is supplied, it overwrites (locally
            only) the encrypted primary_private_seed value, allowing you to load
            in a primary key that you didn't store with Gem. Note that the key
            MUST match the pubkey that this wallet was created with.
        Returns:
          self
        """
        wallet = self.resource
        if not encrypted_seed:
            encrypted_seed = wallet.primary_private_seed
        try:
            if encrypted_seed['nonce']:
                primary_seed = NaclPassphraseBox.decrypt(
                    passphrase, encrypted_seed)
            else:
                primary_seed = PassphraseBox.decrypt(passphrase,
                                                     encrypted_seed)
        except:
            raise InvalidPassphraseError()

        self.multi_wallet = MultiWallet(
            private_seeds={'primary': primary_seed},
            public={
                'cosigner': wallet.cosigner_public_seed,
                'backup': wallet.backup_public_seed
            })
        return self
Exemple #5
0
    def unlock(self, passphrase, encrypted_seed=None):
        """Unlock the Wallet by decrypting the primary_private_seed with the
        supplied passphrase. Once unlocked, the private seed is accessible in
        memory and calls to `account.pay` will succeed. This is a necessary step
        for creating transactions.

        Args:
          passphrase (str): The passphrase the User used to encrypt this wallet.
          encrypted_seed (dict): A dictionary of the form
            {'ciphertext': longhexvalue,
             'iterations': integer of pbkdf2 derivations,
             'nonce': 24-byte hex value
             'salt': 16-byte hex value}
            this dict represents an private seed (not a master key) encrypted
            with the `passphrase` using pbkdf2. You can obtain this value with
            wallet.generate. If this value is supplied, it overwrites (locally
            only) the encrypted primary_private_seed value, allowing you to load
            in a primary key that you didn't store with Gem. Note that the key
            MUST match the pubkey that this wallet was created with.
        Returns:
          self
        """
        wallet = self.resource
        if not encrypted_seed:
            encrypted_seed = wallet.primary_private_seed
        try:
            if encrypted_seed['nonce']:
                primary_seed = NaclPassphraseBox.decrypt(
                    passphrase, encrypted_seed)
            else:
                primary_seed = PassphraseBox.decrypt(
                    passphrase, encrypted_seed)
        except:
            raise InvalidPassphraseError()

        self.multi_wallet = MultiWallet(
            private_seeds={'primary': primary_seed},
            public={'cosigner': wallet.cosigner_public_seed,
                    'backup': wallet.backup_public_seed})
        return self