Skip to content

Commit

Permalink
use mnemonic enum instead of const pointer to global array
Browse files Browse the repository at this point in the history
  • Loading branch information
unicorny committed Aug 14, 2024
1 parent 9b1aecd commit ff6472f
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 84 deletions.
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

0 comments on commit ff6472f

Please sign in to comment.