Improve API to be more Erlang-ish
This commit is contained in:
+25
-46
@@ -1,44 +1,41 @@
|
||||
-module(ecrecover).
|
||||
|
||||
%% API
|
||||
-export([ecrecover/1,
|
||||
ecrecover_hex/1,
|
||||
bin_to_hexstr/1,
|
||||
hexstr_to_bin/1,
|
||||
time_taken_to_execute/1
|
||||
]).
|
||||
-export([recover/2]).
|
||||
|
||||
%% Native library support
|
||||
%% NIF
|
||||
-export([load/0]).
|
||||
-on_load(load/0).
|
||||
|
||||
ecrecover(_Input) ->
|
||||
not_loaded(?LINE).
|
||||
|
||||
ecrecover_hex(Input) ->
|
||||
Decoded = hexstr_to_bin(Input),
|
||||
{ok, PubKey} = ecrecover(Decoded),
|
||||
Encoded = bin_to_hexstr(PubKey),
|
||||
Encoded.
|
||||
|
||||
%%=============================================================================
|
||||
%% NIF API
|
||||
|
||||
load() ->
|
||||
Dir = case code:priv_dir(ecrecoverprebuilt) of
|
||||
{error, bad_name} ->
|
||||
filename:join(
|
||||
filename:dirname(
|
||||
filename:dirname(
|
||||
code:which(?MODULE))), "priv");
|
||||
D -> D
|
||||
end,
|
||||
SoName = filename:join(Dir, atom_to_list(?MODULE)),
|
||||
SoName = filename:join(priv(), atom_to_list(?MODULE)),
|
||||
ok = erlang:load_nif(SoName, 0).
|
||||
|
||||
not_loaded(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()->
|
||||
case code:priv_dir(?MODULE) of
|
||||
case code:priv_dir(ecrecoverprebuilt) of
|
||||
{error, _} ->
|
||||
EbinDir = filename:dirname(code:which(?MODULE)),
|
||||
AppPath = filename:dirname(EbinDir),
|
||||
@@ -47,23 +44,5 @@ priv()->
|
||||
Path
|
||||
end.
|
||||
|
||||
%%
|
||||
time_taken_to_execute(F) -> Start = os:timestamp(),
|
||||
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]).
|
||||
recover_(_Input) ->
|
||||
not_loaded(?LINE).
|
||||
|
||||
@@ -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]).
|
||||
+2
-2
@@ -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 ecrecover = EcRecover { };
|
||||
let _result = match ecrecover.execute(input.as_slice(),
|
||||
&mut BytesRef::Flexible(&mut byte_ref)) {
|
||||
&mut BytesRef::Fixed(&mut byte_ref)) {
|
||||
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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user