Skip to content

Miniscript tapscript support (Pr 2 of 3) #275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 13, 2022

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
@@ -189,34 +189,34 @@ impl<'txin> Interpreter<'txin> {
unsigned_tx: &'a bitcoin::Transaction,
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!

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