Improve API to be more Erlang-ish
This commit is contained in:
parent
f69e1947c7
commit
231415aa99
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,3 +2,6 @@
|
|||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
**/*~
|
**/*~
|
||||||
|
/parity-ethereum
|
||||||
|
/_build
|
||||||
|
/ebin
|
||||||
|
@ -9,7 +9,7 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.10.1"
|
base64 = "0.10.1"
|
||||||
c_vec = "1.3.3"
|
c_vec = "1.3.3"
|
||||||
ethcore-builtin = { path = "../parity-ethereum/ethcore/builtin" }
|
ethcore-builtin = { path = "parity-ethereum/ethcore/builtin" }
|
||||||
lazy_static = "1.3.0"
|
lazy_static = "1.3.0"
|
||||||
libc = "0.2.60"
|
libc = "0.2.60"
|
||||||
parity-bytes = "0.1.0"
|
parity-bytes = "0.1.0"
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
all: priv/ecrecover.so
|
all: priv/ecrecover.so
|
||||||
|
|
||||||
priv/ecrecover.so: src/lib.rs
|
priv/ecrecover.so: src/lib.rs parity-ethereum/
|
||||||
cargo build --release
|
cargo build --release
|
||||||
cp target/release/libecrecover.so priv/ecrecover.so
|
cp target/release/libecrecover.so priv/ecrecover.so
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f src/ecrecover.so target/release/libecrecover.so
|
rm -f src/ecrecover.so target/release/libecrecover.so
|
||||||
|
|
||||||
|
parity-ethereum/:
|
||||||
|
git clone https://github.com/johnsnewby/parity-ethereum.git
|
@ -1,10 +1,4 @@
|
|||||||
|
|
||||||
{erl_opts, [{parse_transform, lager_transform}, {lager_extra_sinks, [ecrecover]}]}.
|
|
||||||
|
|
||||||
{deps, [
|
{deps, [
|
||||||
{lager, {git, "https://github.com/erlang-lager/lager.git",
|
|
||||||
{ref, "69b4ada"}}}, % tag: 3.6.7
|
|
||||||
|
|
||||||
%% ecrecover prebuilt libraries
|
%% ecrecover prebuilt libraries
|
||||||
{ecrecoverprebuilt,
|
{ecrecoverprebuilt,
|
||||||
{ecrecoverprebuilt_app_with_priv_from_git,
|
{ecrecoverprebuilt_app_with_priv_from_git,
|
||||||
@ -17,8 +11,6 @@
|
|||||||
{ref, "f982da061c5f2e0ffbf1ad58ac25b3b32e182b01"}}}
|
{ref, "f982da061c5f2e0ffbf1ad58ac25b3b32e182b01"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
%%{profiles, [{test, [{deps, [{meck, "0.8.12"}]}]}]}.
|
|
||||||
|
|
||||||
{dialyzer, [{warnings, [unknown]},
|
{dialyzer, [{warnings, [unknown]},
|
||||||
{plt_apps, all_deps},
|
{plt_apps, all_deps},
|
||||||
{base_plt_apps, [erts, kernel, stdlib, crypto]}
|
{base_plt_apps, [erts, kernel, stdlib, crypto]}
|
||||||
|
5
rebar.lock
Normal file
5
rebar.lock
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[{<<"ecrecoverprebuilt">>,
|
||||||
|
{ecrecoverprebuilt_app_with_priv_from_git,
|
||||||
|
{git,"https://github.com/aeternity/ecrecover-prebuilt.git",
|
||||||
|
{ref,"93569ca272e59682366cdf3c7ed2ee991540701a"}}},
|
||||||
|
0}].
|
@ -1,44 +1,41 @@
|
|||||||
-module(ecrecover).
|
-module(ecrecover).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([ecrecover/1,
|
-export([recover/2]).
|
||||||
ecrecover_hex/1,
|
|
||||||
bin_to_hexstr/1,
|
|
||||||
hexstr_to_bin/1,
|
|
||||||
time_taken_to_execute/1
|
|
||||||
]).
|
|
||||||
|
|
||||||
%% Native library support
|
%% NIF
|
||||||
-export([load/0]).
|
-export([load/0]).
|
||||||
-on_load(load/0).
|
-on_load(load/0).
|
||||||
|
|
||||||
ecrecover(_Input) ->
|
%%=============================================================================
|
||||||
not_loaded(?LINE).
|
%% NIF API
|
||||||
|
|
||||||
ecrecover_hex(Input) ->
|
|
||||||
Decoded = hexstr_to_bin(Input),
|
|
||||||
{ok, PubKey} = ecrecover(Decoded),
|
|
||||||
Encoded = bin_to_hexstr(PubKey),
|
|
||||||
Encoded.
|
|
||||||
|
|
||||||
|
|
||||||
load() ->
|
load() ->
|
||||||
Dir = case code:priv_dir(ecrecoverprebuilt) of
|
SoName = filename:join(priv(), atom_to_list(?MODULE)),
|
||||||
{error, bad_name} ->
|
|
||||||
filename:join(
|
|
||||||
filename:dirname(
|
|
||||||
filename:dirname(
|
|
||||||
code:which(?MODULE))), "priv");
|
|
||||||
D -> D
|
|
||||||
end,
|
|
||||||
SoName = filename:join(Dir, atom_to_list(?MODULE)),
|
|
||||||
ok = erlang:load_nif(SoName, 0).
|
ok = erlang:load_nif(SoName, 0).
|
||||||
|
|
||||||
not_loaded(Line) ->
|
not_loaded(Line) ->
|
||||||
erlang:nif_error({error, {not_loaded, [{module, ?MODULE}, {line, Line}]}}).
|
erlang:nif_error({error, {not_loaded, [{module, ?MODULE}, {line, Line}]}}).
|
||||||
|
|
||||||
|
%%=============================================================================
|
||||||
|
%% External API
|
||||||
|
|
||||||
|
recover(<<_:32/binary>> = Hash, <<_:65/binary>> = Sig) ->
|
||||||
|
Input = <<Hash/binary, 0:(8*31), Sig/binary>>,
|
||||||
|
case recover_(Input) of
|
||||||
|
{ok, []} ->
|
||||||
|
<<0:256>>;
|
||||||
|
{ok, Res} ->
|
||||||
|
erlang:list_to_binary(Res);
|
||||||
|
_Err ->
|
||||||
|
<<0:256>>
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%=============================================================================
|
||||||
|
%% Internal Functions
|
||||||
|
|
||||||
priv()->
|
priv()->
|
||||||
case code:priv_dir(?MODULE) of
|
case code:priv_dir(ecrecoverprebuilt) of
|
||||||
{error, _} ->
|
{error, _} ->
|
||||||
EbinDir = filename:dirname(code:which(?MODULE)),
|
EbinDir = filename:dirname(code:which(?MODULE)),
|
||||||
AppPath = filename:dirname(EbinDir),
|
AppPath = filename:dirname(EbinDir),
|
||||||
@ -47,23 +44,5 @@ priv()->
|
|||||||
Path
|
Path
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%
|
recover_(_Input) ->
|
||||||
time_taken_to_execute(F) -> Start = os:timestamp(),
|
not_loaded(?LINE).
|
||||||
F(),
|
|
||||||
io:format("total time taken ~f seconds~n", [timer:now_diff(os:timestamp(), Start) / 1000000]).
|
|
||||||
|
|
||||||
%%
|
|
||||||
bin_to_hexstr(Bin) ->
|
|
||||||
lists:flatten([io_lib:format("~2.16.0B", [X]) ||
|
|
||||||
X <- binary_to_list(Bin)]).
|
|
||||||
|
|
||||||
hexstr_to_bin(S) ->
|
|
||||||
hexstr_to_bin(S, []).
|
|
||||||
hexstr_to_bin([], Acc) ->
|
|
||||||
list_to_binary(lists:reverse(Acc));
|
|
||||||
hexstr_to_bin([X,Y|T], Acc) ->
|
|
||||||
{ok, [V], []} = io_lib:fread("~16u", [X,Y]),
|
|
||||||
hexstr_to_bin(T, [V | Acc]);
|
|
||||||
hexstr_to_bin([X|T], Acc) ->
|
|
||||||
{ok, [V], []} = io_lib:fread("~16u", lists:flatten([X,"0"])),
|
|
||||||
hexstr_to_bin(T, [V | Acc]).
|
|
||||||
|
28
src/ecrecover_util.erl
Normal file
28
src/ecrecover_util.erl
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-module(ecrecover_util).
|
||||||
|
|
||||||
|
-export([ recover_from_hex/1
|
||||||
|
, bin_to_hex/1
|
||||||
|
, hex_to_bin/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
%%=============================================================================
|
||||||
|
%% External API
|
||||||
|
|
||||||
|
recover_from_hex(Input) ->
|
||||||
|
<<Hash:32/binary, _:31/binary, Sig:65/binary>> = hex_to_bin(Input),
|
||||||
|
PubKey = ecrecover:recover(Hash, Sig),
|
||||||
|
bin_to_hex(PubKey).
|
||||||
|
|
||||||
|
bin_to_hex(Bin) ->
|
||||||
|
lists:flatten([io_lib:format("~2.16.0B", [X]) || X <- binary_to_list(Bin)]).
|
||||||
|
|
||||||
|
hex_to_bin(S) ->
|
||||||
|
hex_to_bin(S, []).
|
||||||
|
hex_to_bin([], Acc) ->
|
||||||
|
list_to_binary(lists:reverse(Acc));
|
||||||
|
hex_to_bin([X,Y|T], Acc) ->
|
||||||
|
{ok, [V], []} = io_lib:fread("~16u", [X,Y]),
|
||||||
|
hex_to_bin(T, [V | Acc]);
|
||||||
|
hex_to_bin([X|T], Acc) ->
|
||||||
|
{ok, [V], []} = io_lib:fread("~16u", lists:flatten([X,"0"])),
|
||||||
|
hex_to_bin(T, [V | Acc]).
|
@ -37,9 +37,9 @@ pub fn nif_ecrecover<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Er
|
|||||||
let mut byte_ref = Vec::new();
|
let mut byte_ref = Vec::new();
|
||||||
let ecrecover = EcRecover { };
|
let ecrecover = EcRecover { };
|
||||||
let _result = match ecrecover.execute(input.as_slice(),
|
let _result = match ecrecover.execute(input.as_slice(),
|
||||||
&mut BytesRef::Flexible(&mut byte_ref)) {
|
&mut BytesRef::Fixed(&mut byte_ref)) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_e) => return Err(rustler::Error::Atom("ecrecover failed")),
|
Err(_e) => return Err(rustler::Error::Atom("ecrecover_failed")),
|
||||||
};
|
};
|
||||||
Ok((atoms::ok(), byte_ref.as_slice()).encode(env))
|
Ok((atoms::ok(), byte_ref.as_slice()).encode(env))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user