diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index bf65c20..6bb8d67 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -14,8 +14,8 @@ limitations under the License. ]] -find_package(ethash CONFIG REQUIRED) -find_package(intx CONFIG REQUIRED) +#find_package(ethash CONFIG REQUIRED) +#find_package(intx CONFIG REQUIRED) add_library(silkpre silkpre/blake2b.c diff --git a/lib/silkpre/precompile.cpp b/lib/silkpre/precompile.cpp index a508de4..4d52800 100644 --- a/lib/silkpre/precompile.cpp +++ b/lib/silkpre/precompile.cpp @@ -19,9 +19,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -50,8 +52,13 @@ uint64_t silkpre_ecrec_gas(const uint8_t*, size_t, int) { return 3'000; } SilkpreOutput silkpre_ecrec_run(const uint8_t* input, size_t len) { uint8_t* out{static_cast(std::malloc(32))}; - std::basic_string d(input, len); - right_pad(d, 128); + std::basic_string_view d{input, len}; + uint8_t d_pad[128]; + if (INTX_UNLIKELY(len < 128)) { + std::memcpy(d_pad, input, len); + std::memset(d_pad + len, '\0', 128 - len); + d = {d_pad, 128}; + } const auto v{intx::be::unsafe::load(&d[32])}; const auto r{intx::be::unsafe::load(&d[64])}; @@ -67,7 +74,7 @@ SilkpreOutput silkpre_ecrec_run(const uint8_t* input, size_t len) { } std::memset(out, 0, 12); - static secp256k1_context* context{secp256k1_context_create(SILKPRE_SECP256K1_CONTEXT_FLAGS)}; + thread_local secp256k1_context* context{secp256k1_context_create(SILKPRE_SECP256K1_CONTEXT_FLAGS)}; if (!silkpre_recover_address(out + 12, &d[0], &d[64], v != 27, context)) { return {out, 0}; } @@ -118,8 +125,13 @@ static intx::uint256 mult_complexity_eip2565(const intx::uint256& max_length) no uint64_t silkpre_expmod_gas(const uint8_t* ptr, size_t len, int rev) { const uint64_t min_gas{rev < EVMC_BERLIN ? 0 : 200u}; - std::basic_string input(ptr, len); - right_pad(input, 3 * 32); + std::basic_string_view input{ptr, len}; + uint8_t input_pad[96]; + if (INTX_UNLIKELY(len < 96)) { + std::memcpy(input_pad, ptr, len); + std::memset(input_pad + len, '\0', 96 - len); + input = {input_pad, 96}; + } intx::uint256 base_len256{intx::be::unsafe::load(&input[0])}; intx::uint256 exp_len256{intx::be::unsafe::load(&input[32])}; @@ -137,15 +149,20 @@ uint64_t silkpre_expmod_gas(const uint8_t* ptr, size_t len, int rev) { uint64_t base_len64{static_cast(base_len256)}; uint64_t exp_len64{static_cast(exp_len256)}; - input.erase(0, 3 * 32); + input.remove_prefix(96); - intx::uint256 exp_head{0}; // first 32 bytes of the exponent - if (input.length() > base_len64) { - input.erase(0, base_len64); - right_pad(input, 3 * 32); + intx::uint256 exp_head{0}; // first 32 bytes of the exponent + if (input.length() > base_len64) { // input cannot be input_pad + input.remove_prefix(base_len64); + if (INTX_UNLIKELY(input.size() < 32)) { + std::memcpy(input_pad, input.data(), input.size()); + std::memset(input_pad + input.size(), '\0', 32 - input.size()); + input = {input_pad, 32}; + } if (exp_len64 < 32) { - input.erase(exp_len64); - input.insert(0, 32 - exp_len64, '\0'); + std::memset(input_pad, '\0', 32 - exp_len64); + std::memmove(input_pad + (32 - exp_len64), input.data(), exp_len64); + input = {input_pad, 32}; } exp_head = intx::be::unsafe::load(input.data()); } @@ -341,9 +358,10 @@ static std::optional decode_g2_element(const uint8_t bytes_ return point; } -static std::basic_string encode_g1_element(libff::alt_bn128_G1 p) noexcept { - std::basic_string out(64, '\0'); +static std::array encode_g1_element(libff::alt_bn128_G1 p) noexcept { + std::array out; if (p.is_zero()) { + out.fill('\0'); return out; } @@ -364,9 +382,14 @@ static std::basic_string encode_g1_element(libff::alt_bn128_G1 p) noexc uint64_t silkpre_bn_add_gas(const uint8_t*, size_t, int rev) { return rev >= EVMC_ISTANBUL ? 150 : 500; } -SilkpreOutput silkpre_bn_add_run(const uint8_t* ptr, size_t len) { - std::basic_string input(ptr, len); - right_pad(input, 128); +SilkpreOutput silkpre_bn_add_run(const uint8_t* const ptr, const size_t len) { + std::basic_string_view input{ptr, len}; + uint8_t input_pad[128]; + if (INTX_UNLIKELY(len < 128)) { + std::memcpy(input_pad, ptr, len); + std::memset(input_pad + len, '\0', 128 - len); + input = {input_pad, 128}; + } init_libff(); @@ -381,18 +404,23 @@ SilkpreOutput silkpre_bn_add_run(const uint8_t* ptr, size_t len) { } libff::alt_bn128_G1 sum{*x + *y}; - const std::basic_string res{encode_g1_element(sum)}; + const auto res{encode_g1_element(sum)}; - uint8_t* out{static_cast(std::malloc(res.length()))}; - std::memcpy(out, res.data(), res.length()); - return {out, res.length()}; + uint8_t* out{static_cast(std::malloc(res.size()))}; + std::memcpy(out, res.data(), res.size()); + return {out, res.size()}; } uint64_t silkpre_bn_mul_gas(const uint8_t*, size_t, int rev) { return rev >= EVMC_ISTANBUL ? 6'000 : 40'000; } -SilkpreOutput silkpre_bn_mul_run(const uint8_t* ptr, size_t len) { - std::basic_string input(ptr, len); - right_pad(input, 96); +SilkpreOutput silkpre_bn_mul_run(const uint8_t* const ptr, const size_t len) { + std::basic_string_view input{ptr, len}; + uint8_t input_pad[96]; + if (INTX_UNLIKELY(len < 96)) { + std::memcpy(input_pad, ptr, len); + std::memset(input_pad + len, '\0', 96 - len); + input = {input_pad, 96}; + } init_libff(); @@ -404,11 +432,11 @@ SilkpreOutput silkpre_bn_mul_run(const uint8_t* ptr, size_t len) { Scalar n{to_scalar(&input[64])}; libff::alt_bn128_G1 product{n * *x}; - const std::basic_string res{encode_g1_element(product)}; + const auto res{encode_g1_element(product)}; - uint8_t* out{static_cast(std::malloc(res.length()))}; - std::memcpy(out, res.data(), res.length()); - return {out, res.length()}; + uint8_t* out{static_cast(std::malloc(res.size()))}; + std::memcpy(out, res.data(), res.size()); + return {out, res.size()}; } static constexpr size_t kSnarkvStride{192}; diff --git a/test/hex.cpp b/test/hex.cpp index e14d9bd..3bf9d75 100644 --- a/test/hex.cpp +++ b/test/hex.cpp @@ -17,6 +17,7 @@ #include "hex.hpp" #include +#include std::string to_hex(const uint8_t* bytes, size_t len) { static const char* kHexDigits{"0123456789abcdef"};