diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index e640c49..6993768 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -460,9 +460,10 @@ global_env() -> %% Crypto/Curve operations CryptoScope = #scope { funs = MkDefs( - [{"ecrecover_secp256k1", Fun([Hash, Bytes(65)], Hash)}, - {"ecverify", Fun([Hash, Address, SignId], Bool)}, - {"ecverify_secp256k1", Fun([Hash, Bytes(64), Bytes(64)], Bool)}, + [{"verify_sig", Fun([Hash, Address, SignId], Bool)}, + {"verify_sig_secp256k1", Fun([Hash, Bytes(64), SignId], Bool)}, + {"ecverify_secp256k1", Fun([Hash, Bytes(20), Bytes(65)], Bool)}, + {"ecrecover_secp256k1", Fun([Hash, Bytes(65)], Option(Bytes(20)))}, {"sha3", Fun1(A, Hash)}, {"sha256", Fun1(A, Hash)}, {"blake2b", Fun1(A, Hash)}]) }, diff --git a/src/aeso_ast_to_fcode.erl b/src/aeso_ast_to_fcode.erl index 91c4dcb..a916d4f 100644 --- a/src/aeso_ast_to_fcode.erl +++ b/src/aeso_ast_to_fcode.erl @@ -32,9 +32,9 @@ map_delete | map_member | map_size | string_length | string_concat | bits_set | bits_clear | bits_test | bits_sum | bits_intersection | bits_union | bits_difference | - contract_to_address | crypto_ecverify | crypto_ecverify_secp256k1 | + contract_to_address | crypto_verify_sig | crypto_verify_sig_secp256k1 | crypto_sha3 | crypto_sha256 | crypto_blake2b | - crypto_ecrecover_secp256k1. + crypto_ecverify_secp256k1 | crypto_ecrecover_secp256k1. -type flit() :: {int, integer()} | {string, binary()} @@ -189,7 +189,8 @@ builtins() -> {"revoke", 3}]}, {["Map"], [{"from_list", 1}, {"to_list", 1}, {"lookup", 2}, {"lookup_default", 3}, {"delete", 2}, {"member", 2}, {"size", 1}]}, - {["Crypto"], [{"ecrecover_secp256k1", 2}, {"ecverify", 3}, {"ecverify_secp256k1", 3}, + {["Crypto"], [{"verify_sig", 3}, {"verify_sig_secp256k1", 3}, + {"ecverify_secp256k1", 3}, {"ecrecover_secp256k1", 2}, {"sha3", 1}, {"sha256", 1}, {"blake2b", 1}]}, {["Auth"], [{"tx_hash", none}]}, {["String"], [{"length", 1}, {"concat", 2}, {"sha3", 1}, {"sha256", 1}, {"blake2b", 1}]}, @@ -822,9 +823,9 @@ op_builtins() -> [map_from_list, map_to_list, map_delete, map_member, map_size, string_length, string_concat, string_sha3, string_sha256, string_blake2b, bits_set, bits_clear, bits_test, bits_sum, bits_intersection, bits_union, - bits_difference, int_to_str, address_to_str, crypto_ecverify, - crypto_ecverify_secp256k1, crypto_sha3, crypto_sha256, crypto_blake2b, - crypto_ecrecover_secp256k1 + bits_difference, int_to_str, address_to_str, crypto_verify_sig, + crypto_verify_sig_secp256k1, crypto_sha3, crypto_sha256, crypto_blake2b, + crypto_ecverify_secp256k1, crypto_ecrecover_secp256k1 ]. builtin_to_fcode(require, [Cond, Msg]) -> diff --git a/src/aeso_ast_to_icode.erl b/src/aeso_ast_to_icode.erl index 184275b..7b0c839 100644 --- a/src/aeso_ast_to_icode.erl +++ b/src/aeso_ast_to_icode.erl @@ -355,21 +355,26 @@ ast_body({map, Ann, Map, [Upd | Upds]}, Icode) -> ast_body({map, Ann, {map, Ann, Map, [Upd]}, Upds}, Icode); %% 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, bytes_t(65)], word); - -ast_body(?qid_app(["Crypto", "ecverify"], [Msg, PK, Sig], _, _), Icode) -> - prim_call(?PRIM_CALL_CRYPTO_ECVERIFY, #integer{value = 0}, +ast_body(?qid_app(["Crypto", "verify_sig"], [Msg, PK, Sig], _, _), Icode) -> + prim_call(?PRIM_CALL_CRYPTO_VERIFY_SIG, #integer{value = 0}, [ast_body(Msg, Icode), ast_body(PK, Icode), ast_body(Sig, Icode)], [word, word, sign_t()], word); -ast_body(?qid_app(["Crypto", "ecverify_secp256k1"], [Msg, PK, Sig], _, _), Icode) -> - prim_call(?PRIM_CALL_CRYPTO_ECVERIFY_SECP256K1, #integer{value = 0}, +ast_body(?qid_app(["Crypto", "verify_sig_secp256k1"], [Msg, PK, Sig], _, _), Icode) -> + prim_call(?PRIM_CALL_CRYPTO_VERIFY_SIG_SECP256K1, #integer{value = 0}, [ast_body(Msg, Icode), ast_body(PK, Icode), ast_body(Sig, Icode)], [bytes_t(32), bytes_t(64), bytes_t(64)], word); +ast_body(?qid_app(["Crypto", "ecverify_secp256k1"], [Msg, Addr, Sig], _, _), Icode) -> + prim_call(?PRIM_CALL_CRYPTO_ECVERIFY_SECP256K1, #integer{value = 0}, + [ast_body(Msg, Icode), ast_body(Addr, Icode), ast_body(Sig, Icode)], + [word, bytes_t(20), bytes_t(65)], word); + +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, bytes_t(65)], aeso_icode:option_typerep(bytes_t(20))); + ast_body(?qid_app(["Crypto", "sha3"], [Term], [Type], _), Icode) -> generic_hash_primop(?PRIM_CALL_CRYPTO_SHA3, Term, Type, Icode); ast_body(?qid_app(["Crypto", "sha256"], [Term], [Type], _), Icode) -> diff --git a/src/aeso_fcode_to_fate.erl b/src/aeso_fcode_to_fate.erl index e735678..ef75237 100644 --- a/src/aeso_fcode_to_fate.erl +++ b/src/aeso_fcode_to_fate.erl @@ -98,19 +98,20 @@ Op =:= 'SHA3' orelse Op =:= 'SHA256' orelse Op =:= 'BLAKE2B' orelse - Op =:= 'ECRECOVER_SECP256K1' orelse - Op =:= 'ECVERIFY' orelse - Op =:= 'ECVERIFY_SECP256K1' orelse - Op =:= 'CONTRACT_TO_ADDRESS' orelse - Op =:= 'AUTH_TX_HASH' orelse - Op =:= 'BYTES_TO_INT' orelse - Op =:= 'BYTES_TO_STR' orelse - Op =:= 'ORACLE_CHECK' orelse - Op =:= 'ORACLE_CHECK_QUERY' orelse - Op =:= 'IS_ORACLE' orelse - Op =:= 'IS_CONTRACT' orelse - Op =:= 'IS_PAYABLE' orelse - Op =:= 'CREATOR' orelse + Op =:= 'VERIFY_SIG' orelse + Op =:= 'VERIFY_SIG_SECP256K1' orelse + Op =:= 'ECVERIFY_SECP256K1' orelse + Op =:= 'ECRECOVER_SECP256K1' orelse + Op =:= 'CONTRACT_TO_ADDRESS' orelse + Op =:= 'AUTH_TX_HASH' orelse + Op =:= 'BYTES_TO_INT' orelse + Op =:= 'BYTES_TO_STR' orelse + Op =:= 'ORACLE_CHECK' orelse + Op =:= 'ORACLE_CHECK_QUERY' orelse + Op =:= 'IS_ORACLE' orelse + Op =:= 'IS_CONTRACT' orelse + Op =:= 'IS_PAYABLE' orelse + Op =:= 'CREATOR' orelse false)). -record(env, { contract, vars = [], locals = [], tailpos = true }). @@ -599,16 +600,17 @@ 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(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(contract_to_address) -> aeb_fate_ops:contract_to_address(?a, ?a); -op_to_scode(crypto_ecrecover_secp256k1) -> aeb_fate_ops:ecrecover_secp256k1(?a, ?a, ?a); -op_to_scode(crypto_ecverify) -> aeb_fate_ops:ecverify(?a, ?a, ?a, ?a); -op_to_scode(crypto_ecverify_secp256k1) -> aeb_fate_ops:ecverify_secp256k1(?a, ?a, ?a, ?a); -op_to_scode(crypto_sha3) -> aeb_fate_ops:sha3(?a, ?a); -op_to_scode(crypto_sha256) -> aeb_fate_ops:sha256(?a, ?a); -op_to_scode(crypto_blake2b) -> aeb_fate_ops:blake2b(?a, ?a); -op_to_scode(string_sha3) -> aeb_fate_ops:sha3(?a, ?a); -op_to_scode(string_sha256) -> aeb_fate_ops:sha256(?a, ?a); -op_to_scode(string_blake2b) -> aeb_fate_ops:blake2b(?a, ?a). +op_to_scode(contract_to_address) -> aeb_fate_ops:contract_to_address(?a, ?a); +op_to_scode(crypto_verify_sig) -> aeb_fate_ops:verify_sig(?a, ?a, ?a, ?a); +op_to_scode(crypto_verify_sig_secp256k1) -> aeb_fate_ops:verify_sig_secp256k1(?a, ?a, ?a, ?a); +op_to_scode(crypto_ecverify_secp256k1) -> aeb_fate_ops:ecverify_secp256k1(?a, ?a, ?a, ?a); +op_to_scode(crypto_ecrecover_secp256k1) -> aeb_fate_ops:ecrecover_secp256k1(?a, ?a, ?a); +op_to_scode(crypto_sha3) -> aeb_fate_ops:sha3(?a, ?a); +op_to_scode(crypto_sha256) -> aeb_fate_ops:sha256(?a, ?a); +op_to_scode(crypto_blake2b) -> aeb_fate_ops:blake2b(?a, ?a); +op_to_scode(string_sha3) -> aeb_fate_ops:sha3(?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 %% easier, and specialize to PUSH (which is cheaper) at the end. @@ -828,9 +830,10 @@ attributes(I) -> {'SHA3', A, B} -> Pure(A, [B]); {'SHA256', 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]); + {'VERIFY_SIG', A, B, C, D} -> Pure(A, [B, C, D]); + {'VERIFY_SIG_SECP256K1', A, B, C, D} -> Pure(A, [B, C, D]); {'ECVERIFY_SECP256K1', A, B, C, D} -> Pure(A, [B, C, D]); + {'ECRECOVER_SECP256K1', A, B, C} -> Pure(A, [B, C]); {'CONTRACT_TO_ADDRESS', A, B} -> Pure(A, [B]); {'AUTH_TX_HASH', A} -> Pure(A, []); {'BYTES_TO_INT', A, B} -> Pure(A, [B]); diff --git a/test/aeso_calldata_tests.erl b/test/aeso_calldata_tests.erl index 579d6ea..aa732a7 100644 --- a/test/aeso_calldata_tests.erl +++ b/test/aeso_calldata_tests.erl @@ -120,7 +120,7 @@ compilable_contracts() -> {"complex_types", "filter_some", ["[Some(11), Some(12), None]"]}, {"complex_types", "init", ["ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ"]}, {"__call" "init", []}, - {"bitcoin_auth", "authorize", ["1", "#0102030405060708090a0b0c0d0e0f101718192021222324252627282930313233343536373839401a1b1c1d1e1f202122232425262728293031323334353637"]}, + {"bitcoin_auth", "authorize", ["1", "#0102030405060708090a0b0c0d0e0f101718192021222324252627282930313233343536373839401a1b1c1d1e1f20212223242526272829303132333435363738"]}, {"bitcoin_auth", "to_sign", ["#0102030405060708090a0b0c0d0e0f1017181920212223242526272829303132", "2"]}, {"stub", "foo", ["42"]}, {"stub", "foo", ["-42"]}, diff --git a/test/contracts/basic_auth.aes b/test/contracts/basic_auth.aes index a70a43d..94be85f 100644 --- a/test/contracts/basic_auth.aes +++ b/test/contracts/basic_auth.aes @@ -10,7 +10,7 @@ contract BasicAuth = put(state{ nonce = n + 1 }) switch(Auth.tx_hash) None => abort("Not in Auth context") - Some(tx_hash) => Crypto.ecverify(to_sign(tx_hash, n), state.owner, s) + Some(tx_hash) => Crypto.verify_sig(to_sign(tx_hash, n), state.owner, s) entrypoint to_sign(h : hash, n : int) = Crypto.blake2b((h, n)) diff --git a/test/contracts/bitcoin_auth.aes b/test/contracts/bitcoin_auth.aes index 738557e..13a6dbb 100644 --- a/test/contracts/bitcoin_auth.aes +++ b/test/contracts/bitcoin_auth.aes @@ -1,9 +1,9 @@ contract BitcoinAuth = - record state = { nonce : int, owner : bytes(64) } + record state = { nonce : int, owner : bytes(20) } - entrypoint init(owner' : bytes(64)) = { nonce = 1, owner = owner' } + entrypoint init(owner' : bytes(20)) = { nonce = 1, owner = owner' } - stateful entrypoint authorize(n : int, s : signature) : bool = + stateful entrypoint authorize(n : int, s : bytes(65)) : bool = require(n >= state.nonce, "Nonce too low") require(n =< state.nonce, "Nonce too high") put(state{ nonce = n + 1 })