Skip to content

Commit

Permalink
Add segwit version field element consts
Browse files Browse the repository at this point in the history
Add two field element consts for segwit version 0 an version 1. This
makes reading the code much easier since one does not have to remember p
ad q.
  • Loading branch information
tcharding committed Aug 16, 2023
1 parent 6c1379b commit 024ed01
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
7 changes: 4 additions & 3 deletions src/primitives/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
//! ```
//! use bech32::{Bech32, Bech32m, Fe32, Hrp};
//! use bech32::primitives::decode::{CheckedHrpstring, SegwitHrpstring, UncheckedHrpstring};
//! use bech32::segwit::VERSION_1;
//!
//! // An arbitrary HRP and a string of valid bech32 characters.
//! let s = "abcd143hj65vxw49rts6kcw35u6r6tgzguyr03vvveeewjqpn05efzq444444";
Expand Down Expand Up @@ -66,7 +67,7 @@
//! let segwit = SegwitHrpstring::new(address).expect("valid segwit address");
//! let _encoded_data = segwit.byte_iter();
//! assert_eq!(segwit.hrp(), Hrp::parse("bc").unwrap());
//! assert_eq!(segwit.witness_version(), Fe32::P);
//! assert_eq!(segwit.witness_version(), VERSION_1);
//! ```
//!
//! [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
Expand All @@ -78,7 +79,7 @@ use crate::primitives::checksum::{self, Checksum};
use crate::primitives::gf32::Fe32;
use crate::primitives::hrp::{self, Hrp};
use crate::primitives::iter::{Fe32IterExt, FesToBytes};
use crate::primitives::segwit::{self, WitnessLengthError};
use crate::primitives::segwit::{self, WitnessLengthError, VERSION_0};
use crate::{write_err, Bech32, Bech32m};

/// Separator between the hrp and payload (as defined by BIP-173).
Expand Down Expand Up @@ -363,7 +364,7 @@ impl<'s> SegwitHrpstring<'s> {
}

let checked: CheckedHrpstring<'s> = match witness_version {
Fe32::Q => unchecked.validate_and_remove_checksum::<Bech32>()?,
VERSION_0 => unchecked.validate_and_remove_checksum::<Bech32>()?,
_ => unchecked.validate_and_remove_checksum::<Bech32m>()?,
};

Expand Down
7 changes: 6 additions & 1 deletion src/primitives/segwit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ use core::fmt;

use crate::primitives::gf32::Fe32;

/// The field element representing segwit version 0.
pub const VERSION_0: Fe32 = Fe32::Q;
/// The field element representing segwit version 1 (taproot).
pub const VERSION_1: Fe32 = Fe32::P;

/// Returns true if given field element represents a valid segwit version.
pub fn is_valid_witness_version(witness_version: Fe32) -> bool {
validate_witness_version(witness_version).is_ok()
Expand Down Expand Up @@ -41,7 +46,7 @@ pub fn validate_witness_program_length(
if length > 40 {
return Err(TooLong);
}
if version == Fe32::Q && length != 20 && length != 32 {
if version == VERSION_0 && length != 20 && length != 32 {
return Err(InvalidSegwitV0);
}
Ok(())
Expand Down
23 changes: 11 additions & 12 deletions src/segwit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
//! let _ = segwit::encode_v0(&hrp::TB, &witness_prog);
//!
//! // If you have the witness version already you can use:
//! # let witness_version = Fe32::Q;
//! # let witness_version = segwit::VERSION_0;
//! let _ = segwit::encode(&hrp::BC, witness_version, &witness_prog);
//!
//! // Decode a Bitcoin bech32 segwit address.
Expand All @@ -50,9 +50,8 @@ use crate::primitives::decode::{SegwitHrpstring, SegwitHrpstringError};
use crate::primitives::gf32::Fe32;
use crate::primitives::hrp::Hrp;
use crate::primitives::iter::{ByteIterExt, Fe32IterExt};
#[cfg(feature = "alloc")]
use crate::primitives::segwit;
use crate::primitives::segwit::{InvalidWitnessVersionError, WitnessLengthError};
use crate::primitives::segwit::{self, InvalidWitnessVersionError, WitnessLengthError};
pub use crate::primitives::segwit::{VERSION_0, VERSION_1};
use crate::primitives::{Bech32, Bech32m};
use crate::write_err;

Expand Down Expand Up @@ -102,13 +101,13 @@ pub fn encode(
/// Encodes a segwit version 0 address.
#[cfg(feature = "alloc")]
pub fn encode_v0(hrp: &Hrp, witness_program: &[u8]) -> Result<String, EncodeError> {
encode(hrp, Fe32::Q, witness_program)
encode(hrp, VERSION_0, witness_program)
}

/// Encodes a segwit version 1 address.
#[cfg(feature = "alloc")]
pub fn encode_v1(hrp: &Hrp, witness_program: &[u8]) -> Result<String, EncodeError> {
encode(hrp, Fe32::P, witness_program)
encode(hrp, VERSION_1, witness_program)
}

/// Encodes a segwit address to a writer ([`fmt::Write`]) using lowercase characters.
Expand All @@ -123,8 +122,8 @@ pub fn encode_to_fmt_unchecked<W: fmt::Write>(
) -> fmt::Result {
let iter = witness_program.iter().copied().bytes_to_fes();
match witness_version {
Fe32::Q => {
for c in iter.with_checksum::<Bech32>(hrp).with_witness_version(Fe32::Q).chars() {
VERSION_0 => {
for c in iter.with_checksum::<Bech32>(hrp).with_witness_version(VERSION_0).chars() {
fmt.write_char(c)?;
}
}
Expand All @@ -151,8 +150,8 @@ pub fn encode_to_fmt_unchecked_uppercase<W: fmt::Write>(
) -> fmt::Result {
let iter = witness_program.iter().copied().bytes_to_fes();
match witness_version {
Fe32::Q => {
for c in iter.with_checksum::<Bech32>(hrp).with_witness_version(Fe32::Q).chars() {
VERSION_0 => {
for c in iter.with_checksum::<Bech32>(hrp).with_witness_version(VERSION_0).chars() {
fmt.write_char(c.to_ascii_uppercase())?;
}
}
Expand Down Expand Up @@ -247,7 +246,7 @@ mod tests {
fn encode_to_fmt_lowercase() {
let program = witness_program();
let mut address = String::new();
encode_to_fmt_unchecked(&mut address, &hrp::BC, Fe32::Q, &program)
encode_to_fmt_unchecked(&mut address, &hrp::BC, VERSION_0, &program)
.expect("failed to encode address to QR code");

let want = "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4";
Expand All @@ -258,7 +257,7 @@ mod tests {
fn encode_to_fmt_uppercase() {
let program = witness_program();
let mut address = String::new();
encode_to_fmt_unchecked_uppercase(&mut address, &hrp::BC, Fe32::Q, &program)
encode_to_fmt_unchecked_uppercase(&mut address, &hrp::BC, VERSION_0, &program)
.expect("failed to encode address to QR code");

let want = "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4";
Expand Down

0 comments on commit 024ed01

Please sign in to comment.