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 {
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user