@@ -9,7 +9,7 @@ library Base58 {
99 /* CUSTOM ERRORS */
1010 /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
1111
12- /// @dev An unrecognized character was encountered during decoding.
12+ /// @dev An unrecognized character or overflow was encountered during decoding.
1313 error Base58DecodingError ();
1414
1515 /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
@@ -174,16 +174,32 @@ library Base58 {
174174
175175 /// @dev Decodes `encoded`, a Base58 string, into the original word.
176176 function decodeWord (string memory encoded ) internal pure returns (bytes32 result ) {
177- // Specializing and optimizing this for bytes32 is left as an exercise to the reader.
178- bytes memory t = decode (encoded) ;
177+ uint256 n = bytes (encoded). length ;
178+ if (n == uint256 ( 0 )) return result ;
179179 /// @solidity memory-safe-assembly
180180 assembly {
181- let n := mload (t)
182- if iszero (lt (n, 0x21 )) {
183- mstore (0x00 , 0xe8fad793 ) // `Base58DecodingError()`.
184- revert (0x1c , 0x04 )
181+ let m := mload (0x40 ) // Cache the free memory pointer.
182+ let s := add (encoded, 0x20 )
183+ let t := add (1 , div (not (0 ), 58 )) // Overflow threshold for multiplication.
184+ // Use the extended scratch space for the lookup. We'll restore 0x40 later.
185+ mstore (0x2a , 0x30313233343536373839 )
186+ mstore (0x20 , 0x1718191a1b1c1d1e1f20ffffffffffff2122232425262728292a2bff2c2d2e2f )
187+ mstore (0x00 , 0x000102030405060708ffffffffffffff090a0b0c0d0e0f10ff1112131415ff16 )
188+
189+ for { let j := 0 } 1 {} {
190+ let c := sub (byte (0 , mload (add (s, j))), 49 )
191+ let p := mul (result, 58 )
192+ let acc := add (byte (0 , mload (c)), p)
193+ // Check if the input character is valid.
194+ if iszero (and (0x3fff7ff03ffbeff01ff , shl (c, lt (lt (acc, p), lt (result, t))))) {
195+ mstore (0x00 , 0xe8fad793 ) // `Base58DecodingError()`.
196+ revert (0x1c , 0x04 )
197+ }
198+ result := acc
199+ j := add (j, 1 )
200+ if eq (j, n) { break }
185201 }
186- result := mload ( add (t, n))
202+ mstore ( 0x40 , m) // Restore the free memory pointer.
187203 }
188204 }
189205}
0 commit comments