diff --git a/src/mpir_and_base58.h b/src/mpir_and_base58.h index 13f2389..d22b566 100644 --- a/src/mpir_and_base58.h +++ b/src/mpir_and_base58.h @@ -52,20 +52,22 @@ extern thread_local thread_local__* thl; namespace ro { using ristretto255::scalar, ristretto255::point; + template concept has_type_indentifier + = requires(T v) { + { v.type_indentifier } -> std::convertible_to; + }; + auto fasthash(uint64_t, std::span)->uint32_t; void right_justify_string(char*, char*); bool is_alphanumeric_fixed_length(unsigned int, const char*); - template typename std::enable_if< - ro::blob_type, - decltype(T::type_indentifier, uint32_t()) - >::type fasthash(const T& p_blob) { + template 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(&p_blob.blob[0]), - p_blob.blob.size() / 8 + reinterpret_cast(&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 class base58 : public CompileSizedString< + template class base58 : public CompileSizedString< ((sizeof(T) * 8 + 4) * 4943ui64 + 28955ui64) / 28956ui64 - (std::is_same_v, 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& str, T& sc); @@ -102,7 +104,7 @@ namespace ro { } }; - template typename const decltype(base58::length, T::type_indentifier, uint32_t()) + template 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 const uint32_t check_range_m{ check_range() }; - template const char* base58::bin( - typename const decltype(T::type_indentifier, char())* p, + template const char* base58::bin( + const char* p, T& sc ) { const uint32_t range = check_range_m; @@ -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(fasthash(sc)) * static_cast(range)) >> 32 }; if (ck != mpz_get_ui(thl->q)) throw BadStringRepresentationOfCryptoIdException(); return p + base58::length; @@ -152,13 +156,13 @@ namespace ro { const T& sc ) { mpir_ui ck{ (static_cast(fasthash(sc)) * static_cast(check_range_m)) >> 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, 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 base58::base58(const T& el) { + template base58::base58(const T& el) { to_base58(static_cast(*this), el); } - template base58::base58(const char* p) { + template base58::base58(const char* p) { memmove(this, p, (this->length)); std::arraylength)> test; map_base_to_mpir58(this, test, this->length); //Force an exception for bad char