--- Log opened Thu Jan 26 00:00:27 2023 04:09 -!- josie_ is now known as info 04:09 -!- info is now known as josie 08:36 < josie> hey all, I've updated the BIP draft and I think it's ready for a round of feedback: https://hackmd.io/@silent-payments/HyTiH5r5j 08:37 < josie> a few major changes: I made the overview section less detailed and moved the nitty gritty details to the specification section 08:38 < josie> I also added a section detailing how the sender can create multiple outputs for the receiver 08:39 < josie> the motivation section is still pretty weak imo, so I'll also be refining that quite a bit over the next few days 08:40 < josie> It also occurred to me that we probably want to define two new output descriptor types: 1) for the silent payment address and 2) a new taproot descriptor for adding the silent payment outputs to the wallet 08:42 < josie> the new taproot descriptor would be something like `tr(KEY, TWEAK)`, where `TWEAK = HASH(outpoints_hash·s·input_pubkeys) + A + l·G) mod P` 08:43 < josie> this way, if we separate scanning and spending, we can pass the new taproot descriptor to the signing device and it will have all of the data it needs to calculate the tweaked private key and verify that the tweaked private key can sign for the output KEY 08:43 < josie> e.g tweaked priv key = a + TWEAK 08:44 < sipa> Why not use rawtr(TWEAKEDKEY), if the TWEAK itself is going to be a precomputed value anyway? 08:45 < sipa> ah, to let signers find the corresponding private key easily? 08:46 < josie> sipa: yep! the scanning device will need to pass the TWEAK data to the signer anyways so the signer can sign with a + TWEAK 08:46 < josie> so rather than leave it up to the implementation, my thinking was lets just standardize it as an output descriptor 08:47 < sipa> That's pretty scary, because the signing device can't tell that the tweak isn't something malicious (e.g. a a Merkle root of a tree that includes a script that lets some third party spend the coins). 08:48 < sipa> Perhaps you want an additional tagged hash step around it that's SP specific, so `TWEAK = H_"SPTweak"(SHA256(outpoints ....))`. Then you can reveal the inner SHA256 in the descriptor, and anyone can derive the corresponding tweaked pubkey without worry it may be committing to something else. 08:56 < josie> I'm not sure I follow. How it works today is Alice scans the blockchain and finds an output pubkey, D. She knows its hers because she can verify `D = HASH(outpoints*s*input_pubkeys) + A`, where s is her scan private key and A is her public silent payment address 08:57 < josie> to spend these, she needs privkey = `a + HASH(outpoints*s*input_pubkeys)`, so we need to pass HASH(outpoints*s*input_pubkeys) to the signing device 08:57 < josie> if we also pass D to the signing device, cant the signing device confirm that the passed HASH is not malicious? otherwise a + HASH(..) wont actually work for the pubkey D 08:58 < sipa> A descriptor of the form tr(KEY, TWEAK) (which would map the P2TR output with pubkey equal to KEY+TWEAK*G) prevents the signer from understanding what the output is doing. The TWEAK could be a normal script-bearing P2TR construction. 08:58 < sipa> And e.g. for change analysis a signing device may care. 08:59 < sipa> In this case it may be useful to prove to the signing device that it is in fact a tweak that cannot possibly be a commitment to a script tree. 09:01 < sipa> Oh, or does your envisioned tr(KEY, TWEAK) correspond to the equivalent tr((KEY+G*TWEAK))? Then you already get no-script protection. 09:10 < josie> maybe it's better to avoid the tr() notation to avoid confusion. What I'm envisioning is an entirely new output descriptor type (lets call it sp()) which takes two arguments: the full pubkey D, which alice found while scanning, and the hash data which is needed for tweaking the private key (lets call it priv_tweak) 09:11 < josie> so sp(D, priv_tweak) could be passed to a signing device and it would then know that D is a pubkey which corresponds to a taproot output with no script path, and that priv_tweak is what it needs to add to it's private key a 09:11 < josie> if a + priv_tweak cant sign for D, then the signing device would know it was passed malicious/incorrect data 09:18 < sipa> I think you misunderstand my point, but possibly I'm also misunderstanding mine. 09:18 < sipa> *yours 09:24 < josie> haha its likely a mix of both 09:36 < sipa> I think you're talking about a scenario where the descriptor that the signing device is trusted, and pointing out that it won't sign anything not corresponding to it, or that it would be invalid. 09:37 < sipa> I'm not talking about signing at all. I mean that some signers may want to be able to ascertain that the descriptor it's given isn't actually corresponding to a normal key+script tree p2tr outputs. 09:41 < josie> I see, I think I understand your point now 09:42 < josie> altho its not clear to me at what point the tagged hash step would be applied 09:54 < sipa> So, just background: today, if you use tr(KEY) descriptor, the P2TR output that corresponds to encodes the public key KEY+HASH(KEY)*G. 09:54 < sipa> While if you use rawtr(KEY), you get a P2TR output that encodes KEY directly. 09:54 < sipa> Right? 09:58 < sipa> The reason for that distinction is so that someone who gets a tr(...) descriptor knows that there is no hidden script tree that they don't know about (something which is definitely possible with rawtr(). 10:43 < josie> thanks, that's helpful background. so if I'm following, we could create a whole new output type for SP outputs, something like spo(KEY, TWEAK_DATA). reusing the example above, Bob would create the destination pubkey for Alice like so: D = H_"SPTweak"(HASH(outpoints*S*inputs_priv))*G + A. Alice would scan using H_"SPTweak"(HASH(outpoints*s*inputs_pub))*G + A, and when she finds an output, 10:43 < josie> adds it to her wallet using spo(A, HASH(outpoints*s*inputs_pub)) 10:44 < sipa> What scriptPubKeys would spo(KEY, TWEAK_DATA) correspond to? 10:44 < sipa> (I'm not well versed in silent payment details, so I can't follow everything) 10:50 < josie> spo(A, HASH(outputs..)) would correspond to a single scriptPubKey which is a taproot output: OP_1 A+ H_"SPTweak"(HASH(outpoints..))*G 10:50 < josie> with the private key a + H_"SPTweak"(HASH(TWEAK_DATA)) 10:50 < sipa> Yup, that works. 10:51 < sipa> You might want to give A as input to H_"SPTweak" too. 10:51 < sipa> But I don't think it's strictly necessary. 10:55 < josie> Alice and Bob would both have access to A when computing the tweak, so no reason not to add it, I guess 10:57 < sipa> I suggest it because it mirrors what tr script tree tweaking does, namely OP_1 (A + H_"TapTweak"(A || MerkleRoot) * G). 10:58 < sipa> There it's actually necessary for collision resistance of the tweaking. 11:01 < josie> so for spo() it would be OP_1 (A + H_"SPTweak"(A || TWEAK_DATA)*G), and for the private key (a + H_"SPTweak"(A || TWEAK_DATA)), right? 11:01 < sipa> Yeah. 11:02 < josie> cool, I like that. thanks for working through that with me! 22:55 < w0xlt> Hi, 22:56 < w0xlt> Thanks for all the great work on the BIP, josie. I think it's getting really good. 22:56 < w0xlt> I rebased the PR yesterday and will review it to remember the details as it's been a long time since I've worked on it. 22:56 < w0xlt> Not sure if I'm following, but currently a specific descriptor is implemented: `sp(SPEND_SEC_KEY)`. 22:57 < w0xlt> `SCAN_SEC_KEY` is derived via `HASH(SPEND_SEC_KEY)`. 22:58 < w0xlt> The generated address is: `HRP + spend x-only pubkey + scan x-only pubkey`, according to the identifier. 23:00 < w0xlt> Originally, the `rawtr()` descriptor was used, but a silent payment address doesn't need a script, it just exposes two public keys. 23:00 < w0xlt> Example: 23:00 < w0xlt> ``` 23:00 < w0xlt> $ ./src/bitcoin-cli -regtest getsilentaddress 'donation' 23:00 < w0xlt> { 23:00 < w0xlt> "address": "sprt1mx0828tmms6v4dzjvwyp8w3aus350k9fthlrj8v8zxmp9w2tf88l3kqh6rr98xx05mv444npzkj9j7wrxzj9tc7v0w7jl0xhpc6wzpc0l5gcq", 23:00 < w0xlt> "label": "donation", 23:00 < w0xlt> "identifier": 1 23:00 < w0xlt> } 23:00 < w0xlt> $ ./src/bitcoin-cli -regtest decodesilentaddress "sprt1mx0828tmms6v4dzjvwyp8w3aus350k9fthlrj8v8zxmp9w2tf88l3kqh6rr98xx05mv444npzkj9j7wrxzj9tc7v0w7jl0xhpc6wzpc0l5gcq" 23:00 < w0xlt> { 23:00 < w0xlt> "address": "sprt1mx0828tmms6v4dzjvwyp8w3aus350k9fthlrj8v8zxmp9w2tf88l3kqh6rr98xx05mv444npzkj9j7wrxzj9tc7v0w7jl0xhpc6wzpc0l5gcq", 23:00 < w0xlt> "scan_pubkey": "d99e751d7bdc34cab452638813ba3de42347d8a95dfe391d8711b612b94b49cf", 23:00 < w0xlt> "spend_pubkey": "f8d817d0c65398cfa6d95ad66115a45979c330a455e3cc7bbd2fbcd70e34e107", 23:00 < w0xlt> "label": "donation", 23:00 < w0xlt> "identifier": 1 23:01 < w0xlt> } 23:01 -!- w0xlt [sid555702@id-555702.ilkley.irccloud.com] has quit [] 23:01 -!- w0xlt [sid555702@id-555702.ilkley.irccloud.com] has joined #silentpayments 23:02 < w0xlt> Example: 23:03 < w0xlt> https://www.irccloud.com/pastebin/1FV90j5B/ --- Log closed Fri Jan 27 00:00:27 2023