Skip to content

Commit

Permalink
Amend
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph committed Aug 25, 2024
1 parent c70bb89 commit 7652a9e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ generic message signing and verification.

## Types of Signatures

At the moment this crate supports `P2TR`, `P2WPKH` and `P2SH-P2WPKH` addresses.
Feedback through issues or PRs on the interface design and security is welcome
and encouraged.
At the moment this crate supports `P2TR`, `P2WPKH` and `P2SH-P2WPKH` single-sig
addresses. Feedback through issues or PRs on the interface design and security
is welcome and encouraged.

- [x] simple
- [x] full
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub enum Error {
},
#[snafu(display("Failed to parse private key"))]
PrivateKeyParse { source: bitcoin::key::Error },
#[snafu(display("Unsuported address `{address}`, only P2TR or P2WPKH allowed"))]
#[snafu(display("Unsuported address `{address}`, only P2TR, P2WPKH and P2SH-P2WPKH allowed"))]
UnsupportedAddress { address: String },
#[snafu(display("Decode error for signature `{signature}`"))]
SignatureDecode {
Expand Down
18 changes: 16 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ mod tests {
const WIF_PRIVATE_KEY: &str = "L3VFeEujGtevx9w18HD1fhRbCH67Az2dpCymeRE1SoPK6XQtaN2k";
const SEGWIT_ADDRESS: &str = "bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l";
const TAPROOT_ADDRESS: &str = "bc1ppv609nr0vr25u07u95waq5lucwfm6tde4nydujnu8npg4q75mr5sxq8lt3";
const INVALID_ADDRESS: &str = "14vV3aCHBeStb5bkenkNHbe2YAFinYdXgc";

const _UNUSED_PRIVATE_KEY: &str = "KwTbAxmBXjoZM3bzbXixEr9nxLhyYSM4vp2swet58i19bw9sqk5z";
const NESTED_SEGWIT_ADDRESS: &str = "3HSVzEhCFuH9Z3wvoWTexy7BMVVp3PjS6f";

#[test]
fn message_hashes_are_correct() {
Expand Down Expand Up @@ -161,10 +165,10 @@ mod tests {
#[test]
fn invalid_address() {
assert_eq!(verify::verify_simple_encoded(
"3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV",
INVALID_ADDRESS,
"",
"AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI=").unwrap_err().to_string(),
"Unsuported address `3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV`, only P2TR or P2WPKH allowed"
"Unsuported address `14vV3aCHBeStb5bkenkNHbe2YAFinYdXgc`, only P2TR, P2WPKH and P2SH-P2WPKH allowed"
)
}

Expand Down Expand Up @@ -274,4 +278,14 @@ mod tests {
)
.is_ok());
}

#[test]
fn simple_verify_and_falsify_p2sh_p2wpkh() {
assert!(verify::verify_simple_encoded(
NESTED_SEGWIT_ADDRESS,
"Hello World",
"AkgwRQIhAMd2wZSY3x0V9Kr/NClochoTXcgDaGl3OObOR17yx3QQAiBVWxqNSS+CKen7bmJTG6YfJjsggQ4Fa2RHKgBKrdQQ+gEhAxa5UDdQCHSQHfKQv14ybcYm1C9y6b12xAuukWzSnS+w"
).is_ok()
);
}
}
31 changes: 24 additions & 7 deletions src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,28 @@ pub fn verify_simple(address: &Address, message: &[u8], signature: Witness) -> R

/// Verifies the BIP-322 full from proper Rust types.
pub fn verify_full(address: &Address, message: &[u8], to_sign: Transaction) -> Result<()> {
match address.payload() {
Payload::WitnessProgram(wp) if wp.version().to_num() == 0 && wp.program().len() == 20 => {
match dbg!(address.payload()) {
Payload::WitnessProgram(witness)
if witness.version().to_num() == 1 && witness.program().len() == 32 =>
{
let pub_key = XOnlyPublicKey::from_slice(witness.program().as_bytes())
.map_err(|_| Error::InvalidPublicKey)?;

verify_full_p2tr(address, message, to_sign, pub_key)
}
Payload::WitnessProgram(witness)
if witness.version().to_num() == 0 && witness.program().len() == 20 =>
{
let pub_key =
PublicKey::from_slice(&to_sign.input[0].witness[1]).map_err(|_| Error::InvalidPublicKey)?;
verify_full_p2wpkh(address, message, to_sign, pub_key)

verify_full_p2wpkh(address, message, to_sign, pub_key, false)
}
Payload::WitnessProgram(wp) if wp.version().to_num() == 1 && wp.program().len() == 32 => {
Payload::ScriptHash(_) => {
let pub_key =
XOnlyPublicKey::from_slice(wp.program().as_bytes()).map_err(|_| Error::InvalidPublicKey)?;
verify_full_p2tr(address, message, to_sign, pub_key)
PublicKey::from_slice(&to_sign.input[0].witness[1]).map_err(|_| Error::InvalidPublicKey)?;

verify_full_p2wpkh(address, message, to_sign, pub_key, true)
}
_ => Err(Error::UnsupportedAddress {
address: address.to_string(),
Expand All @@ -74,6 +86,7 @@ fn verify_full_p2wpkh(
message: &[u8],
to_sign: Transaction,
pub_key: PublicKey,
is_p2sh: bool,
) -> Result<()> {
let to_spend = create_to_spend(address, message)?;
let to_sign = create_to_sign(&to_spend, Some(to_sign.input[0].witness.clone()))?;
Expand Down Expand Up @@ -131,7 +144,11 @@ fn verify_full_p2wpkh(
let sighash = sighash_cache
.p2wpkh_signature_hash(
0,
&to_spend.output[0].script_pubkey,
&if is_p2sh {
ScriptBuf::new_p2wpkh(&pub_key.wpubkey_hash().unwrap())
} else {
to_spend.output[0].script_pubkey.clone()
},
to_spend.output[0].value,
sighash_type,
)
Expand Down

0 comments on commit 7652a9e

Please sign in to comment.