forked from cheng/wallet
removed requirement for a blob field from base58
This commit is contained in:
parent
acf980a5a1
commit
8792d59c67
@ -52,20 +52,22 @@ extern thread_local thread_local__* thl;
|
||||
namespace ro {
|
||||
using ristretto255::scalar, ristretto255::point;
|
||||
|
||||
template <typename T> concept has_type_indentifier
|
||||
= requires(T v) {
|
||||
{ v.type_indentifier } -> std::convertible_to<uint64_t>;
|
||||
};
|
||||
|
||||
auto fasthash(uint64_t, std::span<const uint64_t>)->uint32_t;
|
||||
void right_justify_string(char*, char*);
|
||||
bool is_alphanumeric_fixed_length(unsigned int, const char*);
|
||||
|
||||
template <class T> typename std::enable_if<
|
||||
ro::blob_type<T>,
|
||||
decltype(T::type_indentifier, uint32_t())
|
||||
>::type fasthash(const T& p_blob) {
|
||||
template <has_type_indentifier T> auto fasthash(const T& sc) {
|
||||
static_assert(sizeof(T) % 8 == 0, "fasthash assumes a multiple of 8 bytes");
|
||||
return fasthash(
|
||||
T::type_indentifier,
|
||||
std::span< const uint64_t >(
|
||||
reinterpret_cast<const uint64_t*>(&p_blob.blob[0]),
|
||||
p_blob.blob.size() / 8
|
||||
reinterpret_cast<const uint64_t*>(&sc),
|
||||
sizeof(sc) / 8
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -73,7 +75,7 @@ namespace ro {
|
||||
void map_base_from_mpir58(char*);
|
||||
void map_base_to_mpir58(const char*, char*, size_t);
|
||||
|
||||
template <typename T> class base58 : public CompileSizedString<
|
||||
template <has_type_indentifier T> class base58 : public CompileSizedString<
|
||||
((sizeof(T) * 8 + 4) * 4943ui64 + 28955ui64) / 28956ui64 - (std::is_same_v<std::remove_cvref_t<T>, scalar> ? 1 : 0)> {
|
||||
public:
|
||||
// The rational number 4943 / 28956 is minisculy larger than log(2)/log(58)
|
||||
@ -83,7 +85,7 @@ namespace ro {
|
||||
base58(const T&);
|
||||
base58(const char* p);
|
||||
static const char* bin(
|
||||
typename const decltype(T::type_indentifier, char())* p,
|
||||
const char* p,
|
||||
T& sc
|
||||
);
|
||||
static void bin(const base58<T>& str, T& sc);
|
||||
@ -102,7 +104,7 @@ namespace ro {
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> typename const decltype(base58<T>::length, T::type_indentifier, uint32_t())
|
||||
template <has_type_indentifier T> const uint32_t
|
||||
// cannot be consteval or constexpr, because has to be called after the mpir temp values are constructed
|
||||
check_range() {
|
||||
if (thl == nullptr)thl = new thread_local__();
|
||||
@ -120,8 +122,8 @@ namespace ro {
|
||||
|
||||
template <class T> const uint32_t check_range_m{ check_range<T>() };
|
||||
|
||||
template <class T> const char* base58<T>::bin(
|
||||
typename const decltype(T::type_indentifier, char())* p,
|
||||
template <has_type_indentifier T> const char* base58<T>::bin(
|
||||
const char* p,
|
||||
T& sc
|
||||
) {
|
||||
const uint32_t range = check_range_m<T>;
|
||||
@ -134,12 +136,14 @@ namespace ro {
|
||||
mpz_fdiv_qr(thl->q, thl->r, thl->n, mpir::ristretto25519_curve_order);
|
||||
}
|
||||
else {
|
||||
mpz_fdiv_q_2exp(thl->q, thl->n, sizeof(sc.blob) * 8);
|
||||
mpz_fdiv_r_2exp(thl->r, thl->n, sizeof(sc.blob) * 8);
|
||||
mpz_fdiv_q_2exp(thl->q, thl->n, sizeof(sc) * 8);
|
||||
mpz_fdiv_r_2exp(thl->r, thl->n, sizeof(sc) * 8);
|
||||
}
|
||||
size_t count;
|
||||
mpz_export(&(sc.blob[0]), &count, -1, 1, -1, 0, thl->r);
|
||||
if (count < sizeof(sc.blob))memset(&sc.blob[count], 0, sizeof(sc.blob) - count);
|
||||
mpz_export(&(sc), &count, -1, 1, -1, 0, thl->r);
|
||||
if (count < sizeof(sc)) {
|
||||
memset(((byte*)&sc) + count, 0, sizeof(sc) - count);
|
||||
}
|
||||
mpir_ui ck{ (static_cast<uint64_t>(fasthash(sc)) * static_cast<uint64_t>(range)) >> 32 };
|
||||
if (ck != mpz_get_ui(thl->q)) throw BadStringRepresentationOfCryptoIdException();
|
||||
return p + base58<T>::length;
|
||||
@ -152,13 +156,13 @@ namespace ro {
|
||||
const T& sc
|
||||
) {
|
||||
mpir_ui ck{ (static_cast<uint64_t>(fasthash(sc)) * static_cast<uint64_t>(check_range_m<T>)) >> 32 };
|
||||
mpz_import(thl->n, sizeof(sc.blob), -1, 1, -1, 0, &sc.blob[0]);
|
||||
mpz_import(thl->n, sizeof(sc), -1, 1, -1, 0, &sc);
|
||||
if constexpr (std::is_same_v<std::remove_cvref_t<T>, scalar>) {
|
||||
mpz_addmul_ui(thl->n, mpir::ristretto25519_curve_order, ck);
|
||||
}
|
||||
else {
|
||||
mpz_set_ui(thl->r, ck);
|
||||
mpz_mul_2exp(thl->r, thl->r, sizeof(sc.blob) * 8);
|
||||
mpz_mul_2exp(thl->r, thl->r, sizeof(sc) * 8);
|
||||
mpz_add(thl->n, thl->n, thl->r);
|
||||
}
|
||||
mpz_get_str(p, 58, thl->n);
|
||||
@ -169,11 +173,11 @@ namespace ro {
|
||||
// return value points to trailing null
|
||||
}
|
||||
|
||||
template <class T> base58<T>::base58(const T& el) {
|
||||
template <has_type_indentifier T> base58<T>::base58(const T& el) {
|
||||
to_base58<T>(static_cast<char*>(*this), el);
|
||||
}
|
||||
|
||||
template <class T> base58<T>::base58(const char* p) {
|
||||
template <has_type_indentifier T> base58<T>::base58(const char* p) {
|
||||
memmove(this, p, (this->length));
|
||||
std::array<char, (this->length)> test;
|
||||
map_base_to_mpir58(this, test, this->length); //Force an exception for bad char
|
||||
|
Loading…
Reference in New Issue
Block a user