Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.1] Changes need to crypto-primitives host functions #498

Merged
merged 11 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions libraries/chain/include/eosio/chain/webassembly/error_codes.hpp

This file was deleted.

24 changes: 12 additions & 12 deletions libraries/chain/include/eosio/chain/webassembly/interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <eosio/chain/types.hpp>
#include <eosio/chain/webassembly/common.hpp>
#include <eosio/chain/webassembly/return_codes.hpp>
#include <fc/crypto/sha1.hpp>
#include <boost/hana/string.hpp>

Expand Down Expand Up @@ -1706,7 +1707,7 @@ namespace webassembly {
* @param op1 - a span containing the first operand G1 point.
* @param op2 - a span containing the second operand G1 point.
* @param[out] result - the result op1 + op2.
* @return 1 if there was an error 0 otherwise
* @return -1 if there was an error 0 otherwise
*/
int32_t alt_bn128_add(span<const char> op1, span<const char> op2, span<char> result) const;

Expand All @@ -1717,7 +1718,7 @@ namespace webassembly {
* @param g1_point - a span containing G1 point.
* @param scalar - a span containing the scalar.
* @param[out] result - g1 * scalar.
* @return 1 if there was an error 0 otherwise
* @return -1 if there was an error 0 otherwise
*/
int32_t alt_bn128_mul(span<const char> g1_point, span<const char> scalar, span<char> result) const;

Expand All @@ -1726,10 +1727,9 @@ namespace webassembly {
*
* @ingroup crypto
* @param g1_g2_pairs - a span containing pairs of G1,G2 points. (2 * 32 bytes) + (2 * 64 bytes)
* @param[out] result - true if pairing evaluates to 1, false otherwise
* @return 1 if there was an error 0 otherwise
* @return -1 if there was an error, 1 if false and 0 if true
*/
int32_t alt_bn128_pair(span<const char> g1_g2_pairs, bool* result) const;
int32_t alt_bn128_pair(span<const char> g1_g2_pairs) const;

/**
* Big integer modular exponentiation
Expand All @@ -1742,7 +1742,7 @@ namespace webassembly {
* @param exp - a span containing EXPONENT.
* @param modulus - a span containing MODULUS.
* @param[out] out - the result (BASE**EXPONENT) % MODULUS
* @return 1 if there was an error 0 otherwise
* @return -1 if there was an error 0 otherwise
*/
int32_t mod_exp(span<const char> base, span<const char> exp, span<const char> modulus, span<char> out) const;

Expand All @@ -1757,21 +1757,21 @@ namespace webassembly {
* @param message - a span containing the message block vector - 16 unsigned 64-bit little-endian words
* @param t0_offset - offset counters - unsigned 64-bit little-endian word
* @param t1_offset - offset counters - unsigned 64-bit little-endian word
* @param final - the final block indicator flag - 8-bit word
* @param final - the final block indicator flag - (1-true, all other values == false)
* @param[out] result - the result
* @return 1 if there was an error 0 otherwise
* @return -1 if there was an error 0 otherwise
*/
int32_t blake2_f( uint32_t rounds, span<const char> state, span<const char> message, span<const char> t0_offset, span<const char> t1_offset, bool final, span<char> result) const;
int32_t blake2_f( uint32_t rounds, span<const char> state, span<const char> message, span<const char> t0_offset, span<const char> t1_offset, int32_t final, span<char> result) const;

/**
* Hashes data using SHA3.
*
* @ingroup crypto
* @param data - a span containing the data.
* @param[out] hash_val - the resulting digest.
* @param keccak - use keccak version.
* @param keccak - use keccak version (1-true, all other values == false).
*/
void sha3( span<const char> data, span<char> hash_val, bool keccak) const;
void sha3( span<const char> data, span<char> hash_val, int32_t keccak) const;

/**
* Calculates the uncompressed public key used for a given signature on a given digest.
Expand All @@ -1781,7 +1781,7 @@ namespace webassembly {
* @param digest - digest of the message that was signed.
* @param[out] pub - output buffer for the public key result.
*
* @return 1 if there was an error 0 otherwise.
* @return -1 if there was an error 0 otherwise.
*/
int32_t k1_recover( span<const char> signature, span<const char> digest, span<char> pub) const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ namespace eosio { namespace chain { namespace webassembly {

template <typename T>
struct is_whitelisted_type {
static constexpr bool value = is_wasm_arithmetic_type_v<T> ||
std::is_same_v<name, T>;
static constexpr bool value = (is_wasm_arithmetic_type_v<T> || std::is_same_v<name, T>) &&
!(std::is_pointer_v<T> || std::is_reference_v<T>);
};
template <typename T>
struct is_whitelisted_type<vm::span<T>> {
Expand Down
11 changes: 11 additions & 0 deletions libraries/chain/include/eosio/chain/webassembly/return_codes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once


namespace eosio::chain::webassembly {

enum return_code : int32_t {
failure = -1,
success = 0,
};

} // ns eosio::chain::webassembly
4 changes: 2 additions & 2 deletions libraries/chain/protocol_feature_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,12 @@ Enables new `get_code_hash` intrinsic which gets the current code hash of an acc
} )
( builtin_protocol_feature_t::crypto_primitives, builtin_protocol_feature_spec{
"CRYPTO_PRIMITIVES",
fc::variant("7d9d4e4365f803e5d5fd2e2bd792026b3995765b4a833f32f8c09d66bd94c705").as<digest_type>(),
fc::variant("68d6405cb8df3de95bd834ebb408196578500a9f818ff62ccc68f60b932f7d82").as<digest_type>(),
// SHA256 hash of the raw message below within the comment delimiters (do not modify message below).
/*
Builtin protocol feature: CRYPTO_PRIMITIVES

Adds new crypto host functions
Adds new cryptographic host functions
- Big integer modular exponentiation (mod_exp)
- Add, multiply, and pairing check functions for the alt_bn128 elliptic curve. (alt_bn128_add, alt_bn128_mul, alt_bn128_pair)
- BLAKE2b F compression function (blake2_f)
Expand Down
64 changes: 26 additions & 38 deletions libraries/chain/webassembly/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <eosio/chain/protocol_state_object.hpp>
#include <eosio/chain/transaction_context.hpp>
#include <eosio/chain/apply_context.hpp>
#include <eosio/chain/webassembly/error_codes.hpp>
#include <fc/crypto/alt_bn128.hpp>
#include <fc/crypto/modular_arithmetic.hpp>
#include <fc/crypto/blake2.hpp>
Expand Down Expand Up @@ -108,116 +107,107 @@ namespace eosio { namespace chain { namespace webassembly {
}

int32_t interface::alt_bn128_add(span<const char> op1, span<const char> op2, span<char> result ) const {
using error_code = eosio::chain::webassembly::error_codes::crypto;

bytes bop1(op1.data(), op1.data() + op1.size());
bytes bop2(op2.data(), op2.data() + op2.size());

auto maybe_err = fc::alt_bn128_add(bop1, bop2);
if(std::holds_alternative<fc::alt_bn128_error>(maybe_err)) {
return error_code::fail;
return return_code::failure;
}

const auto& res = std::get<bytes>(maybe_err);

if( result.size() < res.size() )
return error_code::fail;
return return_code::failure;

std::memcpy( result.data(), res.data(), res.size() );
return error_code::none;
return return_code::success;
}

int32_t interface::alt_bn128_mul(span<const char> g1_point, span<const char> scalar, span<char> result) const {
using error_code = eosio::chain::webassembly::error_codes::crypto;

bytes bg1_point(g1_point.data(), g1_point.data() + g1_point.size());
bytes bscalar(scalar.data(), scalar.data() + scalar.size());

auto maybe_err = fc::alt_bn128_mul(bg1_point, bscalar);
if(std::holds_alternative<fc::alt_bn128_error>(maybe_err)) {
return error_code::fail;
return return_code::failure;
}

const auto& res = std::get<bytes>(maybe_err);

if( result.size() < res.size() )
return error_code::fail;
return return_code::failure;

std::memcpy( result.data(), res.data(), res.size() );
return error_code::none;
return return_code::success;
}

int32_t interface::alt_bn128_pair(span<const char> g1_g2_pairs, bool* result) const {
using error_code = eosio::chain::webassembly::error_codes::crypto;

int32_t interface::alt_bn128_pair(span<const char> g1_g2_pairs) const {
bytes bg1_g2_pairs(g1_g2_pairs.data(), g1_g2_pairs.data() + g1_g2_pairs.size());

auto checktime = [this]() { context.trx_context.checktime(); };
auto maybe_err = fc::alt_bn128_pair(bg1_g2_pairs, checktime);
if(std::holds_alternative<fc::alt_bn128_error>(maybe_err)) {
return error_code::fail;
auto res = fc::alt_bn128_pair(bg1_g2_pairs, checktime);
if(std::holds_alternative<fc::alt_bn128_error>(res)) {
return return_code::failure;
}

*result = std::get<bool>(maybe_err);
return error_code::none;
return !std::get<bool>(res);
}

int32_t interface::mod_exp(span<const char> base,
span<const char> exp,
span<const char> modulus,
span<char> out) const {
using error_code = eosio::chain::webassembly::error_codes::crypto;

bytes bbase(base.data(), base.data() + base.size());
bytes bexp(exp.data(), exp.data() + exp.size());
bytes bmod(modulus.data(), modulus.data() + modulus.size());

auto maybe_err = fc::modexp(bbase, bexp, bmod);
if(std::holds_alternative<fc::modular_arithmetic_error>(maybe_err)) {
return error_code::fail;
return return_code::failure;
}

const auto& res = std::get<bytes>(maybe_err);

if( out.size() < res.size() )
return error_code::fail;
return return_code::failure;

std::memcpy( out.data(), res.data(), res.size() );
return error_code::none;
return return_code::success;
}

int32_t interface::blake2_f( uint32_t rounds,
span<const char> state,
span<const char> message,
span<const char> t0_offset,
span<const char> t1_offset,
bool final,
int32_t final,
span<char> out) const {

using error_code = eosio::chain::webassembly::error_codes::crypto;

bool _final = final == 1;
bytes bstate(state.data(), state.data() + state.size());
bytes bmessage(message.data(), message.data() + message.size());
bytes bt0_offset(t0_offset.data(), t0_offset.data() + t0_offset.size());
bytes bt1_offset(t1_offset.data(), t1_offset.data() + t1_offset.size());

auto checktime = [this]() { context.trx_context.checktime(); };

auto maybe_err = fc::blake2b(rounds, bstate, bmessage, bt0_offset, bt1_offset, final, checktime);
auto maybe_err = fc::blake2b(rounds, bstate, bmessage, bt0_offset, bt1_offset, _final, checktime);
if(std::holds_alternative<fc::blake2b_error>(maybe_err)) {
return error_code::fail;
return return_code::failure;
}

const auto& res = std::get<bytes>(maybe_err);

if( out.size() < res.size() )
return error_code::fail;
return return_code::failure;

std::memcpy( out.data(), res.data(), res.size() );
return error_code::none;
return return_code::success;
}

void interface::sha3( span<const char> input, span<char> output, bool keccak ) const {
void interface::sha3( span<const char> input, span<char> output, int32_t keccak ) const {
bool _keccak = keccak == 1;
const size_t bs = eosio::chain::config::hashing_checktime_block_size;
const char* data = input.data();
uint32_t datalen = input.size();
Expand All @@ -229,30 +219,28 @@ namespace eosio { namespace chain { namespace webassembly {
context.trx_context.checktime();
}
enc.write( data, datalen);
auto res = enc.result(!keccak);
auto res = enc.result(!_keccak);

auto copy_size = std::min( output.size(), res.data_size() );
std::memcpy( output.data(), res.data(), copy_size );
}

int32_t interface::k1_recover( span<const char> signature, span<const char> digest, span<char> pub) const {
using error_code = eosio::chain::webassembly::error_codes::crypto;

bytes bsignature(signature.data(), signature.data() + signature.size());
bytes bdigest(digest.data(), digest.data() + digest.size());

auto maybe_err = fc::k1_recover(bsignature, bdigest);
if( std::holds_alternative<fc::k1_recover_error>(maybe_err)) {
return error_code::fail;
return return_code::failure;
}

const auto& res = std::get<bytes>(maybe_err);

if( pub.size() < res.size() )
return error_code::fail;
return return_code::failure;

std::memcpy( pub.data(), res.data(), res.size() );
return error_code::none;
return return_code::success;
}

}}} // ns eosio::chain::webassembly
2 changes: 1 addition & 1 deletion tests/plugin_http_api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def test_ChainApi(self) :
"c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071",
"e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526",
"f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d",
"02960778343add9a58245a63a9fae9693d007794d06feaa5be7bae1d4b5d9b29",
"6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc",
"35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b",
]

Expand Down
Loading