NIF goodness!
This commit is contained in:
parent
74e20f3a9d
commit
e6e6b94b5b
@ -7,6 +7,7 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
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"
|
||||||
|
24
src/lib.rs
24
src/lib.rs
@ -13,6 +13,8 @@ use crate::ethcore_builtin::Implementation;
|
|||||||
use c_vec::{CVec};
|
use c_vec::{CVec};
|
||||||
use parity_bytes::BytesRef;
|
use parity_bytes::BytesRef;
|
||||||
use rustler::*;
|
use rustler::*;
|
||||||
|
use rustler::types::atom::ok;
|
||||||
|
use std::io::Write;
|
||||||
use std::ptr::copy_nonoverlapping;
|
use std::ptr::copy_nonoverlapping;
|
||||||
|
|
||||||
const INPUT_LENGTH: usize = 512;
|
const INPUT_LENGTH: usize = 512;
|
||||||
@ -27,37 +29,27 @@ mod atoms {
|
|||||||
rustler_export_nifs!(
|
rustler_export_nifs!(
|
||||||
"nifecrecover",
|
"nifecrecover",
|
||||||
[
|
[
|
||||||
("ecrecover", 2, nif_ecrecover),
|
("ecrecover", 1, nif_ecrecover),
|
||||||
],
|
],
|
||||||
Some(on_load)
|
Some(on_load)
|
||||||
);
|
);
|
||||||
|
|
||||||
struct EcrecoverResource { }
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn on_load(env: Env, _load_info: Term) -> bool {
|
fn on_load(env: Env, _load_info: Term) -> bool {
|
||||||
println!("on_load");
|
|
||||||
rustler::resource_struct_init!(EcrecoverResource, env);
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nif_ecrecover<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Error> {
|
pub fn nif_ecrecover<'a>(env: Env<'a>, args: &[Term<'a>]) -> NifResult<Term<'a>> {
|
||||||
let input: String = args[0].decode()?;
|
let input: Binary = args[0].decode()?;
|
||||||
let mut output: String = args[1].decode()?;
|
|
||||||
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_bytes(),
|
let result = match ecrecover.execute(input.as_slice(),
|
||||||
&mut BytesRef::Flexible(&mut byte_ref)) {
|
&mut BytesRef::Flexible(&mut byte_ref)) {
|
||||||
Ok(x) => x,
|
Ok(_) => (),
|
||||||
Err(e) => return Err(rustler::Error::Atom("ecrecover failed")),
|
Err(e) => return Err(rustler::Error::Atom("ecrecover failed")),
|
||||||
};
|
};
|
||||||
match String::from_utf8(byte_ref) {
|
Ok(byte_ref.as_slice().encode(env))
|
||||||
Ok(x) => {
|
|
||||||
output.push_str(&x);
|
|
||||||
Ok((atoms::ok(), true).encode(env))
|
|
||||||
},
|
|
||||||
Err(x) => Err(rustler::Error::Atom("Invalid UTF-8")),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,17 +1,29 @@
|
|||||||
-module(nifecrecover).
|
-module(nifecrecover).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([ecrecover/2]).
|
-export([ecrecover/1,
|
||||||
|
ecrecover_hex/1,
|
||||||
|
bin_to_hexstr/1,
|
||||||
|
hexstr_to_bin/1,
|
||||||
|
time_taken_to_execute/1
|
||||||
|
]).
|
||||||
|
|
||||||
%% Native library support
|
%% Native library support
|
||||||
-export([load/0]).
|
-export([load/0]).
|
||||||
-on_load(load/0).
|
-on_load(load/0).
|
||||||
|
|
||||||
ecrecover(_Input, _Output) ->
|
ecrecover(_Input) ->
|
||||||
not_loaded(?LINE).
|
not_loaded(?LINE).
|
||||||
|
|
||||||
|
ecrecover_hex(Input) ->
|
||||||
|
Decoded = hexstr_to_bin(Input),
|
||||||
|
{ok, PubKey} = ecrecover(Decoded),
|
||||||
|
Encoded = bin_to_hexstr(PubKey),
|
||||||
|
Encoded.
|
||||||
|
|
||||||
|
|
||||||
load() ->
|
load() ->
|
||||||
ok = erlang:load_nif("/home/newby/projects/ethereum/ecrecover/target/debug/libecrecover", 0).
|
ok = erlang:load_nif("/home/newby/projects/ethereum/ecrecover/target/release/libecrecover", 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}]}}).
|
||||||
@ -25,3 +37,24 @@ priv()->
|
|||||||
Path ->
|
Path ->
|
||||||
Path
|
Path
|
||||||
end.
|
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]).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user