wallet/src/mpir_and_base58.cpp

130 lines
4.5 KiB
C++
Raw Normal View History

#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> index{ 0, };
charmap() = delete;
constexpr charmap(const char * p, const char * q) {
while (unsigned int pu{ static_cast<unsigned char>(*p++) }) {
assert(index[pu] == 0);
index[pu] = *q++;
}
2022-06-21 00:37:48 -04:00
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,
2022-06-21 00:37:48 -04:00
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<unsigned char>(*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<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 constexpr charmap map(index2MpirBase58, index2cryptoBase58);
while (uint8_t pu{ static_cast<uint8_t>(*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<unsigned char>(*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<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 };