diff --git a/Cargo.toml b/Cargo.toml index a23edf5..287f70a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,7 @@ edition = "2018" c_vec = "1.3.3" libc = "0.2.60" parity-bytes = "0.1.0" -ethcore-builtin = { path = "../parity-ethereum/ethcore/builtin" } \ No newline at end of file +ethcore-builtin = { path = "../parity-ethereum/ethcore/builtin" } + +[lib] +crate-type = ["cdylib"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3b01bad --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ + +CC = gcc +LIBS = -llibecrecover.so +LDPATH = -Ltarget/debug + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< + + + +test: src/test.c include/ecrecover.h target/debug/libecrecover.so + $(CC) -o $@ $^ $(CFLAGS) $(LDPATH) diff --git a/include/ecrecover.h b/include/ecrecover.h new file mode 100644 index 0000000..fc53f50 --- /dev/null +++ b/include/ecrecover.h @@ -0,0 +1,2 @@ + +void ecrecover(const unsigned char *input, unsigned char *output); diff --git a/src/lib.rs b/src/lib.rs index 7dee6ee..ccd6751 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,20 +10,16 @@ use c_vec::{CVec}; use parity_bytes::BytesRef; use std::ptr::copy_nonoverlapping; -const LENGTH: usize = 32; -#[repr(C)] -struct Buffer { - data: *mut [u8;LENGTH], -} - +const INPUT_LENGTH: usize = 512; +const OUTPUT_LENGTH: usize = 32; #[no_mangle] pub unsafe extern "C" fn ecrecover(input: *const libc::c_uchar, output: *mut libc::c_uchar) { let ecrecover = EcRecover { }; let mut byte_ref = Vec::new(); - ecrecover.execute(unsafe { std::slice::from_raw_parts(input as *const u8, LENGTH) }, + ecrecover.execute(unsafe { std::slice::from_raw_parts(input as *const u8, INPUT_LENGTH) }, &mut BytesRef::Flexible(&mut byte_ref)); - let mut ptr: &mut[u8] = unsafe { std::slice::from_raw_parts_mut(output as *mut u8, LENGTH) }; + let mut ptr: &mut[u8] = unsafe { std::slice::from_raw_parts_mut(output as *mut u8, OUTPUT_LENGTH) }; ptr.copy_from_slice(byte_ref.as_slice()); } diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..47e8d45 --- /dev/null +++ b/src/test.c @@ -0,0 +1,95 @@ +// -*- C -*- +#include +#include +#include + +#include "../include/ecrecover.h" + + +char *bin2hex(unsigned char*, int); + +unsigned char *hex2bin(const char*); + +#define OUTPUT_LENGTH 32 + +int main(int arc, char **argv) { + unsigned char *input = hex2bin("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03"); + unsigned char *expected = "000000000000000000000000c08b5542d177ac6686946920409741463a15dddb"; + unsigned char *output = malloc(OUTPUT_LENGTH * sizeof(unsigned char)); + ecrecover(input, output); + assert(strcmp(bin2hex(output, OUTPUT_LENGTH), expected) == 0); +} + + +char *bin2hex(unsigned char *p, int len) +{ + char *hex = malloc(((2*len) + 1)); + char *r = hex; + + while(len && p) + { + (*r) = ((*p) & 0xF0) >> 4; + (*r) = ((*r) <= 9 ? '0' + (*r) : 'a' - 10 + (*r)); + r++; + (*r) = ((*p) & 0x0F); + (*r) = ((*r) <= 9 ? '0' + (*r) : 'a' - 10 + (*r)); + r++; + p++; + len--; + } + *r = '\0'; + + return hex; +} + +unsigned char *hex2bin(const char *str) +{ + int len, h; + unsigned char *result, *err, *p, c; + + err = malloc(1); + *err = 0; + + if (!str) + return err; + + if (!*str) + return err; + + len = 0; + p = (unsigned char*) str; + while (*p++) + len++; + + result = malloc((len/2)+1); + h = !(len%2) * 4; + p = result; + *p = 0; + + c = *str; + while(c) + { + if(('0' <= c) && (c <= '9')) + *p += (c - '0') << h; + else if(('A' <= c) && (c <= 'F')) + *p += (c - 'A' + 10) << h; + else if(('a' <= c) && (c <= 'f')) + *p += (c - 'a' + 10) << h; + else + return err; + + str++; + c = *str; + + if (h) + h = 0; + else + { + h = 4; + p++; + *p = 0; + } + } + + return result; +}