Skip to content

Commit

Permalink
[fold] Address misc PR issues
Browse files Browse the repository at this point in the history
  • Loading branch information
seelabs committed Mar 23, 2023
1 parent 845d2bd commit 3c80d53
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 73 deletions.
37 changes: 19 additions & 18 deletions src/ripple/protocol/impl/b58_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,24 @@ div_rem(std::uint64_t a, std::uint64_t b)
[[nodiscard]] inline std::tuple<std::uint64_t, std::uint64_t>
carrying_mul(std::uint64_t a, std::uint64_t b, std::uint64_t carry)
{
unsigned __int128 x = a;
unsigned __int128 y = b;
unsigned __int128 c = x * y + carry;
return {c & 0xffffffffffffffff, c >> 64};
unsigned __int128 const x = a;
unsigned __int128 const y = b;
unsigned __int128 const c = x * y + carry;
return {c & 0xffff'ffff'ffff'ffff, c >> 64};
}

[[nodiscard]] inline std::tuple<std::uint64_t, std::uint64_t>
carrying_add(std::uint64_t a, std::uint64_t b)
{
unsigned __int128 x = a;
unsigned __int128 y = b;
unsigned __int128 c = x + y;
return {c & 0xffffffffffffffff, c >> 64};
unsigned __int128 const x = a;
unsigned __int128 const y = b;
unsigned __int128 const c = x + y;
return {c & 0xffff'ffff'ffff'ffff, c >> 64};
}

// Add a u64 to a "big uint" value inplace.
// The bitint value is stored with the smallest coefficients first
// (i.e a[0] is the 2^0 coefficient, a[n] is the 2^n coefficient)
// The bigint value is stored with the smallest coefficients first
// (i.e a[0] is the 2^0 coefficient, a[n] is the 2^(64*n) coefficient)
// panics if overflows (this is a specialized adder for b58 decoding.
// it should never overflow).
inline void
Expand Down Expand Up @@ -124,16 +124,16 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
{
auto to_u128 = [](std::uint64_t high,
std::uint64_t low) -> unsigned __int128 {
unsigned __int128 result = high;
unsigned __int128 low128 = low;
return ((result << 64) | low128);
unsigned __int128 const high128 = high;
unsigned __int128 const low128 = low;
return ((high128 << 64) | low128);
};
auto div_rem_64 =
[](unsigned __int128 num,
std::uint64_t denom) -> std::tuple<std::uint64_t, std::uint64_t> {
unsigned __int128 denom128 = denom;
unsigned __int128 d = num / denom128;
unsigned __int128 r = num % denom128;
unsigned __int128 const denom128 = denom;
unsigned __int128 const d = num / denom128;
unsigned __int128 const r = num - (denom128 * d);
return {static_cast<std::uint64_t>(d), static_cast<std::uint64_t>(r)};
};

Expand All @@ -143,14 +143,15 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
div_rem(numerator[last_index], divisor);
for (int i = last_index - 1; i >= 0; --i)
{
unsigned __int128 cur_num = to_u128(prev_rem, numerator[i]);
unsigned __int128 const cur_num = to_u128(prev_rem, numerator[i]);
std::tie(numerator[i], prev_rem) = div_rem_64(cur_num, divisor);
}
return prev_rem;
}

// convert from base 58^10 to base 58
// put largest coeffs first
// the `_be` suffix stands for "big endian"
[[nodiscard]] inline std::array<std::uint8_t, 10>
b58_10_to_b58_be(std::uint64_t input)
{
Expand All @@ -173,4 +174,4 @@ b58_10_to_b58_be(std::uint64_t input)
#endif

} // namespace ripple
#endif // B58_UTILS_H_
#endif // RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
36 changes: 18 additions & 18 deletions src/ripple/protocol/impl/token_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@

namespace ripple {
enum class TokenCodecErrc {
Success = 0,
InputTooLarge,
InputTooSmall,
BadB58Character,
OutputTooSmall,
MismatchedTokenType,
MismatchedChecksum,
InvalidEncodingChar,
Unknown,
success = 0,
inputTooLarge,
inputTooSmall,
badB58Character,
outputTooSmall,
mismatchedTokenType,
mismatchedChecksum,
invalidEncodingChar,
unknown,
};
}

Expand Down Expand Up @@ -60,23 +60,23 @@ class TokenCodecErrcCategory : public std::error_category
{
switch (static_cast<TokenCodecErrc>(c))
{
case TokenCodecErrc::Success:
case TokenCodecErrc::success:
return "conversion successful";
case TokenCodecErrc::InputTooLarge:
case TokenCodecErrc::inputTooLarge:
return "input too large";
case TokenCodecErrc::InputTooSmall:
case TokenCodecErrc::inputTooSmall:
return "input too small";
case TokenCodecErrc::BadB58Character:
case TokenCodecErrc::badB58Character:
return "bad base 58 character";
case TokenCodecErrc::OutputTooSmall:
case TokenCodecErrc::outputTooSmall:
return "output too small";
case TokenCodecErrc::MismatchedTokenType:
case TokenCodecErrc::mismatchedTokenType:
return "mismatched token type";
case TokenCodecErrc::MismatchedChecksum:
case TokenCodecErrc::mismatchedChecksum:
return "mismatched checksum";
case TokenCodecErrc::InvalidEncodingChar:
case TokenCodecErrc::invalidEncodingChar:
return "invalid encoding char";
case TokenCodecErrc::Unknown:
case TokenCodecErrc::unknown:
return "unknown";
default:
return "unknown";
Expand Down
51 changes: 31 additions & 20 deletions src/ripple/protocol/impl/tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
//
/* The base58 encoding & decoding routines in the b58_ref namespace are taken
* from Bitcoin but have been modified from the original.
*
* Copyright (c) 2014 The Bitcoin Core developers
* Distributed under the MIT software license, see the accompanying
* file COPYING or http://www.opensource.org/licenses/mit-license.php.
*/

#include <ripple/protocol/tokens.h>

Expand Down Expand Up @@ -264,6 +272,8 @@ decodeBase58Token(std::string const& s, TokenType type)
} // namespace b58_ref

#ifndef _MSC_VER
// The algorithms use gcc's int128 (fast MS version will have to wait, in the
// meantime MS falls back to the slow code)
namespace b58_fast {
namespace detail {
B58Result<std::span<std::uint8_t>>
Expand All @@ -274,10 +284,11 @@ b256_to_b58(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
// log(2^(38*8),58^10)) ~= 5.18. So 6 coeff are enough
if (input.size() > 38)
{
return Unexpected(TokenCodecErrc::InputTooLarge);
return Unexpected(TokenCodecErrc::inputTooLarge);
};

auto count_leading_zeros = [&](auto const& col) -> std::size_t {
auto count_leading_zeros =
[](std::span<std::uint8_t const> const& col) -> std::size_t {
std::size_t count = 0;
for (auto const& c : col)
{
Expand All @@ -293,15 +304,14 @@ b256_to_b58(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
auto const input_zeros = count_leading_zeros(input);
input = input.subspan(input_zeros);

std::array<std::uint64_t, 6> base_58_10_coeff{};
std::array<std::uint64_t, 5> base_2_64_coeff_buf{};
std::span<std::uint64_t> const base_2_64_coeff =
[&]() -> std::span<std::uint64_t> {
// convert from input from big endian to native u64, lowest coeff first
// convert input from big endian to native u64, lowest coeff first
std::size_t num_coeff = 0;
for (int i = 0; i < 5; ++i)
for (int i = 0; i < base_2_64_coeff_buf.size(); ++i)
{
if (i * 8 > input.size())
if (i * 8 >= input.size())
{
break;
}
Expand All @@ -328,6 +338,7 @@ b256_to_b58(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
return std::span(base_2_64_coeff_buf.data(), num_coeff);
}();

std::array<std::uint64_t, 6> base_58_10_coeff{};
constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
std::size_t num_58_10_coeffs = 0;
std::size_t cur_2_64_end = base_2_64_coeff.size();
Expand Down Expand Up @@ -360,7 +371,7 @@ b256_to_b58(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
{
continue;
}
auto const b58_be =
std::array<std::uint8_t, 10> const b58_be =
ripple::b58_fast::detail::b58_10_to_b58_be(base_58_10_coeff[i]);
std::size_t to_skip = 0;
std::span<std::uint8_t const> b58_be_s{b58_be.data(), b58_be.size()};
Expand All @@ -370,7 +381,7 @@ b256_to_b58(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
skip_zeros = false;
if (out.size() < (i + 1) * 10 - to_skip)
{
return Unexpected(TokenCodecErrc::OutputTooSmall);
return Unexpected(TokenCodecErrc::outputTooSmall);
}
}
for (auto b58_coeff : b58_be_s.subspan(to_skip))
Expand All @@ -394,11 +405,11 @@ b58_to_b256(std::string_view input, std::span<std::uint8_t> out)
// log(2^(38*8),58) ~= 51.9
if (input.size() > 52)
{
return Unexpected(TokenCodecErrc::InputTooLarge);
return Unexpected(TokenCodecErrc::inputTooLarge);
};
if (out.size() < 8)
{
return Unexpected(TokenCodecErrc::OutputTooSmall);
return Unexpected(TokenCodecErrc::outputTooSmall);
}

auto count_leading_zeros = [&](auto const& col) -> std::size_t {
Expand Down Expand Up @@ -430,7 +441,7 @@ b58_to_b256(std::string_view input, std::span<std::uint8_t> out)
auto cur_val = ::ripple::alphabetReverse[c];
if (cur_val < 0)
{
return Unexpected(TokenCodecErrc::InvalidEncodingChar);
return Unexpected(TokenCodecErrc::invalidEncodingChar);
}
b_58_10_coeff[0] *= 58;
b_58_10_coeff[0] += cur_val;
Expand All @@ -443,7 +454,7 @@ b58_to_b256(std::string_view input, std::span<std::uint8_t> out)
auto cur_val = ::ripple::alphabetReverse[c];
if (cur_val < 0)
{
return Unexpected(TokenCodecErrc::InvalidEncodingChar);
return Unexpected(TokenCodecErrc::invalidEncodingChar);
}
b_58_10_coeff[num_partial_coeffs + j] *= 58;
b_58_10_coeff[num_partial_coeffs + j] += cur_val;
Expand All @@ -458,7 +469,7 @@ b58_to_b256(std::string_view input, std::span<std::uint8_t> out)
std::size_t cur_result_size = 1;
for (int i = 1; i < num_b_58_10_coeffs; ++i)
{
auto c = b_58_10_coeff[i];
std::uint64_t const c = b_58_10_coeff[i];
ripple::b58_fast::detail::inplace_bigint_mul(
std::span(&result[0], cur_result_size + 1), B_58_10);
ripple::b58_fast::detail::inplace_bigint_add(
Expand Down Expand Up @@ -493,7 +504,7 @@ b58_to_b256(std::string_view input, std::span<std::uint8_t> out)
}
if ((cur_out_i + 8 * (cur_result_size - 1)) > out.size())
{
return Unexpected(TokenCodecErrc::OutputTooSmall);
return Unexpected(TokenCodecErrc::outputTooSmall);
}

for (int i = cur_result_size - 2; i >= 0; --i)
Expand All @@ -518,11 +529,11 @@ encodeBase58Token(
std::array<std::uint8_t, tmpBufSize> buf;
if (input.size() > tmpBufSize - 5)
{
return Unexpected(TokenCodecErrc::InputTooLarge);
return Unexpected(TokenCodecErrc::inputTooLarge);
}
if (input.size() == 0)
{
return Unexpected(TokenCodecErrc::InputTooSmall);
return Unexpected(TokenCodecErrc::inputTooSmall);
}
// <type (1 byte)><token (input len)><checksum (4 bytes)>
buf[0] = static_cast<std::uint8_t>(token_type);
Expand Down Expand Up @@ -556,23 +567,23 @@ decodeBase58Token(

// Reject zero length tokens
if (ret.size() < 6)
return Unexpected(TokenCodecErrc::InputTooSmall);
return Unexpected(TokenCodecErrc::inputTooSmall);

// The type must match.
if (type != static_cast<TokenType>(static_cast<std::uint8_t>(ret[0])))
return Unexpected(TokenCodecErrc::MismatchedTokenType);
return Unexpected(TokenCodecErrc::mismatchedTokenType);

// And the checksum must as well.
std::array<std::uint8_t, 4> guard;
checksum(guard.data(), ret.data(), ret.size() - guard.size());
if (!std::equal(guard.rbegin(), guard.rend(), ret.rbegin()))
{
return Unexpected(TokenCodecErrc::MismatchedChecksum);
return Unexpected(TokenCodecErrc::mismatchedChecksum);
}

std::size_t const outSize = ret.size() - 1 - guard.size();
if (outBuf.size() < outSize)
return Unexpected(TokenCodecErrc::OutputTooSmall);
return Unexpected(TokenCodecErrc::outputTooSmall);
// Skip the leading type byte and the trailing checksum.
std::copy(ret.begin() + 1, ret.begin() + outSize + 1, outBuf.begin());
return outBuf.subspan(0, outSize);
Expand Down
2 changes: 1 addition & 1 deletion src/ripple/protocol/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ encodeBase58Token(TokenType type, void const* token, std::size_t size);
decodeBase58Token(std::string const& s, TokenType type);

namespace b58_ref {
// Use the reference version is not using gcc extensions (int128 in particular)
// The reference version does not use gcc extensions (int128 in particular)
[[nodiscard]] std::string
encodeBase58Token(TokenType type, void const* token, std::size_t size);

Expand Down
Loading

0 comments on commit 3c80d53

Please sign in to comment.