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

use mnemonic enum instead of const pointer to global array #8

Merged
merged 1 commit into from
Aug 14, 2024
Merged
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
3 changes: 3 additions & 0 deletions include/gradido_blockchain/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@

#define GRADIDO_DEFERRED_TRANSFER_MAX_TIMEOUT_INTERVAL std::chrono::months(3)

// passphrase word count
#define PHRASE_WORD_COUNT 24

#endif //__GRADIDO_BLOCKCHAIN_CONST_H
2 changes: 2 additions & 0 deletions include/gradido_blockchain/crypto/CryptoConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ namespace CryptoConfig
GRADIDOBLOCKCHAIN_EXPORT extern memory::BlockPtr g_SupportPublicKey;
GRADIDOBLOCKCHAIN_EXPORT extern Mnemonic g_Mnemonic_WordLists[magic_enum::enum_integer(MnemonicType::MAX)];


// throw exception on error
//!
//! \param printToFile if true, print every word list in a separat txt file for debugging
GRADIDOBLOCKCHAIN_EXPORT void loadMnemonicWordLists(bool printToFile = false);
GRADIDOBLOCKCHAIN_EXPORT bool loadCryptoKeys(const MapEnvironmentToConfig& cfg);
GRADIDOBLOCKCHAIN_EXPORT void unload();
GRADIDOBLOCKCHAIN_EXPORT const Mnemonic* getWordList(MnemonicType type);

class GRADIDOBLOCKCHAIN_EXPORT MissingKeyException : GradidoBlockchainException
{
Expand Down
15 changes: 8 additions & 7 deletions include/gradido_blockchain/crypto/Passphrase.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#define __GRADIDO_LOGIN_SERVER_CRYPTO_PASSPHRASE_H

#include "gradido_blockchain/memory/Block.h"
#include "mnemonic.h"
#include "MnemonicType.h"
#include "gradido_blockchain/GradidoBlockchainException.h"
#include "gradido_blockchain/const.h"

#include <memory>
#include <array>
Expand All @@ -14,17 +15,17 @@ class GRADIDOBLOCKCHAIN_EXPORT Passphrase
{
public:
Passphrase() = delete;
Passphrase(const std::string& passphrase, const Mnemonic* wordSource);
Passphrase(const std::string& passphrase, MnemonicType wordListType);

static std::shared_ptr<Passphrase> create(const std::array<uint16_t, PHRASE_WORD_COUNT>& wordIndices, const Mnemonic* wordSource);
static std::shared_ptr<Passphrase> create(const std::array<uint16_t, PHRASE_WORD_COUNT>& wordIndices, MnemonicType wordListType);
//! \brief generate new passphrase with random
static std::shared_ptr<Passphrase> generate(const Mnemonic* wordSource);
static std::shared_ptr<Passphrase> generate(MnemonicType wordListType);

static const Mnemonic* detectMnemonic(const std::string& passphrase, const KeyPairEd25519* userKeyPair = nullptr);
static MnemonicType detectMnemonic(const std::string& passphrase, const KeyPairEd25519* userKeyPair = nullptr);

//! \brief transform passphrase into another language/mnemonic source
//! \return this if targetWordSource is the same as mWordSource
std::shared_ptr<Passphrase> transform(const Mnemonic* targetWordSource);
std::shared_ptr<Passphrase> transform(MnemonicType wordListType);

//! \brief create clear passphrase from word indices from bitcoin word list (bip0039)
//!
Expand All @@ -49,7 +50,7 @@ class GRADIDOBLOCKCHAIN_EXPORT Passphrase
void createWordIndices();

std::string mPassphraseString;
const Mnemonic* mWordSource;
MnemonicType mWordListType;
std::array<uint16_t, PHRASE_WORD_COUNT> mWordIndices;
};

Expand Down
10 changes: 4 additions & 6 deletions include/gradido_blockchain/crypto/mnemonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@
*/
#include "gradido_blockchain/GradidoBlockchainException.h"
#include "gradido_blockchain/lib/DRHashList.h"
#include "MnemonicType.h"
#include <string>
#include <shared_mutex>
#include <map>
#include <list>
#include <vector>

#define PHRASE_WORD_COUNT 24


class GRADIDOBLOCKCHAIN_EXPORT Mnemonic
{
public:
Expand Down Expand Up @@ -65,12 +63,12 @@ class MnemonicException : public GradidoBlockchainException
explicit MnemonicException(const char* what, const char* word = nullptr);
std::string getFullString() const noexcept;

MnemonicException& setMnemonic(const Mnemonic* mnemonic);
inline int getMnemonicIndex() { return mMnemonicIndex; }
MnemonicException& setWordListType(MnemonicType type) { mMnemonicType = type; return *this; }
inline MnemonicType getWordListType() { return mMnemonicType; }

protected:
std::string mWord;
int mMnemonicIndex;
MnemonicType mMnemonicType;
};


Expand Down
7 changes: 6 additions & 1 deletion src/crypto/CryptoConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace CryptoConfig
}
catch (MnemonicException& ex) {
// add info and rethrow
throw ex.setMnemonic(&g_Mnemonic_WordLists[i]);
throw ex.setWordListType(type);
}
if (printToFile) {
std::string fileName(enum_name(type));
Expand Down Expand Up @@ -91,6 +91,11 @@ namespace CryptoConfig
g_SupportPublicKey.reset();
}

const Mnemonic* getWordList(MnemonicType type)
{
return &CryptoConfig::g_Mnemonic_WordLists[enum_integer(type)];
}

// ####################### exception ##################################
MissingKeyException::MissingKeyException(const char* what, const char* keyName) noexcept
: GradidoBlockchainException(what), mKeyName(keyName)
Expand Down
50 changes: 22 additions & 28 deletions src/crypto/Passphrase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ static std::vector<std::pair<int, std::string>> g_specialChars = {
{ 0x9f, "szlig" }
};

Passphrase::Passphrase(const std::string& passphrase, const Mnemonic* wordSource)
: mPassphraseString(filter(passphrase)), mWordSource(wordSource)
Passphrase::Passphrase(const std::string& passphrase, MnemonicType wordListType)
: mPassphraseString(filter(passphrase)), mWordListType(wordListType)
{
mWordIndices.fill(0);
createWordIndices();
Expand Down Expand Up @@ -103,19 +103,16 @@ std::string Passphrase::filter(const std::string& passphrase)
return filteredPassphrase;
}

std::shared_ptr<Passphrase> Passphrase::transform(const Mnemonic* targetWordSource)
std::shared_ptr<Passphrase> Passphrase::transform(MnemonicType wordListType)
{
if (!targetWordSource || !mWordSource) {
return nullptr;
}
return create(mWordIndices, targetWordSource);
return create(mWordIndices, wordListType);
}

std::string Passphrase::createClearPassphrase() const
{
auto word_indices = getWordIndices();
std::string clear_passphrase;
auto word_source = &CryptoConfig::g_Mnemonic_WordLists[enum_integer(MnemonicType::BIP0039_SORTED_ORDER)];
auto word_source = CryptoConfig::getWordList(MnemonicType::BIP0039_SORTED_ORDER);
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
auto word = word_source->getWord(word_indices[i]);
if (word) {
Expand All @@ -126,11 +123,11 @@ std::string Passphrase::createClearPassphrase() const
return clear_passphrase;
}

std::shared_ptr<Passphrase> Passphrase::create(const std::array<uint16_t, PHRASE_WORD_COUNT>& wordIndices, const Mnemonic* wordSource)
std::shared_ptr<Passphrase> Passphrase::create(const std::array<uint16_t, PHRASE_WORD_COUNT>& wordIndices, MnemonicType wordListType)
{
std::string clearPassphrase;
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
auto word = wordSource->getWord(wordIndices[i]);
auto word = CryptoConfig::getWordList(wordListType)->getWord(wordIndices[i]);
if (word) {
clearPassphrase += word;
clearPassphrase += " ";
Expand All @@ -139,28 +136,26 @@ std::shared_ptr<Passphrase> Passphrase::create(const std::array<uint16_t, PHRASE
return nullptr;
}
}
return std::shared_ptr<Passphrase>(new Passphrase(clearPassphrase, wordSource));
return std::shared_ptr<Passphrase>(new Passphrase(clearPassphrase, wordListType));
}

std::shared_ptr<Passphrase> Passphrase::generate(const Mnemonic* wordSource)
std::shared_ptr<Passphrase> Passphrase::generate(MnemonicType wordListType)
{
std::array<uint16_t, PHRASE_WORD_COUNT> word_indices;
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
word_indices[i] = randombytes_random() % 2048;
}
return create(word_indices, wordSource);
return create(word_indices, wordListType);
}

void Passphrase::createWordIndices()
{
if (!mWordSource) {
throw PassphraseEmptyWordSourceException();
}
size_t passphraseSize = mPassphraseString.size();

std::array<char, STR_BUFFER_SIZE> buffer;
buffer.fill(0);
size_t bufferCursor = 0;
auto wordList = CryptoConfig::getWordList(mWordListType);

// get word indices for hmac key
unsigned char word_cursor = 0;
Expand All @@ -170,12 +165,12 @@ void Passphrase::createWordIndices()
if (bufferCursor < 3) {
continue;
}
if (PHRASE_WORD_COUNT > word_cursor && mWordSource->isWordExist(buffer.data())) {
mWordIndices[word_cursor] = mWordSource->getWordIndex(buffer.data());
if (PHRASE_WORD_COUNT > word_cursor && wordList->isWordExist(buffer.data())) {
mWordIndices[word_cursor] = wordList->getWordIndex(buffer.data());
}
else {
MnemonicException exception("word don't exist", buffer.data());
exception.setMnemonic(mWordSource);
exception.setWordListType(mWordListType);
throw exception;
}
word_cursor++;
Expand All @@ -188,14 +183,13 @@ void Passphrase::createWordIndices()
buffer[bufferCursor++] = *it;
}
}
if (PHRASE_WORD_COUNT > word_cursor && mWordSource->isWordExist(buffer.data())) {
mWordIndices[word_cursor] = mWordSource->getWordIndex(buffer.data());
if (PHRASE_WORD_COUNT > word_cursor && wordList->isWordExist(buffer.data())) {
mWordIndices[word_cursor] = wordList->getWordIndex(buffer.data());
}
}

bool Passphrase::checkIfValid()
{
if (!mWordSource) return false;
std::istringstream iss(mPassphraseString);
std::vector<std::string> results(
std::istream_iterator<std::string>{iss},
Expand All @@ -205,13 +199,13 @@ bool Passphrase::checkIfValid()
bool existAll = true;
for (auto it = results.begin(); it != results.end(); it++) {
if (*it == "\0" || *it == "" || it->size() < 3) continue;
if (!mWordSource->isWordExist(it->data())) {
if (!CryptoConfig::getWordList(mWordListType)->isWordExist(it->data())) {
return false;
}
}
return true;
}
const Mnemonic* Passphrase::detectMnemonic(const std::string& passphrase, const KeyPairEd25519* userKeyPair /* = nullptr*/)
MnemonicType Passphrase::detectMnemonic(const std::string& passphrase, const KeyPairEd25519* userKeyPair /* = nullptr*/)
{
std::istringstream iss(passphrase);
std::vector<std::string> results(
Expand All @@ -229,9 +223,9 @@ const Mnemonic* Passphrase::detectMnemonic(const std::string& passphrase, const
}
#endif
std::string last_words_not_found[enum_integer(MnemonicType::MAX)];
Mnemonic* result = nullptr;
MnemonicType result = MnemonicType::MAX;
enum_for_each<MnemonicType>([&](auto val) {
if (result) return;
if (result != MnemonicType::MAX) return;
constexpr MnemonicType type = val;
if(type == MnemonicType::MAX) return;
int i = enum_integer(type);
Expand All @@ -256,7 +250,7 @@ const Mnemonic* Passphrase::detectMnemonic(const std::string& passphrase, const
{
if (userKeyPair)
{
std::shared_ptr<Passphrase> test_passphrase(new Passphrase(passphrase, &m));
std::shared_ptr<Passphrase> test_passphrase(new Passphrase(passphrase, type));
test_passphrase->createWordIndices();
auto keyPairFromPassphrase = KeyPairEd25519::create(test_passphrase);
if (keyPairFromPassphrase)
Expand All @@ -276,7 +270,7 @@ const Mnemonic* Passphrase::detectMnemonic(const std::string& passphrase, const
}
}
}
result = &CryptoConfig::g_Mnemonic_WordLists[i];
result = type;
// return &CryptoConfig::g_Mnemonic_WordLists[i];
}
#ifdef _DEBUG
Expand Down
20 changes: 2 additions & 18 deletions src/crypto/mnemonic.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

#include "gradido_blockchain/crypto/CryptoConfig.h"
#include "gradido_blockchain/crypto/MnemonicType.h"
#include "gradido_blockchain/crypto/mnemonic.h"
#include "gradido_blockchain/const.h"

#include "tinf.h"
#include "magic_enum/magic_enum_utility.hpp"
Expand Down Expand Up @@ -340,29 +340,13 @@ std::string Mnemonic::getSortedWordListJsonString()


MnemonicException::MnemonicException(const char* what, const char* word/* = nullptr*/) :
GradidoBlockchainException(what), mMnemonicIndex(-1)
GradidoBlockchainException(what), mMnemonicType(MnemonicType::BIP0039_SORTED_ORDER)
{
if (word) {
mWord = word;
}
}

MnemonicException& MnemonicException::setMnemonic(const Mnemonic* mnemonic)
{
int mnemonicIndex = 0;
enum_for_each<MnemonicType>([&mnemonicIndex, mnemonic](auto val) {
if (mnemonicIndex) return;
constexpr MnemonicType type = val;
int i = enum_integer(type);
if (&CryptoConfig::g_Mnemonic_WordLists[i] == mnemonic) {
mnemonicIndex = i;
return;
}
});
mMnemonicIndex = mnemonicIndex;
return *this;
}

std::string MnemonicException::getFullString() const noexcept
{
if (mWord.size()) {
Expand Down
Loading
Loading