2022-02-16 00:53:01 -05:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
using ristretto255::hash, ristretto255::hsh, ristretto255::scalar, ristretto255::point;
|
|
|
|
|
namespace ro {
|
2022-02-18 15:59:12 -05:00
|
|
|
|
// fasthash fails at obliterating some forms of order in its input, but
|
2022-02-16 00:53:01 -05:00
|
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-12 03:38:26 -04:00
|
|
|
|
class charmap {
|
2022-02-16 00:53:01 -05:00
|
|
|
|
public:
|
2022-06-12 03:38:26 -04:00
|
|
|
|
std::array< char, 0x100> index{ 0, };
|
2022-02-16 00:53:01 -05:00
|
|
|
|
charmap() = delete;
|
2022-06-12 03:38:26 -04:00
|
|
|
|
constexpr charmap(const char * p, const char * q) {
|
2022-02-16 00:53:01 -05:00
|
|
|
|
while (unsigned int pu{ static_cast<unsigned char>(*p++) }) {
|
2022-06-12 03:38:26 -04:00
|
|
|
|
assert(index[pu] == 0);
|
|
|
|
|
index[pu] = *q++;
|
2022-02-16 00:53:01 -05:00
|
|
|
|
}
|
2022-06-12 03:38:26 -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,
|
|
|
|
|
|
|
|
|
|
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';
|
2022-02-16 00:53:01 -05:00
|
|
|
|
assert(*(p - 1) == '\0' && *q == '\0');
|
2022-06-12 03:38:26 -04:00
|
|
|
|
/* 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.
|
|
|
|
|
*/
|
2022-02-16 00:53:01 -05:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-12 03:38:26 -04:00
|
|
|
|
|
2022-02-16 00:53:01 -05:00
|
|
|
|
//template <> class base58<scalar> : public CompileSizedString<44> {};
|
|
|
|
|
static_assert(sizeof(base58<point>) == 46, "base58 point strings unexpected size");
|
|
|
|
|
|
2022-03-07 23:46:14 -05:00
|
|
|
|
static constexpr char index2cryptoBase58[] { "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" };
|
|
|
|
|
static constexpr char index2MpirBase58[] { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv" };
|
2022-02-16 00:53:01 -05:00
|
|
|
|
|
|
|
|
|
void map_base_from_mpir58(char* p) {
|
2022-06-12 03:38:26 -04:00
|
|
|
|
static constexpr charmap map(index2MpirBase58, index2cryptoBase58);
|
|
|
|
|
while (uint8_t pu{ static_cast<uint8_t>(*p) }) {
|
|
|
|
|
*p++ = map.index[pu];
|
2022-02-16 00:53:01 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void map_base_to_mpir58(const char* p, char* q, size_t count) {
|
2022-06-12 03:38:26 -04:00
|
|
|
|
static constexpr charmap map(index2cryptoBase58, index2MpirBase58);
|
|
|
|
|
static_assert(map.index[0xF0] == 0);
|
2022-02-16 00:53:01 -05:00
|
|
|
|
while (count--) {
|
|
|
|
|
unsigned int pu{ static_cast<unsigned char>(*p++) };
|
2022-06-12 03:38:26 -04:00
|
|
|
|
char c{ map.index[pu] };
|
2022-02-16 00:53:01 -05:00
|
|
|
|
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');
|
|
|
|
|
}
|
2022-02-18 15:59:12 -05:00
|
|
|
|
}
|
2022-03-07 23:46:14 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 };
|