11# Base58 Encoding Library
22
3- A .NET 9 .0 Base58 encoding and decoding library with support for multiple alphabet variants.
3+ A .NET 10 .0 Base58 encoding and decoding library with support for multiple alphabet variants.
44
55## Features
66
7- - ** Multiple Alphabets** : Built-in support for Bitcoin(IFPS/Sui), Ripple, and Flickr alphabets
7+ - ** Multiple Alphabets** : Built-in support for Bitcoin(IFPS/Sui/Solana ), Ripple, and Flickr alphabets
88- ** Memory Efficient** : Uses stackalloc operations when possible to minimize allocations
99- ** Type Safe** : Leverages ReadOnlySpan and ReadOnlyMemory for safe memory operations
1010- ** Intrinsics** : Uses SIMD ` Vector128/Vector256 ` and unrolled loop for counting leading zeros
11+ - ** Optimized Hot Paths** : Fast fixed-length encode/decode for 32-byte and 64-byte inputs using Firedancer-like optimizations
1112
1213## Usage
1314
@@ -24,50 +25,69 @@ byte[] decoded = Base58.Bitcoin.Decode(encoded);
2425// Ripple / Flickr
2526Base58 .Ripple .Encode (data );
2627Base58 .Flickr .Encode (data );
28+ ```
29+
30+ ## Performance
31+
32+ The library automatically uses optimized fast paths for common fixed-size inputs:
33+ - ** 32-byte inputs** (Bitcoin/Solana addresses, SHA-256 hashes): 8.5x faster encoding
34+ - ** 64-byte inputs** (SHA-512 hashes): Similar performance improvements
35+
36+ These optimizations are based on Firedancer's specialized Base58 algorithms and are transparent to the user. Unlike Firedancer however, we fallback to the generic approach in case of edge-cases.
37+
38+ ** Algorithm Details:**
39+ - Uses ** Mixed Radix Conversion (MRC)** with intermediate base 58^5 representation
40+ - Precomputed multiplication tables replace expensive division operations
41+ - Converts binary data to base 58^5 limbs, then to raw base58 digits
42+ - Matrix multiplication approach processes 5 base58 digits simultaneously
43+ - Separate encode/decode tables for 32-byte and 64-byte fixed sizes
44+ - Achieves ~ 2.5x speedup through table-based optimizations vs iterative division
45+
46+ ** References:**
47+ - [ Firedancer C implementation] ( https://github.com/firedancer-io/firedancer/tree/main/src/ballet/base58 )
2748
28- // Custom
29- new Base58 (Base58Alphabet .Custom (" " ));
3049```
3150
3251## Benchmarks
3352
3453```
35- BenchmarkDotNet v0.15.2 , Windows 11 (10.0.26100.4946/24H2/2024Update/HudsonValley )
54+ BenchmarkDotNet v0.15.8 , Windows 11 (10.0.26200.7462/25H2/2025Update/HudsonValley2 )
365513th Gen Intel Core i7-13700KF 3.40GHz, 1 CPU, 24 logical and 16 physical cores
37- .NET SDK 9.0.304
38- [Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
39- .NET 9.0 : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
56+ .NET SDK 10.0.101
57+ [ Host] : .NET 10.0.1 (10.0.1, 10.0.125.57005), X64 RyuJIT x86-64-v3
58+ DefaultJob : .NET 10.0.1 (10.0.1, 10.0.125.57005), X64 RyuJIT x86-64-v3
59+
60+ Job=DefaultJob
4061
41- Job=.NET 9.0 Runtime=.NET 9.0
4262```
43- | Method | VectorType | Mean | Error | StdDev | Median |
44- | --------------------------- | --------------- | ------------:| ----------:| ----------:| ------------:|
45- | ** ' Our Base58 Encode' ** | ** BitcoinAddress** | ** 519.2 ns** | ** 1.99 ns ** | ** 1.76 ns ** | ** 519.2 ns ** |
46- | ' SimpleBase Base58 Encode' | BitcoinAddress | 770.1 ns | 4.93 ns | 4.61 ns | 769.8 ns |
47- | ' Our Base58 Decode' | BitcoinAddress | 187.5 ns | 2.06 ns | 1.93 ns | 187.8 ns |
48- | ' SimpleBase Base58 Decode' | BitcoinAddress | 502.1 ns | 6.95 ns | 5.43 ns | 502.4 ns |
49- | | | | | | |
50- | ** ' Our Base58 Encode' ** | ** SolanaAddress** | ** 1,375.9 ns** | ** 36.83 ns ** | ** 108.59 ns ** | ** 1,410.7 ns ** |
51- | ' SimpleBase Base58 Encode' | SolanaAddress | 2,546.5 ns | 112.91 ns | 329.36 ns | 2,661.5 ns |
52- | ' Our Base58 Decode' | SolanaAddress | 536.5 ns | 24.89 ns | 73.39 ns | 564.3 ns |
53- | ' SimpleBase Base58 Decode' | SolanaAddress | 1,210.2 ns | 31.14 ns | 90.33 ns | 1,236.8 ns |
54- | | | | | | |
55- | ** ' Our Base58 Encode' ** | ** SolanaTx** | ** 4,185.4 ns** | ** 48.51 ns ** | ** 37.87 ns ** | ** 4,173.0 ns ** |
56- | ' SimpleBase Base58 Encode' | SolanaTx | 10,844.0 ns | 337.01 ns | 988.40 ns | 11,158.2 ns |
57- | ' Our Base58 Decode' | SolanaTx | 2,159.0 ns | 116.99 ns | 344.95 ns | 2,294.0 ns |
58- | ' SimpleBase Base58 Decode' | SolanaTx | 5,357.9 ns | 177.28 ns | 494.18 ns | 5,506.1 ns |
59- | | | | | | |
60- | ** ' Our Base58 Encode' ** | ** IPFSHash** | ** 1,285.9 ns** | ** 80.51 ns ** | ** 237.37 ns ** | ** 1,081.6 ns ** |
61- | ' SimpleBase Base58 Encode' | IPFSHash | 1,654.3 ns | 4.14 ns | 3.88 ns | 1,653.9 ns |
62- | ' Our Base58 Decode' | IPFSHash | 347.0 ns | 1.19 ns | 0.99 ns | 347.0 ns |
63- | ' SimpleBase Base58 Decode' | IPFSHash | 883.4 ns | 16.93 ns | 15.01 ns | 883.2 ns |
64- | | | | | | |
65- | ** ' Our Base58 Encode' ** | ** MoneroAddress** | ** 4,907.0 ns** | ** 13.36 ns ** | ** 11.84 ns ** | ** 4,907.9 ns ** |
66- | ' SimpleBase Base58 Encode' | MoneroAddress | 8,998.7 ns | 25.07 ns | 20.94 ns | 8,998.8 ns |
67- | ' Our Base58 Decode' | MoneroAddress | 1,367.1 ns | 4.38 ns | 3.89 ns | 1,366.5 ns |
68- | ' SimpleBase Base58 Decode' | MoneroAddress | 3,809.8 ns | 59.58 ns | 55.73 ns | 3,797.3 ns |
63+ | Method | VectorType | Mean | Ratio | Gen0 | Allocated | Alloc Ratio |
64+ |--------------------------- |--------------- |------------:|------:|--- ----:|----------:|------------:|
65+ | **' Our Base58 Encode' ** | **BitcoinAddress** | **537.07 ns** | **1.00** | **0.0057** | **96 B ** | **1.00 ** |
66+ | ' SimpleBase Base58 Encode' | BitcoinAddress | 782.31 ns | 1.46 | 0.0057 | 96 B | 1.00 |
67+ | ' Our Base58 Decode' | BitcoinAddress | 168.95 ns | 0.31 | 0.0033 | 56 B | 0.58 |
68+ | ' SimpleBase Base58 Decode' | BitcoinAddress | 352.63 ns | 0.66 | 0.0033 | 56 B | 0.58 |
69+ | | | | | | | |
70+ | **' Our Base58 Encode' ** | **SolanaAddress** | **93.41 ns** | **1.00 ** | **0.0070** | **112 B** | **1.00 ** |
71+ | ' SimpleBase Base58 Encode' | SolanaAddress | 1,430.37 ns | 15.31 | 0.0057 | 112 B | 1.00 |
72+ | ' Our Base58 Decode' | SolanaAddress | 181.71 ns | 1.95 | 0.0035 | 56 B | 0.50 |
73+ | ' SimpleBase Base58 Decode' | SolanaAddress | 837.03 ns | 8.96 | 0.0019 | 56 B | 0.50 |
74+ | | | | | | | |
75+ | **' Our Base58 Encode' ** | **SolanaTx** | **252.31 ns** | **1.00** | **0.0124** | **200 B ** | **1.00 ** |
76+ | ' SimpleBase Base58 Encode' | SolanaTx | 7,247.09 ns | 28.73 | 0.0076 | 200 B | 1.00 |
77+ | ' Our Base58 Decode' | SolanaTx | 178.05 ns | 0.71 | 0.0055 | 88 B | 0.44 |
78+ | ' SimpleBase Base58 Decode' | SolanaTx | 2,379.54 ns | 9.43 | 0.0038 | 88 B | 0.44 |
79+ | | | | | | | |
80+ | **' Our Base58 Encode' ** | **IPFSHash** | **1,096.58 ns** | **1.00 ** | **0.0076** | **120 B** | **1.00 ** |
81+ | ' SimpleBase Base58 Encode' | IPFSHash | 1,644.83 ns | 1.50 | 0.0076 | 120 B | 1.00 |
82+ | ' Our Base58 Decode' | IPFSHash | 287.87 ns | 0.26 | 0.0038 | 64 B | 0.53 |
83+ | ' SimpleBase Base58 Decode' | IPFSHash | 643.63 ns | 0.59 | 0.0038 | 64 B | 0.53 |
84+ | | | | | | | |
85+ | **' Our Base58 Encode' ** | **MoneroAddress** | **4,998.35 ns** | **1.00** | **0.0076** | **216 B ** | **1.00 ** |
86+ | ' SimpleBase Base58 Encode' | MoneroAddress | 8,585.92 ns | 1.72 | - | 216 B | 1.00 |
87+ | ' Our Base58 Decode' | MoneroAddress | 1,173.48 ns | 0.23 | 0.0057 | 96 B | 0.44 |
88+ | ' SimpleBase Base58 Decode' | MoneroAddress | 3,716.38 ns | 0.74 | 0.0038 | 96 B | 0.44 |
6989
7090
7191## License
7292
73- This project is available under the MIT License.
93+ This project is available under the MIT License.
0 commit comments