Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Passphrase to use a different dictionary for each word #2

Open
kalekundert opened this issue Apr 10, 2022 · 0 comments
Open

Allow Passphrase to use a different dictionary for each word #2

kalekundert opened this issue Apr 10, 2022 · 0 comments

Comments

@kalekundert
Copy link
Collaborator

In order to make passphrases that satisfy requirements for numeric/uppercase/special characters enforced by many services, it's often necessary to add hard-coded prefixes or suffixes. However, doing this makes the passphrase feel more like a janky password. I think a more elegant solution would be to allow a different dictionary to be used for each word. This way, instead of a passphrase like "correct horse battery staple1!", you could have "correct horse battery staple 1+2=3". I think the latter is much easier to remember and more consistent with the idea of a passphrase.

I think the best way to do something like this is to provide the callable form of the dictionary argument to Passphrase with the index of the desired word. This would allow dictionary functions like the following to be written:

def multi(*dictionaries):
    """
    Use the given dictionaries in the given order.  If there are fewer 
    dictionaries than words, the last dictionary will be used for all extra 
    words.
    """

    def dictionary(i):
        return dictionaries[min(i, len(dictionaries))]

    return dictionary

def numbers(i):
     return map(str, range(1000))

This would be used as follows, to generate passphrases like "123 correct horse battery":

class MyAccount(Account):
    passcode = Passphrase(
        dictionary=multi(numbers, 'default'),
    )

Some miscellaneous related thoughts:

  • In order for this feature to really be convenient, dictionary callables would need to be able to return dictionaries in any of the forms currently accepted by the dictionary argument (i.e. strings, list of strings, or callables). This might already be the case, I haven't checked.
  • I just thought of using arithmetic expressions as words when I wrote the "1+2=3" example above, but I think it's a good idea. It wouldn't be too hard to generate the set of all arithmetic operations involving two 1-2 digit whole numbers that result in a whole number, and that'd be a great way to get numbers and special characters into a passphrase.
  • It would also be nice to have built-in functions that transform dictionaries into upper/title case. Such functions would also have to support all three dictionary forms (strings, list of strings, callables), which would be the tricky part.
  • In the interest of future compatibility, it might be better to make the "i" argument an object instead of an integer index. That would make it easy to provide more information to these functions, just by adding more attributes.

Don't feel any pressure to work on this. This has just been bugging me for a while, and I finally had an idea for how to address it, so I wanted to record it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant