<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

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

    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**: @PieterWuille 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

