That's correct, the optimizations from this paper became available in SQLite version 3.38.0.
As we were writing the paper, we did consider implementing hash joins in SQLite. However, we ultimately went with the Bloom filter methods because they resulted in large performance gains for minimal added complexity (2 virtual instructions, a simple data structure, and a small change to the query planner). Hash joins may indeed provide some additional performance gains, but the question (as noted above) is whether they are worth the added complexity.
The paper mentions implementing Bloom filters for analytical queries an explains how they're used. I wonder if this is related to the query planner enhancements that landed on SQLite 3.38.0 [2]
[0]: https://www.sqlite.org/optoverview.html#hash_joins[1]: https://github.com/UWHustle/sqlite-past-present-future
[2]: https://www.sqlite.org/releaselog/3_38_0.html