Skip to content

Commit

Permalink
Amend
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph committed Aug 22, 2024
1 parent 1bfca3e commit 0821856
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 44 deletions.
52 changes: 26 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ use {
};

mod error;
pub mod sign;
pub mod util;
pub mod verify;
mod sign;
mod util;
mod verify;

use util::*;
pub use {sign::*, util::*, verify::*};

type Result<T = (), E = Error> = std::result::Result<T, E>;

Expand Down Expand Up @@ -113,15 +113,15 @@ mod tests {
#[test]
fn simple_verify_and_falsify_taproot() {
assert!(
verify::simple_encoded(
verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World",
"AUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
).is_ok()
);

assert_eq!(
verify::simple_encoded(
verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World -- This should fail",
"AUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
Expand All @@ -133,34 +133,34 @@ mod tests {
#[test]
fn simple_sign_taproot() {
assert_eq!(
sign::simple_encoded(TAPROOT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap(),
sign::sign_simple_encoded(TAPROOT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap(),
"AUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
);
}

#[test]
fn roundtrip_taproot_simple() {
assert!(verify::simple_encoded(
assert!(verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World",
&sign::simple_encoded(TAPROOT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
&sign::sign_simple_encoded(TAPROOT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
)
.is_ok());
}

#[test]
fn roundtrip_taproot_full() {
assert!(verify::full_encoded(
assert!(verify::verify_full_encoded(
TAPROOT_ADDRESS,
"Hello World",
&sign::full_encoded(TAPROOT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
&sign::sign_full_encoded(TAPROOT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
)
.is_ok());
}

#[test]
fn invalid_address() {
assert_eq!(verify::simple_encoded(
assert_eq!(verify::verify_simple_encoded(
"3B5fQsEXEaV8v6U3ejYc8XaKXAkyQj2MjV",
"",
"AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI=").unwrap_err().to_string(),
Expand All @@ -171,7 +171,7 @@ mod tests {
#[test]
fn signature_decode_error() {
assert_eq!(
verify::simple_encoded(
verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World",
"invalid signature not in base64 encoding"
Expand All @@ -182,7 +182,7 @@ mod tests {
);

assert_eq!(
verify::simple_encoded(
verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World",
"AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViH"
Expand All @@ -194,47 +194,47 @@ mod tests {
#[test]
fn simple_verify_and_falsify_p2wpkh() {
assert!(
verify::simple_encoded(
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"Hello World",
"AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI="
).is_ok()
);

assert!(
verify::simple_encoded(
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"Hello World - this should fail",
"AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI="
).is_err()
);

assert!(
verify::simple_encoded(
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"Hello World",
"AkgwRQIhAOzyynlqt93lOKJr+wmmxIens//zPzl9tqIOua93wO6MAiBi5n5EyAcPScOjf1lAqIUIQtr3zKNeavYabHyR8eGhowEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
).is_ok()
);

assert!(
verify::simple_encoded(
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"",
"AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI="
).is_ok()
);

assert!(
verify::simple_encoded(
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"fail",
"AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI="
).is_err()
);

assert!(
verify::simple_encoded(
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"",
"AkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
Expand All @@ -245,32 +245,32 @@ mod tests {
#[test]
fn simple_sign_p2wpkh() {
assert_eq!(
sign::simple_encoded(SEGWIT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap(),
sign::sign_simple_encoded(SEGWIT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap(),
"AkgwRQIhAOzyynlqt93lOKJr+wmmxIens//zPzl9tqIOua93wO6MAiBi5n5EyAcPScOjf1lAqIUIQtr3zKNeavYabHyR8eGhowEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
);

assert_eq!(
sign::simple_encoded(SEGWIT_ADDRESS, "", WIF_PRIVATE_KEY).unwrap(),
sign::sign_simple_encoded(SEGWIT_ADDRESS, "", WIF_PRIVATE_KEY).unwrap(),
"AkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
);
}

#[test]
fn roundtrip_p2wpkh_simple() {
assert!(verify::simple_encoded(
assert!(verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"Hello World",
&sign::simple_encoded(SEGWIT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
&sign::sign_simple_encoded(SEGWIT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
)
.is_ok());
}

#[test]
fn roundtrip_p2wpkh_full() {
assert!(verify::full_encoded(
assert!(verify::verify_full_encoded(
SEGWIT_ADDRESS,
"Hello World",
&sign::full_encoded(SEGWIT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
&sign::sign_full_encoded(SEGWIT_ADDRESS, "Hello World", WIF_PRIVATE_KEY).unwrap()
)
.is_ok());
}
Expand Down
18 changes: 11 additions & 7 deletions src/sign.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use super::*;

/// Signs the BIP-322 simple from spec-compliant string encodings.
pub fn simple_encoded(address: &str, message: &str, wif_private_key: &str) -> Result<String> {
pub fn sign_simple_encoded(address: &str, message: &str, wif_private_key: &str) -> Result<String> {
let address = Address::from_str(address)
.context(error::AddressParse { address })?
.assume_checked();

let private_key = PrivateKey::from_wif(wif_private_key).context(error::PrivateKeyParse)?;

let witness = simple(&address, message.as_bytes(), private_key)?;
let witness = sign_simple(&address, message.as_bytes(), private_key)?;

let mut buffer = Vec::new();

Expand All @@ -20,14 +20,14 @@ pub fn simple_encoded(address: &str, message: &str, wif_private_key: &str) -> Re
}

/// Signs the BIP-322 full from spec-compliant string encodings.
pub fn full_encoded(address: &str, message: &str, wif_private_key: &str) -> Result<String> {
pub fn sign_full_encoded(address: &str, message: &str, wif_private_key: &str) -> Result<String> {
let address = Address::from_str(address)
.context(error::AddressParse { address })?
.assume_checked();

let private_key = PrivateKey::from_wif(wif_private_key).context(error::PrivateKeyParse)?;

let tx = full(&address, message.as_bytes(), private_key)?;
let tx = sign_full(&address, message.as_bytes(), private_key)?;

let mut buffer = Vec::new();

Expand All @@ -38,16 +38,20 @@ pub fn full_encoded(address: &str, message: &str, wif_private_key: &str) -> Resu
}

/// Signs in the BIP-322 simple format from proper Rust types and returns the witness.
pub fn simple(address: &Address, message: &[u8], private_key: PrivateKey) -> Result<Witness> {
pub fn sign_simple(address: &Address, message: &[u8], private_key: PrivateKey) -> Result<Witness> {
Ok(
full(address, message, private_key)?.input[0]
sign_full(address, message, private_key)?.input[0]
.witness
.clone(),
)
}

/// Signs in the BIP-322 full format from proper Rust types and returns the full transaction.
pub fn full(address: &Address, message: &[u8], private_key: PrivateKey) -> Result<Transaction> {
pub fn sign_full(
address: &Address,
message: &[u8],
private_key: PrivateKey,
) -> Result<Transaction> {
let to_spend = create_to_spend(address, message)?;
let mut to_sign = create_to_sign(&to_spend, None)?;

Expand Down
3 changes: 3 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::*;

const TAG: &str = "BIP0322-signed-message";

/// Create the tagged message hash.
pub fn message_hash(message: &[u8]) -> Vec<u8> {
let mut tag_hash = sha256::Hash::hash(TAG.as_bytes()).to_byte_array().to_vec();
tag_hash.extend(tag_hash.clone());
Expand All @@ -12,6 +13,7 @@ pub fn message_hash(message: &[u8]) -> Vec<u8> {
.to_vec()
}

/// Create the `to_spend` transaction.
pub fn create_to_spend(address: &Address, message: &[u8]) -> Result<Transaction> {
Ok(Transaction {
version: Version(0),
Expand All @@ -37,6 +39,7 @@ pub fn create_to_spend(address: &Address, message: &[u8]) -> Result<Transaction>
})
}

/// Create the `to_sign` transaction.
pub fn create_to_sign(to_spend: &Transaction, witness: Option<Witness>) -> Result<Psbt> {
let inputs = vec![TxIn {
previous_output: OutPoint {
Expand Down
22 changes: 11 additions & 11 deletions src/verify.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::*;

/// Verifies the BIP-322 simple from spec-compliant string encodings.
pub fn simple_encoded(address: &str, message: &str, signature: &str) -> Result<()> {
pub fn verify_simple_encoded(address: &str, message: &str, signature: &str) -> Result<()> {
let address = Address::from_str(address)
.context(error::AddressParse { address })?
.assume_checked();
Expand All @@ -15,11 +15,11 @@ pub fn simple_encoded(address: &str, message: &str, signature: &str) -> Result<(
let witness =
Witness::consensus_decode_from_finite_reader(&mut cursor).context(error::WitnessMalformed)?;

simple(&address, message.as_bytes(), witness)
verify_simple(&address, message.as_bytes(), witness)
}

/// Verifies the BIP-322 full from spec-compliant string encodings.
pub fn full_encoded(address: &str, message: &str, to_sign: &str) -> Result<()> {
pub fn verify_full_encoded(address: &str, message: &str, to_sign: &str) -> Result<()> {
let address = Address::from_str(address)
.context(error::AddressParse { address })?
.assume_checked();
Expand All @@ -36,12 +36,12 @@ pub fn full_encoded(address: &str, message: &str, to_sign: &str) -> Result<()> {
},
)?;

full(&address, message.as_bytes(), to_sign)
verify_full(&address, message.as_bytes(), to_sign)
}

/// Verifies the BIP-322 simple from proper Rust types.
pub fn simple(address: &Address, message: &[u8], signature: Witness) -> Result<()> {
full(
pub fn verify_simple(address: &Address, message: &[u8], signature: Witness) -> Result<()> {
verify_full(
address,
message,
create_to_sign(&create_to_spend(address, message)?, Some(signature))?
Expand All @@ -51,25 +51,25 @@ pub fn simple(address: &Address, message: &[u8], signature: Witness) -> Result<(
}

/// Verifies the BIP-322 full from proper Rust types.
pub fn full(address: &Address, message: &[u8], to_sign: Transaction) -> Result<()> {
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 => {
let pub_key =
PublicKey::from_slice(&to_sign.input[0].witness[1]).map_err(|_| Error::InvalidPublicKey)?;
full_p2wpkh(address, message, to_sign, pub_key)
verify_full_p2wpkh(address, message, to_sign, pub_key)
}
Payload::WitnessProgram(wp) if wp.version().to_num() == 1 && wp.program().len() == 32 => {
let pub_key =
XOnlyPublicKey::from_slice(wp.program().as_bytes()).map_err(|_| Error::InvalidPublicKey)?;
full_p2tr(address, message, to_sign, pub_key)
verify_full_p2tr(address, message, to_sign, pub_key)
}
_ => Err(Error::UnsupportedAddress {
address: address.to_string(),
}),
}
}

fn full_p2wpkh(
fn verify_full_p2wpkh(
address: &Address,
message: &[u8],
to_sign: Transaction,
Expand Down Expand Up @@ -147,7 +147,7 @@ fn full_p2wpkh(
Ok(())
}

fn full_p2tr(
fn verify_full_p2tr(
address: &Address,
message: &[u8],
to_sign: Transaction,
Expand Down

0 comments on commit 0821856

Please sign in to comment.