wallet/mpir_and_base58.cpp

93 lines
3.3 KiB
C++

#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<const uint64_t> 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> {
public:
charmap() = delete;
constexpr charmap(const char* p, const char* q) {
while (unsigned int pu{ static_cast<unsigned char>(*p++) }) {
assert((*this)[pu] == 0);
(*this)[pu] = *q++;
}
assert(*(p - 1) == '\0' && *q == '\0');
}
};
//template <> class base58<scalar> : public CompileSizedString<44> {};
static_assert(sizeof(base58<point>) == 46, "base58 point strings unexpected size");
static constexpr char index2cryptoBase58[] { "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" };
static constexpr char index2MpirBase58[] { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" };
void map_base_from_mpir58(char* p) {
static const charmap map(index2MpirBase58, index2cryptoBase58);
while (unsigned int pu{ static_cast<unsigned char>(*p) }) {
*p++ = map[pu];
}
}
void map_base_to_mpir58(const char* p, char* q, size_t count) {
static const charmap map(index2cryptoBase58, index2MpirBase58);
while (count--) {
unsigned int pu{ static_cast<unsigned char>(*p++) };
char c{ map[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<thread_local__> thl2{ std::make_unique<thread_local__>() }; //Destructor is not called
std::unique_ptr<thread_local__> thl2{ std::make_unique<thread_local__>() }; //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 };