removed requirement for a blob field from base58

This commit is contained in:
Cheng 2024-07-30 08:01:39 +00:00
parent acf980a5a1
commit 8792d59c67
No known key found for this signature in database

View File

@ -52,20 +52,22 @@ extern thread_local thread_local__* thl;
namespace ro { namespace ro {
using ristretto255::scalar, ristretto255::point; 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; auto fasthash(uint64_t, std::span<const uint64_t>)->uint32_t;
void right_justify_string(char*, char*); void right_justify_string(char*, char*);
bool is_alphanumeric_fixed_length(unsigned int, const char*); bool is_alphanumeric_fixed_length(unsigned int, const char*);
template <class T> typename std::enable_if< template <has_type_indentifier T> auto fasthash(const T& sc) {
ro::blob_type<T>,
decltype(T::type_indentifier, uint32_t())
>::type fasthash(const T& p_blob) {
static_assert(sizeof(T) % 8 == 0, "fasthash assumes a multiple of 8 bytes"); static_assert(sizeof(T) % 8 == 0, "fasthash assumes a multiple of 8 bytes");
return fasthash( return fasthash(
T::type_indentifier, T::type_indentifier,
std::span< const uint64_t >( std::span< const uint64_t >(
reinterpret_cast<const uint64_t*>(&p_blob.blob[0]), reinterpret_cast<const uint64_t*>(&sc),
p_blob.blob.size() / 8 sizeof(sc) / 8
) )
); );
} }
@ -73,7 +75,7 @@ namespace ro {
void map_base_from_mpir58(char*); void map_base_from_mpir58(char*);
void map_base_to_mpir58(const char*, char*, size_t); 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)> { ((sizeof(T) * 8 + 4) * 4943ui64 + 28955ui64) / 28956ui64 - (std::is_same_v<std::remove_cvref_t<T>, scalar> ? 1 : 0)> {
public: public:
// The rational number 4943 / 28956 is minisculy larger than log(2)/log(58) // The rational number 4943 / 28956 is minisculy larger than log(2)/log(58)
@ -83,7 +85,7 @@ namespace ro {
base58(const T&); base58(const T&);
base58(const char* p); base58(const char* p);
static const char* bin( static const char* bin(
typename const decltype(T::type_indentifier, char())* p, const char* p,
T& sc T& sc
); );
static void bin(const base58<T>& str, 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 // cannot be consteval or constexpr, because has to be called after the mpir temp values are constructed
check_range() { check_range() {
if (thl == nullptr)thl = new thread_local__(); 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 uint32_t check_range_m{ check_range<T>() };
template <class T> const char* base58<T>::bin( template <has_type_indentifier T> const char* base58<T>::bin(
typename const decltype(T::type_indentifier, char())* p, const char* p,
T& sc T& sc
) { ) {
const uint32_t range = check_range_m<T>; 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); mpz_fdiv_qr(thl->q, thl->r, thl->n, mpir::ristretto25519_curve_order);
} }
else { else {
mpz_fdiv_q_2exp(thl->q, 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.blob) * 8); mpz_fdiv_r_2exp(thl->r, thl->n, sizeof(sc) * 8);
} }
size_t count; size_t count;
mpz_export(&(sc.blob[0]), &count, -1, 1, -1, 0, thl->r); mpz_export(&(sc), &count, -1, 1, -1, 0, thl->r);
if (count < sizeof(sc.blob))memset(&sc.blob[count], 0, sizeof(sc.blob) - count); 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 }; mpir_ui ck{ (static_cast<uint64_t>(fasthash(sc)) * static_cast<uint64_t>(range)) >> 32 };
if (ck != mpz_get_ui(thl->q)) throw BadStringRepresentationOfCryptoIdException(); if (ck != mpz_get_ui(thl->q)) throw BadStringRepresentationOfCryptoIdException();
return p + base58<T>::length; return p + base58<T>::length;
@ -152,13 +156,13 @@ namespace ro {
const T& sc const T& sc
) { ) {
mpir_ui ck{ (static_cast<uint64_t>(fasthash(sc)) * static_cast<uint64_t>(check_range_m<T>)) >> 32 }; 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>) { if constexpr (std::is_same_v<std::remove_cvref_t<T>, scalar>) {
mpz_addmul_ui(thl->n, mpir::ristretto25519_curve_order, ck); mpz_addmul_ui(thl->n, mpir::ristretto25519_curve_order, ck);
} }
else { else {
mpz_set_ui(thl->r, ck); 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_add(thl->n, thl->n, thl->r);
} }
mpz_get_str(p, 58, thl->n); mpz_get_str(p, 58, thl->n);
@ -169,11 +173,11 @@ namespace ro {
// return value points to trailing null // 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); 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)); memmove(this, p, (this->length));
std::array<char, (this->length)> test; std::array<char, (this->length)> test;
map_base_to_mpir58(this, test, this->length); //Force an exception for bad char map_base_to_mpir58(this, test, this->length); //Force an exception for bad char