Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add arkworks wrapper for bn128 operations #9

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[submodule "rust/librustzcash"]
path = rust/librustzcash
url = https://github.com/tronprotocol/librustzcash.git
branch = release_vm_zksnarks_4.0
ignore=dirty
branch = release_vm_zksnarks_4.0_lto_false
ignore = dirty
44 changes: 39 additions & 5 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ link_directories(lib)

set(zksnark_jni_include org_tron_common_zksnark_Librustzcash_LibrustzcashJNI.h)
set(sodium_jni_include org_tron_common_zksnark_Libsodium_LibsodiumJNI.h)
set(arkworks_jni_include org_tron_common_zksnark_Libarkworks_LibarkworksJNI.h)
set(zksnark_jni_src LibrustzcashJNIImpl.cpp)
set(sodium_jni_src LibsodiumJNIImpl.cpp)
set(arkworks_jni_src LibarkworksJNIImpl.cpp)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src zksnark_srcs)

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include)
Expand All @@ -35,6 +37,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_BINARY_DIR}")
include_directories("${CMAKE_BINARY_DIR}/include")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../rust/librustzcash/librustzcash/include")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../rust/libarkworks/include")

add_custom_command(
OUTPUT "${zksnark_jni_include}"
Expand All @@ -54,10 +57,22 @@ add_custom_command(
DEPENDS ${sodium_jni_include}
)

add_custom_command(
OUTPUT "${arkworks_jni_include}"
COMMAND ${Java_JAVAC_EXECUTABLE} -verbose
-h ${CMAKE_BINARY_DIR}/include
-d ${CMAKE_BINARY_DIR}/tmp
"${CMAKE_CURRENT_SOURCE_DIR}/../src/main/java/org/tron/common/zksnark/Libarkworks.java"
DEPENDS ${arkworks_jni_include}
)

set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/rust)
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
${CMAKE_CURRENT_SOURCE_DIR}/../rust/librustzcash/target
)
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
${CMAKE_CURRENT_SOURCE_DIR}/../rust/libarkworks/target
)

ExternalProject_Add(
librustzcash
Expand All @@ -71,7 +86,22 @@ ExternalProject_Add(
INSTALL_COMMAND ""
LOG_BUILD OFF)

add_custom_target(rust ALL DEPENDS librustzcash)
add_custom_target(rustzcash ALL DEPENDS librustzcash)

# libarkworks
ExternalProject_Add(
libarkworks
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND cargo build
# COMMAND cargo build
--package libarkworks
--release
BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../rust/libarkworks"
INSTALL_COMMAND ""
LOG_BUILD OFF)

add_custom_target(rustarkworks ALL DEPENDS libarkworks)


# libsodium
Expand All @@ -93,27 +123,31 @@ ADD_LIBRARY(zksnarkjni
SHARED
${CMAKE_CURRENT_SOURCE_DIR}/src/${zksnark_jni_src}
${CMAKE_CURRENT_SOURCE_DIR}/src/${sodium_jni_src}
${CMAKE_CURRENT_SOURCE_DIR}/src/${arkworks_jni_src}
${zksnark_src_dependencies}
${zksnark_jni_include}
${sodium_jni_include}
${arkworks_jni_include}
${zksnark_srcs}
)

target_link_libraries(zksnarkjni
${CMAKE_THREAD_LIBS_INIT}
"${CMAKE_CURRENT_SOURCE_DIR}/../rust/librustzcash/target/release/librustzcash.a"
"${CMAKE_CURRENT_SOURCE_DIR}/../rust/libarkworks/target/release/libarkworks.a"
${NACL_DIR}/src/libsodium/src/libsodium/.libs/libsodium.a
)

add_dependencies(zksnarkjni rust)
add_dependencies(zksnarkjni rustzcash)
add_dependencies(zksnarkjni libsodium)
add_dependencies(zksnarkjni rustarkworks)

if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
SET_TARGET_PROPERTIES( zksnarkjni PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,--wrap=memcpy" )
SET_TARGET_PROPERTIES( zksnarkjni PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,--wrap=memcpy -pthread" )
endif()

if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
INSTALL(TARGETS zksnarkjni LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../src/main/resources/native-package/linux)
INSTALL(TARGETS zksnarkjni LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../src/main/resources/META-INF/native/linux64)
else()
INSTALL(TARGETS zksnarkjni LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../src/main/resources/native-package/macos)
INSTALL(TARGETS zksnarkjni LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../src/main/resources/META-INF/native/osx64)
endif()
146 changes: 146 additions & 0 deletions cpp/src/LibarkworksJNIImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#include "org_tron_common_zksnark_Libarkworks_LibarkworksJNI.h"
#include "libarkworks.h"
#include <iostream>

jboolean bool2jbool(bool b) {
if (b) {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
}

/*
* Class: org_tron_common_zksnark_Libarkworks_LibarkworksJNI
* Method: libarkworksG1IsValid
* Signature: ([B[B)Z
*/
JNIEXPORT jboolean JNICALL Java_org_tron_common_zksnark_Libarkworks_00024LibarkworksJNI_libarkworksG1IsValid
(JNIEnv * env, jobject, jbyteArray x, jbyteArray y) {
unsigned char * x_p = (unsigned char *) env->GetByteArrayElements(x, nullptr);
unsigned char * y_p = (unsigned char *) env->GetByteArrayElements(y, nullptr);
if (x_p == NULL || y_p == NULL) {
return JNI_FALSE;
}

bool result = libarkworks_g1_is_valid(x_p, y_p);
env->ReleaseByteArrayElements(x, (jbyte*) x_p, 0);
env->ReleaseByteArrayElements(y, (jbyte*) y_p, 0);
return bool2jbool(result);
}

/*
* Class: org_tron_common_zksnark_Libarkworks_LibarkworksJNI
* Method: libarkworksG2IsValid
* Signature: ([B[B[B[B)Z
*/
JNIEXPORT jboolean JNICALL Java_org_tron_common_zksnark_Libarkworks_00024LibarkworksJNI_libarkworksG2IsValid
(JNIEnv * env, jobject, jbyteArray a, jbyteArray b, jbyteArray c, jbyteArray d) {
unsigned char * a_p = (unsigned char *) env->GetByteArrayElements(a, nullptr);
unsigned char * b_p = (unsigned char *) env->GetByteArrayElements(b, nullptr);
unsigned char * c_p = (unsigned char *) env->GetByteArrayElements(c, nullptr);
unsigned char * d_p = (unsigned char *) env->GetByteArrayElements(d, nullptr);
if (a_p == NULL || b_p == NULL || c_p == NULL || d_p == NULL) {
return JNI_FALSE;
}

bool result = libarkworks_g2_is_valid(a_p, b_p, c_p, d_p);
env->ReleaseByteArrayElements(a, (jbyte*) a_p, 0);
env->ReleaseByteArrayElements(b, (jbyte*) b_p, 0);
env->ReleaseByteArrayElements(c, (jbyte*) c_p, 0);
env->ReleaseByteArrayElements(d, (jbyte*) d_p, 0);
return bool2jbool(result);
}

/*
* Class: org_tron_common_zksnark_Libarkworks_LibarkworksJNI
* Method: libarkworksAddG1
* Signature: ([B[B[B)Z
*/
JNIEXPORT jboolean JNICALL Java_org_tron_common_zksnark_Libarkworks_00024LibarkworksJNI_libarkworksAddG1
(JNIEnv * env, jobject, jbyteArray a, jbyteArray b, jbyteArray result) {
unsigned char * a_p = (unsigned char *) env->GetByteArrayElements(a, nullptr);
unsigned char * b_p = (unsigned char *) env->GetByteArrayElements(b, nullptr);
unsigned char * result_p = (unsigned char *) env->GetByteArrayElements(result, nullptr);
if (a_p == NULL || b_p == NULL || result_p == NULL) {
return JNI_FALSE;
}

bool success = libarkworks_add_g1(a_p, b_p, result_p);
env->ReleaseByteArrayElements(a, (jbyte*) a_p, 0);
env->ReleaseByteArrayElements(b, (jbyte*) b_p, 0);
env->ReleaseByteArrayElements(result, (jbyte*) result_p, 0);
return bool2jbool(success);
}

/*
* Class: org_tron_common_zksnark_Libarkworks_LibarkworksJNI
* Method: libarkworksMulG1
* Signature: ([B[B[B)Z
*/
JNIEXPORT jboolean JNICALL Java_org_tron_common_zksnark_Libarkworks_00024LibarkworksJNI_libarkworksMulG1
(JNIEnv * env, jobject, jbyteArray p, jbyteArray s, jbyteArray result) {
unsigned char * p_p = (unsigned char *) env->GetByteArrayElements(p, nullptr);
unsigned char * s_p = (unsigned char *) env->GetByteArrayElements(s, nullptr);
unsigned char * result_p = (unsigned char *) env->GetByteArrayElements(result, nullptr);
if (p_p == NULL || s_p == NULL || result_p == NULL) {
return JNI_FALSE;
}

bool success = libarkworks_mul_g1(p_p, s_p, result_p);
env->ReleaseByteArrayElements(p, (jbyte*) p_p, 0);
env->ReleaseByteArrayElements(s, (jbyte*) s_p, 0);
env->ReleaseByteArrayElements(result, (jbyte*) result_p, 0);
return bool2jbool(success);
}

/*
* Class: org_tron_common_zksnark_Libarkworks_LibarkworksJNI
* Method: libarkworksPairingCheck
* Signature: ([B[BI)Z
*/
JNIEXPORT jboolean JNICALL Java_org_tron_common_zksnark_Libarkworks_00024LibarkworksJNI_libarkworksPairingCheck
(JNIEnv * env, jobject, jbyteArray g1s, jbyteArray g2s, jint pairs) {
unsigned char * g1s_p = (unsigned char *) env->GetByteArrayElements(g1s, nullptr);
unsigned char * g2s_p = (unsigned char *) env->GetByteArrayElements(g2s, nullptr);
if (g1s_p == NULL || g2s_p == NULL) {
return JNI_FALSE;
}

bool success = libarkworks_pairing_check(g1s_p, g2s_p, pairs);
env->ReleaseByteArrayElements(g1s, (jbyte*) g1s_p, 0);
env->ReleaseByteArrayElements(g2s, (jbyte*) g2s_p, 0);
return bool2jbool(success);
}

/*
* Class: org_tron_common_zksnark_Libarkworks_LibarkworksJNI
* Method: libarkworksRandomG1
* Signature: ([B)V
*/
JNIEXPORT void JNICALL Java_org_tron_common_zksnark_Libarkworks_00024LibarkworksJNI_libarkworksRandomG1
(JNIEnv * env, jobject, jbyteArray g1) {
unsigned char * g1_p = (unsigned char *) env->GetByteArrayElements(g1, nullptr);
if (g1_p == NULL) {
return;
}

libarkworks_random_g1(g1_p);
env->ReleaseByteArrayElements(g1, (jbyte*) g1_p, 0);
}

/*
* Class: org_tron_common_zksnark_Libarkworks_LibarkworksJNI
* Method: libarkworksRandomG2
* Signature: ([B)V
*/
JNIEXPORT void JNICALL Java_org_tron_common_zksnark_Libarkworks_00024LibarkworksJNI_libarkworksRandomG2
(JNIEnv * env, jobject, jbyteArray g2) {
unsigned char * g2_p = (unsigned char *) env->GetByteArrayElements(g2, nullptr);
if (g2_p == NULL) {
return;
}

libarkworks_random_g2(g2_p);
env->ReleaseByteArrayElements(g2, (jbyte*)g2_p, 0);
}
16 changes: 10 additions & 6 deletions cpp/src/memcpy.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#ifdef __linux__

#include <string.h>

#ifdef __linux__
#if defined(__x86_64__) && defined(__GNU_LIBRARY__)
void *__memcpy_old(void *, const void *, size_t);

asm(".symver __memcpy_old, memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
void *__wrap_memcpy(void *dest, const void *src, size_t n) {
return __memcpy_old(dest, src, n);
}

#endif
#else
// https://chromium.googlesource.com/external/github.com/google/protobuf/+/HEAD/ruby/ext/google/protobuf_c/wrap_memcpy.c
void *__wrap_memcpy(void *dest, const void *src, size_t n) {
return memmove(dest, src, n);
}
#endif
#endif
2 changes: 2 additions & 0 deletions rust/libarkworks/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
/Cargo.lock
22 changes: 22 additions & 0 deletions rust/libarkworks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "libarkworks"
version = "0.1.0"
edition = "2021"

[lib]
name = "arkworks"
path = "src/lib.rs"
crate-type = ["staticlib", "cdylib"]

[dependencies]
libc = "0.2"
rand = "0.8.5"
ark-bn254 = "0.4.0"
ark-ff = "0.4.2"
ark-serialize = "0.4.2"
ark-ec = "0.4.2"

[profile.release]
lto = false
panic = 'abort'
codegen-units = 1
52 changes: 52 additions & 0 deletions rust/libarkworks/include/libarkworks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef LIBARKWORKS_INCLUDE_H_
#define LIBARKWORKS_INCLUDE_H_

#include <stdint.h>

extern "C" {
#ifdef WIN32
typedef uint16_t codeunit;
#else
typedef uint8_t codeunit;
#endif

bool libarkworks_g1_is_valid(
const unsigned char *x,
const unsigned char *y
);

bool libarkworks_g2_is_valid(
const unsigned char *a,
const unsigned char *b,
const unsigned char *c,
const unsigned char *d
);

bool libarkworks_add_g1(
const unsigned char *a,
const unsigned char *b,
unsigned char *result
);

bool libarkworks_mul_g1(
const unsigned char *p,
const unsigned char *s,
unsigned char *result
);

bool libarkworks_pairing_check(
const unsigned char *g1s,
const unsigned char *g2s,
const uint32_t pairs
);

void libarkworks_random_g1(
unsigned char *g1
);

void libarkworks_random_g2(
unsigned char *g2
);
}

#endif // LIBARKWORKS_INCLUDE_H_
Loading