Skip to content

Commit

Permalink
Re-write crate level API
Browse files Browse the repository at this point in the history
Now we have all the new `primitives` pieces in place we can re-write the
public API to take advantage of them - WIN!
  • Loading branch information
tcharding committed Sep 11, 2023
1 parent 1867dcf commit c036c7f
Show file tree
Hide file tree
Showing 11 changed files with 361 additions and 1,254 deletions.
17 changes: 9 additions & 8 deletions embedded/no-allocator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#![no_std]

use arrayvec::{ArrayString, ArrayVec};
use bech32::{self, u5, Hrp, Variant, ByteIterExt, Bech32};
use bech32::primitives::decode::CheckedHrpstring;
use bech32::{Bech32, Hrp};
use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
use panic_halt as _;
Expand All @@ -20,20 +20,21 @@ use panic_halt as _;
fn main() -> ! {
let mut encoded = ArrayString::<30>::new();

let base32 = [0x00u8, 0x01, 0x02].iter().copied().bytes_to_fes().collect::<ArrayVec<u5, 30>>();
let data = [0x00u8, 0x01, 0x02];
let hrp = Hrp::parse("bech32").parse("failed to parse hrp");

let hrp = Hrp::parse("bech32").unwrap();

bech32::encode_to_fmt_anycase(&mut encoded, hrp, &base32, Variant::Bech32).unwrap().unwrap();
bech32::encode_to_fmt::<Bech32, ArrayString<30>>(&mut encoded, hrp, &data)
.expect("failed to encode");
test(&*encoded == "bech321qqqsyrhqy2a");

hprintln!("{}", encoded).unwrap();

let unchecked = CheckedHrpstring::new::<Bech32>(&encoded).unwrap();
let unchecked =
CheckedHrpstring::new::<Bech32>(&encoded).expect("failed to construct CheckedHrpstring");
let iter = unchecked.byte_iter().collect::<ArrayVec<u8, 30>>();

test(unchecked.hrp() == hrp);
let res = unchecked.byte_iter().collect::<ArrayVec<u8, 30>>();
test(&res == [0x00, 0x01, 0x02].as_ref());
test(iter.eq(data.iter().map(|&b| b)));

debug::exit(debug::EXIT_SUCCESS);

Expand Down
14 changes: 8 additions & 6 deletions embedded/with-allocator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern crate alloc;
use core::alloc::Layout;

use alloc_cortex_m::CortexMHeap;
use bech32::{self, FromBase32, Hrp, ToBase32, Variant};
use bech32::Hrp;
use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
Expand All @@ -26,16 +26,18 @@ fn main() -> ! {
// Initialize the allocator BEFORE you use it
unsafe { ALLOCATOR.init(cortex_m_rt::heap_start() as usize, HEAP_SIZE) }

let hrp = Hrp::parse("bech32").unwrap();
let encoded = bech32::encode(hrp, vec![0x00, 0x01, 0x02].to_base32(), Variant::Bech32).unwrap();
let data = [0x00u8, 0x01, 0x02];
let hrp = Hrp::parse("bech32").parse("failed to parse hrp");

let encoded = bech32::encode(hrp, &data).expect("failed to encode");
test(encoded == "bech321qqqsyrhqy2a".to_string());

hprintln!("{}", encoded).unwrap();

let (got_hrp, data, variant) = bech32::decode(&encoded).unwrap();
let (got_hrp, got_data) = bech32::decode(&encoded).expect("failed to decode");

test(got_hrp == hrp);
test(Vec::<u8>::from_base32(&data).unwrap() == vec![0x00, 0x01, 0x02]);
test(variant == Variant::Bech32);
test(got_data.iter().eq(data.iter().map(|&b| b)));

debug::exit(debug::EXIT_SUCCESS);

Expand Down
9 changes: 5 additions & 4 deletions fuzz/fuzz_targets/decode_rnd.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
extern crate bech32;

use bech32::Bech32m;

fn do_test(data: &[u8]) {
let data_str = String::from_utf8_lossy(data);
let decoded = bech32::decode(&data_str);
let b32 = match decoded {
Ok(b32) => b32,
let (hrp, data) = match bech32::decode_bech32m(&data_str) {
Ok((hrp, data)) => (hrp, data),
Err(_) => return,
};

assert_eq!(bech32::encode(b32.0, b32.1, b32.2).unwrap(), data_str);
assert_eq!(bech32::encode::<Bech32m>(hrp, &data).unwrap(), data_str);
}

#[cfg(feature = "afl")]
Expand Down
22 changes: 5 additions & 17 deletions fuzz/fuzz_targets/encode_decode.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
extern crate bech32;

use std::convert::TryFrom;
use std::str;

use bech32::Hrp;
use bech32::{Bech32m, Hrp};

fn do_test(data: &[u8]) {
if data.len() < 1 {
Expand All @@ -16,28 +15,17 @@ fn do_test(data: &[u8]) {
return;
}

let dp = data[hrp_end..]
.iter()
.map(|b| bech32::u5::try_from(b % 32).unwrap())
.collect::<Vec<_>>();

let variant = if data[0] > 0x0f {
bech32::Variant::Bech32m
} else {
bech32::Variant::Bech32
};
let dp = &data[hrp_end..];

match str::from_utf8(&data[1..hrp_end]) {
Err(_) => return,
Ok(s) => {
match Hrp::parse(&s) {
Err(_) => return,
Ok(hrp) => {
if let Ok(data_str) = bech32::encode(hrp, &dp, variant).map(|b32| b32.to_string()) {
let decoded = bech32::decode(&data_str);
let b32 = decoded.expect("should be able to decode own encoding");

assert_eq!(bech32::encode(b32.0, &b32.1, b32.2).unwrap(), data_str);
if let Ok(address) = bech32::encode::<Bech32m>(hrp, dp) {
let (hrp, data) = bech32::decode_bech32m(&address).expect("should be able to decode own encoding");
assert_eq!(bech32::encode::<Bech32m>(hrp, &data).unwrap(), address);
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/hrp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT

/// The human-readable part (human readable prefix before the '1' separator).
#[doc(inline)]
pub use crate::primitives::hrp::Hrp;
/// The human-readable part used by the Bitcoin mainnet network.
#[doc(inline)]
pub use crate::primitives::hrp::BC;
/// The human-readable part used when running a Bitcoin regtest network.
#[doc(inline)]
pub use crate::primitives::hrp::BCRT;
/// The human-readable part used by the Bitcoin testnet networks (testnet, signet).
#[doc(inline)]
pub use crate::primitives::hrp::TB;
Loading

0 comments on commit c036c7f

Please sign in to comment.