Add a new base58 crate

Add a new `base58` 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.
This commit is contained in:
Tobin C. Harding 2024-02-15 14:35:29 +11:00
parent 31c0bf8d5f
commit aa8ba118ae
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "base58check"
version = "0.1.0"
dependencies = [
"bitcoin_hashes",
"hex-conservative",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.21.3" version = "0.21.3"
@ -34,6 +42,7 @@ dependencies = [
name = "bitcoin" name = "bitcoin"
version = "0.31.0" version = "0.31.0"
dependencies = [ dependencies = [
"base58check",
"base64", "base64",
"bech32", "bech32",
"bincode", "bincode",

View File

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

View File

@ -1,7 +1,10 @@
[workspace] [workspace]
members = ["bitcoin", "hashes", "internals", "fuzz", "io", "units"] members = ["bitcoin", "hashes", "internals", "fuzz", "io", "units", "base58"]
resolver = "2" resolver = "2"
[patch.crates-io.base58check]
path = "base58"
[patch.crates-io.bitcoin] [patch.crates-io.bitcoin]
path = "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 // SPDX-License-Identifier: CC0-1.0
//! Base58 encoder and decoder. //! Bitcoin base58 encoding and decoding.
//!
//! This module provides functions for encoding and decoding base58 slices and
//! strings respectively.
//! //!
//! 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"; 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] #[rustfmt::skip]
static BASE58_DIGITS: [Option<u8>; 128] = [ static BASE58_DIGITS: [Option<u8>; 128] = [
None, None, None, None, None, None, None, None, // 0-7 None, None, None, None, None, None, None, None, // 0-7

View File

@ -15,7 +15,7 @@ exclude = ["tests", "contrib"]
[features] [features]
default = [ "std", "secp-recovery" ] 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-std = ["secp256k1/rand-std", "std"]
rand = ["secp256k1/rand"] rand = ["secp256k1/rand"]
serde = ["actual-serde", "hashes/serde", "secp256k1/serde", "internals/serde", "units/serde"] serde = ["actual-serde", "hashes/serde", "secp256k1/serde", "internals/serde", "units/serde"]
@ -28,6 +28,7 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"]
[dependencies] [dependencies]
base58 = { package = "base58check", version = "0.1.0", default-features = false }
bech32 = { version = "0.10.0-beta", default-features = false, features = ["alloc"] } 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"] } 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"] } 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 debug = true # symbols are nice and they don't increase the size on Flash
lto = true # better optimizations lto = true # better optimizations
[patch.crates-io.base58check]
path = "../../base58"
[patch.crates-io.bitcoin_hashes] [patch.crates-io.bitcoin_hashes]
path = "../../hashes" path = "../../hashes"

View File

@ -93,7 +93,6 @@ mod serde_utils;
#[macro_use] #[macro_use]
pub mod p2p; pub mod p2p;
pub mod address; pub mod address;
pub mod base58;
pub mod bip152; pub mod bip152;
pub mod bip158; pub mod bip158;
pub mod bip32; 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};
}