Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,16 @@ mod tests {
assert!(
verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World",
"AUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
"Hello World",
"smpAUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
).is_ok()
);

assert_eq!(
verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World -- This should fail",
"AUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
"smpAUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
).unwrap_err().to_string(),
"Invalid signature"
);
Expand All @@ -176,7 +176,7 @@ mod tests {
fn simple_sign_taproot() {
assert_eq!(
sign::sign_simple_encoded(TAPROOT_ADDRESS, "Hello World", &[WIF_PRIVATE_KEY], None).unwrap(),
"AUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
"smpAUHd69PrJQEv+oKTfZ8l+WROBHuy9HKrbFCJu7U1iK2iiEy1vMU5EfMtjc+VSHM7aU0SDbak5IUZRVno2P5mjSafAQ=="
);
}

Expand Down Expand Up @@ -216,8 +216,8 @@ mod tests {
assert_eq!(
verify::verify_simple_encoded(
TAPROOT_ADDRESS,
"Hello World",
"AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViH"
"Hello World",
"smpAkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViH"
).unwrap_err().to_string(),
"Decode error for signature `AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViH`"
)
Expand All @@ -229,47 +229,47 @@ mod tests {
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"Hello World",
"AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI="
"smpAkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI="
).is_ok()
);

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

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

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

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

assert!(
verify::verify_simple_encoded(
SEGWIT_ADDRESS,
"",
"AkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
"smpAkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
).is_ok()
);
}
Expand All @@ -294,12 +294,12 @@ mod tests {
fn simple_sign_p2wpkh() {
assert_eq!(
sign::sign_simple_encoded(SEGWIT_ADDRESS, "Hello World", &[WIF_PRIVATE_KEY], None).unwrap(),
"AkgwRQIhAOzyynlqt93lOKJr+wmmxIens//zPzl9tqIOua93wO6MAiBi5n5EyAcPScOjf1lAqIUIQtr3zKNeavYabHyR8eGhowEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
"smpAkgwRQIhAOzyynlqt93lOKJr+wmmxIens//zPzl9tqIOua93wO6MAiBi5n5EyAcPScOjf1lAqIUIQtr3zKNeavYabHyR8eGhowEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
);

assert_eq!(
sign::sign_simple_encoded(SEGWIT_ADDRESS, "", &[WIF_PRIVATE_KEY], None).unwrap(),
"AkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
"smpAkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy"
);
}

Expand Down Expand Up @@ -328,14 +328,14 @@ mod tests {
assert!(verify::verify_simple_encoded(
NESTED_SEGWIT_ADDRESS,
"Hello World",
"AkgwRQIhAMd2wZSY3x0V9Kr/NClochoTXcgDaGl3OObOR17yx3QQAiBVWxqNSS+CKen7bmJTG6YfJjsggQ4Fa2RHKgBKrdQQ+gEhAxa5UDdQCHSQHfKQv14ybcYm1C9y6b12xAuukWzSnS+w"
"smpAkgwRQIhAMd2wZSY3x0V9Kr/NClochoTXcgDaGl3OObOR17yx3QQAiBVWxqNSS+CKen7bmJTG6YfJjsggQ4Fa2RHKgBKrdQQ+gEhAxa5UDdQCHSQHfKQv14ybcYm1C9y6b12xAuukWzSnS+w"
).is_ok()
);

assert!(verify::verify_simple_encoded(
NESTED_SEGWIT_ADDRESS,
"Hello World - this should fail",
"AkgwRQIhAMd2wZSY3x0V9Kr/NClochoTXcgDaGl3OObOR17yx3QQAiBVWxqNSS+CKen7bmJTG6YfJjsggQ4Fa2RHKgBKrdQQ+gEhAxa5UDdQCHSQHfKQv14ybcYm1C9y6b12xAuukWzSnS+w"
"smpAkgwRQIhAMd2wZSY3x0V9Kr/NClochoTXcgDaGl3OObOR17yx3QQAiBVWxqNSS+CKen7bmJTG6YfJjsggQ4Fa2RHKgBKrdQQ+gEhAxa5UDdQCHSQHfKQv14ybcYm1C9y6b12xAuukWzSnS+w"
).is_err()
);
}
Expand All @@ -344,7 +344,7 @@ mod tests {
fn simple_sign_p2sh_p2wpkh() {
assert_eq!(
sign::sign_simple_encoded(NESTED_SEGWIT_ADDRESS, "Hello World", &[NESTED_SEGWIT_WIF_PRIVATE_KEY], None).unwrap(),
"AkgwRQIhAMd2wZSY3x0V9Kr/NClochoTXcgDaGl3OObOR17yx3QQAiBVWxqNSS+CKen7bmJTG6YfJjsggQ4Fa2RHKgBKrdQQ+gEhAxa5UDdQCHSQHfKQv14ybcYm1C9y6b12xAuukWzSnS+w"
"smpAkgwRQIhAMd2wZSY3x0V9Kr/NClochoTXcgDaGl3OObOR17yx3QQAiBVWxqNSS+CKen7bmJTG6YfJjsggQ4Fa2RHKgBKrdQQ+gEhAxa5UDdQCHSQHfKQv14ybcYm1C9y6b12xAuukWzSnS+w"
);
}

Expand Down
15 changes: 12 additions & 3 deletions src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ pub fn sign_simple_encoded(
.consensus_encode(&mut buffer)
.context(error::WitnessEncoding)?;

Ok(general_purpose::STANDARD.encode(buffer))
Ok(format!(
"{SIMPLE_SIGNATURE_PREFIX}{}",
general_purpose::STANDARD.encode(buffer)
))
}

/// Signs the BIP-322 full from spec-compliant string encodings.
Expand Down Expand Up @@ -109,7 +112,10 @@ pub fn sign_full_encoded(
tx.consensus_encode(&mut buffer)
.context(error::TransactionEncode)?;

Ok(general_purpose::STANDARD.encode(buffer))
Ok(format!(
"{FULL_SIGNATURE_PREFIX}{}",
general_purpose::STANDARD.encode(buffer)
))
}

/// Signs in the BIP-322 simple format and returns the witness.
Expand Down Expand Up @@ -194,7 +200,10 @@ pub fn sign_pof_encoded(
.serialize_to_writer(&mut buffer)
.context(error::TransactionEncode)?;

Ok(general_purpose::STANDARD.encode(buffer))
Ok(format!(
"{POF_SIGNATURE_PREFIX}{}",
general_purpose::STANDARD.encode(buffer)
))
}

/// Signs a BIP-322 full proof
Expand Down
5 changes: 5 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ pub const BIP322_TAG: &str = "BIP0322-signed-message";
/// (PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE).
pub const PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE: u8 = 0x09;

/// Signature variant prefixes.
pub const SIMPLE_SIGNATURE_PREFIX: &str = "smp";
pub const FULL_SIGNATURE_PREFIX: &str = "ful";
pub const POF_SIGNATURE_PREFIX: &str = "pof";

/// Create the tagged message hash.
pub fn tagged_hash(tag: &str, message: impl AsRef<[u8]>) -> [u8; 32] {
let tag_hash = Sha256::new().chain_update(tag).finalize();
Expand Down
12 changes: 12 additions & 0 deletions src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ pub fn verify_simple_encoded(address: &str, message: &str, signature: &str) -> R
.context(error::AddressParse { address })?
.assume_checked();

let signature = signature
.strip_prefix(SIMPLE_SIGNATURE_PREFIX)
.unwrap_or(signature);

let mut cursor = bitcoin::io::Cursor::new(
general_purpose::STANDARD
.decode(signature)
Expand All @@ -74,6 +78,10 @@ pub fn verify_full_encoded(address: &str, message: &str, to_sign: &str) -> Resul
.context(error::AddressParse { address })?
.assume_checked();

let to_sign = to_sign
.strip_prefix(FULL_SIGNATURE_PREFIX)
.unwrap_or(to_sign);

let mut cursor = bitcoin::io::Cursor::new(general_purpose::STANDARD.decode(to_sign).context(
error::TransactionBase64Decode {
transaction: to_sign,
Expand Down Expand Up @@ -103,6 +111,10 @@ pub fn verify_pof_encoded(
.context(error::AddressParse { address })?
.assume_checked();

let to_sign = to_sign
.strip_prefix(POF_SIGNATURE_PREFIX)
.unwrap_or(to_sign);

let bytes =
general_purpose::STANDARD
.decode(to_sign)
Expand Down
Loading