Skip to content

Add shared Bitcoin transaction vectors - #2017

Open
benma-agent wants to merge 2 commits into
BitBoxSwiss:masterfrom
benma-agent:benma-agent/shared-btc-test-vectors
Open

Add shared Bitcoin transaction vectors#2017
benma-agent wants to merge 2 commits into
BitBoxSwiss:masterfrom
benma-agent:benma-agent/shared-btc-test-vectors

Conversation

@benma-agent

@benma-agent benma-agent commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Add a readable source of Bitcoin transaction signing vectors, authored
as PSBTs with the metadata needed by signing APIs. Derive firmware
requests in memory, exercise them in signtx.rs, and remove overlapping
bespoke tests.

For successful vectors, populate the PSBT with the firmware responses
and check that the completed transaction and its signatures are valid.

The generated fixtures are meant to be consumed by client libraries so
firmware and clients can cover the same transactions and versioned
expectations without repo-specific vector sources. They will also be
useful when adding the Bitcoin API to the new bitbox-api-ts library.

Keep the generated JSON synchronized with its Rust source through a
drift test.

benma-agent added a commit to benma-agent/bitbox-api-rs that referenced this pull request Jul 21, 2026
Consume the transaction vectors introduced by
BitBoxSwiss/bitbox02-firmware#2017 in the PSBT
and raw simulator signing tests. Share stdout parsing and check the
versioned screens, errors, signatures, and final transactions.

Teach PSBT signing to use output_script_configs for device-owned outputs
from another account on firmware 9.22 and later, while preserving the
older external-output behavior.
benma-agent added a commit to benma-agent/bitbox-api-rs that referenced this pull request Jul 21, 2026
Consume the transaction vectors introduced by
BitBoxSwiss/bitbox02-firmware#2017 in the PSBT
simulator signing tests. Share stdout parsing and check the versioned
screens, errors, signatures, and final transactions.

Teach PSBT signing to use output_script_configs for device-owned outputs
from another account on firmware 9.22 and later, while preserving the
older external-output behavior.
benma-agent added a commit to benma-agent/bitbox02-api-go that referenced this pull request Jul 21, 2026
Consume the transaction vectors introduced by
BitBoxSwiss/bitbox02-firmware#2017 in the raw
and PSBT simulator signing tests. Centralize simulator stdout parsing
and check versioned screens, errors, signatures, and final transactions.

Close gaps exposed by the vectors: recognize Taproot policies when
loading previous transactions, preserve existing Taproot script-path
signatures, and forward silent-payment and payment-request metadata.
Add a readable source of Bitcoin transaction signing vectors, authored
as PSBTs with the metadata needed by signing APIs. Derive firmware
requests in memory, exercise them in signtx.rs, and remove overlapping
bespoke tests.

The generated fixtures are meant to be consumed by client libraries so
firmware and clients can cover the same transactions and versioned
expectations without repo-specific vector sources. They will also be
useful when adding the Bitcoin API to the new bitbox-api-ts library.

Keep the generated JSON synchronized with its Rust source through a
drift test.
benma-agent added a commit to benma-agent/bitbox-api-rs that referenced this pull request Jul 21, 2026
Consume the PSBT transaction vectors introduced by
BitBoxSwiss/bitbox02-firmware#2017 in
simulator signing tests. The public PSBT API exercises conversion and
the low-level signing protocol without a second raw fixture.

Share stdout parsing and check versioned screens, errors, signature
insertion, and final transactions.

Teach PSBT signing to use output_script_configs for device-owned outputs
from another account on firmware 9.22 and later, while preserving the
older external-output behavior.
benma-agent added a commit to benma-agent/bitbox02-api-go that referenced this pull request Jul 21, 2026
Consume the PSBT transaction vectors introduced by
BitBoxSwiss/bitbox02-firmware#2017 in
simulator signing tests. The PSBT conversion exercises the low-level
signing protocol without duplicating each vector as a raw request.

Centralize simulator stdout parsing and check versioned screens, errors,
signature insertion, generated outputs, and final transactions.

Close gaps exposed by the vectors: recognize Taproot policies when
loading previous transactions, preserve existing Taproot script-path
signatures, and forward silent-payment and payment-request metadata.

Remove obsolete transaction test helpers superseded by the vectors and
keep the simulator harness lint-clean.
@benma-agent
benma-agent force-pushed the benma-agent/shared-btc-test-vectors branch from 7003870 to 51d7b7b Compare July 21, 2026 20:54
@cedwies

cedwies commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Concept ACK, looks good. Here are some points I'd like to raise for continuing:

  1. Manual copying is reasonable for proving the concept. Do you want an automated update/hash check for production?
  2. For some test vectors you check the shape (correct signature kind, valid looking encoding, ...) and not whether the signature is cryptographically correct. Will the finished vector-based firmware tests independently verify all returned signatures, and will client tests keep equivalent validation for every case they support? Or how do we prevent all clients from agreeing with a wrong answer?
  3. I think skipping cases should be made explicit and visible in order to avoid silent skipping while CI remains green. Like: These exact eight vectors are intentionally unsupported. If that list changes, fail (and require a human decision?).

@benma

benma commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Concept ACK, looks good. Here are some points I'd like to raise for continuing:

Thanks!

1. Manual copying is reasonable for proving the concept. Do you want an automated update/hash check for production?

I don't think it's needed, at least not for the time being. Similar to protobuf messages, they are also copied to the client libs on demand. Maybe a small utility tool or Makefile entry to make it easier, but it's only copying one file 🤷

2. For some test vectors you check the shape (correct signature kind, valid looking encoding, ...) and not whether the signature is cryptographically correct. Will the finished vector-based firmware tests independently verify all returned signatures, and will client tests keep equivalent validation for every case they support? Or how do we prevent all clients from agreeing with a wrong answer?

The signatures are created inside the table driven unit tests, and their validity (full tx verification including sigs) is checked in the client libs. I thought this was also done in the vector tests in this repo, but I was wrong, so it slipped through - will add it here too.

3. I think skipping cases should be made explicit and visible in order to avoid silent skipping while CI remains green. Like: `These exact eight vectors are intentionally unsupported. If that list changes, fail (and require a human decision?).`

Skipping happens when the vector is not supported, and it is already explicit. Afaik in the firmware, all vectors are used. In the Rust lib, the vectors with silent_payments / payment_requests are skipped as not supported yet:

fn skip_reason(vector: &TestVector) -> Option<&'static str> {
    if !vector.psbt.options.outputs.is_empty() || !vector.psbt.options.payment_requests.is_empty() {
        return Some("btc_sign_psbt does not expose per-output options or payment requests");
    }
    None
}

The Go lib also supports all.

Did I miss something?

@benma

benma commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

The signatures are created inside the table driven unit tests, and their validity (full tx verification including sigs) is checked in the client libs. I thought this was also done in the vector tests in this repo, but I was wrong, so it slipped through - will add it here too.

@cedwies added the validity/sig-check now in a 2nd commit

@benma
benma marked this pull request as ready for review July 29, 2026 08:18
@benma
benma requested a review from cedwies July 29, 2026 08:18
@cedwies

cedwies commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Nice, regarding 1:

ACK, makes sense.

regarding 3:

The rule is explicit, but my concern was slightly different: The exact amount of skipped coverage is not fixed or enforced. If today 8 vectors match the skip condition, and another vector is added and also skipped, this can be overlooked. But this would be a small follow-up at most, and not relevant to the concept ACK.

@benma

benma commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

regarding 3:

The rule is explicit, but my concern was slightly different: The exact amount of skipped coverage is not fixed or enforced. If today 8 vectors match the skip condition, and another vector is added and also skipped, this can be overlooked. But this would be a small follow-up at most, and not relevant to the concept ACK.

Makes sense to help reviewers see which test inclusions/exclusions happened, but I agree it's not urgent.

I lifted this PR out of draft, ready for actual review (along with the PRs in the other repos)

@cedwies cedwies left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK, please see my comment

}
assert_vector_pubkeys(&mut mock_hal, vector, &sign_request).await;
}
btc_test_vectors::Outcome::InvalidInput => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonblocking: For InvalidInput vectors that are intended to fail during pre-sign validation, would it make sense to also assert that observations.signatures is empty? Before, this was not checked either, so this would not be a regression. It would protect against a regression where the firmware returns a signature for Invalid Input.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants