diff --git a/CMakeLists.txt b/CMakeLists.txt index e57302a..5b51cac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,7 @@ set_target_properties( ) # secp256k1 -add_library(secp256k1 third_party/secp256k1/src/secp256k1.c) +add_library(secp256k1 STATIC third_party/secp256k1/src/secp256k1.c) if(MSVC) target_link_libraries(secp256k1 PRIVATE gmp) target_compile_definitions(secp256k1 PUBLIC USE_NUM_GMP USE_FIELD_INV_NUM USE_SCALAR_INV_NUM) diff --git a/lib/silkpre/precompile.cpp b/lib/silkpre/precompile.cpp index 6b70581..713c9b5 100644 --- a/lib/silkpre/precompile.cpp +++ b/lib/silkpre/precompile.cpp @@ -14,6 +14,8 @@ limitations under the License. */ +#undef NDEBUG + #include "precompile.h" #include @@ -33,6 +35,10 @@ #include #include +inline void require(bool condition) { + if (!condition) __builtin_trap(); +} + enum { EVMC_ISTANBUL = 7, EVMC_BERLIN = 8, @@ -500,3 +506,53 @@ const SilkpreContract kSilkpreContracts[SILKPRE_NUMBER_OF_ISTANBUL_CONTRACTS] = {silkpre_bn_mul_gas, silkpre_bn_mul_run}, {silkpre_snarkv_gas, silkpre_snarkv_run}, {silkpre_blake2_f_gas, silkpre_blake2_f_run}, }; + +SilkpreResult ethprecompiled_ecrecover(const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size) { + assert(output_size == 32); + auto r = silkpre_ecrec_run(input, input_size); + std::copy_n(r.data, output_size, output); + return {0, r.size}; +} + +SilkpreResult ethprecompiled_sha256(const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size) { + assert(output_size == 32); + silkpre_sha256(output, input, input_size, /*use_cpu_extensions=*/true); + return {0, 32}; +} + +SilkpreResult ethprecompiled_ripemd160(const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size) { + assert(output_size == 32); + std::memset(output, 0, 12); + silkpre_rmd160(&output[12], input, input_size); + return {0, 32}; +} + +SilkpreResult ethprecompiled_expmod(const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size) { + const auto r = silkpre_expmod_run(input, input_size); + assert(output_size == r.size); + std::copy_n(r.data, r.size, output); + std::free(r.data); + return {0, r.size}; +} + +SilkpreResult ethprecompiled_ecmul(const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size) { + const auto r = silkpre_bn_mul_run(input, input_size); + if (r.data == nullptr) return {1, 0}; // Error. + + assert(r.size == 64); + assert(output_size == 64); + std::copy_n(r.data, r.size, output); + std::free(r.data); + return {0, r.size}; +} + +SilkpreResult ethprecompiled_blake2bf(const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size) { + const auto r = silkpre_blake2_f_run(input, input_size); + if (r.data == nullptr) return {1, 0}; // Error. + + assert(r.size == 64); + assert(output_size == 64); + std::copy_n(r.data, r.size, output); + std::free(r.data); + return {0, r.size}; +} diff --git a/lib/silkpre/precompile.h b/lib/silkpre/precompile.h index 692b0e3..b29e05d 100644 --- a/lib/silkpre/precompile.h +++ b/lib/silkpre/precompile.h @@ -17,6 +17,8 @@ #ifndef SILKPRE_PRECOMPILE_H_ #define SILKPRE_PRECOMPILE_H_ +#define EXPORT __attribute__((visibility("default"))) + #include #include @@ -45,8 +47,8 @@ typedef struct SilkpreContract { SilkpreRunFunction run; } SilkpreContract; -uint64_t silkpre_ecrec_gas(const uint8_t* input, size_t len, int evmc_revision); -SilkpreOutput silkpre_ecrec_run(const uint8_t* input, size_t len); +EXPORT uint64_t silkpre_ecrec_gas(const uint8_t* input, size_t len, int evmc_revision); +EXPORT SilkpreOutput silkpre_ecrec_run(const uint8_t* input, size_t len); uint64_t silkpre_sha256_gas(const uint8_t* input, size_t len, int evmc_revision); SilkpreOutput silkpre_sha256_run(const uint8_t* input, size_t len); @@ -78,7 +80,24 @@ SilkpreOutput silkpre_snarkv_run(const uint8_t* input, size_t len); uint64_t silkpre_blake2_f_gas(const uint8_t* input, size_t len, int evmc_revision); SilkpreOutput silkpre_blake2_f_run(const uint8_t* input, size_t len); -extern const SilkpreContract kSilkpreContracts[SILKPRE_NUMBER_OF_ISTANBUL_CONTRACTS]; +EXPORT extern const SilkpreContract kSilkpreContracts[SILKPRE_NUMBER_OF_ISTANBUL_CONTRACTS]; + +struct SilkpreResult { + int status_code; + size_t output_size; +}; + +EXPORT SilkpreResult ethprecompiled_ecrecover(const uint8_t* input, size_t input_size, uint8_t* output, + size_t output_size); +EXPORT SilkpreResult ethprecompiled_sha256(const uint8_t* input, size_t input_size, uint8_t* output, + size_t output_size); +EXPORT SilkpreResult ethprecompiled_ripemd160(const uint8_t* input, size_t input_size, uint8_t* output, + size_t output_size); +EXPORT SilkpreResult ethprecompiled_expmod(const uint8_t* input, size_t input_size, uint8_t* output, + size_t output_size); +EXPORT SilkpreResult ethprecompiled_ecmul(const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size); +EXPORT SilkpreResult ethprecompiled_blake2bf(const uint8_t* input, size_t input_size, uint8_t* output, + size_t output_size); #if defined(__cplusplus) }