#include "stdafx.h" using ristretto255::hash, ristretto255::hsh, ristretto255::scalar, ristretto255::point; namespace ro { // fasthash fails at obliterating some forms of order in its input, but // but this is OK, because our inputs are random to start with, and // all we care about is good mixing and dispersion of that randomness. uint32_t fasthash(uint64_t id, std::span sp) { static constexpr uint64_t two_to_the_64_divided_by_golden_ratio{ 11400714819323198485 }; id *= two_to_the_64_divided_by_golden_ratio; for (auto x : sp) { id += x; id *= two_to_the_64_divided_by_golden_ratio; //mixes and disperses the bits. } return id ^ (id >> 32); } class charmap { public: std::array< char, 0x100> index{ 0, }; charmap() = delete; constexpr charmap(const char * p, const char * q) { while (unsigned int pu{ static_cast(*p++) }) { assert(index[pu] == 0); index[pu] = *q++; } assert(*(p - 1) == '\0' && *q == '\0'); /* when an instance of this class is declared constexpr, an assert does not trigger a run time error, because expression evaluated at compile time. Instead the compiler reports that the expression did not evaluate to a constant, The error is confusing, because the error points to the declaration where the initialization was invoked, instead of pointing to the assert. */ } }; class charmapWithFixup { public: std::array< char, 0x100> index{ 0, }; charmapWithFixup() = delete; constexpr charmapWithFixup(const char* p, const char* q) { while (unsigned int pu{ static_cast(*p++) }) { assert(index[pu] == 0); index[pu] = *q++; } index['I'] = index['l']='0'; assert(*(p - 1) == '\0' && *q == '\0'); /* when an instance of this class is declared constexpr, an assert does not trigger a run time error, because expression evaluated at compile time. Instead the compiler reports that the expression did not evaluate to a constant, The error is confusing, because the error points to the declaration where the initialization was invoked, instead of pointing to the assert. */ } }; //template <> class base58 : public CompileSizedString<44> {}; static_assert(sizeof(base58) == 46, "base58 point strings unexpected size"); static constexpr char index2cryptoBase58[] { "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" }; static constexpr char index2MpirBase58[] { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" }; void map_base_from_mpir58(char* p) { static constexpr charmap map(index2MpirBase58, index2cryptoBase58); while (uint8_t pu{ static_cast(*p) }) { *p++ = map.index[pu]; } } void map_base_to_mpir58(const char* p, char* q, size_t count) { static constexpr charmap map(index2cryptoBase58, index2MpirBase58); static_assert(map.index[0xF0] == 0); while (count--) { unsigned int pu{ static_cast(*p++) }; char c{ map.index[pu] }; if (c == '\0') throw NotBase58Exception(); *q++ = c; } *q = '\0'; } // If the string does not fill the space, pushes it rightwards // and pads with leading zeroes. void right_justify_string(char* p, char* terminal_null) { char* x = p; for (; *x && x < terminal_null; x++) { } if (x != terminal_null) { assert(x < terminal_null); memmove(terminal_null - x + p, p, x - p); memset(p, '0', terminal_null - x); *terminal_null = '\0'; } else assert(*terminal_null == '\0'); } } namespace mpir { mpz ristretto25519_curve_order("1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", 16); } /* thread_local std::unique_ptr thl2{ std::make_unique() }; //Destructor is not called std::unique_ptr thl2{ std::make_unique() }; //Destructor is called looks like cannot use smart pointers with thread_local The destructor will not be called on thread_local variables The machinery of classes just does not work with thread local variables. A thread local variable can only be defined outside of the stack, its destructor will probably not be called, and there are whimsical, arbitrary, and incomprehensible restrictions on its constructor */ // The class thread_locall__, which holds all my thread_local global values // has to be explicitly constructed in code with new // and explicitly with delete destructed at program // termination // Because the compiler will not generate code // for construction and destruction of thread_local // values. thread_local thread_local__* thl{ nullptr };