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

Add functions to handle unique prefix mnemonics #99

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/mnemonic.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ char *mnemonic_from_bytes(const struct words *w, const unsigned char *bytes, siz
return str;
}

int mnemonic_to_bytes(const struct words *w, const char *mnemonic,
unsigned char *bytes_out, size_t len, size_t *written)
int mnemonic_to_bytes_internal(const struct words *w, const char *mnemonic,
size_t(*lookup_fn)(const struct words *, const char *),
unsigned char *bytes_out, size_t len, size_t *written)
{
struct words *mnemonic_w = wordlist_init(mnemonic);
size_t i;
Expand All @@ -80,7 +81,7 @@ int mnemonic_to_bytes(const struct words *w, const char *mnemonic,
wally_clear(bytes_out, len);

for (i = 0; i < mnemonic_w->len; ++i) {
size_t idx = wordlist_lookup_word(w, mnemonic_w->indices[i]);
size_t idx = lookup_fn(w, mnemonic_w->indices[i]);
if (!idx) {
wordlist_free(mnemonic_w);
wally_clear(bytes_out, len);
Expand All @@ -95,3 +96,13 @@ int mnemonic_to_bytes(const struct words *w, const char *mnemonic,
wordlist_free(mnemonic_w);
return WALLY_OK;
}

int mnemonic_to_bytes(const struct words *w, const char *mnemonic,
unsigned char *bytes_out, size_t len, size_t *written) {
return mnemonic_to_bytes_internal(w, mnemonic, wordlist_lookup_word, bytes_out, len, written);
}

int mnemonic_prefix_to_bytes(const struct words *w, const char *mnemonic,
unsigned char *bytes_out, size_t len, size_t *written) {
return mnemonic_to_bytes_internal(w, mnemonic, wordlist_lookup_prefix, bytes_out, len, written);
}
16 changes: 16 additions & 0 deletions src/mnemonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,20 @@ int mnemonic_to_bytes(
size_t len,
size_t *written);

/**
* Convert a mnemonic representation into a block of bytes. Accepts unique prefixes of wordlist words.
*
* @w: List of words.
* @mnemonic: Mnemonic sentence to store.
* @bytes_out: Where to store the converted representation.
* @len: The length of @bytes_out in bytes.
* @written: Destination for the number of bytes written.
*/
int mnemonic_prefix_to_bytes(
const struct words *w,
const char *mnemonic,
unsigned char *bytes_out,
size_t len,
size_t *written);

#endif /* LIBWALLY_MNEMONIC_H */
18 changes: 18 additions & 0 deletions src/wordlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ size_t wordlist_lookup_word(const struct words *w, const char *word)
return found ? found - w->indices + 1u : 0u;
}

size_t wordlist_lookup_prefix(const struct words *w, const char *prefix)
Copy link
Contributor

@instagibbs instagibbs Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this breaks with act versus actual/actress/actor/etc mnemonic words, since act prefix matches for 2+ entries.

I think we should restrict the prefix input to length 3 or 4, and if length 3 it must be an exact match.

{
const size_t prefix_len = strlen(prefix);
size_t found = 0;

size_t i;
for (i = 0; i < w->len; ++i) {
if (!strncmp(prefix, w->indices[i], prefix_len)) {
if (found) {
return 0; // prefix match is not unique
}
found = i + 1;
}
}

return found;
}

const char *wordlist_lookup_index(const struct words *w, size_t idx)
{
if (idx >= w->len)
Expand Down
13 changes: 13 additions & 0 deletions src/wordlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ size_t wordlist_lookup_word(
const struct words *w,
const char *word);

/**
* Find the unique word matching a given prefix in a wordlist.
*
* @w: Parsed list of words to look up in.
* @word: The prefix to look up.
*
* Returns 0 if not found OR not unique, idx + 1 otherwise.
* @see wordlist_init.
*/
size_t wordlist_lookup_prefix(
const struct words *w,
const char *prefix);

/**
* Return the Nth word in a wordlist.
*
Expand Down