Skip to content

Dual signature causing ReachedPrunedBranch #333

Closed

Description

@topologoanatom

1. Description

Double verification of Schnorr signatures causes a ReachedPrunedBranch error.

/// Verify Schnorr signature for dual oracle price attestation
/// Message format: SHA256(timestamp || price)
fn checksig_price_attestation(pk: Pubkey, timestamp: u32, price: u64, sig: Signature) {
    let hasher: Ctx8 = jet::sha_256_ctx_8_init();
    let hasher: Ctx8 = jet::sha_256_ctx_8_add_4(hasher, timestamp);
    let hasher: Ctx8 = jet::sha_256_ctx_8_add_8(hasher, price);
    let msg: u256 = jet::sha_256_ctx_8_finalize(hasher);
    jet::bip_0340_verify((pk, msg), sig);
}

fn settlement_positive_path(
    current_price: u64,
    new_price: u64,
    timestamp: u32,
    amount: u64,
    oracle_sig: Signature,
    secondary_sig: Signature
) {
    assert!(jet::eq_64(current_price, current_price));
    assert!(jet::eq_64(new_price, new_price));
    assert!(jet::eq_32(timestamp, timestamp));
    assert!(jet::eq_64(amount, amount));

    checksig_price_attestation(param::ORACLE_PK, timestamp, new_price, oracle_sig);
    checksig_price_attestation(param::USER_PK, timestamp, new_price, secondary_sig);
}

However, if comment out current_price and/or amount assertions, bug disappears.
The reproduction code includes both cases.


2. Steps to Reproduce

  1. Use https://github.com/topologoanatom/simplicity-contracts/tree/bug/dual_sig
  2. Run
cargo test test_settlement_positive_dual_sig_bug 

Activity

  1. apoelstra commented on Dec 31, 2025

    @apoelstra
    Collaborator

    Can you find a smaller reproduction? This calls through simplicityhl_core and simplicityhl and it's hard to tell how anything from rust-simplicity is being invoked.

  2. KyrylR commented on Jan 2, 2026

    @KyrylR
    Collaborator

    The bug disappears if the public keys used in checksig_price_attestation are distinct.

    I was able to reproduce the bug with distinct public keys too (all details are here: BlockstreamResearch/simplicity-contracts#39)

  3. topologoanatom commented on Jan 2, 2026

    @topologoanatom
    Author

    The bug disappears if the public keys used in checksig_price_attestation are distinct.

    I was able to reproduce the bug with distinct public keys too (all details are here: BlockstreamResearch/simplicity-contracts#39)

    It seems that commenting out the assert on amount or current_price actually makes the bug disappear, rather than introducing distinct keys (I accidentally deleted the assert line).

  4. KyrylR commented on Jan 2, 2026

    @KyrylR
    Collaborator
  5. topologoanatom commented on Jan 7, 2026

    @topologoanatom
    Author

    Can you find a smaller reproduction? This calls through simplicityhl_core and simplicityhl and it's hard to tell how anything from rust-simplicity is being invoked.

    It seems the bug depends on that complex structure. In the original code, commenting out the asserts that depend on unused witness values solves the problem. However, this case does not reproduce the bug on its own, nor does the case containing only the bugged branch.

    I’m not sure if this will be helpful, but I have visualized the SimplicityHL compiled output here.

  6. KyrylR commented on Mar 13, 2026

    @KyrylR
    Collaborator

    Fixed in: #348

  7. apoelstra commented on Mar 13, 2026

    @apoelstra
    Collaborator

    I hope so. Regardless, I think we need to close this as "can't reproduce" since the only example provided uses other crates which are larger than this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions