@@ -114,16 +114,16 @@ internal byte[] DecodeGeneric(ReadOnlySpan<char> encoded)
114114 else
115115 {
116116 char c = encoded [ j - prepend0 ] ;
117- // Validate + convert using Bitcoin decode table (return null for invalid chars)
117+ // Validate + convert using Bitcoin decode table
118118 if ( c >= 128 || bitcoinDecodeTable [ c ] == 255 )
119- return null ;
119+ ThrowHelper . ThrowInvalidCharacter ( c ) ;
120120
121121 rawBase58 [ j ] = bitcoinDecodeTable [ c ] ;
122122 }
123123 }
124124
125125 // Convert to intermediate format (base 58^5)
126- Span < ulong > intermediate = stackalloc ulong [ Base58BitcoinTables . IntermediateSz32 ] ; // 9 elements
126+ Span < ulong > intermediate = stackalloc ulong [ Base58BitcoinTables . IntermediateSz32 ] ;
127127
128128 for ( int i = 0 ; i < Base58BitcoinTables . IntermediateSz32 ; i ++ )
129129 {
@@ -135,7 +135,7 @@ internal byte[] DecodeGeneric(ReadOnlySpan<char> encoded)
135135 }
136136
137137 // Convert to overcomplete base 2^32 using decode table
138- Span < ulong > binary = stackalloc ulong [ Base58BitcoinTables . BinarySz32 ] ; // 8 elements
138+ Span < ulong > binary = stackalloc ulong [ Base58BitcoinTables . BinarySz32 ] ;
139139
140140 for ( int j = 0 ; j < Base58BitcoinTables . BinarySz32 ; j ++ )
141141 {
@@ -183,6 +183,8 @@ internal byte[] DecodeGeneric(ReadOnlySpan<char> encoded)
183183 }
184184
185185 // Leading zeros in output must match leading '1's in input
186+ // might be edge case since base58 of 32bytes can be between 32 and 44 characters.
187+ // will be handled by generic decoder if lengths don't match
186188 if ( outputLeadingZeros != inputLeadingOnes ) return null ;
187189
188190 // Return the full 32 bytes - the result should always be 32 bytes for 32-byte decode
@@ -194,7 +196,7 @@ internal byte[] DecodeGeneric(ReadOnlySpan<char> encoded)
194196 int charCount = encoded . Length ;
195197
196198 // Convert to raw base58 digits with validation + conversion in one pass
197- Span < byte > rawBase58 = stackalloc byte [ Base58BitcoinTables . Raw58Sz64 ] ; // 90 bytes
199+ Span < byte > rawBase58 = stackalloc byte [ Base58BitcoinTables . Raw58Sz64 ] ;
198200 var bitcoinDecodeTable = Base58Alphabet . Bitcoin . DecodeTable . Span ;
199201
200202 // Prepend zeros to make exactly Raw58Sz64 characters
@@ -208,16 +210,16 @@ internal byte[] DecodeGeneric(ReadOnlySpan<char> encoded)
208210 else
209211 {
210212 char c = encoded [ j - prepend0 ] ;
211- // Validate + convert using Bitcoin decode table (return null for invalid chars)
213+ // Validate + convert using Bitcoin decode table
212214 if ( c >= 128 || bitcoinDecodeTable [ c ] == 255 )
213- return null ;
215+ ThrowHelper . ThrowInvalidCharacter ( c ) ;
214216
215217 rawBase58 [ j ] = bitcoinDecodeTable [ c ] ;
216218 }
217219 }
218220
219221 // Convert to intermediate format (base 58^5)
220- Span < ulong > intermediate = stackalloc ulong [ Base58BitcoinTables . IntermediateSz64 ] ; // 18 elements
222+ Span < ulong > intermediate = stackalloc ulong [ Base58BitcoinTables . IntermediateSz64 ] ;
221223
222224 for ( int i = 0 ; i < Base58BitcoinTables . IntermediateSz64 ; i ++ )
223225 {
@@ -229,7 +231,7 @@ internal byte[] DecodeGeneric(ReadOnlySpan<char> encoded)
229231 }
230232
231233 // Convert to overcomplete base 2^32 using decode table
232- Span < ulong > binary = stackalloc ulong [ Base58BitcoinTables . BinarySz64 ] ; // 16 elements
234+ Span < ulong > binary = stackalloc ulong [ Base58BitcoinTables . BinarySz64 ] ;
233235
234236 for ( int j = 0 ; j < Base58BitcoinTables . BinarySz64 ; j ++ )
235237 {
@@ -277,6 +279,8 @@ internal byte[] DecodeGeneric(ReadOnlySpan<char> encoded)
277279 }
278280
279281 // Leading zeros in output must match leading '1's in input
282+ // might be edge case since base58 of 64bytes can be between 64 and 88 characters.
283+ // will be handled by generic decoder if lengths don't match
280284 if ( outputLeadingZeros != inputLeadingOnes ) return null ;
281285
282286 // Return the full 64 bytes - the result should always be 64 bytes for 64-byte decode
0 commit comments