java bindings initial try

This commit is contained in:
Stefan Bratanov 2022-11-22 20:25:01 +00:00
parent 895700f4ca
commit accc70c6cd
9 changed files with 355 additions and 0 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@
inc/blst.h*
inc/blst_aux.h*
.vscode/
.idea/
.clang-format
*bindings/*/*.so
*bindings/csharp/*.exe

1
bindings/java/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
generated/

2
bindings/java/Makefile Normal file
View File

@ -0,0 +1,2 @@
ckzg4844:
swig -c++ -java -outdir generated/ -I../../src c_kzg_4844.swg

1
bindings/java/README.md Normal file
View File

@ -0,0 +1 @@
## Build Instructions

View File

@ -0,0 +1,93 @@
#ifndef ___BLS12_381_HPP___
#define ___BLS12_381_HPP___
#include <vector>
#include "../../src/c_kzg_4844.h"
#include "exception.hpp"
class Fr
{
private:
fr_t fr;
Fr(fr_t _fr) { fr = _fr; }
Fr(int64_t arr[4])
{
blst_fr_from_uint64(&fr, (const uint64_t *)arr);
}
public:
static Fr from_jlongs(int64_t arr[4])
{
return Fr(arr);
}
Fr() {}
std::vector<long long> to_longs()
{
std::vector<long long> ret(4);
blst_uint64_from_fr((uint64_t *)&ret[0], &fr);
return ret;
}
};
class G1
{
private:
g1_t g1;
G1(g1_t g1_) { g1 = g1_; }
G1(uint8_t arr[48])
throw(KZGException)
{
bytes_to_g1(&g1, arr);
}
public:
static G1 from_compressed(uint8_t arr[48]) throw(KZGException)
{
return G1(arr);
}
G1() {}
void to_compressed(uint8_t out[48])
{
bytes_from_g1(out, &g1);
}
};
class G2
{
private:
g2_t g2;
G2() {}
G2(g2_t g2_) { g2 = g2_; }
G2(const byte arr[96])
throw(KZGException)
{
blst_p2_affine p2_aff;
BLST_TRY(blst_p2_uncompress(&p2_aff, arr));
blst_p2_from_affine(&g2, &p2_aff);
}
public:
static G2 from_compressed(const signed char arr[96]) throw(KZGException)
{
return new G2((byte *)arr);
}
G2() {}
void to_compressed(signed char out[96])
{
blst_p2_compress((byte *)out, &g2);
}
};
#endif

View File

@ -0,0 +1,28 @@
#ifndef ___C_KZG_4844_HPP___
#define ___C_KZG_4844_HPP___
#include <vector>
#include "c_kzg_4844.h"
#include "bls12_381.hpp"
#include "setup.hpp"
#include "exception.hpp"
KZGSetup load_trusted_setup_wrap(const char *file)
{
KZGSettings *out = malloc(sizeof(KZGSettings));
FILE *f = fopen(file, "r");
CKZG_TRY(load_trusted_setup(out, f));
return KZGSetup();
}
void free_trusted_setup_wrap(KZGSetup *s)
{
KZGSettings s_;
CKZG_TRY(free_trusted_setup(s_))
}
#endif

View File

@ -0,0 +1,96 @@
%module CKzg4844
%include "exception.i"
%include "std_string.i"
%include "stdint.i"
%include "enums.swg"
%include "arrays_java.i"
%include "std_vector.i"
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("$module");
} catch (UnsatisfiedLinkError ex) {
throw new RuntimeException(ex);
}
}
%}
// copied from blst.swg
// Extensive sorcery to shift memory management to JVM GC. General idea is
// to use Java long[] as opaque storage for blst data. Methods that return
// new objects allocate suitably sized long[] arrays from JVM heap,
// references to which are then assigned to |swigCPtr| on the Java side.
// And when passed back to JNI, |swigCPtr|s are dereferenced with
// GetLongArrayElements... And no destructors!
%nodefaultdtor;
%typemap(javafinalize) SWIGTYPE ""
%typemap(javadestruct) SWIGTYPE ""
%typemap(javabody) SWIGTYPE %{
private transient long[] swigCPtr;
protected $javaclassname(long[] cPtr) { swigCPtr = cPtr; }
protected static long[] getCPtr($javaclassname obj) {
return obj != null ? obj.swigCPtr : null;
}
public $javaclassname dup() { return new $javaclassname(swigCPtr.clone()); }
%}
%ignore dup;
%typemap(javaconstruct) SWIGTYPE { this($imcall); }
%typemap(jni) SWIGTYPE, SWIGTYPE&, SWIGTYPE* "jlongArray"
%typemap(jtype) SWIGTYPE, SWIGTYPE&, SWIGTYPE* "long[]"
%typemap(javaout) SWIGTYPE, SWIGTYPE&, SWIGTYPE* {
return new $javaclassname($jnicall);
}
%typemap(in) SWIGTYPE&, SWIGTYPE* %{
$1 = ($1_ltype)JCALL(GetLongArrayElements, $input, 0);
%}
%typemap(in) const SWIGTYPE&, const SWIGTYPE* %{
$1 = $input ? ($1_ltype)JCALL(GetLongArrayElements, $input, 0) : NULL;
%}
%typemap(out) SWIGTYPE&, SWIGTYPE* %{
if ($1 != $null) {
size_t sz = (sizeof($1_basetype) + sizeof(jlong) - 1)/sizeof(jlong);
$result = JCALL(NewLongArray, sz);
if ($result != $null)
JCALL(SetLongArrayRegion, $result, 0, sz, (const jlong *)$1);
}
%}
%typemap(out) SWIGTYPE {
size_t sz = (sizeof($1_basetype) + sizeof(jlong) - 1)/sizeof(jlong);
$result = JCALL(NewLongArray, sz);
if ($result != $null)
JCALL(SetLongArrayRegion, $result, 0, sz, (const jlong *)&$1);
}
%typemap(newfree) SWIGTYPE* "delete $1;"
%typemap(freearg) SWIGTYPE&, SWIGTYPE* %{
JCALL(ReleaseLongArrayElements, $input, (jlong *)$1, 0);
%}
%typemap(freearg) const SWIGTYPE&, const SWIGTYPE* %{
if ($input) JCALL(ReleaseLongArrayElements, $input, (jlong *)$1, JNI_ABORT);
%}
%typemap(freearg) const std::string& ""
// making the generated java interface prettier and more usable
%template(G1Vector) std::vector<G1>;
%template(G2Vector) std::vector<G2>;
%template(FrVector) std::vector<Fr>;
%template(LongVector) std::vector<long long>;
%begin %{
#include "c_kzg_4844.hpp"
#include "bls12_381.hpp"
#include "setup.hpp"
%}
// remove the _wrap suffix of the functions
%rename("%(regex:/^(.*)(_wrap)$/\\1/)s", %$isfunction) "";
%include "c_kzg_4844.hpp"
%include "bls12_381.hpp"
%include "setup.hpp"

View File

@ -0,0 +1,51 @@
#ifndef ___EXCEPTION_HPP___
#define ___EXCEPTION_HPP___
#include <string>
#include "c_kzg_4844.h"
char *C_KZG_ERRORS[] = {
"C_KZG_OK",
"C_KZG_BADARGS",
"C_KZG_ERROR",
"C_KZG_MALLOC"};
char *BLST_ERRORS[] = {
"BLST_SUCCESS",
"BLST_BAD_ENCODING",
"BLST_POINT_NOT_ON_CURVE",
"BLST_POINT_NOT_IN_GROUP",
"BLST_AGGR_TYPE_MISMATCH",
"BLST_VERIFY_FAIL",
"BLST_PK_IS_INFINITY",
"BLST_BAD_SCALAR"};
class KZGException
{
std::string message;
public:
KZGException(const std::string &msg) : message(msg) {}
std::string message()
{
return message;
}
};
#define CKZG_TRY(result) \
{ \
C_KZG_RET ___ret = (result); \
if (___ret != C_KZG_OK) \
throw KZGException(std::string("C-KZG error: ") + C_KZG_ERRORS[___ret]); \
}
#define BLST_TRY(result) \
{ \
BLST_ERROR ___ret = (result); \
if (___ret != BLST_SUCCESS) \
throw KZGException(std::string("BLST error: ") + BLST_ERRORS[___ret]); \
}
#endif

82
bindings/java/setup.hpp Normal file
View File

@ -0,0 +1,82 @@
#ifndef ___SETUP_HPP___
#define ___SETUP_HPP___
#include <vector>
#include "c_kzg_4844.h"
#include "bls12_381.hpp"
class FFTSetup
{
private:
uint64_t max_width;
std::vector<Fr> expanded_roots_of_unity;
std::vector<Fr> reverse_roots_of_unity;
std::vector<Fr> roots_of_unity;
public:
FFTSetup(uint64_t max_width_, std::vector<Fr> expanded_roots_of_unity_, std::vector<Fr> reverse_roots_of_unity_, std::vector<Fr> roots_of_unity_)
{
max_width = max_width_;
expanded_roots_of_unity = expanded_roots_of_unity_;
reverse_roots_of_unity = reverse_roots_of_unity_;
roots_of_unity = roots_of_unity_;
}
FFTSetup() {}
uint64_t max_width()
{
return max_width;
}
std::vector<Fr> expanded_roots_of_unity()
{
return expanded_roots_of_unity;
}
std::vector<Fr> reverse_roots_of_unity()
{
return reverse_roots_of_unity;
}
std::vector<Fr> roots_of_unity()
{
return roots_of_unity;
}
};
class KZGSetup
{
private:
FFTSetup fs;
std::vector<G1> g1Values;
std::vector<G2> g2Values;
public:
KZGSetup(FFTSetup fs_, std::vector<G1> g1Values_, std::vector<G2> g2Values_)
{
fs = fs_;
g1Values = g1Values_;
g2Values = g2Values_;
}
KZGSetup() {}
FFTSetup fs()
{
return fs;
}
std::vector<G1> g1Values()
{
return g1Values;
}
std::vector<G2> g2Values()
{
return g2Values;
}
};
#endif