Finally documented the api to my hash code.

Also fixed it so that
hash<...> a = hsh() << ...;
Actually works.  Needed a cast in the hsh class that calls
the constructor in the hash class.
This commit is contained in:
Cheng 2023-10-03 01:34:29 +00:00
parent 7ba674c29a
commit 145a3a911f
No known key found for this signature in database
GPG Key ID: 571C3A9C3B9E6FCA

View File

@ -119,6 +119,8 @@ namespace ristretto255 {
assert(i == 0); assert(i == 0);
} }
operator hash<hashsize>();
template<has_machine_independent_representation T, typename... Args> template<has_machine_independent_representation T, typename... Args>
hsh<hashsize>& hashinto(const T& j, Args... args) { hsh<hashsize>& hashinto(const T& j, Args... args) {
auto sj = ro::serialize(j); auto sj = ro::serialize(j);
@ -150,24 +152,51 @@ namespace ristretto255 {
static_assert(!has_machine_independent_representation<hsh<256> >, "Don't want to partially hash partial hashes"); static_assert(!has_machine_independent_representation<hsh<256> >, "Don't want to partially hash partial hashes");
// This constructs a finalized hash. // This constructs a finalized hash.
// If it has one argument, and that argument is hsh (unfinalized hash) object, //
// it finalizes the hash. (see hsh) // Usage:
// Usage // hash c(x, y, z ...);
// hash(a, b, c ...); // creates the variable c, and initializes and finalizes it with the hash of x, y, z ...
// hash and hsh serialize all their arguments, converting them into machine //
// and compiler independent form. If they don't know how to serialize an // is equivalent to
// argument type, you get a compile time error. To serialize a new type, // hsh b();
// b << x << y; b << z << ...; //unfinalized hash
// hash c(b); //creates c and finalizes b
// // Any subsequent operations on b should cause a run time exception.
//
// and equivalent to
// hash<256> c = hsh() << x << y << z << ...;
//
// and equivalent to
// hash<256> c(hsh() << x << y << z << ... )
//
// hash and hsh serialize all their arguments, converting them into machine,
// compiler, and locale independent form. If they don't know how to serialize
// an argument type, you get a compile time error.
// "the concept 'ro::has_machine_independent_representation<...>' evaluated to false"
//
// Suppose you don't want hsh finalized, perhaps because you are creating many
// hashes each with same very lengthy preamble but different suffixes: Then:
// hsh(b);
// b << preamble;
// hash cfoo = hsh(b) << suffix_foo;
// hash cbar = hsh(b) << suffix_bar;
//
// To serialize a new type,
// create a new overload for the function "serialize" // create a new overload for the function "serialize"
// to hash a wxString, use its ToUTF8 member // to hash a wxString, use its ToUTF8 member
// wxString wxsHello(L"Hello world"); // wxString wxsHello(L"Hello world");
// hash hashHello(wxsHello.ToUTF8()); // hash hashHello(wxsHello.ToUTF8());
// C array arguments after the first are vulnerable to array decay to pointer, so use hsh and "<<" // Old type C array arguments after the first are vulnerable to array decay
// for them. or wrap them in std::span(OldTypeCarray) // to pointer, which will generate a compile time error. If this happens use
// hsh and "<<" for them. or wrap them in std::span
// It always a wise precaution to not use old type C arays, or wrap them // It always a wise precaution to not use old type C arays, or wrap them
// in a span. // in a span.
// Old type zero terminated utf8 strings work. The trailing zero is included. // std::strings and old type zero terminated utf8 strings work. The trailing
// zero is included in the hash so that hash("tea", "spoon") != hash("teaspoon")
// The program should by running in the UTF8 locale, attempts to set that // The program should by running in the UTF8 locale, attempts to set that
// locale on startup. and tests for success in the unit test. // locale on startup. and tests for success in the unit test, so that the
// same string will yield the same hash no matter where in the world the code
// is running.
template<unsigned int hashsize = 256> class hash { template<unsigned int hashsize = 256> class hash {
static_assert( static_assert(
hashsize > 63 && hashsize % 64 == 0 hashsize > 63 && hashsize % 64 == 0
@ -220,6 +249,10 @@ namespace ristretto255 {
return blob != pt.blob; //Do not need constant time equality test on hashes return blob != pt.blob; //Do not need constant time equality test on hashes
} }
}; };
template<unsigned int hashsize = 256>
hsh<hashsize>::operator hash<hashsize>() {
return hash(*this);
}
// a class representing ristretto255 elliptic points, // a class representing ristretto255 elliptic points,
// which are conveniently of prime order. // which are conveniently of prime order.