<oembed><type>rich</type><version>1.0</version><title>Erik Aronesty [ARCHIVE] wrote</title><author_name>Erik Aronesty [ARCHIVE] (npub1y2…5taj0)</author_name><author_url>https://yabu.me/npub1y22yec0znyzw8qndy5qn5c2wgejkj0k9zsqra7kvrd6cd6896z4qm5taj0</author_url><provider_name>njump</provider_name><provider_url>https://yabu.me</provider_url><html>📅 Original date posted:2023-07-26&#xA;🗒️ Summary of this message: The author suggests that whenever a public key is transmitted, it should come with a &#34;proof of secret key&#34; to prevent vulnerabilities.&#xA;📝 Original message:&#xA;personally, i think *any* time a public key is transmitted, it should come&#xA;with a &#34;proof of secret key&#34;.   it should be baked-in to low level&#xA;protocols so that people don&#39;t accidentally create vulns.  alt discussion&#xA;link:  https://gist.github.com/RubenSomsen/be7a4760dd4596d06963d67baf140406&#xA;&#xA;On Tue, Jul 25, 2023 at 5:18 PM Tom Trevethan via bitcoin-dev &lt;&#xA;bitcoin-dev at lists.linuxfoundation.org&gt; wrote:&#xA;&#xA;&gt; Thanks for the replies. As I understand it, the v=2 nonces signing&#xA;&gt; protocol of musig2 prevents the Wagner attack. Also, that the challenge&#xA;&gt; value c must be blinded from the server to prevent the server from being&#xA;&gt; able to determine the signature from the on-chain state.&#xA;&gt;&#xA;&gt; In addition, in order to update the server (party 1) keyshare when a&#xA;&gt; statecoin is transferred between users, the key aggregation coefficient&#xA;&gt; must be set to 1 for each key. The purpose of this coefficient in the&#xA;&gt; Musig2 protocol is to prevent &#39;rogue key attacks&#39; where one party can&#xA;&gt; choose a public key derived from both their own secret key and the inverse&#xA;&gt; of the other party&#39;s public key giving them the ability to unilaterally&#xA;&gt; produce a valid signature over the aggregate key. However this can be&#xA;&gt; prevented by the party producing a proof of knowledge of the private key&#xA;&gt; corresponding to their supplied public key. This can be a signature, which&#xA;&gt; is produced in any case by signing the statechain state in the mercury&#xA;&gt; protocol. This signature must be verified by the receiver of a coin (who&#xA;&gt; must also verify the server pubkey combines with the sender pubkey to get&#xA;&gt; the coin address) which proves that the server is required to co-sign to&#xA;&gt; generate any signature for this address.&#xA;&gt;&#xA;&gt; Here is a modified protocol:&#xA;&gt;&#xA;&gt; Keygen:&#xA;&gt;&#xA;&gt; Server generates private key x1 and public key X1 = x1.G and sends X1 to&#xA;&gt; user (party 2)&#xA;&gt; User generates private key x2 and public key X2 = x2.G and (random)&#xA;&gt; blinding nonce z and computes the aggregate public key X = z.(X1 + X2)&#xA;&gt; (server never learns of X, X2 or z).&#xA;&gt;&#xA;&gt; Signing:&#xA;&gt;&#xA;&gt; Server generates nonces r11 and r12 and R11 = r11.G and R12 = r12.G and&#xA;&gt; sends R11 and R12 to the user.&#xA;&gt; User generates nonces r21 and r22 and R21 = r21.G and R22 = r22.G&#xA;&gt; User computes R1 = R11 + R21 and R2 = R12 + R22 and b = H(X,(R1,R2),m) and&#xA;&gt; R = R1 + b.R2 and c = (X,R,m)&#xA;&gt; User sends the values y = cz and b to the server.&#xA;&gt; Server computes s1 = yx1 + r11 + br12 and sends it to the user.&#xA;&gt; User computes s2 = yx2 + r21 + br22 and s = s1 + s2 and signature (s,R)&#xA;&gt;&#xA;&gt; Transfer:&#xA;&gt;&#xA;&gt; In a statecoin transfer, when receiving a statecoin, in order to verify&#xA;&gt; that the coin address (i.e. aggregate public key) is shared correctly&#xA;&gt; between the previous owner and the server, the client must verify the&#xA;&gt; following:&#xA;&gt;&#xA;&gt; Retrieve the CURRENT public key from the server for this coin X1.&#xA;&gt; Retrieve the public key X2 and the blinding nonce z from the sender.&#xA;&gt; Verify that z.X1 + X2 = P the address of the statecoin.&#xA;&gt; Verify that the sender has the private key used to generate X2: this is&#xA;&gt; done by verifying the statechain signature over the receiver public key X3&#xA;&gt; from X2.&#xA;&gt; This proves that the address P was generated (aggregated) with the server&#xA;&gt; and can only be signed with cooperation with the server, i.e. no previous&#xA;&gt; owner can hold the full key.&#xA;&gt;&#xA;&gt; In order to update the key shares on transfer, the following protocol can&#xA;&gt; be used:&#xA;&gt;&#xA;&gt; Server (party 1) generates a random blinding nonce e and sends it to user.&#xA;&gt; User adds their private key to the nonce: t1 = e + x2&#xA;&gt; Client sends t1 and z to the reciever as part of transfer_msg (encrypted&#xA;&gt; with the receiver public key X3 = x3.G).&#xA;&gt; Receiver client decrypts t1 and then subtracts their private key x3: t2 =&#xA;&gt; e + x2 - x3.&#xA;&gt; Receiver client sends t2 to the server as part of transfer_receiver.&#xA;&gt; Server the updates the private key share x1_2 = x1 + t2 - e = x1 + e + x2&#xA;&gt; - x3 - e = x1 + x2 - x3&#xA;&gt; So now, x1_2 + x3 (the aggregation of the new server key share with the&#xA;&gt; new client key share) is equal to x1 + x2 (the aggregation of the old&#xA;&gt; server key share with the old client key share).&#xA;&gt; The server deletes x1.&#xA;&gt;&#xA;&gt; On Tue, Jul 25, 2023 at 3:12 PM Erik Aronesty &lt;erik at q32.com&gt; wrote:&#xA;&gt;&#xA;&gt;&gt; posk is &#34;proof of secret key&#34;.   so you cannot use wagner to select R&#xA;&gt;&gt;&#xA;&gt;&gt; On Mon, Jul 24, 2023 at 1:59 PM AdamISZ via bitcoin-dev &lt;&#xA;&gt;&gt; bitcoin-dev at lists.linuxfoundation.org&gt; wrote:&#xA;&gt;&gt;&#xA;&gt;&gt;&gt; @ZmnSCPxj:&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; yes, Wagner is the attack you were thinking of.&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; And yeah, to avoid it, you should have the 3rd round of MuSig1, i.e. the&#xA;&gt;&gt;&gt; R commitments.&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; @Tom:&#xA;&gt;&gt;&gt; As per above it seems you were more considering MuSig1 here, not MuSig2.&#xA;&gt;&gt;&gt; At least in this version. So you need the initial commitments to R.&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; Jonas&#39; reply clearly has covered a lot of what matters here, but I&#xA;&gt;&gt;&gt; wanted to mention (using your notation):&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; in s1 = c * a1 * x1 + r1, you expressed the idea that the challenge c&#xA;&gt;&gt;&gt; could be given to the server, to construct s1, but since a1 = H(L, X1) and&#xA;&gt;&gt;&gt; L is the serialization of all (in this case, 2) keys, that wouldn&#39;t work&#xA;&gt;&gt;&gt; for blinding the final key, right?&#xA;&gt;&gt;&gt; But, is it possible that this addresses the other problem?&#xA;&gt;&gt;&gt; If the server is given c1*a1 instead as the challenge for signing (with&#xA;&gt;&gt;&gt; their &#34;pure&#34; key x1), then perhaps it avoids the issue? Given what&#39;s on the&#xA;&gt;&gt;&gt; blockchain ends up allowing calculation of &#39;c&#39; and the aggregate key a1X1 +&#xA;&gt;&gt;&gt; a2X2, is it the case that you cannot find a1 and therefore you cannot&#xA;&gt;&gt;&gt; correlate the transaction with just the quantity &#39;c1*a1&#39; which the server&#xA;&gt;&gt;&gt; sees?&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; But I agree with Jonas that this is just the start, i.e. the fundamental&#xA;&gt;&gt;&gt; requirement of a blind signing scheme is there has to be some guarantee of&#xA;&gt;&gt;&gt; no &#39;one more forgery&#39; possibility, so presumably there has to be some proof&#xA;&gt;&gt;&gt; that the signing request is &#39;well formed&#39; (Jonas expresses it below as a&#xA;&gt;&gt;&gt; ZKP of a SHA2 preimage .. it does not seem pretty but I agree that on the&#xA;&gt;&gt;&gt; face of it, that is what&#39;s needed).&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; @Jonas, Erik:&#xA;&gt;&gt;&gt; &#39;posk&#39; is probably meant as &#39;proof of secret key&#39; which may(?) be a&#xA;&gt;&gt;&gt; mixup with what is sometimes referred to in the literature as &#34;KOSK&#34; (iirc&#xA;&gt;&gt;&gt; they used it in FROST for example). It isn&#39;t clear to me yet how that&#xA;&gt;&gt;&gt; factors into this scenario, although ofc it is for sure a potential&#xA;&gt;&gt;&gt; building block of these constructions.&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; Sent with Proton Mail secure email.&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; ------- Original Message -------&#xA;&gt;&gt;&gt; On Monday, July 24th, 2023 at 08:12, Jonas Nick via bitcoin-dev &lt;&#xA;&gt;&gt;&gt; bitcoin-dev at lists.linuxfoundation.org&gt; wrote:&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt;&#xA;&gt;&gt;&gt; &gt; Hi Tom,&#xA;&gt;&gt;&gt; &gt;&#xA;&gt;&gt;&gt; &gt; I&#39;m not convinced that this works. As far as I know blind musig is&#xA;&gt;&gt;&gt; still an open&#xA;&gt;&gt;&gt; &gt; research problem. What the scheme you propose appears to try to&#xA;&gt;&gt;&gt; prevent is that&#xA;&gt;&gt;&gt; &gt; the server signs K times, but the client ends up with K+1 Schnorr&#xA;&gt;&gt;&gt; signatures for&#xA;&gt;&gt;&gt; &gt; the aggregate of the server&#39;s and the clients key. I think it&#39;s&#xA;&gt;&gt;&gt; possible to&#xA;&gt;&gt;&gt; &gt; apply a variant of the attack that makes MuSig1 insecure if the nonce&#xA;&gt;&gt;&gt; commitment&#xA;&gt;&gt;&gt; &gt; round was skipped or if the message isn&#39;t determined before sending&#xA;&gt;&gt;&gt; the nonce.&#xA;&gt;&gt;&gt; &gt; Here&#39;s how a malicious client would do that:&#xA;&gt;&gt;&gt; &gt;&#xA;&gt;&gt;&gt; &gt; - Obtain K R-values R1[0], ..., R1[K-1] from the server&#xA;&gt;&gt;&gt; &gt; - Let&#xA;&gt;&gt;&gt; &gt; R[i] := R1[i] + R2[i] for all i &lt;= K-1&#xA;&gt;&gt;&gt; &gt; R[K] := R1[0] + ... + R1[K-1]&#xA;&gt;&gt;&gt; &gt; c[i] := H(X, R[i], m[i]) for all i &lt;= K.&#xA;&gt;&gt;&gt; &gt; Using Wagner&#39;s algorithm, choose R2[0], ..., R2[K-1] such that&#xA;&gt;&gt;&gt; &gt; c[0] + ... + c[K-1] = c[K].&#xA;&gt;&gt;&gt; &gt; - Send c[0], ..., c[K-1] to the server to obtain s[0], ..., s[K-1].&#xA;&gt;&gt;&gt; &gt; - Let&#xA;&gt;&gt;&gt; &gt; s[K] = s[0] + ... + s[K-1].&#xA;&gt;&gt;&gt; &gt; Then (s[K], R[K]) is a valid signature from the server, since&#xA;&gt;&gt;&gt; &gt; s[K]G = R[K] + c[K]a1X1,&#xA;&gt;&gt;&gt; &gt; which the client can complete to a signature for public key X.&#xA;&gt;&gt;&gt; &gt;&#xA;&gt;&gt;&gt; &gt; What may work in your case is the following scheme:&#xA;&gt;&gt;&gt; &gt; - Client sends commitment to the public key X2, nonce R2 and message m&#xA;&gt;&gt;&gt; to the&#xA;&gt;&gt;&gt; &gt; server.&#xA;&gt;&gt;&gt; &gt; - Server replies with nonce R1 = k1G&#xA;&gt;&gt;&gt; &gt; - Client sends c to the server and proves in zero knowledge that c =&#xA;&gt;&gt;&gt; &gt; SHA256(X1 + X2, R1 + R2, m).&#xA;&gt;&gt;&gt; &gt; - Server replies with s1 = k1 + c*x1&#xA;&gt;&gt;&gt; &gt;&#xA;&gt;&gt;&gt; &gt; However, this is just some quick intuition and I&#39;m not sure if this&#xA;&gt;&gt;&gt; actually&#xA;&gt;&gt;&gt; &gt; works, but maybe worth exploring.&#xA;&gt;&gt;&gt; &gt; _______________________________________________&#xA;&gt;&gt;&gt; &gt; bitcoin-dev mailing list&#xA;&gt;&gt;&gt; &gt; bitcoin-dev at lists.linuxfoundation.org&#xA;&gt;&gt;&gt; &gt; https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev&#xA;&gt;&gt;&gt; _______________________________________________&#xA;&gt;&gt;&gt; bitcoin-dev mailing list&#xA;&gt;&gt;&gt; bitcoin-dev at lists.linuxfoundation.org&#xA;&gt;&gt;&gt; https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev&#xA;&gt;&gt;&gt;&#xA;&gt;&gt; _______________________________________________&#xA;&gt; bitcoin-dev mailing list&#xA;&gt; bitcoin-dev at lists.linuxfoundation.org&#xA;&gt; https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev&#xA;&gt;&#xA;-------------- next part --------------&#xA;An HTML attachment was scrubbed...&#xA;URL: &lt;http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20230726/b46458c8/attachment-0001.html&gt;</html></oembed>