Skip to content

Commit eeeb722

Browse files
clarkmoodydr-orlovsky
authored andcommitted
Bump bech32 to 0.8.0 and use BIP-0350 Bech32m checksum
Replace BIP-0173 test vectors with those in BIP-0350.
1 parent 5573a54 commit eeeb722

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

src/util/address.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ pub enum Error {
6060
Bech32(bech32::Error),
6161
/// The bech32 payload was empty
6262
EmptyBech32Payload,
63+
/// The wrong checksum algorithm was used. See BIP-0350.
64+
InvalidBech32Variant,
6365
/// Script version must be 0 to 16 inclusive
6466
InvalidWitnessVersion(u8),
6567
/// Unable to parse witness version from string
@@ -82,6 +84,7 @@ impl fmt::Display for Error {
8284
Error::Base58(ref e) => write!(f, "base58: {}", e),
8385
Error::Bech32(ref e) => write!(f, "bech32: {}", e),
8486
Error::EmptyBech32Payload => write!(f, "the bech32 payload was empty"),
87+
Error::InvalidBech32Variant => write!(f, "invalid bech32 checksum variant"),
8588
Error::InvalidWitnessVersion(v) => write!(f, "invalid witness script version: {}", v),
8689
Error::UnparsableWitnessVersion(ref e) => write!(f, "Incorrect format of a witness version byte: {}", e),
8790
Error::MalformedWitnessVersion => f.write_str("bitcoin script opcode does not match any known witness version, the script is malformed"),
@@ -319,6 +322,14 @@ impl WitnessVersion {
319322
pub fn into_num(self) -> u8 {
320323
self as u8
321324
}
325+
326+
/// Determine the checksum variant. See BIP-0350 for specification.
327+
pub fn bech32_variant(&self) -> bech32::Variant {
328+
match self {
329+
WitnessVersion::V0 => bech32::Variant::Bech32,
330+
_ => bech32::Variant::Bech32m,
331+
}
332+
}
322333
}
323334

324335
impl From<WitnessVersion> for ::bech32::u5 {
@@ -634,15 +645,14 @@ impl fmt::Display for Address {
634645
Network::Testnet | Network::Signet => "tb",
635646
Network::Regtest => "bcrt",
636647
};
637-
let bech_ver = if version.into_num() > 0 { bech32::Variant::Bech32m } else { bech32::Variant::Bech32 };
638648
let mut upper_writer;
639649
let writer = if fmt.alternate() {
640650
upper_writer = UpperWriter(fmt);
641651
&mut upper_writer as &mut dyn fmt::Write
642652
} else {
643653
fmt as &mut dyn fmt::Write
644654
};
645-
let mut bech32_writer = bech32::Bech32Writer::new(hrp, bech_ver, writer)?;
655+
let mut bech32_writer = bech32::Bech32Writer::new(hrp, version.bech32_variant(), writer)?;
646656
bech32::WriteBase32::write_u5(&mut bech32_writer, version.into())?;
647657
bech32::ToBase32::write_base32(&prog, &mut bech32_writer)
648658
}
@@ -705,10 +715,9 @@ impl FromStr for Address {
705715
return Err(Error::InvalidSegwitV0ProgramLength(program.len()));
706716
}
707717

708-
// Bech32 encoding check
709-
if (version.into_num() > 0 && variant != bech32::Variant::Bech32m) ||
710-
(version.into_num() == 0 && variant != bech32::Variant::Bech32) {
711-
return Err(Error::InvalidWitnessVersion(version.into_num()))
718+
// Encoding check
719+
if version.bech32_variant() != variant {
720+
return Err(Error::InvalidBech32Variant);
712721
}
713722

714723
return Ok(Address {

0 commit comments

Comments
 (0)