Merge rust-bitcoin/rust-bitcoin#2480: Add a new base58 crate

aa8ba118ae Add a new base58 crate (Tobin C. Harding)

Pull request description:

  Add a new `base58check` crate to the workspace and move the `bitcoin::base58` module to it.

  Done as part of crate smashing, specifically so that we can make `bip32` into a separate crate.

ACKs for top commit:
  Kixunil:
    ACK aa8ba118ae
  apoelstra:
    ACK aa8ba118ae though is this `pub mod` thing equivalent to `pub extern crate`?

Tree-SHA512: a8db975655029b46df3b40ceca064ba708ce2f5fff0cfd6776d691441356c8a58fe6bdae6a1bf495da5112962e73c2b46df740a4041bed56f2559cb3c47ff34a
This commit is contained in:
Andrew Poelstra 2024-02-24 14:26:14 +00:00
commit 6d36c35914
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
10 changed files with 121 additions and 10 deletions

View File

@ -8,6 +8,14 @@ version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "base58check"
version = "0.1.0"
dependencies = [
"bitcoin_hashes",
"hex-conservative",
]
[[package]]
name = "base64"
version = "0.21.3"
@ -34,6 +42,7 @@ dependencies = [
name = "bitcoin"
version = "0.31.0"
dependencies = [
"base58check",
"base64",
"bech32",
"bincode",

View File

@ -8,6 +8,14 @@ version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
[[package]]
name = "base58check"
version = "0.1.0"
dependencies = [
"bitcoin_hashes",
"hex-conservative",
]
[[package]]
name = "base64"
version = "0.21.3"
@ -33,6 +41,7 @@ dependencies = [
name = "bitcoin"
version = "0.31.0"
dependencies = [
"base58check",
"base64",
"bech32",
"bincode",

View File

@ -1,7 +1,10 @@
[workspace]
members = ["bitcoin", "hashes", "internals", "fuzz", "io", "units"]
members = ["bitcoin", "hashes", "internals", "fuzz", "io", "units", "base58"]
resolver = "2"
[patch.crates-io.base58check]
path = "base58"
[patch.crates-io.bitcoin]
path = "bitcoin"

27
base58/Cargo.toml Normal file
View File

@ -0,0 +1,27 @@
[package]
name = "base58check"
version = "0.1.0"
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
license = "CC0-1.0"
repository = "https://github.com/rust-bitcoin/rust-bitcoin/"
description = "Bitcoin base58 encoding with checksum."
categories = ["cryptography::cryptocurrencies", "encoding"]
keywords = ["bitcoin", "base58", "encode", "decode", "checksum"]
readme = "README.md"
edition = "2021"
rust-version = "1.56.1"
exclude = ["tests", "contrib"]
[features]
default = ["std"]
std = ["hashes/std"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false, features = ["alloc"] }
[dev-dependencies]
hex = { package = "hex-conservative", version = "0.1.1", default-features = false, features = ["alloc"] }

27
base58/README.md Normal file
View File

@ -0,0 +1,27 @@
Bitcoin base58 encoding
=======================
This crate provides encoding and decoding of base58 strings as defined by the Bitcoin ecosystem
including the checksum.
There are two other crates on crates.io that implement base58 encoding and decoding. This
crate differs from them because:
1. [bitcoin-base58](https://crates.io/crates/bitcoin-base58) is transpiled from the C++ code in
Bitcoin Core as part of a large long-term transpilation project; this crate is a pure Rust
implementation intended to be production-ready and to provide an Rust-idiomatic API.
2. [base58](https://crates.io/crates/base58) is incomplete and appears unmaintained as of
February 2024. It does not validate checksums and will therefore accept invalid Bitcoin
addresses. It may be appropriate in cases where performance is more important than safety.
## Minimum Supported Rust Version (MSRV)
This library should always compile with any combination of features on **Rust 1.56.1**.
## Licensing
The code in this project is licensed under the [Creative Commons CC0 1.0 Universal license](LICENSE).
We use the [SPDX license list](https://spdx.org/licenses/) and [SPDX IDs](https://spdx.dev/ids/).

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Test all these features with "std" enabled.
FEATURES_WITH_STD=""
# Test all these features without "std" enabled.
FEATURES_WITHOUT_STD=""
# Run and lint these examples.
EXAMPLES=""

View File

@ -1,19 +1,37 @@
// SPDX-License-Identifier: CC0-1.0
//! Base58 encoder and decoder.
//!
//! This module provides functions for encoding and decoding base58 slices and
//! strings respectively.
//! Bitcoin base58 encoding and decoding.
//!
//! This crate can be used in a no-std environment but requires an allocator.
use core::{fmt, iter, slice, str};
#![no_std]
// Experimental features we need.
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(bench, feature(test))]
// Coding conventions.
#![warn(missing_docs)]
// Instead of littering the codebase for non-fuzzing code just globally allow.
#![cfg_attr(fuzzing, allow(dead_code, unused_imports))]
// Exclude lints we don't think are valuable.
#![allow(clippy::needless_question_mark)] // https://github.com/rust-bitcoin/rust-bitcoin/pull/2134
#![allow(clippy::manual_range_contains)] // More readable than clippy's format.
use hashes::{sha256d, Hash};
#[macro_use]
extern crate alloc;
use crate::prelude::*;
#[cfg(feature = "std")]
extern crate std;
static BASE58_CHARS: &[u8] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
use core::{fmt, iter, slice, str};
#[cfg(not(feature = "std"))]
pub use alloc::{string::String, vec::Vec};
#[cfg(feature = "std")]
pub use std::{string::String, vec::Vec};
use hashes::{sha256d, Hash};
#[rustfmt::skip]
static BASE58_DIGITS: [Option<u8>; 128] = [
None, None, None, None, None, None, None, None, // 0-7

View File

@ -15,7 +15,7 @@ exclude = ["tests", "contrib"]
[features]
default = [ "std", "secp-recovery" ]
std = ["bech32/std", "hashes/std", "hex/std", "internals/std", "io/std", "secp256k1/std", "units/std"]
std = ["base58/std", "bech32/std", "hashes/std", "hex/std", "internals/std", "io/std", "secp256k1/std", "units/std"]
rand-std = ["secp256k1/rand-std", "std"]
rand = ["secp256k1/rand"]
serde = ["actual-serde", "hashes/serde", "secp256k1/serde", "internals/serde", "units/serde"]
@ -28,6 +28,7 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
base58 = { package = "base58check", version = "0.1.0", default-features = false }
bech32 = { version = "0.10.0-beta", default-features = false, features = ["alloc"] }
hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false, features = ["alloc", "io"] }
hex = { package = "hex-conservative", version = "0.1.1", default-features = false, features = ["alloc"] }

View File

@ -27,6 +27,9 @@ codegen-units = 1 # better optimizations
debug = true # symbols are nice and they don't increase the size on Flash
lto = true # better optimizations
[patch.crates-io.base58check]
path = "../../base58"
[patch.crates-io.bitcoin_hashes]
path = "../../hashes"

View File

@ -93,7 +93,6 @@ mod serde_utils;
#[macro_use]
pub mod p2p;
pub mod address;
pub mod base58;
pub mod bip152;
pub mod bip158;
pub mod bip32;
@ -196,3 +195,8 @@ pub mod amount {
}
}
}
pub mod base58 {
//! Bitcoin base58 encoding and decoding.
pub use base58::{decode, decode_check, encode, encode_check, encode_check_to_fmt, Error};
}