rust-bitcoin / rust-bitcoin/rust-miniscript

Using KeyMap and DescriptorSecretKey for signing transactions

Open
#495 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
426
Forks
200
Avg merge
7d 17h
Merged PRs (30d)
8

Description

From an outsider point of view KeyMap looks like interesting way to handle keys after importing descriptor.

Let's say for example we have such descriptor where we supply tprv which will be imported into KeyMap

"wsh(t:or_c(pk(02a7d30ac6b0cd55b6868f5a65aff1dbdaa18f4315fe04de809fffb2899340ae0f),v:multi(1,[255f0d9b]tprv8ZgxMBicQKsPerMTN7nhwCpqaAEPkaBCDeE8c9ekAY1xhPmF3HM9r3oz33V8JTwsJYp9FYLDQumLzNssLo6UNMNesVwPP1KcgA5atrSqU2w/84'/1'/1/0/0,02f17cce1778c101e3b0ac5c76997af3752b0a221b1ebffc23af679328f3f5d6fc,02350b5a9a12df96579d150f3f751de416e58a67f2ba9bc99f6964b7a48a79042b)))"

We could use KeyMap later in similar loop

        for (public, private) in &keys {
                  // ... doing something with keys
        }

The problem though is that public and private are DescriptorPublicKey and DescriptorSecretKey objects do not really contain convenient API even for extracting keys and using them in signing. I have a code example and honestly I am not entirely sure I didn't something wrong. Besides It doesn't actually work and I think the problem is that there is just wrong key in &prv.xkey.private_key.

        for (pk, prv) in &self.keys {
            match prv {
                DescriptorSecretKey::Single(prv) => {
                    let sig = self.secp.sign_ecdsa(&msg, &prv.key.inner);
                    let public = &prv.key.inner.public_key(&self.secp);
                    assert!(self.secp.verify_ecdsa(&msg, &sig, public).is_ok());
                    psbt.inputs[0].partial_sigs.insert(
                        public.to_public_key(),
                        bitcoin::EcdsaSig {
                            sig,
                            hash_ty: hash_ty,
                        },
                    );
                },
                DescriptorSecretKey::XPrv(prv) => {
                    let sig = self.secp.sign_ecdsa(&msg, &prv.xkey.private_key);
                    let public = &prv.xkey.private_key.public_key(&self.secp);
                    println!("{}", &public);
                    assert!(self.secp.verify_ecdsa(&msg, &sig, public).is_ok());
                    psbt.inputs[0].partial_sigs.insert(
                        public.to_public_key(),
                        bitcoin::EcdsaSig {
                            sig,
                            hash_ty: hash_ty,
                        },
                    );
                },
            };
        }

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the KeyMap and DescriptorSecretKey APIs referenced in the issue, then inspect the supplied Rust signing example and the XPrv handling. Determine how imported descriptor keys are intended to map to signing keys and what API behavior is missing; the issue names no files, tests, or concrete completion criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cryptography
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.