05:16:31 UkoeHB it can be called in a background thread at startup, no need for embedded table 05:32:05 sech1: ok that should work fine, will need a little work to make this thread safe https://github.com/UkoeHB/monero/blob/seraphis_lib/src/seraphis/sp_generator_factory.cpp 05:34:41 If it's only 524 Kb, I don't see a problem including it in the binary 05:35:09 Monero binaries are already quite large 05:35:32 it will save you from thread synchronization headache 05:37:36 A boost::shared_mutex in that file would work, though idk what the reader lock overhead is 05:43:11 Or just a std::call_once and hard-code the max number of generators needed. 09:15:51 "> <@dangerousfreedom:matrix.org>..." <- Thanks 14:16:22 "perhaps BP++ will gain enough..." <- what kind of gains can we expect with BP++? 14:19:36 it's smaller, but may be slower (needs a proof of concept for performance tests), and may not even be secure (needs good review) 15:04:48 "what kind of gains can we expect..." <- I believe swapping BP+ with BP++ would allow for 2 more decoys at roughly the same tx size 18:20:42 UkoeHB: If you want, I can get benchmarks with dalek. It's 128 generators @ 2ms using your existing algo? 18:21:16 The CN hash_to_point itself is probably largely just as fast. It may be 20% faster/slower, yet I wouldn't know. My main question would its squaring. 18:21:29 It does x = H(m); x * x % l 18:21:46 I don't believe that specific part would be efficient, and I don't believe Elligator2 does it (would have to check). 18:22:07 But I think the main issue with your algo is simply the double hashing :p 18:26:00 the cost of a blake2b hash is negligible compared to ECC ops 18:29:45 https://github.com/MerosCrypto/Meros/blob/master/e2e/Libs/Ristretto/Ristretto.py#L136-L181 <- for an old Python impl of mine. Looks like it does two decodes and a group addition. I assume it'd be slower accordingly. 18:31:00 So sounds like the real solution would just be to use a static table for the generators, confirming their accuracy in a test instead of generating them in real time. 18:33:01 I'll leave that as a project for someone else lol. For now it's just in a `std::call_once()`so you can initialize them from a background thread on startup. 20:58:45 ukoehb: since c++11 all `static` variables in function scope are guaranteed to be thread-safe initialized once, and its basically always with a simple double-check lock 20:59:14 so you put everything in a struct/class as members with constructor to initialize, then create a singleton 21:01:48 its probably similar in efficiency to `call_once`, but flows more naturally (if the variables can be used in multiple entry points `call_once` has to be carefully used in each spot_ 22:55:45 vtnerd: with `std::call_once()` I can avoid introducing any new design patterns (file-scope data is used in a couple other places) 22:56:29 simple enough: https://github.com/UkoeHB/monero/blob/seraphis_lib/src/seraphis/sp_generator_factory.cpp 23:41:09 its not a new design pattern, its already in use 23:43:06 ukoehb: ^ and the benefit is that every public (via header) function that references the relevant variables must go through the static; compared to every one of those functions needing to reference `std::call_once` before accessing the variable 23:43:26 its an offshoot of the initialization-order issue - but in this situation the file is unlikely to change much at least 23:51:52 so as an example, if you miss a `prepare_generators()` call the next line bombs, typically why function-level statics is recommended even in this situation (you can't screw it up, its either inefficiently creating multiple or creating just one safely) 23:55:36 and oh yeah everything (the class variables and static variable) can be marked `const`, although it looks like this ia return by copy to prevent massive screwups 23:56:04 yes I figured a return by const ref can be reinterpretted to change the data 23:57:50 hmm. I wonder how that get optimized though. Im guessing in most cases its probably doing a copy either way, the ref just changes the function sig