2021-10-13 16:44:13 +02:00
|
|
|
/*
|
|
|
|
|
* This file is part of the Flowee project
|
2025-04-07 13:40:31 +02:00
|
|
|
* Copyright (C) 2021-2025 Tom Zander <tom@flowee.org>
|
2021-10-13 16:44:13 +02:00
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
2024-01-22 19:32:15 +01:00
|
|
|
#ifndef FLOWEE_MNEMONIC_H
|
|
|
|
|
#define FLOWEE_MNEMONIC_H
|
2021-10-13 16:44:13 +02:00
|
|
|
|
|
|
|
|
#include <QMap>
|
|
|
|
|
#include <QStringList>
|
2021-10-25 13:36:53 +02:00
|
|
|
#include <vector>
|
2021-10-13 16:44:13 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Supplies validation of the BIP39 style mnemonics
|
|
|
|
|
*
|
|
|
|
|
* Notice that other than validation this class is not going to be helpful to
|
|
|
|
|
* process the actual data, check out the class HDMasterKey for that.
|
|
|
|
|
*
|
|
|
|
|
* A single Mnemonic instance holds a list of possible dictionaries and allows
|
|
|
|
|
* UI validation of the text using findWord() an clearSelectedLanguage().
|
|
|
|
|
* If it looks like the user is done with the whole 12 or more words mnemonic
|
|
|
|
|
* you can use the validateMnemonic() call. When this returns `Valid` we know that
|
|
|
|
|
* the mnemonic sentence is proper and checksums pass.
|
|
|
|
|
*/
|
|
|
|
|
class Mnemonic
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* Used by validateMnemonic()
|
|
|
|
|
*/
|
|
|
|
|
enum Validity {
|
|
|
|
|
Valid, ///< A fully valid mnemonic was found.
|
|
|
|
|
WhitespaceError, ///< please fix your whitespace before validating.
|
|
|
|
|
IncorrectWordCount, ///< failed basic checks
|
|
|
|
|
UnknownLanguage, ///< first word can not be found.
|
|
|
|
|
UnknownWord, ///< word can not be found in selected dict
|
|
|
|
|
ChecksumFailure ///< Incorrect checksum
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Find a word in the dictionary, or a dictionary to fit the word.
|
|
|
|
|
* This method will fill the \a dict on first use and fetch the
|
|
|
|
|
* index on further usages from the existng dict.
|
|
|
|
|
* @return the word, or -1 if not found.
|
|
|
|
|
*/
|
|
|
|
|
int findWord(const QString &word);
|
2025-04-07 13:40:31 +02:00
|
|
|
QStringList completeWords(const QString &partialWord) const;
|
2021-10-13 16:44:13 +02:00
|
|
|
|
|
|
|
|
/// returns the selected id of the wordlist. Or empty if nothing is selected.
|
|
|
|
|
QString languageId() const;
|
|
|
|
|
void clearSelectedLanguage();
|
|
|
|
|
|
|
|
|
|
/// Add a word-list and languageId.
|
|
|
|
|
void registerWordList(const QString &id, const QString &filename);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Validate the mnemonic string on correctness.
|
|
|
|
|
* This method will check the individual words actually match
|
|
|
|
|
* a known word-list and also check the checksum build into the bip32-style
|
|
|
|
|
* mnemonics.
|
|
|
|
|
* @param mnemonic the actual full sentence of words.
|
|
|
|
|
* @param[out] index-in-text of the first word not recognized, if any.
|
2023-10-18 20:50:41 +03:00
|
|
|
* @param[out] optional out param to store a flag if this phrase is valid
|
|
|
|
|
* as an Electrum mnemonic. This flag can only be set to true
|
|
|
|
|
* if this function returns either Valid or ChecksumFailure.
|
2021-10-13 16:44:13 +02:00
|
|
|
*/
|
2023-10-18 20:50:41 +03:00
|
|
|
Validity validateMnemonic(const QString &mnemonic, int &errorIndex, bool *maybeElectrum = nullptr);
|
2021-10-13 16:44:13 +02:00
|
|
|
|
2021-10-25 13:36:53 +02:00
|
|
|
QString generateMnemonic(const std::vector<uint8_t> &entropy, const QString &langId = QString("en")) const;
|
|
|
|
|
|
2021-10-13 16:44:13 +02:00
|
|
|
private:
|
2023-10-18 20:50:41 +03:00
|
|
|
/**
|
|
|
|
|
* Validate the mnemonic against the old legacy "Electrum" mnemonic format,
|
|
|
|
|
* which uses the same word list as BIP39, but uses a different checksum
|
|
|
|
|
* mechanism as well as a different pbkdf512 hash salt.
|
|
|
|
|
* Note: A correct Electrum mnemonic always either turns out to be BIP39
|
|
|
|
|
* "valid" or has the same word list but fails the BIP39 checksum. If
|
|
|
|
|
* neither of these criteria are met, it cannot be a valid Electrum
|
|
|
|
|
* mnemonic. For simplicity, this helper function does not check that these
|
|
|
|
|
* criteria are met, it simply hashes the mnemonic and checks its checksum.
|
|
|
|
|
* @param mnemonic the actual full sentence of words.
|
|
|
|
|
* @return true if the mnemonic validates as Electrum, false otherwise; note
|
|
|
|
|
* that 1/256th of the time, it's possible for the same mnemonic
|
|
|
|
|
* phrase to validate correctly as both BIP39 and Electrum
|
|
|
|
|
* simultaneously, hence the "maybe" name for this function.
|
|
|
|
|
*/
|
|
|
|
|
bool maybeValidElectrumMnemonic(const QString &mnemonic) const;
|
|
|
|
|
|
2021-10-13 16:44:13 +02:00
|
|
|
QMap<QString, QString> m_wordLists; // id -> filename
|
|
|
|
|
|
|
|
|
|
QString m_languageId;
|
|
|
|
|
QStringList m_words;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|