Skip to content

Commit

Permalink
Merge pull request #498 from eosnetworkfoundation/larryk85/crypto-pri…
Browse files Browse the repository at this point in the history
…mitive-changes

Changes need to crypto-primitives host functions
  • Loading branch information
Bucky Kittinger authored Jun 22, 2022
2 parents f0bd4e0 + 6949e8f commit 4a4f589
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 160 deletions.
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

0 comments on commit 4a4f589

Please sign in to comment.