--- Day changed Wed Oct 21 2020 00:17 -!- jonatack [~jon@37.165.188.225] has joined #bitcoin-core-pr-reviews 01:00 -!- jonatack [~jon@37.165.188.225] has quit [Read error: Connection reset by peer] 01:31 -!- belcher_ [~belcher@unaffiliated/belcher] has joined #bitcoin-core-pr-reviews 01:32 -!- jonatack [~jon@37.165.188.225] has joined #bitcoin-core-pr-reviews 01:34 -!- belcher [~belcher@unaffiliated/belcher] has quit [Ping timeout: 256 seconds] 01:36 -!- belcher_ is now known as belcher 01:40 -!- jesseposner [~jesse@98.37.146.62] has joined #bitcoin-core-pr-reviews 01:45 -!- jesseposner [~jesse@98.37.146.62] has quit [Ping timeout: 264 seconds] 03:07 -!- vasild_ [~vd@gateway/tor-sasl/vasild] has joined #bitcoin-core-pr-reviews 03:11 -!- vasild [~vd@gateway/tor-sasl/vasild] has quit [Ping timeout: 240 seconds] 03:11 -!- vasild_ is now known as vasild 03:16 -!- user___ [~user@mail.deeplinkmedia.com] has joined #bitcoin-core-pr-reviews 03:18 -!- Penelope10Nikola [~Penelope1@static.57.1.216.95.clients.your-server.de] has joined #bitcoin-core-pr-reviews 03:23 -!- Penelope10Nikola [~Penelope1@static.57.1.216.95.clients.your-server.de] has quit [Ping timeout: 265 seconds] 03:34 -!- worc3131 [~quassel@2a02:c7f:c026:9500:a0d2:b9d1:42a4:69b4] has joined #bitcoin-core-pr-reviews 03:41 -!- jesseposner [~jesse@98.37.146.62] has joined #bitcoin-core-pr-reviews 03:46 -!- jesseposner [~jesse@98.37.146.62] has quit [Ping timeout: 256 seconds] 04:02 -!- da39a3ee5e6b4b0d [~textual@n11211935170.netvigator.com] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 04:24 -!- jonatack [~jon@37.165.188.225] has quit [Ping timeout: 260 seconds] 05:15 -!- midnight [~midnight@unaffiliated/midnightmagic] has quit [Ping timeout: 244 seconds] 05:20 -!- midnight [~midnight@unaffiliated/midnightmagic] has joined #bitcoin-core-pr-reviews 05:28 -!- da39a3ee5e6b4b0d [~textual@n11211935170.netvigator.com] has joined #bitcoin-core-pr-reviews 05:38 -!- ares_ [~ares@gateway/tor-sasl/virtu] has quit [Remote host closed the connection] 05:38 -!- ares_ [~ares@gateway/tor-sasl/virtu] has joined #bitcoin-core-pr-reviews 05:42 -!- jesseposner [~jesse@98.37.146.62] has joined #bitcoin-core-pr-reviews 05:47 -!- jesseposner [~jesse@98.37.146.62] has quit [Ping timeout: 260 seconds] 06:16 -!- molz_ [~mol@unaffiliated/molly] has joined #bitcoin-core-pr-reviews 06:20 -!- mol_ [~mol@unaffiliated/molly] has quit [Ping timeout: 272 seconds] 06:44 -!- jonatack [~jon@109.202.107.5] has joined #bitcoin-core-pr-reviews 06:50 -!- user___ [~user@mail.deeplinkmedia.com] has quit [Quit: leaving] 07:14 -!- mol [~mol@unaffiliated/molly] has joined #bitcoin-core-pr-reviews 07:17 -!- molz_ [~mol@unaffiliated/molly] has quit [Ping timeout: 240 seconds] 07:39 -!- da39a3ee5e6b4b0d [~textual@n11211935170.netvigator.com] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 07:40 -!- da39a3ee5e6b4b0d [~textual@n11211935170.netvigator.com] has joined #bitcoin-core-pr-reviews 07:40 -!- da39a3ee5e6b4b0d [~textual@n11211935170.netvigator.com] has quit [Client Quit] 07:43 -!- jesseposner [~jesse@98.37.146.62] has joined #bitcoin-core-pr-reviews 07:48 -!- jesseposner [~jesse@98.37.146.62] has quit [Ping timeout: 260 seconds] 07:51 -!- mol_ [~mol@unaffiliated/molly] has joined #bitcoin-core-pr-reviews 07:53 -!- mol [~mol@unaffiliated/molly] has quit [Ping timeout: 240 seconds] 08:01 -!- glozow [uid453516@gateway/web/irccloud.com/x-ekezvtdtaohyoovr] has joined #bitcoin-core-pr-reviews 08:04 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has joined #bitcoin-core-pr-reviews 08:22 < michaelfolkson> I looked up to see what coverage of MuHash there had been in Optech. It refers to a "MuHash based checksum" https://bitcoinops.org/en/newsletters/2020/07/15/#bitcoin-core-19328 08:25 < michaelfolkson> Is the plan to compare checksums rather than the full hashes? 08:26 < sipa> what's the difference? 08:28 < michaelfolkson> I understand checksum as a bech32 address like check that you haven't screwed up the address. So comparing a fraction of the hash rather than the full hash 08:29 < michaelfolkson> More efficient but also open to checksum collisions? 08:29 < emzy> FYI we have a somewhat experimental live-Socratic, accompanying today's PR Review Club session. https://www.meetup.com/Bitcoin-Munich/events/272514618/ 08:31 < michaelfolkson> Cool. You going to give context before it starts emzy? Quite a lot of background to this one... 08:31 -!- thomasb06 [~user@eth-west-pareq2-46-193-0-224.wb.wifirst.net] has joined #bitcoin-core-pr-reviews 08:32 < sipa> michaelfolkson: a checksum is a hash that's used to compare things... in this case, it's a 256-bit checksum 08:32 < sipa> perhaps the term is chosen confusingly 08:32 < sipa> but the point is certainly not to use anything shorter than that 08:32 < emzy> michaelfolkson: I hope fjahr will do. But I also know the context. 08:33 < sipa> it's a checksum as it allows you to compare UTXO sets without comparing the actual full UTXO set 08:35 < michaelfolkson> Ok thanks. So a checksum can be a fraction of a hash checking you've got the right hash. Or the full hash 08:35 < sipa> it's just whatever you use to compare things 08:35 < sipa> a crc is a checksum and it doesn't even qualify as a hash 08:36 < sipa> it's actually better than a hash (of the same length) for comparing things 08:36 < sipa> ever used the md5sum or sha1sum or sha256sum command line tools to verify you downloaded the correct binaries? those are comparing checksums (implemented as hashes) 08:36 < emzy> In my mind a checksum is less secure then a hash. But really it will depend on the type of hash/checksum. 08:38 < michaelfolkson> That's what sipa is saying emzy. A hash can be a checksum 08:38 < michaelfolkson> The class of checksums is much larger than I initially thought from bech32 like checksums 08:39 < sipa> michaelfolkson: in this case, forget about the checksum: muhash is a cryptographic hash function for _sets_, that can be efficiently updated with changes to the set (removing/adding elements to the set doesn't require re-hashing the whole thing) 08:39 < michaelfolkson> OK no more talk of checksums ;) 08:39 -!- shaunsun [shaunsun@gateway/vpn/privateinternetaccess/shaunsun] has joined #bitcoin-core-pr-reviews 08:40 -!- jesseposner [~jesse@98.37.146.62] has joined #bitcoin-core-pr-reviews 08:43 -!- fdhetj [5f5af563@ip5f5af563.dynamic.kabel-deutschland.de] has joined #bitcoin-core-pr-reviews 08:44 -!- fdhetj [5f5af563@ip5f5af563.dynamic.kabel-deutschland.de] has quit [Remote host closed the connection] 08:44 -!- mep1911 [bc62cb6b@dslb-188-098-203-107.188.098.pools.vodafone-ip.de] has joined #bitcoin-core-pr-reviews 08:53 -!- CD36 [4fdc3cd3@p4fdc3cd3.dip0.t-ipconnect.de] has joined #bitcoin-core-pr-reviews 09:13 -!- lightlike [~lightlike@p200300c7ef132a00e4632f50a6292277.dip0.t-ipconnect.de] has joined #bitcoin-core-pr-reviews 09:16 -!- blueskies [~blueskies@185.152.67.4] has joined #bitcoin-core-pr-reviews 09:18 -!- Emzy-web [577a71ed@87.122.113.237] has joined #bitcoin-core-pr-reviews 09:23 -!- Talkless [~Talkless@mail.dargis.net] has joined #bitcoin-core-pr-reviews 09:29 -!- Emzy-web [577a71ed@87.122.113.237] has quit [Remote host closed the connection] 09:29 -!- emzy-web [577a71ed@87.122.113.237] has joined #bitcoin-core-pr-reviews 09:41 -!- mep1911 [bc62cb6b@dslb-188-098-203-107.188.098.pools.vodafone-ip.de] has quit [Remote host closed the connection] 09:44 -!- andrewtoth [~andrewtot@gateway/tor-sasl/andrewtoth] has joined #bitcoin-core-pr-reviews 09:44 -!- jonatack [~jon@109.202.107.5] has quit [Quit: jonatack] 09:44 -!- stacie [~stacie@c-24-60-139-217.hsd1.ma.comcast.net] has joined #bitcoin-core-pr-reviews 09:45 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has quit [Remote host closed the connection] 09:46 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has joined #bitcoin-core-pr-reviews 09:46 <@jnewbery> We'll get started in 15 minutes 09:51 -!- elle [~ellemouto@155.93.252.70] has joined #bitcoin-core-pr-reviews 09:51 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has quit [Ping timeout: 264 seconds] 09:53 -!- jcg [446b68d7@ip68-107-104-215.sd.sd.cox.net] has joined #bitcoin-core-pr-reviews 09:57 -!- buzz08 [~buzz@2401:4900:234f:2eb8:c205:792e:739:63f1] has joined #bitcoin-core-pr-reviews 10:00 <@jnewbery> #startmeeting 10:00 <@jnewbery> Hi folks! Welcome to Bitcoin Core PR Review Club. 10:00 < emzy> hi 10:00 < felixweis> hi! 10:00 < kanzure> hi 10:00 < glozow> hi jnewbery! 10:00 < stacie> hi 10:00 < willcl_ark> hi 10:00 < jesseposner> hi 10:00 <@jnewbery> Feel free to say hi to let us all know you're here. 10:00 < fjahr> hi 10:00 < blueskies> hi 10:00 < elle> hi! 10:00 < sipa> hi 10:00 < lightlike> hi 10:00 < michaelfolkson> hi 10:00 < jcg> hi 10:00 <@jnewbery> Anyone here for the first time? 10:00 < buzz08> hi 10:01 < blueskies> first time for me 10:01 < jcg> me 10:01 -!- PatrickLemke [4d0901d4@dynamic-077-009-001-212.77.9.pool.telefonica.de] has joined #bitcoin-core-pr-reviews 10:01 <@jnewbery> welcome blueskies and jcg :) 10:01 < jcg> thanks 10:01 < blueskies> thank you :) 10:01 <@jnewbery> notes and questions are in the normal place: https://bitcoincore.reviews/19055-2 10:02 <@jnewbery> A reminder of the format: I've prepared some questions to guide the discussion a bit, but feel free to jump in at any point if you have a question 10:02 -!- gentile [~gentile@195.181.160.175.adsl.inet-telecom.org] has joined #bitcoin-core-pr-reviews 10:02 <@jnewbery> All questions are welcome. This is a place for us to all learn from each other 10:02 < gentile> hi 10:03 <@jnewbery> ok, who had a chance to review the PR this week? (y/n) 10:03 < jesseposner> y 10:03 < felixweis> y 10:03 < willcl_ark> y 10:03 < jcg> y 10:03 < blueskies> n 10:03 < michaelfolkson> y 10:03 < glozow> 0.5y 10:03 < stacie> 50% - got through the concept/spec, but not so much the code 10:03 < emzy> n 10:03 < lightlike> y 10:03 < buzz08> n 10:03 -!- jonatack [~jon@213.152.161.40] has joined #bitcoin-core-pr-reviews 10:04 < elle> y-ish 10:04 < jonatack> hi 10:04 <@jnewbery> that's great. Any first impressions? I really enjoyed getting stuck into the low level cryptographic code. It's not something I look at very much 10:04 < willcl_ark> some of the operations def appear quite inaccessible at first look 10:05 < glozow> i finally got to use math 10:05 <@jnewbery> willcl_ark: I agree. Definitely took a lot of thinking to work out what's going on 10:05 <@jnewbery> First question: How much state is stored inside the MuHash3072 rolling hash object? How much data is returned to a user requesting the set hash? 10:05 < felixweis> yes i spend quite some more time on the python implementation because its a lot easier to understand 10:05 < willcl_ark> but they get a _bit_ better once you try to match them up with the crypto scheme itself 10:05 <@jnewbery> felixweiss: yeah, it's nice that python just does bignums and modular inverses for you 10:06 < glozow> Just a Num3072 which is an array of “limbs” (represented as uints size depending on what system supports) for a total = 3072 bits. Output is a 384b hash 10:06 < stacie> The rolling hash object stores 2 pieces of information - (1) the product of hashes for all the elements that have entered the set, and (2) the product of hashes for all elements that have been removed from the set. (at least that's what I gathered from the mailing list post :) ) When a user requests the hash, only a 256 bit hash is returned (but I see in the code that a 384 byte hash is returned). 10:06 < willcl_ark> looks like MuHash3072 stores 3072 bits and returns a 256 bit hash to the user 10:06 < jesseposner> Finalize returns a 384-byte hash, however, the spec calls for a compression step that reduces it to 256 bits 10:06 < willcl_ark> TBH I was confused by the user bit -- the C++ code looked like 384 bit hash, but the python code looked like a 256 bit hash 10:07 < sipa> 384 *bytes* 10:07 < sipa> aka 3072 bits 10:07 -!- webtricks [6742d10c@103.66.209.12] has joined #bitcoin-core-pr-reviews 10:07 < sipa> which is the observable state 10:07 < sipa> the hash of that is the output hash 10:07 < felixweis> wasn't there both a numerator and denumerator before finalization? 10:08 < sipa> yes, but those aren't observable 10:08 <@jnewbery> very good everyone! Yes, the question was a bit vague. The MuHash class returns a 3072 bit object to the client code. When that gets integrated into Bitcoin Core, it'd be hashed down to 256 bits before returning it to the end user 10:08 < sipa> it's just an optimization to delay divisions/inverses as long as possible 10:08 < felixweis> which is quite smart considering how much slower div is to mul 10:09 < sipa> so instead of computing a1/d1*a2/d2*a3/d3 (for 3 adds and 3 deletes), it's computing (a1*a2*a3)/(d1*d2*d3) 10:09 < willcl_ark> ^ which is the answer to a later question IIRC 10:09 < sipa> sorry. 10:09 <@jnewbery> stacie: Storing a numerator and denominator would be an optimization. In the actual implementation we just store one Num3072 (the numerator/denominator) 10:09 <@jnewbery> Why was 3072 bits chosen as the size of the group? 10:09 < jesseposner> 3072-bit DL has about 128 bits of 10:10 < jesseposner> security 10:10 < jesseposner> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-May/014337.html 10:10 < glozow> I try answer: security = we’re trying to prevent collisions. Usually we’d like something like 128 bits of security, i.e. O(2^128) time to break. Muhash incremental hashing also makes it possible to attack slightly more efficiently than brute force, i.e. in O(2^(2*sqrt(n)-1) time. So 2*sqrt(3072) - 1 ~= 128 bits of security 10:10 <@jnewbery> (that's question 2, not a question for sipa :) ) 10:10 < CD36> I am new to this code base. I am just curious if you guys thought of using ISO CPP guideline and Google Cpp Style Guide. 10:10 < willcl_ark> 3072-bit DL has about 128 bits of security when used modulo a sufficiently large prime or an elliptic curve group 10:10 < stacie> I don’t have a better answer to why 3072 bits other than it’s best practice. Wagner’s Birthday Problem/k-sum paper shows that when MuHash uses a sufficiently large prime for the modulo step, it is provably secure under the discrete log assumption. Common guidelines state that 3072 bits is enough security. 10:10 < sipa> in ECC 256-bit is enough for 128 bits of security 10:10 < jesseposner> and 128 bits of security is sufficient until the next revolutionary breakthrough in either mathematics or technology 10:11 <@jnewbery> jesseposner glozow willcl_ark stacie: yes! 10:11 < sipa> in modulo prime groups, 3072 bits is needed 10:11 < sipa> jesseposner: also, bitcoin has 128-bit security for lots of things already - it doesn't make sense to target higher 10:11 <@jnewbery> 3. Can the Muhash of a single object (eg a transaction) be calculated and cached? Would we do this in practice? 10:11 < stacie> jnewbery ah! noted. I thought the numerator/denominator thing was so cool 10:11 < willcl_ark> sipa: is that because of the RIPMD160? 10:11 < michaelfolkson> Yes. No 10:12 < sipa> willcl_ark: no... secp256k1 has 128 bit security, and 256-bit hashes for transactions have 128 bit collision resistance 10:12 < willcl_ark> jnewbery: because we can add or delete in any order, there's no need to cache individual elements 10:12 <@jnewbery> CD36: That's a bit off topic for now, but you can find our style guide at https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md#coding-style-general 10:12 < [filebot]> doc/developer-notes.md#coding-style-general 10:12 < jesseposner> You could calculate a single object but if you don't need the homomorphic properties then there is no reason to use it because it's slow and complex when compared with sha256 10:12 < jonatack> CD36: see https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md ... the guides you refer to are indeed sometimes referenced by reviewers 10:12 < [filebot]> doc/developer-notes.md 10:12 < michaelfolkson> Caches are large 10:13 < michaelfolkson> (768 bytes) 10:13 < sipa> willcl_ark: P2SH has only 80 bits of collision resistance which matters for some uses, which is why P2WSH only has a 256-bit script hash mode 10:13 < willcl_ark> sipa: thanks, that's very helpful! 10:14 <@jnewbery> michaelfolkson: right (althought with this implementation, it'd be 384 bytes since we're not storing numerator and denominator) 10:14 < sipa> it depends on whether you'd be willing to do the inverse for every transactions 10:15 <@jnewbery> again, the question was a bit vague. The idea here is that it doesn't make sense to precompute the muhash of individual transactions in the mempool, since the cached muhash of the transaction would be large 10:15 < sipa> yeah, 384 or 768, it's both pretty big compared to average transaction-in-memory sizes 10:16 <@jnewbery> under a different scheme like ECMH, the cache would only be 64 bytes per object 10:16 < michaelfolkson> "slow and complex when compared with sha256" This isn't the case I don't think. Or at least not specific jesseposner 10:16 < sipa> michaelfolkson: it is many times slower than just SHA256'ing the whole UTXO set 10:17 <@jnewbery> sipa: if you were pre-caching, perhaps you'd want to store 384 bytes and then have half the multiplications and no inverse on the critical path? 10:17 -!- solvangv [ac5a0816@cpe-172-90-8-22.socal.res.rr.com] has joined #bitcoin-core-pr-reviews 10:17 < sipa> jnewbery: or you'd use ECMH instead :) 10:17 <@jnewbery> indeed 10:17 <@jnewbery> ok, next question has already been answered. What is the most expensive operation to carry out in the rolling hash? What can we do to reduce the number of times we need to carry out this operation? 10:18 <@jnewbery> (partly answered) 10:18 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has joined #bitcoin-core-pr-reviews 10:18 < jesseposner> the modular inverse is the most expensive operation so we wait to compute an inverse until the final hash is needed 10:18 < willcl_ark> calculating the modular inverse 10:18 < stacie> The most expensive operation to carry out in the rolling hash is computing the modular inverse. The rest of my answer to the rest is based on what I learned from the mailing list post, but as of 5 min ago I learned the actual implementation stores just one Num3072 for the numerator/denominator. To minimize the amount of times the inverse computation has to happen, the running hash is stored as a fraction. Newly 10:18 < stacie> created UTXOs (aka new elements in the set) are multiplied into the numerator, and spent UTXOs (aka elements needing removal from the set) are multiplied into the denominator. The inverse operation is only performed when a final hash is needed. 10:18 < michaelfolkson> That is very quick typing stacie 10:18 <@jnewbery> jesseposner willcl_ark stacie: exactly right! 10:18 * michaelfolkson needs time to read 10:19 < lightlike> In the python implementation, the numerator and denominator are part of the internal state, while here, it seems that the user is responsible for keeping track of them. Why the difference? 10:19 < jesseposner> I was wondering about that as well 10:19 < glozow> lightlike what do you mean user is responsible for keeping track? 10:19 <@jnewbery> lightlike: what do you mean by the user keeping track of them? The user just passes objects to add to and remove from the set 10:19 < stacie> michaelfolkson haha I did (some) of my homework this time ;) but I'm reaching the end of my answer sheet :P 10:20 < jesseposner> the numerator/denominator logic seems like it maps to the limb arithmetic 10:20 -!- webtricks [6742d10c@103.66.209.12] has quit [Remote host closed the connection] 10:21 < lightlike> glozow: i thought the user would have a local var for both, and multiply the right one for adding/removing, and only doing division at the end - like it is done in crypto_test.cpp unit test. 10:21 -!- syrex [~deamon@p5b25566e.dip0.t-ipconnect.de] has joined #bitcoin-core-pr-reviews 10:21 < sipa> i think the reason is just that in python the bignum arithmetic is trivial, and doesn't deserve a class on its own - it's just a number 10:21 < willcl_ark> I would also say I was surprised to see the optimisation left on the table for follow up; was it much harder to implement? 10:21 <@jnewbery> jesseposner: The limb arithmetic is to implement wide (3072 bit) integers. Python allows you to do arithmetic on arbitrarily large ints, so it's not needed in the Python implementation 10:21 < felixweis> my guess is limb arithmetic is used because unlike python it doesn't do infinitly large integers 10:22 < sipa> so the data structure there is a higher-level thing doing something more high-level 10:22 < jesseposner> jnewbery: ah that makes sense, thanks! 10:22 < sipa> in the C++ code, MuHash3072 is really just a specialized 3072-bit bignum implementation 10:22 <@jnewbery> lightlike: That's just for the unit test. In normal usage, the client code would just pass objects to the MuHash object to add and subtract from the set 10:22 < sipa> if we'd want you could write a higher-level wrapper around that for the actual multiset hash scheme 10:22 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has quit [Ping timeout: 256 seconds] 10:23 <@jnewbery> Next question: How can we test for membership in the Muhash set? 10:23 < glozow> nope 10:23 < willcl_ark> You can't? 10:23 < michaelfolkson> Trick question 10:23 < jesseposner> We can't. In fact, it's not a set, but rather a hash representing a set: https://github.com/bitcoin/bitcoin/pull/19105/files#r438847029 10:23 <@jnewbery> very good. None of you fell for the trick question 10:23 < sipa> it's trivial, you recompute it from the entire set ;) 10:23 < jesseposner> :-) 10:23 < lightlike> jnewbery: I thought the user would use the "/" operator as rarely as possible because it involves a costly "Inverse" call. instead, they would keep a local running variable for the denominator, and only divide numerator/denominator at the end. 10:24 < michaelfolkson> Though sipa did say in the mailing list post that it doesn't support compact proofs of existence 10:24 < sipa> Here's why to do if you want to compactly test for membership in MuHash: lie down, cry, cry a lot 10:24 <@jnewbery> yes, this is a hashed representation of a set, not an accumulator 10:24 < felixweis> so for c++ we do the combination of numerator and denominator later outside of 2 MuHash3072 instances 10:25 <@jnewbery> lightlike: that'd be quite an imposition to place on the client code I think 10:25 < lightlike> jnewbery: but otherwise, if we'd call "/" immediately, it seem really inefficient 10:25 < sipa> that's what the C++ code does, though? 10:26 < sipa> let the user maintain numerator and denominator explicitly 10:26 <@jnewbery> It'd be trivial to enhance the implementation to store both the numerator and denominator 10:26 < fjahr> I am doing it in the implementation of the index right now, yes 10:26 <@jnewbery> sipa: oh! Is that how it's supposed to be used? 10:26 < sipa> jnewbery: yes 10:26 < willcl_ark> lightbulb.gif 10:27 < sipa> it would be totally reasonable to provide a higher-level class that does that for you 10:27 < sipa> matching the Python code 10:27 <@jnewbery> lightlike: I apologise. You were right. I haven't looked at how this code is integrated into the UTXO index 10:27 < sipa> the MuHash3072 class in C++ is *just* a specialized 3072-bit bignum implementation; it's not really the full set hash scheme (as it excludes the ChaCha20 and SHA256 too) 10:28 < sipa> ah no, it does the ChaCha20'ing, but not the hashing 10:29 < willcl_ark> a little confusingly-named if it's not the full implementation, but makes a lot of sense now 10:29 < sipa> it may make sense to refactor that 10:29 < sipa> into a Num3072 class that's just the numbers, and MuHash3072 that does num/denom/chacha20/sha256 10:29 < willcl_ark> what would you call the higher-level class otherwise 10:29 < willcl_ark> I think that would be nice 10:29 < gentile> agreed 10:30 <@jnewbery> sipa: Don't we already have that? Num3072 is the bignum class 10:30 < jesseposner> +1 10:30 < sipa> jnewbery: eh, it's just the storage without operations 10:30 < sipa> but good point 10:31 <@jnewbery> so you're saying move all the functions into class methods in Num3072? 10:31 < PatrickLemke> sipa Is there a specific reason why you implemented your own bignum support for C++? 10:31 < sipa> though in some cases you don't actually need the num/denom trick (if you're computing the muhash3072 from the utxo set in full, you're never deleting) 10:31 < sipa> PatrickLemke: avoiding a dependency for something that's possibly consensus critical at some point 10:32 <@jnewbery> we have quite a lot of questions to get through, so let's keep moving. What public methods does the MuHash3072 object expose to clients? What is the Span<> class template that’s used in some of those public methods? 10:32 < willcl_ark> The *= and /= operators 10:32 < jesseposner> *=, /=, Finalize 10:32 < nehan> Span is sort of like a slice in Go. It points to some range in another datastructure 10:33 < nehan> hi 10:33 < felixweis> i wasn't quite sure about the span because the INPUT_SIZE is supposedly fixed 10:33 <@jnewbery> hi nehan! 10:33 < felixweis> makes sense if we hash in the instanciation tho 10:33 < nehan> i wasn't clear on why Span either 10:33 <@jnewbery> yes, we have multiplication and division operators, a constructor and a Finalize() function 10:34 < willcl_ark> A span is just a template for a sequence of value of the same type I think 10:34 <@jnewbery> We talked about Spans in a previous review club meeting: https://bitcoincore.reviews/18468 10:34 < sipa> willcl_ark: it's not a template 10:34 < sipa> it's a way of passing a (pointer to array, length of array) conveniently, so it works with any container that stores sequential elements of that type 10:35 <@jnewbery> they're a lightwight, non-owning reference to some contiguous sequence of objects (bytes in this case) 10:35 < sipa> but it's a concrete data type, not a way of just making your function templated in the type of the passed object (which is an alternative that also works0 10:35 < jonatack> A Span represents a vector-like view to a range of contiguous elements in memory analogous to std::span in C++20 10:35 < jonatack> (one more definition ;) 10:36 <@jnewbery> Next question. What does the #ifdef HAVE___INT128 code in muhash.h do? 10:36 < jonatack> they're becoming quite ubiquitous in the codebase 10:36 < glozow> HAVE___INT128 = whether your system supports 128b integers? 10:36 < willcl_ark> If you have BigInt support, you can use MuHash with fewer, larger limbs to make up your 3072 bits. Does this require fewer inverse/multiplications when computing the hash? 10:37 <@jnewbery> willcl_ark: not fewer inverse/multiplications, but each inverse/multiplication requires fewer operations 10:37 < glozow> I imagine bigger integers = fewer operations = more optimized ? 10:37 <@jnewbery> glozow: right 10:37 < jesseposner> the HAVE___INT128 branch is optimized for 64-bit multiplication hardware (https://github.com/bitcoin/bitcoin/pull/19055/files#r507238291) 10:37 < willcl_ark> jnewbery: ah right, thanks 10:37 < glozow> How would one test consistency between HAVE___INT128 and !HAVE___INT128 platforms? 10:38 < sipa> willcl_ark: not fewer inverses, but each inverse (and 3072-bit multiplication) consists of 4x fewer limb multiplications if they're twice as big 10:38 < felixweis> https://www.youtube.com/watch?v=FRkJCvHWdwQ from 45:25 has a good short overview of in c++20. Span behaves similar 10:39 <@jnewbery> fjahr helpfully did some benchmarking of the performance difference between using int128 and not: https://github.com/bitcoin/bitcoin/pull/19055#discussion_r508093977 10:39 < syrex> Which C++ standard is used? 10:39 <@jnewbery> glozow: very good question. What do people think? 10:39 < willcl_ark> That's a decent speedup 10:40 < nehan> well you need the hardware, but presumably you could #define it off and compare the results in a test? 10:40 < sipa> syrex: bitcoin core master is C++11 right now, but we'll transition to C++17 probably in the next few weeks (after 0.21 branch off) 10:40 < jonatack> syrex: c++11, migration to 17 is planned during the next release or so. 10:41 <@jnewbery> nehan: yeah, that sounds sensible. It'd be quite nice to do it automatically though 10:41 <@jnewbery> 4. How is a MuHash3072 object constructed and initialized? What happens if the ChaCha20 output is larger than the group order? 10:41 < willcl_ark> glozow: perhaps you exercise each mathmatical operation with and without it using some edge-sized values? 10:41 -!- CD36 [4fdc3cd3@p4fdc3cd3.dip0.t-ipconnect.de] has quit [Remote host closed the connection] 10:42 < michaelfolkson> You take the output modulo the group order..? 10:43 < willcl_ark> Looks like it must be initialised with a Span of type `unsigned char` containing one 32B key otherwise `assert(key32.size() == INPUT_SIZE)` will trigger 10:43 < sipa> michaelfolkson: you're confused; there is no group here (except the multiplicative group we're working in) 10:43 <@jnewbery> michaelfolkson: that's a good guess but it's not the right answer 10:44 < sipa> it's just taken modulo the modulus 10:44 < sipa> that modulus is not the order of some other group 10:44 <@jnewbery> sipa: I don't understand 10:45 < sipa> MuHash3072 is doing arithmetic in the field of integers modulo 2^3072 - 1103717 10:45 < sipa> in particular, the multiplication subgroup of that field is what we use 10:45 -!- jcg [446b68d7@ip68-107-104-215.sd.sd.cox.net] has left #bitcoin-core-pr-reviews [] 10:46 < sipa> but 2^3072 - 1103717 isn't the order of some other group (like scalar arithmetic is arithmetic modulo the order of an EC group) 10:46 < sipa> it's just a constant we've chosen 10:46 < jesseposner> This comment refers to the "order of the group" (perhaps it should be revised?): https://github.com/bitcoin/bitcoin/pull/19055/files#diff-ccad840af4d1bda6dda986297fdd142a8cf433cd4ab4222eea20fe1fd229a158R16 10:47 < sipa> no, that's correct 10:47 < sipa> actually, it's not 10:47 -!- [filebot] [~filebot@95.211.225.220] has quit [Remote host closed the connection] 10:47 * Murch is waiting for sipa's computing process to halt 10:47 -!- [filebot] [~filebot@95.211.225.220] has joined #bitcoin-core-pr-reviews 10:47 < sipa> it is the order of the additive group of integers modulus that number, trivially 10:48 < sipa> but that additive group isn't relevant to us here; we only multiply and divide 10:48 < sipa> it should just say "is chosen as modulus" 10:48 < fjahr> noted :) 10:48 <@jnewbery> ah! I think that's what's confused me 10:48 < sipa> jesseposner: thanks for pointing that out, i guess past-me made the same mistake 10:49 < lightlike> hmm, where exactly is the modulus taken? No "%" exists in all of muhash.cpp 10:49 < sipa> lightlike: thankfully! modulus operations are slow 10:49 <@jnewbery> ok, so let me revise my question. What happens if the output of the chacha20 is greater than the modulus? 10:49 < sipa> lightlike: like 100x slower than a multiplication 10:50 < sipa> lightlike: and the modulus is computed inside the Multiply and Square functions, simultaneously with the multiplication 10:50 < lightlike> sipa: ah, thanks! 10:51 < gentile> 9 minutes left 10:51 <@jnewbery> right, so if the output of the chacha20 is greater than the modulus, we don't do anything, because we reduce in the Finalize() function 10:51 < sipa> lightlike: there is a name for this technique, but if you want to compute (x mod (2^N - C)), where x is up to 2N bits, you can observe that it's equal to (x_low) + (x_high * C), where _low and _high are the bottom and upper half of x 10:52 <@jnewbery> Next question: The Finalize() method has a comment “Does not change this object’s value.” Why is the function not marked const? 10:52 < felixweis> I probably have to read this 2^N times to understand it... 10:53 < glozow> Wale, the effective value is never changed, but Finalize might call FullReduce() in case IsOverflow(), which mutates the Num3072 object? 10:53 <@jnewbery> glozow: exactly right! 10:53 < sipa> felixweis: what is 1437 mod 99? 10:53 < sipa> quick 10:53 < Murch> 51? 10:54 < sipa> indeed, why? 10:54 < Murch> 37+14 10:54 < sipa> bingo; 1400 mod 99 = 14 10:54 < glozow> 🤯 10:54 < sipa> what is 1437 mod 97? 10:54 <@jnewbery> FullReduce() doesn't change the value modulo 2^3072 - 1103717, but it may change the internal Num3072 representation 10:55 < Murch> 79 10:55 < sipa> yup, why? 10:55 < glozow> i needed some time to multiply 14*3 tho 10:55 < sipa> :D 10:55 < Murch> 3*14+37 < 97 10:55 < sipa> exactly, it's the same here: by having a modulus close to a power of two, we can reduce by multiplying the top half by C, and adding to the lower half 10:56 <@jnewbery> ok, we're almost out of time, so I'm going to skip to the last question. How is this new code tested? Can you think of other ways that it could be tested? 10:56 < felixweis> interesting 10:56 < felixweis> TIL 10:57 < glozow> we can test by having sipa do it in his head and compare with the code's results 10:57 < buzz08> :-D 10:57 < sipa> or use the python code 10:57 < sipa> it's faster 10:58 <@jnewbery> sipa: good answer! 10:58 < michaelfolkson> There are some unit test cases and some fuzzing. 10:58 < buzz08> sipa: good comeback 10:58 -!- maxg [6b4de1ea@mobile-107-77-225-234.mobile.att.net] has joined #bitcoin-core-pr-reviews 10:58 <@jnewbery> I think it'd be really cool if we integrated something like this: https://github.com/bitcoin/bitcoin/pull/19841#issuecomment-687667841 10:59 <@jnewbery> Where the python implementation and c++ implementation are tested against the same random input and checked that they arrive at the same result 10:59 < buzz08> a functional test case with sample I/O values ? 10:59 < Murch> jnewbery: Of course that only proves that they are coming to the same result, not that the result is correct ;) 11:00 < willcl_ark> Murch: we only need consensus though, right :P 11:00 <@jnewbery> buzz08: yeah, we do have test vectors, but it's also nice to have more random coverage 11:00 < Murch> willcl_ark: touche 11:00 <@jnewbery> ok, that's time. Thanks everyone! Hope you enjoyed looking at some lower level code this week 11:00 < sipa> if there is a bug in this code, it'll likely result in different results on 32-bit and 64-bit code 11:00 -!- PatrickLemke [4d0901d4@dynamic-077-009-001-212.77.9.pool.telefonica.de] has quit [Remote host closed the connection] 11:00 < willcl_ark> thanks jnewbery, sipa! 11:01 < stacie> thanks for hosting jnewbery! 11:01 < felixweis> great thanks jnewbery for hosting :-) 11:01 < glozow> thanks jnewbery! 11:01 < buzz08> great info guys, thanks to all 11:01 < nehan> thanks! 11:01 < blueskies> this was fascinating. thank you all! 11:01 < fjahr> thanks jnewbery :) 11:01 < thomasb06> (order of a group G, say o(G), implies that for all g in G, g * g * ... * g done o(G) times always gives the neutral element of G, say 1 with multiplicative notation. But by definition, the order of a group is the number of element of the group. The g * g * ... * g = 1 is a consequence. For example the group of symmetries that keep a cube invariant is of order 48, that is there are 48 symmetries in the group. Bu 11:01 < thomasb06> it takes g * g * ... * g done 48 times to get the neutral element, here the identity transformation. If you consider only the rotational symemetries, the group is of order 24 only.) 11:01 < lightlike> thanks! 11:01 < willcl_ark> Who is compiling the review-club compendium of factoids anyway 11:02 < thomasb06> thanks jnewberry 11:02 < michaelfolkson> "do you plan to add tests using the just-added Python MuHash3072 implementation?" jonatack 11:02 < gentile> thanks jnewbery 11:02 < elle> thanks! 11:02 -!- maxg [6b4de1ea@mobile-107-77-225-234.mobile.att.net] has quit [Remote host closed the connection] 11:02 < sipa> thomasb06: groups can be larger than their order 11:03 < michaelfolkson> Thanks jnewbery 11:03 < jonatack> michaelfolkson: is that from my review last May? 11:03 < fjahr> michaelfolkson: they are there in the follow-up pr 11:03 < michaelfolkson> Yup 11:03 < michaelfolkson> Ah nice fjahr 11:03 < sipa> thomasb06: the addition group of GF(2^2) has order 2, but size 4 11:03 < emzy> Tnx anyone 11:03 < jonatack> thanks jnewbery and fjahr, I'll re-review completely after branch-off 11:04 < jonatack> I have a fun favor to ask while you are here: if you haven't seen it yet, check out this tweet by Murch https://twitter.com/murchandamus/status/1318898781618917378 11:04 < jonatack> and cast your vote in these two twitter polls about bitcoin feerate units https://twitter.com/jonatack/status/1318890833131823104 11:04 -!- elle [~ellemouto@155.93.252.70] has quit [Quit: leaving] 11:05 -!- buzz08 [~buzz@2401:4900:234f:2eb8:c205:792e:739:63f1] has left #bitcoin-core-pr-reviews ["Leaving"] 11:05 < thomasb06> sipa well, as far as I remember, the order was the number of element when talking of a group 11:05 < michaelfolkson> Surely for users it has to be sat/VB... (don't want to swing poll) 11:05 < Murch> jonatack: So far people seem to be fairly unambiguous 11:05 < thomasb06> (my computer is swaping) 11:06 < jonatack> Murch: the first poll, definitely 11:08 < jonatack> michaelfolkson: seems so but i'm unsure how much of that preference is habit or unfamiliarity. for now proceeding with sat/vB 11:09 < michaelfolkson> Right thomasb06 11:10 < michaelfolkson> https://en.wikipedia.org/wiki/Order_(group_theory) 11:12 < thomasb06> hehe, the memories were not bad. It starts to be far though... 11:14 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has joined #bitcoin-core-pr-reviews 11:15 -!- shaunsun [shaunsun@gateway/vpn/privateinternetaccess/shaunsun] has quit [Quit: Leaving] 11:16 < michaelfolkson> I've been flailing around in EC world too recently. Have to remember which world you are operating in 11:18 < glozow> wait so group order != size? 11:18 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has quit [Ping timeout: 264 seconds] 11:19 < thomasb06> glozow: when talking of the set, no 11:19 -!- emzy-web [577a71ed@87.122.113.237] has quit [Remote host closed the connection] 11:19 < thomasb06> but in the case of sepc256k1, the group is cyclic so it's the same 11:20 < thomasb06> G = 11:20 < thomasb06> so o(G) = o(g) 11:22 < thomasb06> michaelfolkson: yes, the ECs are defined over finite fields, it's always confusing 11:24 < glozow> the group = the underlying set + the binary operation, in this case mod multiplication? 11:26 < thomasb06> glozow: leave the mod multiplication, takes the symmetries that keep a cube invariant. It's a simple group 11:26 < thomasb06> *take 11:30 -!- blueskies [~blueskies@185.152.67.4] has quit [Quit: WeeChat 2.9] 11:30 < sipa> glozow: the group we're working over here is the multiplication modulo 2^3072-1103717 11:30 < sipa> the _order_ of that group is (2^3072-1103717)-1, as it excludes the 0 element 11:30 < sipa> (which is not considered part of the multiplicative group) 11:31 < sipa> so the integers modulo P=2^3072-1103717 has P elements, but only P-1 of those participate in the multiplicative group 11:32 < sipa> that also means that if you take any number (except 0), and raise it to the power P-1, modulo P, you get 1 11:32 < sipa> which is the identity in that group 11:32 < sipa> as it's a cyclic group, its size is equal to its order, but that order is _not_ the modulus 11:39 < glozow> sipa that makes sense, thank you 11:45 -!- gentile [~gentile@195.181.160.175.adsl.inet-telecom.org] has left #bitcoin-core-pr-reviews [] 11:49 -!- syrex [~deamon@p5b25566e.dip0.t-ipconnect.de] has quit [Read error: Connection reset by peer] 12:04 < jesseposner> So if I'm getting this right, the modulus, 2^3072 - 1103717 (the largest 3072-bit safe prime number), is used to define a finite field. The order of that finite field is the modulus. However, the non-zero elements of the finite field form a multiplicative group, and thus the order of the group is (2^3072-1103717)-1 because it excludes the 0 element. 12:06 < thomasb06> jesseposner: it sounds good but I don't know what a modulus is... The number of elements? 12:07 < jesseposner> It is equal to the number of elements in the finite field, but is not equal to the number of elements in the group (because the group excludes the zero element of the field). 12:07 < thomasb06> jesseposner: order is for groups rather, so a finite field has a modulus but no order 12:08 < jesseposner> I believe both a group and a finite field have an order. 12:08 < thomasb06> then, the field is of modulus 2^3072 - 1103717 12:08 < jesseposner> yes 12:08 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has joined #bitcoin-core-pr-reviews 12:09 < thomasb06> and the invertibles are a group of order 2^3072 - 1103717 - 1 12:09 < thomasb06> (not used to the order term for fields though) 12:10 < jesseposner> I believe so 12:11 < sipa> jesseposner: yes, "order of a field" is really "order of its additive group" 12:11 < sipa> jesseposner: and the field we have here has an additive group (which we don't use!) of order MODULUS, and a multiplicative group of order MODULUS-1 12:11 < sipa> that is the case only because MODULUS is a prime 12:12 < sipa> if MODULUS was not a prime, then (integers mod MODULUS) would not be a field (it would be a ring instead), and its multiplicative group would have an order less than MODULUS-1 12:12 < jesseposner> ah, interesting! 12:13 < sipa> this is used in RSA, for example, where the ring (integers modulo p*q) is used; that ring has additive group of order p*q, but multiplicative group of order (p-1)*(q-1) 12:13 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has quit [Ping timeout: 256 seconds] 12:13 < sipa> and security relies on attackers not being able to figure out the order (p-1)*(q-1) given just p*q 12:13 < sipa> (obviously, if you have p and q individually, that's trivial, but they don't) 12:14 -!- slowmotion [b2aec10e@h-178-174-193-14.NA.cust.bahnhof.se] has joined #bitcoin-core-pr-reviews 12:14 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has joined #bitcoin-core-pr-reviews 12:15 < sipa> the fact that the multiplicative group for us has order MODULUS-1 is used to compute inverses, btw: if x^(MODULUS-1)=1 for all x != 0, then x^(MODULUS-2) must be x^-1 12:15 < sipa> just divide both sides by x 12:16 -!- Talkless [~Talkless@mail.dargis.net] has quit [Quit: Konversation terminated!] 12:18 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has quit [Ping timeout: 272 seconds] 12:18 -!- stacie [~stacie@c-24-60-139-217.hsd1.ma.comcast.net] has quit [Quit: stacie] 12:19 -!- slowmotion [b2aec10e@h-178-174-193-14.NA.cust.bahnhof.se] has quit [Remote host closed the connection] 12:28 < jesseposner> interesting, and x^(MODULUS-3) == x^-2, and so on 12:30 < sipa> indeed 12:31 < sipa> that's fermat's little theorem btw, which can be stated as "the order of the multiplicative group of integers modulo a prime p is p-1" 12:35 <@jnewbery> The log from today's meeting is posted: https://bitcoincore.reviews/19055-2 12:38 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has joined #bitcoin-core-pr-reviews 12:38 -!- Fichte42 [~fichte42@213-47-47-176.cable.dynamic.surfer.at] has quit [Client Quit] 12:42 -!- lightlike [~lightlike@p200300c7ef132a00e4632f50a6292277.dip0.t-ipconnect.de] has quit [Quit: Leaving] 12:51 < sipa> https://en.wikipedia.org/wiki/Solinas_prime 13:05 -!- solvangv [ac5a0816@cpe-172-90-8-22.socal.res.rr.com] has quit [Remote host closed the connection] 14:01 -!- thomasb06 [~user@eth-west-pareq2-46-193-0-224.wb.wifirst.net] has quit [Remote host closed the connection] 14:50 -!- [filebot] [~filebot@95.211.225.220] has quit [Remote host closed the connection] 14:50 -!- [filebot] [~filebot@95.211.225.220] has joined #bitcoin-core-pr-reviews 14:52 -!- illlicit_ [uid109953@gateway/web/irccloud.com/x-gcthnvdowdyrmsma] has joined #bitcoin-core-pr-reviews 14:56 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 15:01 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has joined #bitcoin-core-pr-reviews 15:11 -!- vasild [~vd@gateway/tor-sasl/vasild] has quit [Ping timeout: 240 seconds] 15:12 -!- vasild [~vd@gateway/tor-sasl/vasild] has joined #bitcoin-core-pr-reviews 15:15 -!- vasild [~vd@gateway/tor-sasl/vasild] has quit [Remote host closed the connection] 15:16 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 15:17 -!- vasild [~vd@gateway/tor-sasl/vasild] has joined #bitcoin-core-pr-reviews 15:23 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has joined #bitcoin-core-pr-reviews 16:01 -!- andrewtoth [~andrewtot@gateway/tor-sasl/andrewtoth] has quit [Remote host closed the connection] 16:02 -!- andrewtoth [~andrewtot@gateway/tor-sasl/andrewtoth] has joined #bitcoin-core-pr-reviews 16:29 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 17:00 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has joined #bitcoin-core-pr-reviews 17:15 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 17:26 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has joined #bitcoin-core-pr-reviews 17:51 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 17:52 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has joined #bitcoin-core-pr-reviews 17:58 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 18:04 -!- glozow [uid453516@gateway/web/irccloud.com/x-ekezvtdtaohyoovr] has quit [Quit: Connection closed for inactivity] 18:11 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has joined #bitcoin-core-pr-reviews 18:24 -!- dome [~e-mod@c-73-46-0-211.hsd1.fl.comcast.net] has quit [Quit: My MacBook has gone to sleep. ZZZzzz…] 23:17 -!- davterra [~davterra@gateway/tor-sasl/tralfaz] has joined #bitcoin-core-pr-reviews 23:41 -!- jonatack [~jon@213.152.161.40] has quit [Ping timeout: 256 seconds] 23:43 -!- jonatack [~jon@88.124.242.136] has joined #bitcoin-core-pr-reviews