<p>I am working on verifying a Schnorr signature for a Bitcoin transaction, and despite the signature verification succeeding, I'm encountering the following error when broadcasting the transaction:</p>
<pre><code>Status Err(&quot;RPC error: Object {\&quot;code\&quot;: Number(-26), \&quot;message\&quot;: String(\&quot;non-mandatory-script-verify-flag (Invalid Schnorr signature)\&quot;)}&quot;)
</code></pre>
<p>Here are the details of my transaction:</p>
<p><strong>Unsigned Transaction Hex</strong>:</p>
<pre><code>0200000000010274e1be2d0692b65bd22f61ab77af5840446529bb43c21f99d86461250126563e0000000000ffffffffc68b4cfa8bda7eb1f473b0c42c51bde3d62df313416b090bebc9b8f36b1c48250000000000ffffffff0417270000000000002251200ea2746ae09dfcd1bfbf0f1bc819f7d1192c8fefd65d4ce3a0f510737a18d61a10270000000000002251207c019aba4fe8376b2ca2e4afa89c6a995d973ae55039a505badf55cb3b8fd21b6ad0029500000000225120b8df80071cd758e45bb1345559936864c6ba38bb78663eb13e96b56a459ef3520000000000000000096a5d06008b01016301000247304402204317d0cbaa1f264f536ba1bca4fa66d8c5a54228b8935065f7bee4dc3f7ce32f02205ef2ae85228797824f3ad1e94ec6662992a3a83dcb485a638e7ba5843a8f24b4012102787804fc6954ad0777e2e0717ed775e5344bb9da6307c1d3f3b4df642782622b00000000
</code></pre>
<p><strong>Signed Transaction Hex</strong>:</p>
<pre><code>0200000000010274e1be2d0692b65bd22f61ab77af5840446529bb43c21f99d86461250126563e0000000000ffffffffc68b4cfa8bda7eb1f473b0c42c51bde3d62df313416b090bebc9b8f36b1c48250000000000ffffffff0417270000000000002251200ea2746ae09dfcd1bfbf0f1bc819f7d1192c8fefd65d4ce3a0f510737a18d61a10270000000000002251207c019aba4fe8376b2ca2e4afa89c6a995d973ae55039a505badf55cb3b8fd21b6ad0029500000000225120b8df80071cd758e45bb1345559936864c6ba38bb78663eb13e96b56a459ef3520000000000000000096a5d06008b0101630101407032ca6ad2a3e473f03dd594d9b071ff22bb12e2da4648d33e89a898e4fbd0c423f14a4ddf13f083413877487bc868ae8affb9f9a672bf54197c5b17391409a40247304402204317d0cbaa1f264f536ba1bca4fa66d8c5a54228b8935065f7bee4dc3f7ce32f02205ef2ae85228797824f3ad1e94ec6662992a3a83dcb485a638e7ba5843a8f24b4012102787804fc6954ad0777e2e0717ed775e5344bb9da6307c1d3f3b4df642782622b00000000
</code></pre>
<p>I've verified the Schnorr signature using the appropriate sighash, and everything checks out. Yet, when I try to broadcast the transaction, I receive the above RPC error.</p>
<p>What could be causing this error, and how can I resolve it?</p>
<p><strong>Additional Context</strong>:</p>
<ul>
<li>I'm working with SegWit v1 Taproot outputs.</li>
<li>The signature verification process uses the correct sighash.</li>
<li>The <code>nLockTime</code> and <code>nSequence</code> fields are properly set.</li>
</ul>
<p>Any insights or suggestions would be greatly appreciated!</p>
<p>Code to generate  signature  and verify</p>
<pre class="lang-rust prettyprint-override"><code>
pub fn sign_transaction(
    tx: &amp;mut Transaction,
    priv_key: &amp;PrivateKey,
    mpc_group_pub_key: String,
    funding_script: String,
) -&gt; Result&lt;Transaction, String&gt; {

    let secp = Secp256k1::new();

    // Create sighasher using a mutable reference to tx instead of cloning it.
    let mut sighasher = SighashCache::new(tx.clone());
    //Vault Pub Key
    println!(&quot;MPC key :{:?}&quot;,mpc_group_pub_key);
    let prev_out_1 = ScriptBuf::from_hex(&amp;format!(&quot;5120{}&quot;, mpc_group_pub_key)).unwrap();

    let prev_out_2 = ScriptBuf::from_hex(&amp;funding_script).unwrap();

    // Define previous UTXOs
    let prev_utxo_0 = TxOut {
        value: 10007,
        script_pubkey: prev_out_1,
    };

    let prev_utxo_1 = TxOut {
        //   value: tx.output.get(1).unwrap().value,
        value: 2500000000,
        script_pubkey: prev_out_2,
    };

    let prev_utxo = vec![prev_utxo_0, prev_utxo_1];
    let prevouts: bdk::bitcoin::psbt::Prevouts&lt;_&gt; = Prevouts::All(&amp;prev_utxo);

    let sighash: bdk::bitcoin::sighash::TapSighash = sighasher
        .taproot_key_spend_signature_hash(
            0,
            &amp;prevouts,
            bdk::bitcoin::sighash::TapSighashType::Default,
        )
        .map_err(|e| e.to_string())?;

    let msg = Message::from(sighash);


    // Sign the sighash using the secp256k1 library (exported by rust-bitcoin).
    let key_pair = KeyPair::from_secret_key(&amp;secp, &amp;priv_key.inner);


    let signature = secp.sign_schnorr_no_aux_rand(&amp;msg, &amp;key_pair);


    // Update the witness stack.
    let signature = Signature {
        sig: signature,
        hash_ty: bdk::bitcoin::sighash::TapSighashType::Default,
    };
    println!(&quot;Signature :{:?}&quot;, hex::encode(signature.to_vec()));

    let witness = sighasher.witness_mut(0).ok_or(&quot;Failed to get witness&quot;)?;
    witness.push(&amp;signature.to_vec());
   
    Ok(sighasher.into_transaction().clone())
}
let sk = SecretKey::from_str(&quot;8756415bbbbf1ce134ca7b97e2ca584cb52150783cb37f78cc41ccc7aacc10f1&quot;).unwrap();

let secp = Secp256k1::new();
let hex_msg = &quot;0b5d2c9103c794eec24dd3dbbbfc8c8efc377d3fd613b958bdfc9d649166dc5f&quot;;
let msg = bdk::bitcoin::secp256k1::Message::from_slice(&amp;hex::decode(hex_msg).unwrap()).unwrap();
let sig = bdk::bitcoin::secp256k1::schnorr::Signature::from_slice(&amp;hex::decode(&quot;b9ca544040e9dee3b547b5c781ae13d15a5b20369e522b684c240a9e353b9b4bde1bca69642963801b33dd8ecc50c8714cfa4bb386390a867baabafde59dfd30&quot;).unwrap()).unwrap();

let pubkey = bdk::bitcoin::key::PublicKey::from_str(&quot;020ea2746ae09dfcd1bfbf0f1bc819f7d1192c8fefd65d4ce3a0f510737a18d61a&quot;).unwrap();

println!(&quot;Status {}&quot;, secp.verify_schnorr(&amp;sig, &amp;msg, &amp;pubkey.to_x_only_pubkey()).is_ok());
</code></pre>

CC BY-SA 4.0
2024-08-08T17:38:29.110Z
Are you sure that the sighash is correct? That's the only reason why an otherwise correct signature would not validate.
Pieter Wuille
CC BY-SA 4.0
2024-08-08T17:47:24.367Z
@PieterWuille I added the sighash code now , kindly check, Also added verification code, Kindly check it
Vinay Sawant
CC BY-SA 4.0
2024-08-08T18:11:42.110Z
Does your signing implementation pass the BIP 340 test vectors?
Murch
CC BY-SA 4.0
2024-08-09T03:51:22.173Z
@Murch I have attached the code to verify signature,Same vectors
Vinay Sawant
CC BY-SA 4.0
2024-08-09T04:02:47.717Z
@Murch I have added code to sign_transaction,
Vinay Sawant
<taproot><schnorr-signatures>
"non-mandatory-script-verify-flag (Invalid Schnorr signature)" error despite successful Schnorr signature verification?
Vinay Sawant
# "non-mandatory-script-verify-flag (Invalid Schnorr signature)" error despite successful Schnorr signature verification?

(Asked by: username_0 on 2024-08-08)

I am working on verifying a Schnorr signature for a Bitcoin transaction, and despite the signature verification succeeding, I'm encountering the following error when broadcasting the transaction:

```
Status Err("RPC error: Object {\"code\": Number(-26), \"message\": String(\"non-mandatory-script-verify-flag (Invalid Schnorr signature)\")}")

```

Here are the details of my transaction:

**Unsigned Transaction Hex**:

```
0200000000010274e1be2d0692b65bd22f61ab77af5840446529bb43c21f99d86461250126563e0000000000ffffffffc68b4cfa8bda7eb1f473b0c42c51bde3d62df313416b090bebc9b8f36b1c48250000000000ffffffff0417270000000000002251200ea2746ae09dfcd1bfbf0f1bc819f7d1192c8fefd65d4ce3a0f510737a18d61a10270000000000002251207c019aba4fe8376b2ca2e4afa89c6a995d973ae55039a505badf55cb3b8fd21b6ad0029500000000225120b8df80071cd758e45bb1345559936864c6ba38bb78663eb13e96b56a459ef3520000000000000000096a5d06008b01016301000247304402204317d0cbaa1f264f536ba1bca4fa66d8c5a54228b8935065f7bee4dc3f7ce32f02205ef2ae85228797824f3ad1e94ec6662992a3a83dcb485a638e7ba5843a8f24b4012102787804fc6954ad0777e2e0717ed775e5344bb9da6307c1d3f3b4df642782622b00000000

```

**Signed Transaction Hex**:

```
0200000000010274e1be2d0692b65bd22f61ab77af5840446529bb43c21f99d86461250126563e0000000000ffffffffc68b4cfa8bda7eb1f473b0c42c51bde3d62df313416b090bebc9b8f36b1c48250000000000ffffffff0417270000000000002251200ea2746ae09dfcd1bfbf0f1bc819f7d1192c8fefd65d4ce3a0f510737a18d61a10270000000000002251207c019aba4fe8376b2ca2e4afa89c6a995d973ae55039a505badf55cb3b8fd21b6ad0029500000000225120b8df80071cd758e45bb1345559936864c6ba38bb78663eb13e96b56a459ef3520000000000000000096a5d06008b0101630101407032ca6ad2a3e473f03dd594d9b071ff22bb12e2da4648d33e89a898e4fbd0c423f14a4ddf13f083413877487bc868ae8affb9f9a672bf54197c5b17391409a40247304402204317d0cbaa1f264f536ba1bca4fa66d8c5a54228b8935065f7bee4dc3f7ce32f02205ef2ae85228797824f3ad1e94ec6662992a3a83dcb485a638e7ba5843a8f24b4012102787804fc6954ad0777e2e0717ed775e5344bb9da6307c1d3f3b4df642782622b00000000

```

I've verified the Schnorr signature using the appropriate sighash, and everything checks out. Yet, when I try to broadcast the transaction, I receive the above RPC error.

What could be causing this error, and how can I resolve it?

**Additional Context**:

* I'm working with SegWit v1 Taproot outputs.
* The signature verification process uses the correct sighash.
* The `nLockTime` and `nSequence` fields are properly set.

Any insights or suggestions would be greatly appreciated!

Code to generate signature and verify

```rust

pub fn sign_transaction(
    tx: &mut Transaction,
    priv_key: &PrivateKey,
    mpc_group_pub_key: String,
    funding_script: String,
) -> Result<Transaction, String> {

    let secp = Secp256k1::new();

    // Create sighasher using a mutable reference to tx instead of cloning it.
    let mut sighasher = SighashCache::new(tx.clone());
    //Vault Pub Key
    println!("MPC key :{:?}",mpc_group_pub_key);
    let prev_out_1 = ScriptBuf::from_hex(&format!("5120{}", mpc_group_pub_key)).unwrap();

    let prev_out_2 = ScriptBuf::from_hex(&funding_script).unwrap();

    // Define previous UTXOs
    let prev_utxo_0 = TxOut {
        value: 10007,
        script_pubkey: prev_out_1,
    };

    let prev_utxo_1 = TxOut {
        //   value: tx.output.get(1).unwrap().value,
        value: 2500000000,
        script_pubkey: prev_out_2,
    };

    let prev_utxo = vec![prev_utxo_0, prev_utxo_1];
    let prevouts: bdk::bitcoin::psbt::Prevouts<_> = Prevouts::All(&prev_utxo);

    let sighash: bdk::bitcoin::sighash::TapSighash = sighasher
        .taproot_key_spend_signature_hash(
            0,
            &prevouts,
            bdk::bitcoin::sighash::TapSighashType::Default,
        )
        .map_err(|e| e.to_string())?;

    let msg = Message::from(sighash);

    // Sign the sighash using the secp256k1 library (exported by rust-bitcoin).
    let key_pair = KeyPair::from_secret_key(&secp, &priv_key.inner);

    let signature = secp.sign_schnorr_no_aux_rand(&msg, &key_pair);

    // Update the witness stack.
    let signature = Signature {
        sig: signature,
        hash_ty: bdk::bitcoin::sighash::TapSighashType::Default,
    };
    println!("Signature :{:?}", hex::encode(signature.to_vec()));

    let witness = sighasher.witness_mut(0).ok_or("Failed to get witness")?;
    witness.push(&signature.to_vec());
   
    Ok(sighasher.into_transaction().clone())
}
let sk = SecretKey::from_str("8756415bbbbf1ce134ca7b97e2ca584cb52150783cb37f78cc41ccc7aacc10f1").unwrap();

let secp = Secp256k1::new();
let hex_msg = "0b5d2c9103c794eec24dd3dbbbfc8c8efc377d3fd613b958bdfc9d649166dc5f";
let msg = bdk::bitcoin::secp256k1::Message::from_slice(&hex::decode(hex_msg).unwrap()).unwrap();
let sig = bdk::bitcoin::secp256k1::schnorr::Signature::from_slice(&hex::decode("b9ca544040e9dee3b547b5c781ae13d15a5b20369e522b684c240a9e353b9b4bde1bca69642963801b33dd8ecc50c8714cfa4bb386390a867baabafde59dfd30").unwrap()).unwrap();

let pubkey = bdk::bitcoin::key::PublicKey::from_str("020ea2746ae09dfcd1bfbf0f1bc819f7d1192c8fefd65d4ce3a0f510737a18d61a").unwrap();

println!("Status {}", secp.verify_schnorr(&sig, &msg, &pubkey.to_x_only_pubkey()).is_ok());

```

**Tags:** taproot, schnorr-signatures

> **Comments:**
> **username_1**: Are you sure that the sighash is correct? That's the only reason why an otherwise correct signature would not validate.  
> **username_0**: @username_1 I added the sighash code now , kindly check, Also added verification code, Kindly check it  
> **username_2**: Does your signing implementation pass the BIP 340 test vectors?  
> **username_0**: @username_2 I have attached the code to verify signature,Same vectors  
> **username_0**: @username_2 I have added code to sign_transaction,  

---

## 0 answers

