nostr-connect / nostrum

iOS & Android reference implementation of a Nostr Connect NIP-46 remote signer. Written with React Native Expo
MIT License
61 stars 4 forks source link

sign the hash of the message, not the message #15

Closed bordalix closed 1 year ago

bordalix commented 1 year ago

I think this is the correct behaviour.

tiero commented 1 year ago

Not really: I mean for a taproot transaction we will likely send the sighash already, no real way to send the preimage (ie. raw transaction) I think

bordalix commented 1 year ago

But if you send the hash, the user will not be able to confirm the message he's signing.

tiero commented 1 year ago

But if you send the hash, the user will not be able to confirm the message he's signing.

indeed! One proposal could be to send both the actual sighash along with the psbt/pset? so the app can serialize independently, hash it show "Verified" badge if the sighash matched the given tx.

bordalix commented 1 year ago

Maybe is easier if we forget sign_schnorr and have a sign_message instead, for general text messages. The signer receives the message in plain, shows and asks the user for permission and then returns both signatures:

        const msgHash = await secp256k1.utils.sha256(Buffer.from(message));
        const ecdsa = await secp256k1.sign(msgHash, this.self.secret);
        const schnorr = await secp256k1.schnorr.sign(msgHash, this.self.secret);
        return {
          ecdsa: secp256k1.utils.bytesToHex(ecdsa),
          schnorr: secp256k1.utils.bytesToHex(schnorr),
        }

For psbt/pset, we should have a sign_pbst where the signer receives the hex of the transaction, and at minimum tries to find out the amount the user is spending and asks permission to sign their inputs. Something like this (not tested):

https://github.com/bordalix/marina-mobile/blob/psbt/src/utils/psbt.ts

tiero commented 1 year ago

sign_message as a term has a specific meaning ie. bitcoin signed messages

I am more in favor of having one method > one duty: so would keep spitting sign_schnorr and sign_ecdsa, I am not aware of uses cases where you need to have done both same.

Other than that I am fine with the idea

The signer receives the message in plain

This will be hard to work out of the box with bitcoinJS/liquidJS: unless web apps serialize the transaction by hand, the libraries have methods like hashForWitnessV0 or hashForWitnessV1 which takes a Transaction instance and create the sighash, I am not aware a way to the "preimage" sighash