An update on progress on the development of the blinded two-party Schnorr scheme for statechains. 

As stated previously, we believe that one-more-signature and Wagner attacks are mitigated by the client committing the values of the blinding nonce used (labeled f) and the value of R2 used in a signing session to the server before the server responds with their value of R1. Then each time the generated signature is verified (in our application this is a new statecoin owner), the verifier retrieves the commitments and blinded challenge value from the server (c, SHA256(f) and SHA256(R2)) and f and R2 from the co-signer, and verifies that the blinded challenge value c = f + SHA256(X, R1 + R2 + f.X, m) and the commitments match f,R2. This ensures the signer cannot have chosen the values of f and R2 after the value of R1 is randomly generated by the server.  

This scheme has been implemented in a forked version of the secp256k1-zkp library: https://github.com/ssantos21/secp256k1-zkp where a new function has been added secp256k1_blinded_musig_nonce_process ( https://github.com/ssantos21/secp256k1-zkp/blob/ed08ad7603f211fdf39b5f6db9d7e99cf048a56c/src/modules/musig/session_impl.h#L580 ) which is required for the client generation of the blinded challenge value. 

One issue that came up and had to be solved was ensuring the R (curve point) is even (in MuSig2 the secret nonce is negated if R is odd) with the point f.X added (and f committed to). We will add a complete explanation of this to the updated spec. 

The scheme is implemented in a blind server:
https://github.com/ssantos21/blinded-musig-sgx-server

And client:
https://github.com/ssantos21/blinded-musig2-client

Any comments or questions appreciated. 

On Mon, Aug 7, 2023 at 1:55 AM Tom Trevethan <tom@commerceblock.com> wrote:
A follow up to this, I have updated the blinded statechain protocol description to include the mitigation to the Wagner attack by requiring the server to send R1 values only after commitments made to the server of the R2 values used by the user, and that all the previous computed c values are verified by each new statecoin owner. 
https://github.com/commerceblock/mercury/blob/master/layer/protocol.md

Essentially, the attack is possible because the server cannot verify that the blinded challenge (c) value it has been sent by the user has been computed honestly (i.e. c = SHA256(X1 + X2, R1 + R2, m) ), however this CAN be verified by each new owner of a statecoin for all the previous signatures. 

Each time an owner cooperates with the server to generate a signature on a backup tx, the server will require that the owner send a commitment to their R2 value: e.g. SHA256(R2). The server will store this value before responding with it's R1 value. This way, the owner cannot choose the value of R2 (and hence c). 

When the statecoin is received by a new owner, they will receive ALL previous signed backup txs for that coin from the sender, and all the corresponding R2 values used for each signature. They will then ask the server (for each previous signature), the commitments SHA256(R2) and the corresponding server generated R1 value and c value used. The new owner will then verify that each backup tx is valid, and that each c value was computed c = SHA256(X1 + X2, R1 + R2, m)  and each commitment equals SHA256(R2). This ensures that a previous owner could not have generated more valid signatures than the server has partially signed. 

On Thu, Jul 27, 2023 at 2:25 PM Tom Trevethan <tom@commerceblock.com> wrote:

On Thu, Jul 27, 2023 at 9:08 AM Jonas Nick <jonasdnick@gmail.com> wrote:
No, proof of knowledge of the r values used to generate each R does not prevent
Wagner's attack. I wrote

 >   Using Wagner's algorithm, choose R2[0], ..., R2[K-1] such that
 >    c[0] + ... + c[K-1] = c[K].

You can think of this as actually choosing scalars r2[0], ..., r2[K-1] and
define R2[i] = r2[i]*G. The attacker chooses r2[i]. The attack wouldn't make
sense if he didn't.