From bc3f2c9dafe765c1d4fec454e26f1e82e885fc4b Mon Sep 17 00:00:00 2001 From: Cheng Date: Sat, 30 Sep 2023 05:13:25 +0000 Subject: [PATCH] Removed the old "is_serializable" in favor of C++20 concepts syntax. Changed the name to "has_machine_independent_representation" for a more intellible error explanation --- src/db_accessors.h | 2 +- src/ristretto255.h | 32 ++++++++++++++++--------------- src/serialization.h | 46 +++++++++++++++++++++------------------------ src/testbed.cpp | 2 +- src/unit_test.cpp | 2 +- 5 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/db_accessors.h b/src/db_accessors.h index 500c86f..a3f601b 100644 --- a/src/db_accessors.h +++ b/src/db_accessors.h @@ -107,7 +107,7 @@ namespace ro { template < typename T, typename std::enable_if::value, int >::type dummy_arg = 0 > void bind(int i, const T& j) { - static_assert(ro::serializable, "Don't know how to store this type in a database"); + static_assert(ro::has_machine_independent_representation, "Don't know how to store this type in a database"); (*this)->Isqlite3_bind(i, ro::serialize(j)); } typedef Icompiled_sql::sql_result result; diff --git a/src/ristretto255.h b/src/ristretto255.h index 3a4eb57..7faf593 100644 --- a/src/ristretto255.h +++ b/src/ristretto255.h @@ -61,7 +61,7 @@ namespace ristretto255 { ro::to_base64_string, ro::is_serializable, ro::serialize, ro::bin2hex, ro::hex2bin, ro::bin2hex, ro::CompileSizedString, - ro::serializable; + ro::has_machine_independent_representation; ; // a class representing ristretto255 elliptic points class point; @@ -119,7 +119,7 @@ namespace ristretto255 { assert(i == 0); } - template + template hsh& hashinto(const T& j, Args... args) { auto sj = ro::serialize(j); int i = crypto_generichash_blake2b_update( @@ -134,7 +134,7 @@ namespace ristretto255 { return *this; } - template hsh& operator << (const T& j) { + template hsh& operator << (const T& j) { auto sj = ro::serialize(j); auto i = crypto_generichash_blake2b_update( &(this->st), @@ -147,7 +147,7 @@ namespace ristretto255 { }; - static_assert(!serializable >, "Don't want to partially hash partial hashes"); + static_assert(!has_machine_independent_representation >, "Don't want to partially hash partial hashes"); // This constructs a finalized hash. // If it has one argument, and that argument is hsh (unfinalized hash) object, @@ -194,11 +194,12 @@ namespace ristretto255 { assert(i == 0); if (i) throw HashReuseException(); } - template< serializable T, typename... Args>explicit hash(const T& first, Args... args) { + template< has_machine_independent_representation T, typename... Args>explicit hash(const T& first, Args... args) { + hsh in; in << first; if constexpr (sizeof...(args) > 0) { - in.hashinto(args...); + in.hashinto( args...); } int i = crypto_generichash_blake2b_final( &in.st, @@ -280,6 +281,7 @@ namespace ristretto255 { "we need 512 bit randoms to ensure our points and scalars are uniformly distributed" ); // There should be scalar from hash, not point from hash + // libsodium already supplies a random point int i{ crypto_core_ristretto255_from_hash(&blob[0], &(x.blob)[0]) }; assert(i == 0); @@ -434,21 +436,21 @@ namespace ristretto255 { static_assert(ro::is_blob_field_type::value); static_assert(ro::is_blob_field_type >::value); static_assert(false == ro::is_blob_field_type::value); - static_assert(ro::is_serializable::value); - static_assert(ro::is_serializable&>::value); + static_assert(ro::has_machine_independent_representation); + static_assert(ro::has_machine_independent_representation&>); static_assert(ro::is_blob_field_type::value == false); - static_assert(ro::is_serializable::value); - static_assert(ro::is_serializable::value); - static_assert(ro::is_serializable::value == false); //false because uint8_t * has no inband terminator - static_assert(false == ro::is_serializable::value && !ro::is_constructible_from_v, wxString>, "wxStrings are apt to convert anything to anything, with surprising and unexpected results"); - static_assert(ro::is_serializable().ToUTF8())>::value == true); + static_assert(ro::has_machine_independent_representation); + static_assert(ro::has_machine_independent_representation); + static_assert(ro::has_machine_independent_representation == false); //false because uint8_t * has no inband terminator + static_assert(false == ro::has_machine_independent_representation && !ro::is_constructible_from_v, wxString>, "wxStrings are apt to convert anything to anything, with surprising and unexpected results"); + static_assert(ro::has_machine_independent_representation().ToUTF8())> == true); static_assert(ro::is_constructible_from_all_of, std::array>); - static_assert(ro::is_constructible_from_all_of, char*, short, unsigned short, hash<512>, point, scalar>, "want to be able to hash anything serializable"); + static_assert(ro::is_constructible_from_all_of, char*, short, unsigned short, hash<512>, point, scalar>, "want to be able to hash anything has_machine_independent_representation"); static_assert(false == ro::is_constructible_from_any_of, hash<256>>); static_assert(false == ro::is_constructible_from_any_of , byte*>, "do not want indiscriminate casts"); static_assert(false == ro::is_constructible_from_any_of , byte*>, "do not want indiscriminate casts "); static_assert(false == ro::is_constructible_from_v, float>); - static_assert(ro::is_serializable::value == false);//Need to convert floats to + static_assert(ro::has_machine_independent_representation == false);//Need to convert floats to // their machine independent representation, possibly through idexp, frexp // and DBL_MANT_DIG static_assert(sizeof(decltype(ro::serialize(std::declval())[0])) == 1); diff --git a/src/serialization.h b/src/serialization.h index cf6a371..0fcae03 100644 --- a/src/serialization.h +++ b/src/serialization.h @@ -59,12 +59,14 @@ // This template generates a span over an indexable byte type, // such as a C array or an std::array, but not pointers - template < typename T> - std::enable_if_t< - !std::is_pointer::value && - sizeof(std::declval()[0]) == 1, - std::span - > serialize(const T& a) { + template + concept byte_spannable = requires (T a) { + std::size(a); + a[0]; + } && sizeof(std::declval()[0]) == 1; + + template + auto serialize(const T& a) { int l; const void* pt; if constexpr (std::is_same_v, std::string>) { @@ -301,27 +303,21 @@ format being 44 digits in a base 58 representation.*/ // a compile time test to check if an object class has a machine independent representation - template struct is_serializable{ - template - static constexpr decltype(ro::serialize(std::declval()), bool()) test() { - if constexpr (sizeof...(Args2) > 0) { - return is_serializable::template test(); - } - else { - return true; - } - } - template static constexpr bool test(int = 0) { - return false; - } - static constexpr bool value = is_serializable::template test(); + template concept has_machine_independent_representation = requires (T a) { + serialize(a); }; - + + template static constexpr bool is_serializable() { + if constexpr (!has_machine_independent_representation) return false; + else if constexpr (sizeof...(Args) > 0) return is_serializable(); + else return true; + }; + template - concept serializable = is_serializable::value; + concept allserializable = is_serializable(); - static_assert( !serializable - && serializable, char*, std::span>, + static_assert( !has_machine_independent_representation + && allserializable, char*, std::span>, "concepts needed"); template ro::CompileSizedString< (2 * sizeof(T))>bin2hex(const T& pt) { @@ -351,4 +347,4 @@ return sz; } -} //End ro namespace \ No newline at end of file +} //End ro namespace diff --git a/src/testbed.cpp b/src/testbed.cpp index 1a44eac..a0ab14e 100644 --- a/src/testbed.cpp +++ b/src/testbed.cpp @@ -28,7 +28,7 @@ namespace testbed { using /*ristretto255::hash, ristretto255::hsh, */ristretto255::scalar, ristretto255::point, ro::serialize, ro::bin2hex, ro::hex2bin, ro::bin2hex, ro::fasthash, ro::CompileSizedString, - ro::base58, ro::serializable; + ro::base58, ro::has_machine_independent_representation; static constexpr char SrcFilename[]{ "src/testbed.cpp" }; diff --git a/src/unit_test.cpp b/src/unit_test.cpp index 47403d5..62ea8f5 100644 --- a/src/unit_test.cpp +++ b/src/unit_test.cpp @@ -238,7 +238,7 @@ static bool checkDataConversionsProduceExpected(void){ point pt_a{ scl_a.timesBase() }; std::string str_pt_a = &(base58(pt_a))[0]; assert(base58::bin(str_pt_a.c_str()) == pt_a); - hash<256> hash_b{ hash_a,str_hash_a,scl_a,str_sclr_a,pt_a,str_pt_a,33, 66ull }; + hash<256> hash_b{ hash_a, str_hash_a, scl_a, str_sclr_a, pt_a, str_pt_a, 33, 66ull }; auto str_b = base58(hash_b).operator std::string(); if (str_b != "7cTScjKyUtmbvc28BV3ok51szgrQmaBa2YE5HPBcukC9e" ) {