-/// Indicates a message can be encoded using bech32.
-pub(super) trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError> {
- /// Human readable part of the message's bech32 encoding.
- const BECH32_HRP: &'static str;
-
- /// Parses a bech32-encoded message into a TLV stream.
- fn from_bech32_str(s: &str) -> Result<Self, ParseError> {
- // Offer encoding may be split by '+' followed by optional whitespace.
- let encoded = match s.split('+').skip(1).next() {
- Some(_) => {
- for chunk in s.split('+') {
- let chunk = chunk.trim_start();
- if chunk.is_empty() || chunk.contains(char::is_whitespace) {
- return Err(ParseError::InvalidContinuation);
+#[cfg(not(fuzzing))]
+pub(super) use sealed::Bech32Encode;
+
+#[cfg(fuzzing)]
+pub use sealed::Bech32Encode;
+
+mod sealed {
+ use bitcoin::bech32;
+ use bitcoin::bech32::{FromBase32, ToBase32};
+ use core::convert::TryFrom;
+ use core::fmt;
+ use super::ParseError;
+
+ use crate::prelude::*;
+
+ /// Indicates a message can be encoded using bech32.
+ pub trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError> {
+ /// Human readable part of the message's bech32 encoding.
+ const BECH32_HRP: &'static str;
+
+ /// Parses a bech32-encoded message into a TLV stream.
+ fn from_bech32_str(s: &str) -> Result<Self, ParseError> {
+ // Offer encoding may be split by '+' followed by optional whitespace.
+ let encoded = match s.split('+').skip(1).next() {
+ Some(_) => {
+ for chunk in s.split('+') {
+ let chunk = chunk.trim_start();
+ if chunk.is_empty() || chunk.contains(char::is_whitespace) {
+ return Err(ParseError::InvalidContinuation);
+ }