Skip to content

feat: Add type secpCtx for Wallet#1049

Open
ItoroD wants to merge 1 commit into
bitcoindevkit:masterfrom
ItoroD:add-secp
Open

feat: Add type secpCtx for Wallet#1049
ItoroD wants to merge 1 commit into
bitcoindevkit:masterfrom
ItoroD:add-secp

Conversation

@ItoroD

@ItoroD ItoroD commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Description

Addresses #1048

Notes to the reviewers

This exposes Secp256k1 for the purposes of using this in our psbt sign. Especially if we want the API to be as close to bdk-wallet as possible.

Documentation

Changelog

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing
  • I've added exactly one changelog:* label
  • I've linked the relevant upstream docs or specs above

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

@thunderbiscuit thunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Secp context is only really useful if you need to keep one around and not have to re-create it every time you need it, but in this case we can't actually pass ownership of it to the bindings side and instead do a full copy of it, defeating the purpose.

My take on this is that we should create a new secp context inside the Psbt::sign wrapper instead, and not require it as an argument. Note that this is also what we do with all our other APIs that require a secp context; we just create one on the fly.

Asking Claude to dig into this a bit here is what I get:


The secp parameter in Psbt::sign is a Rust-ergonomics affordance (letting callers amortize context creation across many calls in hot loops), not a semantic input: any Signing-capable context produces identical signatures, and there is nothing about the wallet's context that Psbt::sign needs — it doesn't even have to come from a wallet.

The rationale was that it was easier to keep one context around because they were costly to create. This is largely historical now.

Why it used to matter: in older versions of libsecp256k1, creating a context computed large precomputed multiplication tables (on the order of a megabyte of table generation work) used to accelerate the elliptic-curve operations. Doing that per signature would have dwarfed the cost of the signature itself, so the library was designed around "create one context at startup, pass it everywhere" — and every API downstream (rust-secp256k1, rust-bitcoin, BDK) inherited that shape.

What changed: around libsecp256k1 v0.5.0 (rust-secp256k1 ~0.22, 2022), the precomputed tables were moved into the library binary as static data. A new context is now a small heap allocation plus initialization — cheap enough that creating one per operation is fine for anything that isn't a tight loop signing thousands of times.

@ItoroD

ItoroD commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

My take on this is that we should create a new secp context inside the Psbt::sign wrapper instead, and not require it as an argument. Note that this is also what we do with all our other APIs that require a secp context; we just create one on the fly.

Yes this is true and something I also considered. Secp does not need to be passed as a param and can be handled and used under the hood. The only reason I did this is trying to make the sign method as close to the rust API as possible. Because I assumed that there can be a custom secp256k1 instances user might want to pass. This is possible in rust. I can also see there are different context that Secp256k1 can have. i.e just signing or just verifying or all.

But I think in our context we sticking to a default which is All. Which is what wallets secpCtx always returns anyway. This is why not making it a param can work.

Note that this is also what we do with all our other APIs that require a secp context; we just create one on the fly.

True. Only thing is that the way psbt sign has been presented seemed like, now a user has full control of how they want to sign even down to the sepCtx.

Signing-capable context produces identical signatures, and there is nothing about the wallet's context that Psbt::sign needs — it doesn't even have to come from a wallet.

I agree as from my tests it spits out the same sepcCtx value every time. Makes me wonder why we have this method in Wallet. I should ask

Since we will not pass this as param for psbt.sign, I assume we do not want to expose this on wallet too ?

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

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants