Add opcode for ecrecover

This commit is contained in:
Tino Breddin 2019-08-13 16:41:02 +02:00
parent b669d2df1e
commit b0e07ef4e7
4 changed files with 36 additions and 24 deletions

View File

@ -460,7 +460,8 @@ global_env() ->
%% Crypto/Curve operations %% Crypto/Curve operations
CryptoScope = #scope CryptoScope = #scope
{ funs = MkDefs( { funs = MkDefs(
[{"ecverify", Fun([Hash, Address, SignId], Bool)}, [{"ecrecover_secp256k1", Fun([Hash, Bytes(64)], Hash)},
{"ecverify", Fun([Hash, Address, SignId], Bool)},
{"ecverify_secp256k1", Fun([Hash, Bytes(64), Bytes(64)], Bool)}, {"ecverify_secp256k1", Fun([Hash, Bytes(64), Bytes(64)], Bool)},
{"sha3", Fun1(A, Hash)}, {"sha3", Fun1(A, Hash)},
{"sha256", Fun1(A, Hash)}, {"sha256", Fun1(A, Hash)},

View File

@ -33,7 +33,8 @@
string_concat | bits_set | bits_clear | bits_test | bits_sum | string_concat | bits_set | bits_clear | bits_test | bits_sum |
bits_intersection | bits_union | bits_difference | bits_intersection | bits_union | bits_difference |
contract_to_address | crypto_ecverify | crypto_ecverify_secp256k1 | contract_to_address | crypto_ecverify | crypto_ecverify_secp256k1 |
crypto_sha3 | crypto_sha256 | crypto_blake2b. crypto_sha3 | crypto_sha256 | crypto_blake2b |
crypto_ecrecover_secp256k1.
-type flit() :: {int, integer()} -type flit() :: {int, integer()}
| {string, binary()} | {string, binary()}
@ -187,8 +188,8 @@ builtins() ->
{"revoke", 3}]}, {"revoke", 3}]},
{["Map"], [{"from_list", 1}, {"to_list", 1}, {"lookup", 2}, {["Map"], [{"from_list", 1}, {"to_list", 1}, {"lookup", 2},
{"lookup_default", 3}, {"delete", 2}, {"member", 2}, {"size", 1}]}, {"lookup_default", 3}, {"delete", 2}, {"member", 2}, {"size", 1}]},
{["Crypto"], [{"ecverify", 3}, {"ecverify_secp256k1", 3}, {"sha3", 1}, {["Crypto"], [{"ecrecover_secp256k1", 2}, {"ecverify", 3}, {"ecverify_secp256k1", 3},
{"sha256", 1}, {"blake2b", 1}]}, {"sha3", 1}, {"sha256", 1}, {"blake2b", 1}]},
{["Auth"], [{"tx_hash", none}]}, {["Auth"], [{"tx_hash", none}]},
{["String"], [{"length", 1}, {"concat", 2}, {"sha3", 1}, {"sha256", 1}, {"blake2b", 1}]}, {["String"], [{"length", 1}, {"concat", 2}, {"sha3", 1}, {"sha256", 1}, {"blake2b", 1}]},
{["Bits"], [{"set", 2}, {"clear", 2}, {"test", 2}, {"sum", 1}, {"intersection", 2}, {["Bits"], [{"set", 2}, {"clear", 2}, {"test", 2}, {"sum", 1}, {"intersection", 2},
@ -818,7 +819,9 @@ op_builtins() ->
string_length, string_concat, string_sha3, string_sha256, string_blake2b, string_length, string_concat, string_sha3, string_sha256, string_blake2b,
bits_set, bits_clear, bits_test, bits_sum, bits_intersection, bits_union, bits_set, bits_clear, bits_test, bits_sum, bits_intersection, bits_union,
bits_difference, int_to_str, address_to_str, crypto_ecverify, bits_difference, int_to_str, address_to_str, crypto_ecverify,
crypto_ecverify_secp256k1, crypto_sha3, crypto_sha256, crypto_blake2b]. crypto_ecverify_secp256k1, crypto_sha3, crypto_sha256, crypto_blake2b,
crypto_ecrecover_secp256k1
].
builtin_to_fcode(require, [Cond, Msg]) -> builtin_to_fcode(require, [Cond, Msg]) ->
make_if(Cond, {tuple, []}, {builtin, abort, [Msg]}); make_if(Cond, {tuple, []}, {builtin, abort, [Msg]});

View File

@ -350,6 +350,11 @@ ast_body({map, Ann, Map, [Upd | Upds]}, Icode) ->
ast_body({map, Ann, {map, Ann, Map, [Upd]}, Upds}, Icode); ast_body({map, Ann, {map, Ann, Map, [Upd]}, Upds}, Icode);
%% Crypto %% Crypto
ast_body(?qid_app(["Crypto", "ecrecover_secp256k1"], [Msg, Sig], _, _), Icode) ->
prim_call(?PRIM_CALL_CRYPTO_ECRECOVER_SECP256K1, #integer{value = 0},
[ast_body(Msg, Icode), ast_body(Sig, Icode)],
[word, sign_t()], word);
ast_body(?qid_app(["Crypto", "ecverify"], [Msg, PK, Sig], _, _), Icode) -> ast_body(?qid_app(["Crypto", "ecverify"], [Msg, PK, Sig], _, _), Icode) ->
prim_call(?PRIM_CALL_CRYPTO_ECVERIFY, #integer{value = 0}, prim_call(?PRIM_CALL_CRYPTO_ECVERIFY, #integer{value = 0},
[ast_body(Msg, Icode), ast_body(PK, Icode), ast_body(Sig, Icode)], [ast_body(Msg, Icode), ast_body(PK, Icode), ast_body(Sig, Icode)],

View File

@ -98,17 +98,18 @@
Op =:= 'SHA3' orelse Op =:= 'SHA3' orelse
Op =:= 'SHA256' orelse Op =:= 'SHA256' orelse
Op =:= 'BLAKE2B' orelse Op =:= 'BLAKE2B' orelse
Op =:= 'ECVERIFY' orelse Op =:= 'ECRECOVER_SECP256K1' orelse
Op =:= 'ECVERIFY_SECP256K1' orelse Op =:= 'ECVERIFY' orelse
Op =:= 'ECVERIFY_SECP256K1' orelse
Op =:= 'CONTRACT_TO_ADDRESS' orelse Op =:= 'CONTRACT_TO_ADDRESS' orelse
Op =:= 'AUTH_TX_HASH' orelse Op =:= 'AUTH_TX_HASH' orelse
Op =:= 'BYTES_TO_INT' orelse Op =:= 'BYTES_TO_INT' orelse
Op =:= 'BYTES_TO_STR' orelse Op =:= 'BYTES_TO_STR' orelse
Op =:= 'ORACLE_CHECK' orelse Op =:= 'ORACLE_CHECK' orelse
Op =:= 'ORACLE_CHECK_QUERY' orelse Op =:= 'ORACLE_CHECK_QUERY' orelse
Op =:= 'IS_ORACLE' orelse Op =:= 'IS_ORACLE' orelse
Op =:= 'IS_CONTRACT' orelse Op =:= 'IS_CONTRACT' orelse
Op =:= 'CREATOR' orelse Op =:= 'CREATOR' orelse
false)). false)).
-record(env, { contract, vars = [], locals = [], tailpos = true }). -record(env, { contract, vars = [], locals = [], tailpos = true }).
@ -591,15 +592,16 @@ op_to_scode(bits_union) -> aeb_fate_ops:bits_or(?a, ?a, ?a);
op_to_scode(bits_difference) -> aeb_fate_ops:bits_diff(?a, ?a, ?a); op_to_scode(bits_difference) -> aeb_fate_ops:bits_diff(?a, ?a, ?a);
op_to_scode(address_to_str) -> aeb_fate_ops:addr_to_str(?a, ?a); op_to_scode(address_to_str) -> aeb_fate_ops:addr_to_str(?a, ?a);
op_to_scode(int_to_str) -> aeb_fate_ops:int_to_str(?a, ?a); op_to_scode(int_to_str) -> aeb_fate_ops:int_to_str(?a, ?a);
op_to_scode(contract_to_address) -> aeb_fate_ops:contract_to_address(?a, ?a); op_to_scode(contract_to_address) -> aeb_fate_ops:contract_to_address(?a, ?a);
op_to_scode(crypto_ecverify) -> aeb_fate_ops:ecverify(?a, ?a, ?a, ?a); op_to_scode(crypto_ecrecover_secp256k1) -> aeb_fate_ops:ecrecover_secp256k1(?a, ?a, ?a);
op_to_scode(crypto_ecverify_secp256k1) -> aeb_fate_ops:ecverify_secp256k1(?a, ?a, ?a, ?a); op_to_scode(crypto_ecverify) -> aeb_fate_ops:ecverify(?a, ?a, ?a, ?a);
op_to_scode(crypto_sha3) -> aeb_fate_ops:sha3(?a, ?a); op_to_scode(crypto_ecverify_secp256k1) -> aeb_fate_ops:ecverify_secp256k1(?a, ?a, ?a, ?a);
op_to_scode(crypto_sha256) -> aeb_fate_ops:sha256(?a, ?a); op_to_scode(crypto_sha3) -> aeb_fate_ops:sha3(?a, ?a);
op_to_scode(crypto_blake2b) -> aeb_fate_ops:blake2b(?a, ?a); op_to_scode(crypto_sha256) -> aeb_fate_ops:sha256(?a, ?a);
op_to_scode(string_sha3) -> aeb_fate_ops:sha3(?a, ?a); op_to_scode(crypto_blake2b) -> aeb_fate_ops:blake2b(?a, ?a);
op_to_scode(string_sha256) -> aeb_fate_ops:sha256(?a, ?a); op_to_scode(string_sha3) -> aeb_fate_ops:sha3(?a, ?a);
op_to_scode(string_blake2b) -> aeb_fate_ops:blake2b(?a, ?a). op_to_scode(string_sha256) -> aeb_fate_ops:sha256(?a, ?a);
op_to_scode(string_blake2b) -> aeb_fate_ops:blake2b(?a, ?a).
%% PUSH and STORE ?a are the same, so we use STORE to make optimizations %% PUSH and STORE ?a are the same, so we use STORE to make optimizations
%% easier, and specialize to PUSH (which is cheaper) at the end. %% easier, and specialize to PUSH (which is cheaper) at the end.
@ -819,6 +821,7 @@ attributes(I) ->
{'SHA3', A, B} -> Pure(A, [B]); {'SHA3', A, B} -> Pure(A, [B]);
{'SHA256', A, B} -> Pure(A, [B]); {'SHA256', A, B} -> Pure(A, [B]);
{'BLAKE2B', A, B} -> Pure(A, [B]); {'BLAKE2B', A, B} -> Pure(A, [B]);
{'ECRECOVER_SECP256K1', A, B, C} -> Pure(A, [B, C]);
{'ECVERIFY', A, B, C, D} -> Pure(A, [B, C, D]); {'ECVERIFY', A, B, C, D} -> Pure(A, [B, C, D]);
{'ECVERIFY_SECP256K1', A, B, C, D} -> Pure(A, [B, C, D]); {'ECVERIFY_SECP256K1', A, B, C, D} -> Pure(A, [B, C, D]);
{'CONTRACT_TO_ADDRESS', A, B} -> Pure(A, [B]); {'CONTRACT_TO_ADDRESS', A, B} -> Pure(A, [B]);