Skip to content

Conversation

@sanket1729
Copy link
Member

@sanket1729 sanket1729 commented Oct 21, 2021

Adds support for MultiA script fragment. Builds on top of #255 .

Do not merge this until we have a rust-bitcoin release

@sanket1729 sanket1729 force-pushed the multi_a branch 3 times, most recently from b61d72a to b7961c4 Compare October 21, 2021 22:56
@sanket1729 sanket1729 changed the title Miniscript tapscript support Pr 2 of 3 Miniscript tapscript support (Pr 2 of 3) Oct 21, 2021
@sanket1729 sanket1729 marked this pull request as ready for review October 21, 2021 23:05
@sanket1729 sanket1729 force-pushed the multi_a branch 2 times, most recently from a1b1d09 to cc6786d Compare October 26, 2021 16:08
.expect("Size checked in Miniscript"))
}
ShInner::Ms(ref ms) => {
Ok(bitcoin::Address::p2sh(&ms.encode(), network)
Copy link
Contributor

Choose a reason for hiding this comment

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

why not propagate the error?

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed, it is much safer to do so. This does not rely on size check being the only error.

@sanket1729 sanket1729 changed the title Miniscript tapscript support (Pr 2 of 3) [DO NOT MERGE] Miniscript tapscript support (Pr 2 of 3) Oct 27, 2021
input_idx: usize,
amount: u64,
) -> impl Fn(&bitcoin::PublicKey, BitcoinSig) -> bool + 'a {
) -> Result<impl Fn(&bitcoin::PublicKey, BitcoinSig) -> bool + 'a, Error> {
Copy link
Member

@apoelstra apoelstra Nov 12, 2021

Choose a reason for hiding this comment

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

In e458d98:

I think, rather than returning an error here, we should return a closure that always returns false. But I'm not sure.

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe you want a closure that always returns a Result<bool, Error>?

Copy link
Member Author

Choose a reason for hiding this comment

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

This should return an error if the input_idx is out of bounds.

On related note, I think we need a major redesign of this for taproot support anyways. This is currently hacked together that supports segwitv0 and legacy sighash. For taproot, we need entire sets of prevouts, it may be worth considering redesigning this entire API (yet) again :P

// This a privacy issue, we are only selecting the first available
// sigs. Incase pk at pos 1 is not selected, we know we did not have access to it
// bitcoin core also implements the same logic for MULTISIG, so I am not bothering
// permuting the sigs for now
Copy link
Member

Choose a reason for hiding this comment

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

In c05eb7c:

Ok to leave this comment here, but TBH I don't think there's any way we could eliminate this privacy leak. If the first signature is missing then the resulting witnesses will have a different distribution than if it's not ... which will become apparent over time.

Although, I guess, in practice users are unlikely to reuse keys in visible ways, so an adversary will have only a one-shot view of the signature distribution.

Copy link
Contributor

@dr-orlovsky dr-orlovsky left a comment

Choose a reason for hiding this comment

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

utACK mod some code style comments and proposal to re-use types which will be introduced in rust-bitcoin (once they got merged).

Also think that Tap context should be renamed to TapScript, since taproot may have more scripts in the future and Tap context requirements cover only leaf hash version 0xC0, but not other future versions with their own contexts

Comment on lines +577 to +583
if frag_name == "multi" {
pks.map(|pks| Terminal::Multi(k, pks))
} else {
// must be multi_a
pks.map(|pks| Terminal::MultiA(k, pks))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I do believe this should be match; otherwise with future TapLeaf version-defined post-TapScripts we will not have a compiler error here

Copy link
Member Author

Choose a reason for hiding this comment

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

There is a match check that frag_name is either multi or multi_a. I don't see an issue with doing an if-else here.

("multi", n) | ("multi_a", n) => {
  				// code..
                if frag_name == "multi" {
                    pks.map(|pks| Terminal::Multi(k, pks))
                } else {
                    // must be multi_a
                    pks.map(|pks| Terminal::MultiA(k, pks))
                }
            }

@sanket1729
Copy link
Member Author

Pushed another branch. Some portions of this PR were merged in rust-bitcoin, so the review here should be (slightly) easy. Since this depends on a specific from rust-bitcoin, it is not possible to run integration tests on these because the dependencies operate on rust-bitcoin release.

I think I should have considered this before merging the integration tests PR, but now we have to wait for a rust-bitcoincore-rpc release too.

@sanket1729 sanket1729 changed the title [DO NOT MERGE] Miniscript tapscript support (Pr 2 of 3) Miniscript tapscript support (Pr 2 of 3) Jan 11, 2022
@sanket1729 sanket1729 force-pushed the multi_a branch 2 times, most recently from ed385fc to 7070067 Compare January 11, 2022 15:35
@sanket1729
Copy link
Member Author

The last commit message has a description for why it was needed

Iter keys in `MultiA`

Fix witness generation for `MultiA`
NoChecks context needs to know how to serialize the given public key or
where to lookup for it's signature (schnorr or ecdsa). The simplest way
to convey this information is to separate out NoChecks for ecdsa and
schnorr. When using NoChecksEcdsa the associated type
bitcoin::PublicKey or when using NoChecksSchnorr, the associated type
XOnlyPublicKey should take care of it.
@sanket1729
Copy link
Member Author

Rebased on ready for review.

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK 42e4c50

I'm a little unsure about the last commit - splitting NoChecks. In this PR, NoChecksSchnorr is not actually used and the interpreter continues to be ECDSA-only. It's not obvious how to taproot-enable the interpreter, so I trust you have a plan in mind that will make use of the new split NoChecks.

@sanket1729
Copy link
Member Author

In this PR, NoChecksSchnorr is not actually used and the interpreter continues to be ECDSA-only. It's not obvious how to taproot-enable the interpreter, so I trust you have a plan in mind that will make use of the new split NoChecks.

I do have a plan for it. Our test-cases actually fail if we don't have this. We do a fancy interpreter check after we finalize a psbt to see that everything is good before we spend it. In that we need to serialize a script, We need some way to figure out Miniscript<Pk, NoChecks> should serialize key as 33 byte or 32 byte one or which signature algorithm to use for verification. All other contexts have this information implicitly in them because of associated consensus key type.

This was also done partly to address #275 (comment) in this PR.

@sanket1729 sanket1729 merged commit b8d04ac into rust-bitcoin:master Jan 13, 2022
@apoelstra
Copy link
Member

Ah, I forgot about the PSBT sanity check. Makes sense!

heap-coder added a commit to heap-coder/rust-miniscript that referenced this pull request Sep 27, 2025
…(Pr 2 of 3)

42e4c50689ee96fc0a806f02c88834f24d78fd59 Cleanup context code with SigType enum (sanket1729)
e70e6a3cfe0fd8a4b6aa4968124ec48003410e24 Fix fuzzer crash while allocating keys for multi_a (sanket1729)
f6b2536247fc45ae09df1be4f98937a3c556b338 Add satisfaction tests (sanket1729)
1a7e779408325f5c25e11ba5af1549a5b098f959 Change satisfier to support xonly sigs (sanket1729)
2c32c0396c8fbffb6021228f6b68f9a041902efb Use bitcoin::SchnorrSig type from rust-bitcoin (sanket1729)
e26d4e6bb5ac118b00669e0f9fc1b5898a959f3f Use bitcoin::EcdsaSig from rust-bitcoin (sanket1729)
89e7cb30ae555da3184f7cade065a21696145ae2 add multi_a (sanket1729)

Pull request description:

  Adds support for MultiA script fragment. Builds on top of #255 .

  Do not merge this until we have a rust-bitcoin release

ACKs for top commit:
  apoelstra:
    ACK 42e4c50689ee96fc0a806f02c88834f24d78fd59

Tree-SHA512: 10701266cf6fe436fe07359e67d16bc925ebbcd767d4e5a8d325db61b979bd76b1e0291dd9eae5b7d58f6a385f8f2e16c2657957a597ce18736382b776e20502
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.

4 participants