Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite bech32 crate #102

Closed
wants to merge 2 commits into from
Closed

Conversation

tcharding
Copy link
Member

@tcharding tcharding commented Apr 23, 2023

Draft because done on top of #101, also because @apoelstra suggested doing this in smaller parts but I think it might be easier to just pull the trigger and do it all at once. @clarkmoody please say if you find this approach too much and would prefer to see the PR broken up into multiple PRs.

Why the rewrite?

  • It was observed that the writer API could be generalized to use an iterator API.
  • It was observed that the checksum logic is an implementation of BCH codes, this is the only cryptography part of the crate, as such it is complex, isolating it helps reduce complexity of the code for non-cryptographers.
  • This is a bitcoin crate but currently it supports arbitrary HRP prefixes, by making the top level API more bitcoin specific we can simplify the API.

Aims

  • Make a segwit API that is ergonomic to use for Bitcoin users and that implements the specification laid out in BIP-173 And BIP-350
  • Isolate the cryptography to a submodule
  • Create a stable API that we can commit to maintaining

For example usage in rust-bitcoin see: rust-bitcoin/rust-bitcoin#1809

This requires dropping `Ord` impls from the error types, but IMHO these
didn't really make sense anyway.

This also keeps the `u5` name. We will rename this in a later PR which
replaces the *Base32 traits with iterator adaptors, since at that point
there will be a much smaller API surface to change.
@tcharding tcharding changed the title 04 24 rewrite Rewrite bech32 crate Apr 23, 2023
@tcharding tcharding force-pushed the 04-24-rewrite branch 2 times, most recently from b77ef94 to 13827d3 Compare April 23, 2023 23:37
src/lib.rs Outdated
Comment on lines 438 to 439
/// The codex32 checksum algorithm, defined in BIP-93.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum Codex32 {}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to keep this in?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we'll drop it from the final PR.

@tcharding
Copy link
Member Author

Notes:

  • The fuzzing needs fixing
  • I've managed to loose the benchmark code you wrote @apoelstra

}

#[test]
#[allow(unused_variables)] // Triggered by matches macro.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is triggered because the matches macro is used incorrectly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, and fixed tests to fully implement the test vectors from both bips.

// Written by Clark Moody and the rust-bitcoin developers.
// SPDX-License-Identifier: MIT

//! GF1024 - Galois Field over 1024 elements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unclear on the purpose of including this in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will drop, thanks.

src/lib.rs Outdated

/// True if program length is either 20 bytes (p2wpkh) or 32 bytes (p2wsh).
/// ref: [BIP-141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#user-content-Witness_program)
#[cfg(feature = "alloc")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what part of this function requires an allocator?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to prevent clippy warning when "alloc" is not enabled, I added a comment to it to say as such.

@tcharding tcharding force-pushed the 04-24-rewrite branch 2 times, most recently from a07a1b1 to 035f026 Compare April 26, 2023 03:55
@tcharding
Copy link
Member Author

Is it even worth fuzzing this crate? We accept random data and convert it to a string (filters out invalid utf-8) and then decode (filters out invalid bech32 characters). Won't the number of times this actually succeeds be so small that running the fuzzing is essentially doing nothing? Or is the fuzzing meaningfully helping to prove 1. below?

Am I correct in thinking we want to test that:

  1. arbitrary &str doesn't cause us to panic
  2. all valid bech32 strings are correctly parsed and roundtripped

@apoelstra
Copy link
Member

You can test whether it's able to produce valid checksums. It would surprise me if it can't, given how simple the algorithm is and the fact that it only requires modiying the last 6 characters of the string (and modifying them independently, by simply xoring them with the correct value).

But regardless, it is valuable to fuzz that we don't panic.

src/network.rs Outdated
/// ```
///
/// [segwit address format]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#user-content-Segwit_address_format>
pub const fn to_hrp(&self) -> &'static str {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not return an instance of the human-readable part type instead of a string slice?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a play with introducing the Hrp type as you suggested previously, cheers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aight, I hacked up a new version of this PR that adds an Hrp type, and also a KnownHrp type for segwit specific code. Could be mistakes because it was a fair bit of work and I should really go over it on another day before pushing but I'm pretty psyched for this so if you'll excuse me I'll push right away.

///
/// Parsing as an HRP string does not validate the checksum in any way.
#[derive(Debug)]
pub struct Parsed<'s> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The names here don't make a ton of sense. The module is called hrpstring, but the primary data structure is Parsed and contains not only HRP data but also witness version and the data part.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The data structure is an HRP string which has been parsed into an HRP, witness version, and data part.

We should change this if it's not understandable but it seemed pretty straightforward to me.

@tcharding tcharding force-pushed the 04-24-rewrite branch 2 times, most recently from 67c92ec to 4b841ad Compare April 27, 2023 04:55
@tcharding
Copy link
Member Author

The major change here is that the PR no longer removes the current API. Instead it adds a segwit module that implements bip-173 and 350 using the new primitives stuff. Also:

  • Adds Hrp type
  • Adds KnownHrp type
  • Uses new proposed rust-bitcoin-primitives crate to get the WitnessVersion

Thanks for your patience @clarkmoody and keeping on prodding me about the Hrp type, this worked out really nicely.

@tcharding tcharding force-pushed the 04-24-rewrite branch 4 times, most recently from c518a2c to 33cd60a Compare April 27, 2023 07:05
@tcharding
Copy link
Member Author

Closing since this is stale.

@tcharding tcharding closed this Jul 9, 2023
@tcharding tcharding deleted the 04-24-rewrite branch September 18, 2023 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants