-
Notifications
You must be signed in to change notification settings - Fork 616
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
Taproot PublicKey refactoring #561
Conversation
Found a better way of avoiding key ambiguity during deserialization: db50adb |
Sorry, did not review the PR yet. But I think we should separate the keys from the signatures. Schnorr and ESDSA are signatures, compressed keys can have schnorr signatures and Xonlykeys can have ECDSA signatures. I think we should ideally have, I don't think it is useful to have PublicKey enum containing both types. Users of the application are expected to know what sort of keys they are dealing with. In Witness 1 version programs they will be xonly keys. So, I think it is best if we keep Rust-bitcoin does not have enough context to figure what keys the user is dealing with, so it's best to leave it to the user when they additional metadata to deserialize the keytype. |
@sanket1729 I actually tend to disagree. and if we really need to support this for the sake of compatibility I'd rather it be one way (ie ECDSA keys can be used for schnorr but not the opposite) |
@elichai, I understand your point and I don't think we contradict :) . My initial understanding was that we should name schnorr keys as But I see, what I say may make more sense from libsecp point of view, but from rust-bitcoin(which only really cares about signatures from keys and not anything else), we can name them to |
We have two contradictory goals: (a) make I have a plan to do an alternative PR with separate types for each key kind - just for demo purposes. I had the same idea like @sanket1729, but with four types instead of three:
This will allow slow migration for depended software. Also at Miniscript level the key types may be more strictly enforced and P.S. As for miniscript it's really odd to see the ability to use uncompressed keys - for which reason? Miniscript can't even be used with composing Lightning-specific scripts (which are not that legacy), so why we need to keep compatibility in one part when not being compatible with more recent stuff? You can't do roundtrips on Bitcoin scripts from transactions anyway, and removing uncompressed key support (by converting all keys to compressed on parsing) will not make that anyhow worse. |
I guess this is something that will impact rust-bitcoin ecosystem as a whole so it's better to get as many opinions as possible, but I have a strong +1 for clean separation of PublicKey types. If we ever do this, it might be worth first testing out by updating the dependent libraries onto the candidate see the impact and iterate again.
Unfortunately, lightning scripts are not Miniscripts type system because they rely on checking on the size of some item, and then casting it either as a publickey or a preimage. (I may be wrong on the details here, but there is some casting involved). But that being said, there is nothing us from stopping from creating a legacy lightning descriptor for all the various lightning scripts and we would gladly merge that into rust-miniscript as an additional descriptor. I am not involved in the lighting space, but are the output descriptors for accepted htlc(receiver/sender side), funding tx, claim tx etc? |
@sanket1729 the problem with miniscript is not the lightning scripts only, and the problem can't be solved with a dedicated descriptor. The problem is that there is no deterministic way for general |
FTR I also prefer being Rust-idiomatic over being similar to Core. |
Another consideration: how do we want to work with extended keys going forward? The current impl in this PR would limit them to ECDSA keys. But from the comments I gather that if we do this we want to do a complete key-overhaul with the 3 relevant (and one deprecated) key types, which I personally like so far. But when we do that we need to find a way to make our BIP32 API compatible, two ideas:
Looking at BIP340 it seems to propose to essentially go with the second variant by converting ECDSA keys. The flexibility of v2 is probably also nice when working with one master seed with different sub trees for taproot accounts and other older accounts. |
Re-read BIP340, had a small discussion with Pieter Wuille and came to conclusion that
|
I think I found a relatively non-disrupting way of adding Taproot keys to rust-bitcoin. The plan is:
Next, more invasive change will be to remove Upd: after @sgeisler suggestion we do not need |
Descriptors should just keep using the same type of keys as they always do (either hex 33-byte/65-byte keys, or xpubs + derivation paths). Taproot descriptors would require compressed keys, but ignore the first byte. |
Why Here is the latest (since abandoned) effort of that: #221 Before we start discussions again here (excuse my absence on rust-bitcoin the past 2 months), I'm curious how (rust-)secp256k1 will incorporate the Schnorr/Taproot changes. |
rust-secp follows libsecp. It has new types for xonly public keys and keypairs. |
What is the state of this PR? @dr-orlovsky's latest message says that he is going to leave |
let (len, remaining_bytes) = if bytes[0] == 4 { | ||
(UNCOMPRESSED_PUBLIC_KEY_SIZE, &mut bytes[SCHNORRSIG_PUBLIC_KEY_SIZE..UNCOMPRESSED_PUBLIC_KEY_SIZE]) | ||
} else if bytes[0] == 2 || bytes[0] == 3 { | ||
(ECDSA_PUBLIC_KEY_SIZE, &mut bytes[SCHNORRSIG_PUBLIC_KEY_SIZE..ECDSA_PUBLIC_KEY_SIZE]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NACK
This code, as written, will always throw away the byte immediately following an x-only pubkey, and 50% of the time it will also incorrectly return an error.
Important to note, the |
@apoelstra this was the initial PR, following which we had a different discussion (here and in IRC), where we decided to try a different much less invasive approach from this specific comment: #561 (comment). As I posted to IRC, looking a concept ACK on it to start working on it. |
How about |
What would the type of |
I think this PR is about an outdated approach, with the new one described in #561 (comment). Probably we should close this PR or how to prevent further review of the outdated code? (though discussion here may be kept for further decision making) |
All results of the discussion are put as a separate issue #588, thus this PR is not needed anymore |
First attempt to fit in Taproot keys into current public key type system. Consists of:
PublicKey
intoEcdsaPublicKey
, otherwise leaving the type intact. This will simplify migration (ppl can just douse bitcoin::EcdsaPublicKey as PublicKey
and that's all), however will not allow enforcing of compressed keys as a part of API as was discussed in Make PublicKey API consistent #554PublicKey
type: an enum with two options for older ECDSA public keys and Schorr public keys (however considering of naming themTaproot
andSecp
, since the encoding format is a part of either Taproot-related BIP-340 and Secp paper and not Schnorr signature or ECDSA standard)This also includes a number of improvements to existing API, including making simple
PublicKey
methods inline, extractingKey
trait for public (and in future private) key functionality shared across types, and additionalkey::Error
variant which was previously incorrectly mapped tobase58
error (since it has nothing to do with Base58 and is about binary-encoded data).The largest question however is the universal deserialization for the new
PublicKey
type, since there is no unambiguous way to distinguish Taproot and Secp keys when read from stream: https://github.com/rust-bitcoin/rust-bitcoin/pull/561/files#diff-6e396f6881bb94d1206a4d0d1b3e582f16bbd098c091b07afd8a6a95b450c199R215-R241. Not sure how to solve that w/o abandoning shared API. Had created discussion on the matter here: #554