diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8cbb1b12..b411cb16 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,6 +46,56 @@ jobs: name: jacoco-xml-report path: build/reports/jacoco/test/jacocoTestReport.xml + - name: Install & build herumi/mcl + run: | + git clone https://github.com/herumi/mcl + cd mcl + mkdir build + cd build + cmake .. + make + + - name: Copy mcl library to /usr/local/lib + run: | + sudo cp $HOME/work/java-crypto/java-crypto/mcl/build/lib/libmcl.a /usr/local/lib/ + + - name: Build Java FFI + run: | + cd $HOME/work/java-crypto/java-crypto/mcl/ffi/java + mkdir build + cd build + cmake .. + cmake --build . --config Release + + - name: Copy libmcljava.so to /usr/local/lib + run: | + sudo cp $HOME/work/java-crypto/java-crypto/mcl/ffi/java/build/libmcljava.so /usr/local/lib/ + + - name: Install Nix + uses: cachix/install-nix-action@v27 + + - name: Install libsecp256k1 + run: | + nix profile install nixpkgs#secp256k1 + env: + NIX_PATH: $HOME/.nix-profile/bin + + - name: Set LD_LIBRARY_PATH + run: echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:$HOME/.nix-profile/lib" >> $GITHUB_ENV + + - name: Use Java Version 22 + uses: actions/setup-java@v2 + with: + distribution: "adopt" + java-version: "22" + cache: "gradle" + + - name: Install + run: gradle dependencies + + - name: Test + run: gradle test && gradle jacocoTestReport + - name: Codecov uses: codecov/codecov-action@v3 with: diff --git a/libmcljava.dylib b/libmcljava.dylib new file mode 100644 index 00000000..355362e3 Binary files /dev/null and b/libmcljava.dylib differ diff --git a/src/main/java/com/herumi/mcl/CipherText.java b/src/main/java/com/herumi/mcl/CipherText.java new file mode 100644 index 00000000..73de0798 --- /dev/null +++ b/src/main/java/com/herumi/mcl/CipherText.java @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class CipherText { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected CipherText(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(CipherText obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + ElgamalJNI.delete_CipherText(swigCPtr); + } + swigCPtr = 0; + } + } + + public String toStr() { + return ElgamalJNI.CipherText_toStr(swigCPtr, this); + } + + public String toString() { + return ElgamalJNI.CipherText_toString(swigCPtr, this); + } + + public void fromStr(String str) { + ElgamalJNI.CipherText_fromStr(swigCPtr, this, str); + } + + public void add(CipherText c) { + ElgamalJNI.CipherText_add(swigCPtr, this, CipherText.getCPtr(c), c); + } + + public void mul(int m) { + ElgamalJNI.CipherText_mul__SWIG_0(swigCPtr, this, m); + } + + public void mul(String str) { + ElgamalJNI.CipherText_mul__SWIG_1(swigCPtr, this, str); + } + + public CipherText() { + this(ElgamalJNI.new_CipherText(), true); + } +} diff --git a/src/main/java/com/herumi/mcl/Elgamal.java b/src/main/java/com/herumi/mcl/Elgamal.java new file mode 100644 index 00000000..40084888 --- /dev/null +++ b/src/main/java/com/herumi/mcl/Elgamal.java @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class Elgamal { + public static SWIGTYPE_p_bool new_p_bool() { + long cPtr = ElgamalJNI.new_p_bool(); + return (cPtr == 0) ? null : new SWIGTYPE_p_bool(cPtr, false); + } + + public static SWIGTYPE_p_bool copy_p_bool(boolean value) { + long cPtr = ElgamalJNI.copy_p_bool(value); + return (cPtr == 0) ? null : new SWIGTYPE_p_bool(cPtr, false); + } + + public static void delete_p_bool(SWIGTYPE_p_bool obj) { + ElgamalJNI.delete_p_bool(SWIGTYPE_p_bool.getCPtr(obj)); + } + + public static void p_bool_assign(SWIGTYPE_p_bool obj, boolean value) { + ElgamalJNI.p_bool_assign(SWIGTYPE_p_bool.getCPtr(obj), value); + } + + public static boolean p_bool_value(SWIGTYPE_p_bool obj) { + return ElgamalJNI.p_bool_value(SWIGTYPE_p_bool.getCPtr(obj)); + } + + public static void SystemInit(String param) { + ElgamalJNI.SystemInit(param); + } +} diff --git a/src/main/java/com/herumi/mcl/ElgamalJNI.java b/src/main/java/com/herumi/mcl/ElgamalJNI.java new file mode 100644 index 00000000..45c36d9a --- /dev/null +++ b/src/main/java/com/herumi/mcl/ElgamalJNI.java @@ -0,0 +1,100 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class ElgamalJNI { + public static final native long new_p_bool(); + + public static final native long copy_p_bool(boolean jarg1); + + public static final native void delete_p_bool(long jarg1); + + public static final native void p_bool_assign(long jarg1, boolean jarg2); + + public static final native boolean p_bool_value(long jarg1); + + public static final native void SystemInit(String jarg1); + + public static final native String CipherText_toStr(long jarg1, CipherText jarg1_); + + public static final native String CipherText_toString(long jarg1, CipherText jarg1_); + + public static final native void CipherText_fromStr(long jarg1, CipherText jarg1_, String jarg2); + + public static final native void CipherText_add( + long jarg1, CipherText jarg1_, long jarg2, CipherText jarg2_); + + public static final native void CipherText_mul__SWIG_0( + long jarg1, CipherText jarg1_, int jarg2); + + public static final native void CipherText_mul__SWIG_1( + long jarg1, CipherText jarg1_, String jarg2); + + public static final native long new_CipherText(); + + public static final native void delete_CipherText(long jarg1); + + public static final native String PublicKey_toStr(long jarg1, PublicKey jarg1_); + + public static final native String PublicKey_toString(long jarg1, PublicKey jarg1_); + + public static final native void PublicKey_fromStr(long jarg1, PublicKey jarg1_, String jarg2); + + public static final native void PublicKey_save(long jarg1, PublicKey jarg1_, String jarg2); + + public static final native void PublicKey_load(long jarg1, PublicKey jarg1_, String jarg2); + + public static final native void PublicKey_enc__SWIG_0( + long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, int jarg3); + + public static final native void PublicKey_enc__SWIG_1( + long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, String jarg3); + + public static final native void PublicKey_rerandomize( + long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_); + + public static final native void PublicKey_add__SWIG_0( + long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, int jarg3); + + public static final native void PublicKey_add__SWIG_1( + long jarg1, PublicKey jarg1_, long jarg2, CipherText jarg2_, String jarg3); + + public static final native long new_PublicKey(); + + public static final native void delete_PublicKey(long jarg1); + + public static final native String PrivateKey_toStr(long jarg1, PrivateKey jarg1_); + + public static final native String PrivateKey_toString(long jarg1, PrivateKey jarg1_); + + public static final native void PrivateKey_fromStr(long jarg1, PrivateKey jarg1_, String jarg2); + + public static final native void PrivateKey_save(long jarg1, PrivateKey jarg1_, String jarg2); + + public static final native void PrivateKey_load(long jarg1, PrivateKey jarg1_, String jarg2); + + public static final native void PrivateKey_init(long jarg1, PrivateKey jarg1_); + + public static final native long PrivateKey_getPublicKey(long jarg1, PrivateKey jarg1_); + + public static final native int PrivateKey_dec__SWIG_0( + long jarg1, PrivateKey jarg1_, long jarg2, CipherText jarg2_, long jarg3); + + public static final native int PrivateKey_dec__SWIG_1( + long jarg1, PrivateKey jarg1_, long jarg2, CipherText jarg2_); + + public static final native void PrivateKey_setCache( + long jarg1, PrivateKey jarg1_, int jarg2, int jarg3); + + public static final native void PrivateKey_clearCache(long jarg1, PrivateKey jarg1_); + + public static final native long new_PrivateKey(); + + public static final native void delete_PrivateKey(long jarg1); +} diff --git a/src/main/java/com/herumi/mcl/Fp.java b/src/main/java/com/herumi/mcl/Fp.java new file mode 100644 index 00000000..7adaaf2c --- /dev/null +++ b/src/main/java/com/herumi/mcl/Fp.java @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class Fp { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected Fp(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Fp obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + MclJNI.delete_Fp(swigCPtr); + } + swigCPtr = 0; + } + } + + public Fp() { + this(MclJNI.new_Fp__SWIG_0(), true); + } + + public Fp(Fp rhs) { + this(MclJNI.new_Fp__SWIG_1(Fp.getCPtr(rhs), rhs), true); + } + + public Fp(int x) { + this(MclJNI.new_Fp__SWIG_2(x), true); + } + + public Fp(String str, int base) { + this(MclJNI.new_Fp__SWIG_3(str, base), true); + } + + public Fp(String str) { + this(MclJNI.new_Fp__SWIG_4(str), true); + } + + public boolean equals(Fp rhs) { + return MclJNI.Fp_equals(swigCPtr, this, Fp.getCPtr(rhs), rhs); + } + + public boolean isZero() { + return MclJNI.Fp_isZero(swigCPtr, this); + } + + public boolean isOne() { + return MclJNI.Fp_isOne(swigCPtr, this); + } + + public void setStr(String str, int base) { + MclJNI.Fp_setStr__SWIG_0(swigCPtr, this, str, base); + } + + public void setStr(String str) { + MclJNI.Fp_setStr__SWIG_1(swigCPtr, this, str); + } + + public void setInt(int x) { + MclJNI.Fp_setInt(swigCPtr, this, x); + } + + public void clear() { + MclJNI.Fp_clear(swigCPtr, this); + } + + public void setByCSPRNG() { + MclJNI.Fp_setByCSPRNG(swigCPtr, this); + } + + public String toString(int base) { + return MclJNI.Fp_toString__SWIG_0(swigCPtr, this, base); + } + + public String toString() { + return MclJNI.Fp_toString__SWIG_1(swigCPtr, this); + } + + public void deserialize(byte[] cbuf) { + MclJNI.Fp_deserialize(swigCPtr, this, cbuf); + } + + public byte[] serialize() { + return MclJNI.Fp_serialize(swigCPtr, this); + } +} diff --git a/src/main/java/com/herumi/mcl/Fr.java b/src/main/java/com/herumi/mcl/Fr.java new file mode 100644 index 00000000..15103ce2 --- /dev/null +++ b/src/main/java/com/herumi/mcl/Fr.java @@ -0,0 +1,114 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class Fr { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected Fr(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(Fr obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + MclJNI.delete_Fr(swigCPtr); + } + swigCPtr = 0; + } + } + + public Fr() { + this(MclJNI.new_Fr__SWIG_0(), true); + } + + public Fr(Fr rhs) { + this(MclJNI.new_Fr__SWIG_1(Fr.getCPtr(rhs), rhs), true); + } + + public Fr(int x) { + this(MclJNI.new_Fr__SWIG_2(x), true); + } + + public Fr(String str, int base) { + this(MclJNI.new_Fr__SWIG_3(str, base), true); + } + + public Fr(String str) { + this(MclJNI.new_Fr__SWIG_4(str), true); + } + + public boolean equals(Fr rhs) { + return MclJNI.Fr_equals(swigCPtr, this, Fr.getCPtr(rhs), rhs); + } + + public boolean isZero() { + return MclJNI.Fr_isZero(swigCPtr, this); + } + + public boolean isOne() { + return MclJNI.Fr_isOne(swigCPtr, this); + } + + public void setStr(String str, int base) { + MclJNI.Fr_setStr__SWIG_0(swigCPtr, this, str, base); + } + + public void setStr(String str) { + MclJNI.Fr_setStr__SWIG_1(swigCPtr, this, str); + } + + public void setInt(int x) { + MclJNI.Fr_setInt(swigCPtr, this, x); + } + + public void clear() { + MclJNI.Fr_clear(swigCPtr, this); + } + + public void setByCSPRNG() { + MclJNI.Fr_setByCSPRNG(swigCPtr, this); + } + + public String toString(int base) { + return MclJNI.Fr_toString__SWIG_0(swigCPtr, this, base); + } + + public String toString() { + return MclJNI.Fr_toString__SWIG_1(swigCPtr, this); + } + + public void deserialize(byte[] cbuf) { + MclJNI.Fr_deserialize(swigCPtr, this, cbuf); + } + + public void setLittleEndianMod(byte[] cbuf) { + MclJNI.Fr_setLittleEndianMod(swigCPtr, this, cbuf); + } + + public void setHashOf(byte[] cbuf) { + MclJNI.Fr_setHashOf(swigCPtr, this, cbuf); + } + + public byte[] serialize() { + return MclJNI.Fr_serialize(swigCPtr, this); + } +} diff --git a/src/main/java/com/herumi/mcl/G1.java b/src/main/java/com/herumi/mcl/G1.java new file mode 100644 index 00000000..4f36be2c --- /dev/null +++ b/src/main/java/com/herumi/mcl/G1.java @@ -0,0 +1,114 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class G1 { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected G1(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(G1 obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + MclJNI.delete_G1(swigCPtr); + } + swigCPtr = 0; + } + } + + public G1() { + this(MclJNI.new_G1__SWIG_0(), true); + } + + public G1(G1 rhs) { + this(MclJNI.new_G1__SWIG_1(G1.getCPtr(rhs), rhs), true); + } + + public G1(Fp x, Fp y) { + this(MclJNI.new_G1__SWIG_2(Fp.getCPtr(x), x, Fp.getCPtr(y), y), true); + } + + public boolean equals(G1 rhs) { + return MclJNI.G1_equals(swigCPtr, this, G1.getCPtr(rhs), rhs); + } + + public boolean isZero() { + return MclJNI.G1_isZero(swigCPtr, this); + } + + public boolean isValidOrder() { + return MclJNI.G1_isValidOrder(swigCPtr, this); + } + + public void set(Fp x, Fp y) { + MclJNI.G1_set(swigCPtr, this, Fp.getCPtr(x), x, Fp.getCPtr(y), y); + } + + public void clear() { + MclJNI.G1_clear(swigCPtr, this); + } + + public void setStr(String str, int base) { + MclJNI.G1_setStr__SWIG_0(swigCPtr, this, str, base); + } + + public void setStr(String str) { + MclJNI.G1_setStr__SWIG_1(swigCPtr, this, str); + } + + public String toString(int base) { + return MclJNI.G1_toString__SWIG_0(swigCPtr, this, base); + } + + public String toString() { + return MclJNI.G1_toString__SWIG_1(swigCPtr, this); + } + + public void deserialize(byte[] cbuf) { + MclJNI.G1_deserialize(swigCPtr, this, cbuf); + } + + public byte[] serialize() { + return MclJNI.G1_serialize(swigCPtr, this); + } + + public void normalize() { + MclJNI.G1_normalize(swigCPtr, this); + } + + public void tryAndIncMapTo(Fp x) { + MclJNI.G1_tryAndIncMapTo(swigCPtr, this, Fp.getCPtr(x), x); + } + + public Fp getX() { + return new Fp(MclJNI.G1_getX(swigCPtr, this), true); + } + + public Fp getY() { + return new Fp(MclJNI.G1_getY(swigCPtr, this), true); + } + + public Fp getZ() { + return new Fp(MclJNI.G1_getZ(swigCPtr, this), true); + } +} diff --git a/src/main/java/com/herumi/mcl/G2.java b/src/main/java/com/herumi/mcl/G2.java new file mode 100644 index 00000000..152c75e2 --- /dev/null +++ b/src/main/java/com/herumi/mcl/G2.java @@ -0,0 +1,114 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class G2 { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected G2(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(G2 obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + MclJNI.delete_G2(swigCPtr); + } + swigCPtr = 0; + } + } + + public G2() { + this(MclJNI.new_G2__SWIG_0(), true); + } + + public G2(G2 rhs) { + this(MclJNI.new_G2__SWIG_1(G2.getCPtr(rhs), rhs), true); + } + + public G2(Fp ax, Fp ay, Fp bx, Fp by) { + this( + MclJNI.new_G2__SWIG_2( + Fp.getCPtr(ax), + ax, + Fp.getCPtr(ay), + ay, + Fp.getCPtr(bx), + bx, + Fp.getCPtr(by), + by), + true); + } + + public boolean equals(G2 rhs) { + return MclJNI.G2_equals(swigCPtr, this, G2.getCPtr(rhs), rhs); + } + + public boolean isZero() { + return MclJNI.G2_isZero(swigCPtr, this); + } + + public void set(Fp ax, Fp ay, Fp bx, Fp by) { + MclJNI.G2_set( + swigCPtr, + this, + Fp.getCPtr(ax), + ax, + Fp.getCPtr(ay), + ay, + Fp.getCPtr(bx), + bx, + Fp.getCPtr(by), + by); + } + + public void clear() { + MclJNI.G2_clear(swigCPtr, this); + } + + public void setStr(String str, int base) { + MclJNI.G2_setStr__SWIG_0(swigCPtr, this, str, base); + } + + public void setStr(String str) { + MclJNI.G2_setStr__SWIG_1(swigCPtr, this, str); + } + + public String toString(int base) { + return MclJNI.G2_toString__SWIG_0(swigCPtr, this, base); + } + + public String toString() { + return MclJNI.G2_toString__SWIG_1(swigCPtr, this); + } + + public void deserialize(byte[] cbuf) { + MclJNI.G2_deserialize(swigCPtr, this, cbuf); + } + + public byte[] serialize() { + return MclJNI.G2_serialize(swigCPtr, this); + } + + public void normalize() { + MclJNI.G2_normalize(swigCPtr, this); + } +} diff --git a/src/main/java/com/herumi/mcl/GT.java b/src/main/java/com/herumi/mcl/GT.java new file mode 100644 index 00000000..25ceeca6 --- /dev/null +++ b/src/main/java/com/herumi/mcl/GT.java @@ -0,0 +1,82 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class GT { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected GT(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(GT obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + MclJNI.delete_GT(swigCPtr); + } + swigCPtr = 0; + } + } + + public GT() { + this(MclJNI.new_GT__SWIG_0(), true); + } + + public GT(GT rhs) { + this(MclJNI.new_GT__SWIG_1(GT.getCPtr(rhs), rhs), true); + } + + public boolean equals(GT rhs) { + return MclJNI.GT_equals(swigCPtr, this, GT.getCPtr(rhs), rhs); + } + + public boolean isOne() { + return MclJNI.GT_isOne(swigCPtr, this); + } + + public void clear() { + MclJNI.GT_clear(swigCPtr, this); + } + + public void setStr(String str, int base) { + MclJNI.GT_setStr__SWIG_0(swigCPtr, this, str, base); + } + + public void setStr(String str) { + MclJNI.GT_setStr__SWIG_1(swigCPtr, this, str); + } + + public String toString(int base) { + return MclJNI.GT_toString__SWIG_0(swigCPtr, this, base); + } + + public String toString() { + return MclJNI.GT_toString__SWIG_1(swigCPtr, this); + } + + public void deserialize(byte[] cbuf) { + MclJNI.GT_deserialize(swigCPtr, this, cbuf); + } + + public byte[] serialize() { + return MclJNI.GT_serialize(swigCPtr, this); + } +} diff --git a/src/main/java/com/herumi/mcl/Mcl.java b/src/main/java/com/herumi/mcl/Mcl.java new file mode 100644 index 00000000..9cf2f692 --- /dev/null +++ b/src/main/java/com/herumi/mcl/Mcl.java @@ -0,0 +1,135 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class Mcl implements MclConstants { + public static void SystemInit(int curveType) { + MclJNI.SystemInit(curveType); + } + + public static void neg(Fr y, Fr x) { + MclJNI.neg__SWIG_0(Fr.getCPtr(y), y, Fr.getCPtr(x), x); + } + + public static void inv(Fr y, Fr x) { + MclJNI.inv__SWIG_0(Fr.getCPtr(y), y, Fr.getCPtr(x), x); + } + + public static void add(Fr z, Fr x, Fr y) { + MclJNI.add__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); + } + + public static void sub(Fr z, Fr x, Fr y) { + MclJNI.sub__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); + } + + public static void mul(Fr z, Fr x, Fr y) { + MclJNI.mul__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); + } + + public static void mul(G1 z, G1 x, Fr y) { + MclJNI.mul__SWIG_1(G1.getCPtr(z), z, G1.getCPtr(x), x, Fr.getCPtr(y), y); + } + + public static void mul(G2 z, G2 x, Fr y) { + MclJNI.mul__SWIG_2(G2.getCPtr(z), z, G2.getCPtr(x), x, Fr.getCPtr(y), y); + } + + public static void div(Fr z, Fr x, Fr y) { + MclJNI.div__SWIG_0(Fr.getCPtr(z), z, Fr.getCPtr(x), x, Fr.getCPtr(y), y); + } + + public static void pow(GT z, GT x, Fr y) { + MclJNI.pow(GT.getCPtr(z), z, GT.getCPtr(x), x, Fr.getCPtr(y), y); + } + + public static void neg(Fp y, Fp x) { + MclJNI.neg__SWIG_1(Fp.getCPtr(y), y, Fp.getCPtr(x), x); + } + + public static void inv(Fp y, Fp x) { + MclJNI.inv__SWIG_1(Fp.getCPtr(y), y, Fp.getCPtr(x), x); + } + + public static void add(Fp z, Fp x, Fp y) { + MclJNI.add__SWIG_1(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); + } + + public static void sub(Fp z, Fp x, Fp y) { + MclJNI.sub__SWIG_1(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); + } + + public static void mul(Fp z, Fp x, Fp y) { + MclJNI.mul__SWIG_3(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); + } + + public static void div(Fp z, Fp x, Fp y) { + MclJNI.div__SWIG_1(Fp.getCPtr(z), z, Fp.getCPtr(x), x, Fp.getCPtr(y), y); + } + + public static void neg(G1 y, G1 x) { + MclJNI.neg__SWIG_2(G1.getCPtr(y), y, G1.getCPtr(x), x); + } + + public static void dbl(G1 y, G1 x) { + MclJNI.dbl__SWIG_0(G1.getCPtr(y), y, G1.getCPtr(x), x); + } + + public static void add(G1 z, G1 x, G1 y) { + MclJNI.add__SWIG_2(G1.getCPtr(z), z, G1.getCPtr(x), x, G1.getCPtr(y), y); + } + + public static void sub(G1 z, G1 x, G1 y) { + MclJNI.sub__SWIG_2(G1.getCPtr(z), z, G1.getCPtr(x), x, G1.getCPtr(y), y); + } + + public static void pairing(GT e, G1 P, G2 Q) { + MclJNI.pairing(GT.getCPtr(e), e, G1.getCPtr(P), P, G2.getCPtr(Q), Q); + } + + public static void hashAndMapToG1(G1 P, byte[] cbuf) { + MclJNI.hashAndMapToG1(G1.getCPtr(P), P, cbuf); + } + + public static void neg(G2 y, G2 x) { + MclJNI.neg__SWIG_3(G2.getCPtr(y), y, G2.getCPtr(x), x); + } + + public static void dbl(G2 y, G2 x) { + MclJNI.dbl__SWIG_1(G2.getCPtr(y), y, G2.getCPtr(x), x); + } + + public static void add(G2 z, G2 x, G2 y) { + MclJNI.add__SWIG_3(G2.getCPtr(z), z, G2.getCPtr(x), x, G2.getCPtr(y), y); + } + + public static void sub(G2 z, G2 x, G2 y) { + MclJNI.sub__SWIG_3(G2.getCPtr(z), z, G2.getCPtr(x), x, G2.getCPtr(y), y); + } + + public static void hashAndMapToG2(G2 P, byte[] cbuf) { + MclJNI.hashAndMapToG2(G2.getCPtr(P), P, cbuf); + } + + public static void mul(GT z, GT x, GT y) { + MclJNI.mul__SWIG_4(GT.getCPtr(z), z, GT.getCPtr(x), x, GT.getCPtr(y), y); + } + + public static void inv(GT y, GT x) { + MclJNI.inv__SWIG_2(GT.getCPtr(y), y, GT.getCPtr(x), x); + } + + public static void verifyOrderG1(boolean doVerify) { + MclJNI.verifyOrderG1(doVerify); + } + + public static void verifyOrderG2(boolean doVerify) { + MclJNI.verifyOrderG2(doVerify); + } +} diff --git a/src/main/java/com/herumi/mcl/MclConstants.java b/src/main/java/com/herumi/mcl/MclConstants.java new file mode 100644 index 00000000..9e20bc9d --- /dev/null +++ b/src/main/java/com/herumi/mcl/MclConstants.java @@ -0,0 +1,15 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public interface MclConstants { + public static final int BN254 = 0; + public static final int BLS12_381 = 5; + public static final int SECP256K1 = 102; +} diff --git a/src/main/java/com/herumi/mcl/MclJNI.java b/src/main/java/com/herumi/mcl/MclJNI.java new file mode 100644 index 00000000..81a4fd9d --- /dev/null +++ b/src/main/java/com/herumi/mcl/MclJNI.java @@ -0,0 +1,284 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class MclJNI { + public static final native void SystemInit(int jarg1); + + public static final native void neg__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_); + + public static final native void inv__SWIG_0(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_); + + public static final native void add__SWIG_0( + long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); + + public static final native void sub__SWIG_0( + long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); + + public static final native void mul__SWIG_0( + long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); + + public static final native void mul__SWIG_1( + long jarg1, G1 jarg1_, long jarg2, G1 jarg2_, long jarg3, Fr jarg3_); + + public static final native void mul__SWIG_2( + long jarg1, G2 jarg1_, long jarg2, G2 jarg2_, long jarg3, Fr jarg3_); + + public static final native void div__SWIG_0( + long jarg1, Fr jarg1_, long jarg2, Fr jarg2_, long jarg3, Fr jarg3_); + + public static final native void pow( + long jarg1, GT jarg1_, long jarg2, GT jarg2_, long jarg3, Fr jarg3_); + + public static final native long new_Fr__SWIG_0(); + + public static final native long new_Fr__SWIG_1(long jarg1, Fr jarg1_); + + public static final native long new_Fr__SWIG_2(int jarg1); + + public static final native long new_Fr__SWIG_3(String jarg1, int jarg2); + + public static final native long new_Fr__SWIG_4(String jarg1); + + public static final native boolean Fr_equals(long jarg1, Fr jarg1_, long jarg2, Fr jarg2_); + + public static final native boolean Fr_isZero(long jarg1, Fr jarg1_); + + public static final native boolean Fr_isOne(long jarg1, Fr jarg1_); + + public static final native void Fr_setStr__SWIG_0( + long jarg1, Fr jarg1_, String jarg2, int jarg3); + + public static final native void Fr_setStr__SWIG_1(long jarg1, Fr jarg1_, String jarg2); + + public static final native void Fr_setInt(long jarg1, Fr jarg1_, int jarg2); + + public static final native void Fr_clear(long jarg1, Fr jarg1_); + + public static final native void Fr_setByCSPRNG(long jarg1, Fr jarg1_); + + public static final native String Fr_toString__SWIG_0(long jarg1, Fr jarg1_, int jarg2); + + public static final native String Fr_toString__SWIG_1(long jarg1, Fr jarg1_); + + public static final native void Fr_deserialize(long jarg1, Fr jarg1_, byte[] jarg2); + + public static final native void Fr_setLittleEndianMod(long jarg1, Fr jarg1_, byte[] jarg2); + + public static final native void Fr_setHashOf(long jarg1, Fr jarg1_, byte[] jarg2); + + public static final native byte[] Fr_serialize(long jarg1, Fr jarg1_); + + public static final native void delete_Fr(long jarg1); + + public static final native void neg__SWIG_1(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); + + public static final native void inv__SWIG_1(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); + + public static final native void add__SWIG_1( + long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); + + public static final native void sub__SWIG_1( + long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); + + public static final native void mul__SWIG_3( + long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); + + public static final native void div__SWIG_1( + long jarg1, Fp jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); + + public static final native long new_Fp__SWIG_0(); + + public static final native long new_Fp__SWIG_1(long jarg1, Fp jarg1_); + + public static final native long new_Fp__SWIG_2(int jarg1); + + public static final native long new_Fp__SWIG_3(String jarg1, int jarg2); + + public static final native long new_Fp__SWIG_4(String jarg1); + + public static final native boolean Fp_equals(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); + + public static final native boolean Fp_isZero(long jarg1, Fp jarg1_); + + public static final native boolean Fp_isOne(long jarg1, Fp jarg1_); + + public static final native void Fp_setStr__SWIG_0( + long jarg1, Fp jarg1_, String jarg2, int jarg3); + + public static final native void Fp_setStr__SWIG_1(long jarg1, Fp jarg1_, String jarg2); + + public static final native void Fp_setInt(long jarg1, Fp jarg1_, int jarg2); + + public static final native void Fp_clear(long jarg1, Fp jarg1_); + + public static final native void Fp_setByCSPRNG(long jarg1, Fp jarg1_); + + public static final native String Fp_toString__SWIG_0(long jarg1, Fp jarg1_, int jarg2); + + public static final native String Fp_toString__SWIG_1(long jarg1, Fp jarg1_); + + public static final native void Fp_deserialize(long jarg1, Fp jarg1_, byte[] jarg2); + + public static final native byte[] Fp_serialize(long jarg1, Fp jarg1_); + + public static final native void delete_Fp(long jarg1); + + public static final native void neg__SWIG_2(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_); + + public static final native void dbl__SWIG_0(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_); + + public static final native void add__SWIG_2( + long jarg1, G1 jarg1_, long jarg2, G1 jarg2_, long jarg3, G1 jarg3_); + + public static final native void sub__SWIG_2( + long jarg1, G1 jarg1_, long jarg2, G1 jarg2_, long jarg3, G1 jarg3_); + + public static final native void pairing( + long jarg1, GT jarg1_, long jarg2, G1 jarg2_, long jarg3, G2 jarg3_); + + public static final native void hashAndMapToG1(long jarg1, G1 jarg1_, byte[] jarg2); + + public static final native long new_G1__SWIG_0(); + + public static final native long new_G1__SWIG_1(long jarg1, G1 jarg1_); + + public static final native long new_G1__SWIG_2(long jarg1, Fp jarg1_, long jarg2, Fp jarg2_); + + public static final native boolean G1_equals(long jarg1, G1 jarg1_, long jarg2, G1 jarg2_); + + public static final native boolean G1_isZero(long jarg1, G1 jarg1_); + + public static final native boolean G1_isValidOrder(long jarg1, G1 jarg1_); + + public static final native void G1_set( + long jarg1, G1 jarg1_, long jarg2, Fp jarg2_, long jarg3, Fp jarg3_); + + public static final native void G1_clear(long jarg1, G1 jarg1_); + + public static final native void G1_setStr__SWIG_0( + long jarg1, G1 jarg1_, String jarg2, int jarg3); + + public static final native void G1_setStr__SWIG_1(long jarg1, G1 jarg1_, String jarg2); + + public static final native String G1_toString__SWIG_0(long jarg1, G1 jarg1_, int jarg2); + + public static final native String G1_toString__SWIG_1(long jarg1, G1 jarg1_); + + public static final native void G1_deserialize(long jarg1, G1 jarg1_, byte[] jarg2); + + public static final native byte[] G1_serialize(long jarg1, G1 jarg1_); + + public static final native void G1_normalize(long jarg1, G1 jarg1_); + + public static final native void G1_tryAndIncMapTo(long jarg1, G1 jarg1_, long jarg2, Fp jarg2_); + + public static final native long G1_getX(long jarg1, G1 jarg1_); + + public static final native long G1_getY(long jarg1, G1 jarg1_); + + public static final native long G1_getZ(long jarg1, G1 jarg1_); + + public static final native void delete_G1(long jarg1); + + public static final native void neg__SWIG_3(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_); + + public static final native void dbl__SWIG_1(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_); + + public static final native void add__SWIG_3( + long jarg1, G2 jarg1_, long jarg2, G2 jarg2_, long jarg3, G2 jarg3_); + + public static final native void sub__SWIG_3( + long jarg1, G2 jarg1_, long jarg2, G2 jarg2_, long jarg3, G2 jarg3_); + + public static final native void hashAndMapToG2(long jarg1, G2 jarg1_, byte[] jarg2); + + public static final native long new_G2__SWIG_0(); + + public static final native long new_G2__SWIG_1(long jarg1, G2 jarg1_); + + public static final native long new_G2__SWIG_2( + long jarg1, + Fp jarg1_, + long jarg2, + Fp jarg2_, + long jarg3, + Fp jarg3_, + long jarg4, + Fp jarg4_); + + public static final native boolean G2_equals(long jarg1, G2 jarg1_, long jarg2, G2 jarg2_); + + public static final native boolean G2_isZero(long jarg1, G2 jarg1_); + + public static final native void G2_set( + long jarg1, + G2 jarg1_, + long jarg2, + Fp jarg2_, + long jarg3, + Fp jarg3_, + long jarg4, + Fp jarg4_, + long jarg5, + Fp jarg5_); + + public static final native void G2_clear(long jarg1, G2 jarg1_); + + public static final native void G2_setStr__SWIG_0( + long jarg1, G2 jarg1_, String jarg2, int jarg3); + + public static final native void G2_setStr__SWIG_1(long jarg1, G2 jarg1_, String jarg2); + + public static final native String G2_toString__SWIG_0(long jarg1, G2 jarg1_, int jarg2); + + public static final native String G2_toString__SWIG_1(long jarg1, G2 jarg1_); + + public static final native void G2_deserialize(long jarg1, G2 jarg1_, byte[] jarg2); + + public static final native byte[] G2_serialize(long jarg1, G2 jarg1_); + + public static final native void G2_normalize(long jarg1, G2 jarg1_); + + public static final native void delete_G2(long jarg1); + + public static final native void mul__SWIG_4( + long jarg1, GT jarg1_, long jarg2, GT jarg2_, long jarg3, GT jarg3_); + + public static final native void inv__SWIG_2(long jarg1, GT jarg1_, long jarg2, GT jarg2_); + + public static final native long new_GT__SWIG_0(); + + public static final native long new_GT__SWIG_1(long jarg1, GT jarg1_); + + public static final native boolean GT_equals(long jarg1, GT jarg1_, long jarg2, GT jarg2_); + + public static final native boolean GT_isOne(long jarg1, GT jarg1_); + + public static final native void GT_clear(long jarg1, GT jarg1_); + + public static final native void GT_setStr__SWIG_0( + long jarg1, GT jarg1_, String jarg2, int jarg3); + + public static final native void GT_setStr__SWIG_1(long jarg1, GT jarg1_, String jarg2); + + public static final native String GT_toString__SWIG_0(long jarg1, GT jarg1_, int jarg2); + + public static final native String GT_toString__SWIG_1(long jarg1, GT jarg1_); + + public static final native void GT_deserialize(long jarg1, GT jarg1_, byte[] jarg2); + + public static final native byte[] GT_serialize(long jarg1, GT jarg1_); + + public static final native void delete_GT(long jarg1); + + public static final native void verifyOrderG1(boolean jarg1); + + public static final native void verifyOrderG2(boolean jarg1); +} diff --git a/src/main/java/com/herumi/mcl/PrivateKey.java b/src/main/java/com/herumi/mcl/PrivateKey.java new file mode 100644 index 00000000..978e0d37 --- /dev/null +++ b/src/main/java/com/herumi/mcl/PrivateKey.java @@ -0,0 +1,87 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class PrivateKey { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected PrivateKey(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(PrivateKey obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + ElgamalJNI.delete_PrivateKey(swigCPtr); + } + swigCPtr = 0; + } + } + + public String toStr() { + return ElgamalJNI.PrivateKey_toStr(swigCPtr, this); + } + + public String toString() { + return ElgamalJNI.PrivateKey_toString(swigCPtr, this); + } + + public void fromStr(String str) { + ElgamalJNI.PrivateKey_fromStr(swigCPtr, this, str); + } + + public void save(String fileName) { + ElgamalJNI.PrivateKey_save(swigCPtr, this, fileName); + } + + public void load(String fileName) { + ElgamalJNI.PrivateKey_load(swigCPtr, this, fileName); + } + + public void init() { + ElgamalJNI.PrivateKey_init(swigCPtr, this); + } + + public PublicKey getPublicKey() { + return new PublicKey(ElgamalJNI.PrivateKey_getPublicKey(swigCPtr, this), true); + } + + public int dec(CipherText c, SWIGTYPE_p_bool b) { + return ElgamalJNI.PrivateKey_dec__SWIG_0( + swigCPtr, this, CipherText.getCPtr(c), c, SWIGTYPE_p_bool.getCPtr(b)); + } + + public int dec(CipherText c) { + return ElgamalJNI.PrivateKey_dec__SWIG_1(swigCPtr, this, CipherText.getCPtr(c), c); + } + + public void setCache(int rangeMin, int rangeMax) { + ElgamalJNI.PrivateKey_setCache(swigCPtr, this, rangeMin, rangeMax); + } + + public void clearCache() { + ElgamalJNI.PrivateKey_clearCache(swigCPtr, this); + } + + public PrivateKey() { + this(ElgamalJNI.new_PrivateKey(), true); + } +} diff --git a/src/main/java/com/herumi/mcl/PublicKey.java b/src/main/java/com/herumi/mcl/PublicKey.java new file mode 100644 index 00000000..db8269c7 --- /dev/null +++ b/src/main/java/com/herumi/mcl/PublicKey.java @@ -0,0 +1,82 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class PublicKey { + private transient long swigCPtr; + protected transient boolean swigCMemOwn; + + protected PublicKey(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + protected static long getCPtr(PublicKey obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + @SuppressWarnings("deprecation") + protected void finalize() { + delete(); + } + + public synchronized void delete() { + if (swigCPtr != 0) { + if (swigCMemOwn) { + swigCMemOwn = false; + ElgamalJNI.delete_PublicKey(swigCPtr); + } + swigCPtr = 0; + } + } + + public String toStr() { + return ElgamalJNI.PublicKey_toStr(swigCPtr, this); + } + + public String toString() { + return ElgamalJNI.PublicKey_toString(swigCPtr, this); + } + + public void fromStr(String str) { + ElgamalJNI.PublicKey_fromStr(swigCPtr, this, str); + } + + public void save(String fileName) { + ElgamalJNI.PublicKey_save(swigCPtr, this, fileName); + } + + public void load(String fileName) { + ElgamalJNI.PublicKey_load(swigCPtr, this, fileName); + } + + public void enc(CipherText c, int m) { + ElgamalJNI.PublicKey_enc__SWIG_0(swigCPtr, this, CipherText.getCPtr(c), c, m); + } + + public void enc(CipherText c, String str) { + ElgamalJNI.PublicKey_enc__SWIG_1(swigCPtr, this, CipherText.getCPtr(c), c, str); + } + + public void rerandomize(CipherText c) { + ElgamalJNI.PublicKey_rerandomize(swigCPtr, this, CipherText.getCPtr(c), c); + } + + public void add(CipherText c, int m) { + ElgamalJNI.PublicKey_add__SWIG_0(swigCPtr, this, CipherText.getCPtr(c), c, m); + } + + public void add(CipherText c, String str) { + ElgamalJNI.PublicKey_add__SWIG_1(swigCPtr, this, CipherText.getCPtr(c), c, str); + } + + public PublicKey() { + this(ElgamalJNI.new_PublicKey(), true); + } +} diff --git a/src/main/java/com/herumi/mcl/SWIGTYPE_p_bool.java b/src/main/java/com/herumi/mcl/SWIGTYPE_p_bool.java new file mode 100644 index 00000000..5f7e951a --- /dev/null +++ b/src/main/java/com/herumi/mcl/SWIGTYPE_p_bool.java @@ -0,0 +1,25 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.2 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +package com.herumi.mcl; + +public class SWIGTYPE_p_bool { + private transient long swigCPtr; + + protected SWIGTYPE_p_bool(long cPtr, @SuppressWarnings("unused") boolean futureUse) { + swigCPtr = cPtr; + } + + protected SWIGTYPE_p_bool() { + swigCPtr = 0; + } + + protected static long getCPtr(SWIGTYPE_p_bool obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +} diff --git a/src/main/java/org/arkecosystem/crypto/enums/AbiFunction.java b/src/main/java/org/arkecosystem/crypto/enums/AbiFunction.java index 75202ca8..ee4c269f 100644 --- a/src/main/java/org/arkecosystem/crypto/enums/AbiFunction.java +++ b/src/main/java/org/arkecosystem/crypto/enums/AbiFunction.java @@ -3,6 +3,8 @@ public enum AbiFunction { VOTE("vote"), UNVOTE("unvote"), + USERNAME_REGISTRATION("registerUsername"), + USERNAME_RESIGNATION("resignUsername"), VALIDATOR_REGISTRATION("registerValidator"), VALIDATOR_RESIGNATION("resignValidator"); diff --git a/src/main/java/org/arkecosystem/crypto/signature/bls/Bls.java b/src/main/java/org/arkecosystem/crypto/signature/bls/Bls.java new file mode 100644 index 00000000..e550cf70 --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/signature/bls/Bls.java @@ -0,0 +1,118 @@ +package org.arkecosystem.crypto.signature.bls; + +import com.herumi.mcl.G1; +import com.herumi.mcl.G2; +import com.herumi.mcl.GT; +import com.herumi.mcl.Mcl; +import org.arkecosystem.crypto.Schnorr; + +public class Bls implements BlsConstants { + static { + String lib = "mcljava"; + JNIEnv env = new JNIEnv(); + env.prepare(); + System.loadLibrary(lib); + } + + public void validateBlsPublicKey(String publicKeyHex) { + G1 publicKey = new G1(); + + try { + publicKey.deserialize(Schnorr.hexStringToByteArray(publicKeyHex)); + } catch (Exception e) { + throw new IllegalArgumentException("Invalid BLS public key"); + } + } + + private int curveType; + + /* + * Generate private key + */ + public PrivateKey generateSecKey() { + PrivateKey privateKey = new PrivateKey(curveType); + return privateKey; + } + + public Bls(int curveType) { + this.curveType = curveType; + Mcl.SystemInit(curveType); + } + + /* + * Aggregate signatures + */ + public byte[] aggregateSignature(byte[][] s) { + G2[] ss = new G2[s.length]; + for (int i = 0; i < s.length; i++) { + ss[i] = new G2(); + ss[i].deserialize(s[i]); + } + for (int i = 1; i < s.length; i++) { + Mcl.add(ss[0], ss[0], ss[i]); + } + return ss[0].serialize(); + } + + /* + * Aggregate public key + */ + public byte[] aggregatePublicKey(byte[][] pub) { + G1[] pubs = new G1[pub.length]; + for (int i = 0; i < pub.length; i++) { + pubs[i] = new G1(); + pubs[i].deserialize(pub[i]); + } + for (int i = 1; i < pub.length; i++) { + Mcl.add(pubs[0], pubs[0], pubs[i]); + } + return pubs[0].serialize(); + } + + /* + * Aggregate message to be signed + */ + public byte[] aggregateMsg(byte[][] msg) { + G2[] msgs = new G2[msg.length]; + for (int i = 0; i < msg.length; i++) { + msgs[i] = new G2(); + Mcl.hashAndMapToG2(msgs[i], msg[i]); + } + for (int i = 1; i < msg.length; i++) { + Mcl.add(msgs[0], msgs[0], msgs[i]); + } + return msgs[0].serialize(); + } + + /* + * Verify aggregate signature + * Case: multiple messages, multiple private keys with multiple signatures + */ + public boolean verifyAggregate(byte[][] msg, byte[] sig, byte[][] pub) { + G2[] H = new G2[msg.length]; + for (int i = 0; i < msg.length; i++) { + H[i] = new G2(); + Mcl.hashAndMapToG2(H[i], msg[i]); + } + G1[] pubs = new G1[pub.length]; + for (int i = 0; i < pub.length; i++) { + pubs[i] = new G1(); + pubs[i].deserialize(pub[i]); + } + G1 Q = new G1(); + Q.setStr(Bls.BaseG1); + G2 g2 = new G2(); + g2.deserialize(sig); + GT[] e1 = new GT[msg.length]; + GT e2 = new GT(); + for (int i = 0; i < msg.length; i++) { + e1[i] = new GT(); + Mcl.pairing(e1[i], pubs[i], H[i]); // e1 = e(H, s Q) + } + for (int i = 1; i < msg.length; i++) { + Mcl.mul(e1[0], e1[0], e1[i]); + } + Mcl.pairing(e2, Q, g2); // e2 = e(s H, Q); + return e1[0].equals(e2); + } +} diff --git a/src/main/java/org/arkecosystem/crypto/signature/bls/BlsConstants.java b/src/main/java/org/arkecosystem/crypto/signature/bls/BlsConstants.java new file mode 100644 index 00000000..5954a218 --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/signature/bls/BlsConstants.java @@ -0,0 +1,7 @@ +package org.arkecosystem.crypto.signature.bls; + +public interface BlsConstants { + public static final int BLS12_381 = 5; + public static final String BaseG1 = + "1 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569"; +} diff --git a/src/main/java/org/arkecosystem/crypto/signature/bls/JNIEnv.java b/src/main/java/org/arkecosystem/crypto/signature/bls/JNIEnv.java new file mode 100644 index 00000000..8a37b471 --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/signature/bls/JNIEnv.java @@ -0,0 +1,82 @@ +package org.arkecosystem.crypto.signature.bls; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public class JNIEnv { + byte[] cache; + List sources; + + public JNIEnv() { + cache = new byte[1024]; + sources = new LinkedList(); + String OS = System.getProperty("os.name").toLowerCase(); + String ARCH = System.getProperty(("os.arch")).toLowerCase(); + if (OS.contains("mac") && (ARCH.contains("x86_64") || ARCH.contains("aarch64"))) { + sources.add("libmcljava.dylib"); + } else if (OS.contains("linux") && ARCH.contains("amd64")) { + sources.add("libmcljava.so"); + } + } + + private Boolean sourceExist(String sourceName) { + String[] libraryPaths = System.getProperty("java.library.path").split(File.pathSeparator); + for (String path : libraryPaths) { + File f = new File(path, sourceName); + if (f.exists()) { + return true; + } + } + return false; + } + + public void prepare() { + for (String s : sources) { + copy(s); + } + } + + public Boolean copy(String sourceName) { + if (sourceExist(sourceName)) { + return true; + } else { + try { + String[] libraryPaths = + System.getProperty("java.library.path").split(File.pathSeparator); + File f = + new File( + libraryPaths[0], + sourceName); // Using the first path in java.library.path + if (!f.exists()) { + f.createNewFile(); + System.out.println("[JNIDEV]:DEFAULT JNI INITION:" + sourceName); + } + FileOutputStream os = new FileOutputStream(f); + + InputStream is = + getClass() + .getResourceAsStream( + "/" + sourceName); // Modified to add leading slash + if (is == null) { + os.close(); + return false; + } + Arrays.fill(cache, (byte) 0); + int realRead = is.read(cache); + while (realRead != -1) { + os.write(cache, 0, realRead); + realRead = is.read(cache); + } + os.close(); + } catch (Exception e) { + System.out.println("[JNIDEV]:ERROR IN COPY JNI LIB!"); + return false; + } + } + return true; + } +} diff --git a/src/main/java/org/arkecosystem/crypto/signature/bls/PrivateKey.java b/src/main/java/org/arkecosystem/crypto/signature/bls/PrivateKey.java new file mode 100644 index 00000000..1545cfa9 --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/signature/bls/PrivateKey.java @@ -0,0 +1,62 @@ +package org.arkecosystem.crypto.signature.bls; + +import com.herumi.mcl.Fr; +import com.herumi.mcl.G1; +import com.herumi.mcl.G2; +import com.herumi.mcl.Mcl; + +public class PrivateKey implements java.security.PrivateKey { + private int curveType; + private byte[] secKey; + + @Override + public String getAlgorithm() { + if (curveType == Bls.BLS12_381) { + return "BLS12-381"; + } else { + return "NOT SUPPORTED"; + } + } + + @Override + public String getFormat() { + return null; + } + + @Override + public byte[] getEncoded() { + return secKey; + } + + public PrivateKey(int curveType) { + this.curveType = curveType; + Fr fr = new Fr(); + fr.setByCSPRNG(); + secKey = fr.serialize(); + } + + public PublicKey getPublicKey() { + G1 Q = new G1(); + Q.setStr(Bls.BaseG1); + G1 pub = new G1(); + Fr fr = new Fr(); + fr.deserialize(secKey); + Mcl.mul(pub, Q, fr); + + PublicKey publicKey = new PublicKey(curveType, pub.serialize()); + return publicKey; + } + + /* + * Sign a message + */ + public byte[] sign(byte[] msg) { + G2 H = new G2(); + Mcl.hashAndMapToG2(H, msg); // H = Hash(m) + G2 sig = new G2(); + Fr fr = new Fr(); + fr.deserialize(secKey); + Mcl.mul(sig, H, fr); // signature of m = s H + return sig.serialize(); + } +} diff --git a/src/main/java/org/arkecosystem/crypto/signature/bls/PublicKey.java b/src/main/java/org/arkecosystem/crypto/signature/bls/PublicKey.java new file mode 100644 index 00000000..8ee00c8a --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/signature/bls/PublicKey.java @@ -0,0 +1,78 @@ +package org.arkecosystem.crypto.signature.bls; + +import com.herumi.mcl.G1; +import com.herumi.mcl.G2; +import com.herumi.mcl.GT; +import com.herumi.mcl.Mcl; + +public class PublicKey implements java.security.PublicKey { + private int curveType; + private byte[] pubKey; + + @Override + public String getAlgorithm() { + if (curveType == Bls.BLS12_381) { + return "BLS12-381"; + } else { + return "NOT SUPPORTED"; + } + } + + @Override + public String getFormat() { + return null; + } + + @Override + public byte[] getEncoded() { + return pubKey; + } + + public PublicKey(int curveType, byte[] pubKey) { + this.curveType = curveType; + this.pubKey = pubKey; + } + + /* + * Veryfi signature + * Case 1: single message and single signature + * Case 2: single message and multiple signatures + */ + public boolean verify(byte[] msg, byte[] sig) { + G2 H = new G2(); + Mcl.hashAndMapToG2(H, msg); // H = Hash(m) + G1 pub = new G1(); + pub.deserialize(pubKey); + G1 Q = new G1(); + Q.setStr(Bls.BaseG1); + G2 g2 = new G2(); + g2.deserialize(sig); + GT e1 = new GT(); + GT e2 = new GT(); + Mcl.pairing(e1, pub, H); // e1 = e(H, s Q) + Mcl.pairing(e2, Q, g2); // e2 = e(s H, Q); + return e1.equals(e2); + } + + /* + * Verify mutiple signatures + * Case: Single private key and multiple messages with multiple signatures + * h: Not the message itself, it's result of hashAndMapToG2 + */ + public boolean verifyAggregate(byte[] h, byte[] sig) { + G2 H = new G2(); + H.deserialize(h); // H = Hash(m) + G1 pub = new G1(); + pub.deserialize(pubKey); + G1 Q = new G1(); + Q.setStr(Bls.BaseG1); + + G2 g2 = new G2(); + g2.deserialize(sig); + GT e1 = new GT(); + GT e2 = new GT(); + Mcl.pairing(e1, pub, H); // e1 = e(H, s Q) + Mcl.pairing(e2, Q, g2); // e2 = e(s H, Q); + return e1.equals(e2); + } +} diff --git a/src/main/java/org/arkecosystem/crypto/transactions/TransactionAsset.java b/src/main/java/org/arkecosystem/crypto/transactions/TransactionAsset.java index 650d0449..8406c75c 100644 --- a/src/main/java/org/arkecosystem/crypto/transactions/TransactionAsset.java +++ b/src/main/java/org/arkecosystem/crypto/transactions/TransactionAsset.java @@ -3,6 +3,9 @@ import java.util.HashMap; public class TransactionAsset { + public HashMap customAsset = new HashMap<>(); + public long amount = 0L; + public String username; public EvmCall evmCall = new EvmCall(); // Instance of EvmCall public String vote = ""; public String validatorPublicKey = ""; diff --git a/src/main/java/org/arkecosystem/crypto/transactions/builder/UsernameRegistrationBuilder.java b/src/main/java/org/arkecosystem/crypto/transactions/builder/UsernameRegistrationBuilder.java new file mode 100644 index 00000000..cbfd8814 --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/transactions/builder/UsernameRegistrationBuilder.java @@ -0,0 +1,23 @@ +package org.arkecosystem.crypto.transactions.builder; + +import org.arkecosystem.crypto.transactions.types.AbstractTransaction; +import org.arkecosystem.crypto.transactions.types.UsernameRegistration; + +public class UsernameRegistrationBuilder + extends AbstractTransactionBuilder { + public UsernameRegistrationBuilder username(String username) { + this.transaction.username = username; + + return this; + } + + @Override + public AbstractTransaction getTransactionInstance() { + return new UsernameRegistration(); + } + + @Override + public UsernameRegistrationBuilder instance() { + return this; + } +} diff --git a/src/main/java/org/arkecosystem/crypto/transactions/builder/UsernameResignationBuilder.java b/src/main/java/org/arkecosystem/crypto/transactions/builder/UsernameResignationBuilder.java new file mode 100644 index 00000000..daa4581e --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/transactions/builder/UsernameResignationBuilder.java @@ -0,0 +1,18 @@ +package org.arkecosystem.crypto.transactions.builder; + +import org.arkecosystem.crypto.transactions.types.AbstractTransaction; +import org.arkecosystem.crypto.transactions.types.UsernameResignation; + +public class UsernameResignationBuilder + extends AbstractTransactionBuilder { + + @Override + public AbstractTransaction getTransactionInstance() { + return new UsernameResignation(); + } + + @Override + public UsernameResignationBuilder instance() { + return this; + } +} diff --git a/src/main/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilder.java b/src/main/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilder.java index 01049455..ea8270e0 100644 --- a/src/main/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilder.java +++ b/src/main/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilder.java @@ -1,5 +1,7 @@ package org.arkecosystem.crypto.transactions.builder; +import org.arkecosystem.crypto.signature.bls.Bls; +import org.arkecosystem.crypto.signature.bls.BlsConstants; import org.arkecosystem.crypto.transactions.types.AbstractTransaction; import org.arkecosystem.crypto.transactions.types.ValidatorRegistration; @@ -22,4 +24,14 @@ protected AbstractTransaction getTransactionInstance() { protected ValidatorRegistrationBuilder instance() { return this; } + + private void validateBlsPublicKey(String publicKeyHex) { + if (publicKeyHex.length() != 96) { + throw new IllegalArgumentException("Invalid BLS public key length"); + } + + Bls bls = new Bls(BlsConstants.BLS12_381); + + bls.validateBlsPublicKey(publicKeyHex); + } } diff --git a/src/main/java/org/arkecosystem/crypto/transactions/types/AbstractTransaction.java b/src/main/java/org/arkecosystem/crypto/transactions/types/AbstractTransaction.java index abbf76b6..3a95032d 100644 --- a/src/main/java/org/arkecosystem/crypto/transactions/types/AbstractTransaction.java +++ b/src/main/java/org/arkecosystem/crypto/transactions/types/AbstractTransaction.java @@ -29,6 +29,7 @@ public abstract class AbstractTransaction { public int gasLimit; public int gasPrice; public String validatorPublicKey; + public String username; public String vote; public AbstractTransaction() {} diff --git a/src/main/java/org/arkecosystem/crypto/transactions/types/UsernameRegistration.java b/src/main/java/org/arkecosystem/crypto/transactions/types/UsernameRegistration.java new file mode 100644 index 00000000..7ae16ab7 --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/transactions/types/UsernameRegistration.java @@ -0,0 +1,45 @@ +package org.arkecosystem.crypto.transactions.types; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.arkecosystem.crypto.enums.AbiFunction; +import org.arkecosystem.crypto.utils.AbiEncoder; + +public class UsernameRegistration extends AbstractTransaction { + public UsernameRegistration() { + super(); // Call the default constructor of AbstractTransaction + } + + public UsernameRegistration(Map data) { + super(data); + + // Use a local decodePayload method since we can't rely on AbstractTransaction's data field + List payload = decodePayload(data); + if (payload != null && !payload.isEmpty()) { + Object arg = payload.get(0); + this.username = arg.toString(); + } + } + + @Override + public String getPayload() { + if (this.username == null || this.username.isEmpty()) { + return ""; + } + + List args = new ArrayList<>(); + args.add(this.username); + + try { + return new AbiEncoder() + .encodeFunctionCall(AbiFunction.USERNAME_REGISTRATION.toString(), args); + } catch (Exception e) { + throw new RuntimeException("Error encoding function call", e); + } + } +} diff --git a/src/main/java/org/arkecosystem/crypto/transactions/types/UsernameResignation.java b/src/main/java/org/arkecosystem/crypto/transactions/types/UsernameResignation.java new file mode 100644 index 00000000..a39f4ae7 --- /dev/null +++ b/src/main/java/org/arkecosystem/crypto/transactions/types/UsernameResignation.java @@ -0,0 +1,28 @@ +package org.arkecosystem.crypto.transactions.types; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import org.arkecosystem.crypto.enums.AbiFunction; +import org.arkecosystem.crypto.utils.AbiEncoder; + +public class UsernameResignation extends AbstractTransaction { + public UsernameResignation() { + super(); // Call the default constructor of AbstractTransaction + } + + public UsernameResignation(Map data) { + super(data); + } + + @Override + public String getPayload() { + try { + return new AbiEncoder() + .encodeFunctionCall(AbiFunction.USERNAME_RESIGNATION.toString()); + } catch (Exception e) { + throw new RuntimeException("Error encoding function call", e); + } + } +} diff --git a/src/test/java/org/arkecosystem/crypto/transactions/builder/TransferBuilderTest.java b/src/test/java/org/arkecosystem/crypto/transactions/builder/TransferBuilderTest.java index f8c53e7d..6c1b9e8c 100644 --- a/src/test/java/org/arkecosystem/crypto/transactions/builder/TransferBuilderTest.java +++ b/src/test/java/org/arkecosystem/crypto/transactions/builder/TransferBuilderTest.java @@ -1,5 +1,8 @@ package org.arkecosystem.crypto.transactions.builder; +import java.util.HashMap; +import java.util.List; +import org.arkecosystem.crypto.transactions.types.Transaction; import static org.junit.jupiter.api.Assertions.*; import java.util.Map; @@ -33,4 +36,30 @@ public void it_should_sign_it_with_a_passphrase() throws Exception { assertEquals(data.get("id"), builder.transaction.getId()); assertTrue(builder.verify()); } + + @Test + void buildMultiSignature() { + Transaction actual = + new TransferBuilder() + .recipient("0xb693449AdDa7EFc015D87944EAE8b7C37EB1690A") + .amount(133380000000L) + .expiration(100000) + .vendorField("This is a transaction from Java") + .nonce(3) + .multiSign("secret 1", 0) + .multiSign("secret 2", 1) + .multiSign("secret 3", 2) + .sign("secret 1") + .transaction; + + assertTrue(actual.verify()); + + HashMap actualHashMap = actual.toHashMap(); + + assertNotNull(actualHashMap.get("signatures")); + + List actualSignatures = (List) actualHashMap.get("signatures"); + + assertEquals(3, actualSignatures.size()); + } } diff --git a/src/test/java/org/arkecosystem/crypto/transactions/builder/UsernameRegistrationBuilderTest.java b/src/test/java/org/arkecosystem/crypto/transactions/builder/UsernameRegistrationBuilderTest.java new file mode 100644 index 00000000..d373b3f5 --- /dev/null +++ b/src/test/java/org/arkecosystem/crypto/transactions/builder/UsernameRegistrationBuilderTest.java @@ -0,0 +1,51 @@ +package org.arkecosystem.crypto.transactions.builder; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.HashMap; +import java.util.List; +import org.arkecosystem.crypto.transactions.types.Transaction; +import org.junit.jupiter.api.Test; + +class UsernameRegistrationBuilderTest { + @Test + void build() { + Transaction actual = + new UsernameRegistrationBuilder() + .usernameAsset("alfonsobries") + .nonce(3) + .sign("this is a top secret passphrase") + .transaction; + + HashMap actualHashMap = actual.toHashMap(); + + HashMap asset = (HashMap) actualHashMap.get("asset"); + + assertEquals(asset.get("username"), "alfonsobries"); + + assertTrue(actual.verify()); + } + + @Test + void buildMultiSignature() { + Transaction actual = + new UsernameRegistrationBuilder() + .usernameAsset("alfonsobries") + .nonce(3) + .multiSign("secret 1", 0) + .multiSign("secret 2", 1) + .multiSign("secret 3", 2) + .sign("this is a top secret passphrase") + .transaction; + + assertTrue(actual.verify()); + + HashMap actualHashMap = actual.toHashMap(); + + assertNotNull(actualHashMap.get("signatures")); + + List actualSignatures = (List) actualHashMap.get("signatures"); + + assertEquals(3, actualSignatures.size()); + } +} diff --git a/src/test/java/org/arkecosystem/crypto/transactions/builder/UsernameResignationBuilderTest.java b/src/test/java/org/arkecosystem/crypto/transactions/builder/UsernameResignationBuilderTest.java new file mode 100644 index 00000000..e96e39ed --- /dev/null +++ b/src/test/java/org/arkecosystem/crypto/transactions/builder/UsernameResignationBuilderTest.java @@ -0,0 +1,62 @@ +package org.arkecosystem.crypto.transactions.builder; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.HashMap; +import java.util.List; +import org.arkecosystem.crypto.transactions.types.Transaction; +import org.junit.jupiter.api.Test; + +public class UsernameResignationBuilderTest { + @Test + void build() { + Transaction actual = + new UsernameResignationBuilder() + .nonce(3) + .sign("this is a top secret passphrase") + .transaction; + + HashMap actualHashMap = actual.toHashMap(); + HashMap actualAsset = (HashMap) actualHashMap.get("asset"); + assertNull(actualAsset); + + assertTrue(actual.verify()); + } + + @Test + void buildSecondSignature() { + Transaction actual = + new UsernameResignationBuilder() + .nonce(3) + .sign("this is a top secret passphrase") + .secondSign("this is a top secret second passphrase") + .transaction; + + assertTrue(actual.verify()); + assertTrue( + actual.secondVerify( + "03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609")); + } + + @Test + void buildMultiSignature() { + Transaction actual = + new UsernameResignationBuilder() + .nonce(3) + .multiSign("secret 1", 0) + .multiSign("secret 2", 1) + .multiSign("secret 3", 2) + .sign("this is a top secret passphrase") + .transaction; + + assertTrue(actual.verify()); + + HashMap actualHashMap = actual.toHashMap(); + + assertNotNull(actualHashMap.get("signatures")); + + List actualSignatures = (List) actualHashMap.get("signatures"); + + assertEquals(3, actualSignatures.size()); + } +} diff --git a/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilderTest.java b/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilderTest.java index 340fa7e5..ce44e468 100644 --- a/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilderTest.java +++ b/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorRegistrationBuilderTest.java @@ -2,6 +2,9 @@ import static org.junit.jupiter.api.Assertions.*; +import java.util.HashMap; +import java.util.List; +import org.arkecosystem.crypto.transactions.types.Transaction; import java.util.Map; import org.arkecosystem.crypto.AbstractTest; import org.arkecosystem.crypto.encoding.Hex; @@ -33,4 +36,66 @@ public void it_should_sign_it_with_a_passphrase() throws Exception { assertEquals(data.get("id"), builder.transaction.getId()); assertTrue(builder.verify()); } + + @Test + void testValidatorRegistrationTransactionWithInvalidBlsPublicKey() { + Exception exception = + assertThrows( + IllegalArgumentException.class, + () -> { + new ValidatorRegistrationBuilder() + .publicKeyAsset( + "b5fea88b9aab3f0b122e5a7e1b07917e62a63ea59103d0a0715ecded3c41685af88f0a9606309b148b3b50f51a2edddd") + .nonce(3) + .sign("this is a top secret passphrase"); + }); + + String expectedMessage = "Invalid BLS public key"; + String actualMessage = exception.getMessage(); + + assertTrue(actualMessage.contains(expectedMessage)); + } + + @Test + void testValidatorRegistrationTransactionWithInvalidBlsPublicKeyByLength() { + Exception exception = + assertThrows( + IllegalArgumentException.class, + () -> { + new ValidatorRegistrationBuilder() + .publicKeyAsset( + "023efc1da7f315f3c533a4080e491f32cd4219731cef008976c3876539e1f192d3") + .nonce(3) + .sign("this is a top secret passphrase"); + }); + + String expectedMessage = "Invalid BLS public key"; + String actualMessage = exception.getMessage(); + + assertTrue(actualMessage.contains(expectedMessage)); + } + + @Test + void buildMultiSignature() { + Transaction actual = + new ValidatorRegistrationBuilder() + .publicKeyAsset( + "a08058db53e2665c84a40f5152e76dd2b652125a6079130d4c315e728bcf4dd1dfb44ac26e82302331d61977d3141118") + .nonce(3) + .multiSign("secret 1", 0) + .multiSign("secret 2", 1) + .multiSign("secret 3", 2) + .sign("this is a top secret passphrase") + .transaction; + + assertTrue(actual.verify()); + + HashMap actualHashMap = actual.toHashMap(); + + assertNotNull(actualHashMap.get("signatures")); + + List actualSignatures = (List) actualHashMap.get("signatures"); + + assertEquals(3, actualSignatures.size()); + } } diff --git a/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorResignationBuilderTest.java b/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorResignationBuilderTest.java index 69de48a1..06e2efe3 100644 --- a/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorResignationBuilderTest.java +++ b/src/test/java/org/arkecosystem/crypto/transactions/builder/ValidatorResignationBuilderTest.java @@ -2,6 +2,9 @@ import static org.junit.jupiter.api.Assertions.*; +import java.util.HashMap; +import java.util.List; +import org.arkecosystem.crypto.transactions.types.Transaction; import java.util.Map; import org.arkecosystem.crypto.AbstractTest; import org.arkecosystem.crypto.encoding.Hex; @@ -31,4 +34,26 @@ public void it_should_sign_it_with_a_passphrase() throws Exception { assertEquals(data.get("id"), builder.transaction.getId()); assertTrue(builder.verify()); } + + @Test + void buildMultiSignature() { + Transaction actual = + new ValidatorResignationBuilder() + .nonce(3) + .multiSign("secret 1", 0) + .multiSign("secret 2", 1) + .multiSign("secret 3", 2) + .sign("this is a top secret passphrase") + .transaction; + + assertTrue(actual.verify()); + + HashMap actualHashMap = actual.toHashMap(); + + assertNotNull(actualHashMap.get("signatures")); + + List actualSignatures = (List) actualHashMap.get("signatures"); + + assertEquals(3, actualSignatures.size()); + } } diff --git a/src/test/java/org/arkecosystem/crypto/transactions/builder/VoteBuilderTest.java b/src/test/java/org/arkecosystem/crypto/transactions/builder/VoteBuilderTest.java index cd6bc6ee..cc111fd6 100644 --- a/src/test/java/org/arkecosystem/crypto/transactions/builder/VoteBuilderTest.java +++ b/src/test/java/org/arkecosystem/crypto/transactions/builder/VoteBuilderTest.java @@ -32,4 +32,29 @@ public void it_should_sign_it_with_a_passphrase() throws Exception { assertEquals(data.get("id"), builder.transaction.getId()); assertTrue(builder.verify()); } + + @Test + void buildMultiSignature() { + Transaction actual = + new VoteBuilder() + .addVote( + "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192") + .version(2) + .nonce(3) + .multiSign("secret 1", 0) + .multiSign("secret 2", 1) + .multiSign("secret 3", 2) + .sign("this is a top secret passphrase") + .transaction; + + assertTrue(actual.verify()); + + HashMap actualHashMap = actual.toHashMap(); + + assertNotNull(actualHashMap.get("signatures")); + + List actualSignatures = (List) actualHashMap.get("signatures"); + + assertEquals(3, actualSignatures.size()); + } } diff --git a/src/test/java/org/arkecosystem/crypto/transactions/deserializers/UsernameRegistrationTest.java b/src/test/java/org/arkecosystem/crypto/transactions/deserializers/UsernameRegistrationTest.java new file mode 100644 index 00000000..351563e3 --- /dev/null +++ b/src/test/java/org/arkecosystem/crypto/transactions/deserializers/UsernameRegistrationTest.java @@ -0,0 +1,35 @@ +package org.arkecosystem.crypto.transactions.deserializers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.internal.LinkedTreeMap; +import org.arkecosystem.crypto.transactions.Deserializer; +import org.arkecosystem.crypto.transactions.FixtureLoader; +import org.arkecosystem.crypto.transactions.types.Transaction; +import org.junit.jupiter.api.Test; + +public class UsernameRegistrationTest { + + @Test + void passphrase() { + LinkedTreeMap fixture = + FixtureLoader.load("transactions/username_registration/username-registration-sign"); + + LinkedTreeMap data = (LinkedTreeMap) fixture.get("data"); + + Transaction actual = new Deserializer(fixture.get("serialized").toString()).deserialize(); + + assertEquals(((Double) data.get("version")).intValue(), actual.version); + assertEquals(((Double) data.get("network")).intValue(), actual.network); + assertEquals(((Double) data.get("type")).intValue(), actual.type); + assertEquals((Long.valueOf((String) data.get("nonce"))), actual.nonce); + assertEquals(data.get("senderPublicKey").toString(), actual.senderPublicKey); + assertEquals((Long.valueOf((String) data.get("fee"))), actual.fee); + assertEquals(data.get("signature").toString(), actual.signature); + assertEquals(data.get("id").toString(), actual.id); + + LinkedTreeMap asset = (LinkedTreeMap) data.get("asset"); + + assertEquals((asset.get("username")), actual.asset.username); + } +} diff --git a/src/test/java/org/arkecosystem/crypto/transactions/deserializers/UsernameResignationTest.java b/src/test/java/org/arkecosystem/crypto/transactions/deserializers/UsernameResignationTest.java new file mode 100644 index 00000000..a177227a --- /dev/null +++ b/src/test/java/org/arkecosystem/crypto/transactions/deserializers/UsernameResignationTest.java @@ -0,0 +1,34 @@ +package org.arkecosystem.crypto.transactions.deserializers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import com.google.gson.internal.LinkedTreeMap; +import org.arkecosystem.crypto.transactions.Deserializer; +import org.arkecosystem.crypto.transactions.FixtureLoader; +import org.arkecosystem.crypto.transactions.types.Transaction; +import org.junit.jupiter.api.Test; + +class UsernameResignationTest { + + @Test + void passphrase() { + LinkedTreeMap fixture = + FixtureLoader.load("transactions/username_resignation/username-resignation-sign"); + + LinkedTreeMap data = (LinkedTreeMap) fixture.get("data"); + + Transaction actual = new Deserializer(fixture.get("serialized").toString()).deserialize(); + + assertEquals(((Double) data.get("version")).intValue(), actual.version); + assertEquals(((Double) data.get("network")).intValue(), actual.network); + assertEquals(((Double) data.get("type")).intValue(), actual.type); + assertEquals((Long.valueOf((String) data.get("nonce"))), actual.nonce); + assertEquals(data.get("senderPublicKey").toString(), actual.senderPublicKey); + assertEquals((Long.valueOf((String) data.get("fee"))), actual.fee); + assertEquals(data.get("signature").toString(), actual.signature); + assertEquals(data.get("id").toString(), actual.id); + + assertNull(data.get("asset")); + } +} diff --git a/src/test/java/org/arkecosystem/crypto/transactions/serializers/UsernameRegistrationTest.java b/src/test/java/org/arkecosystem/crypto/transactions/serializers/UsernameRegistrationTest.java new file mode 100644 index 00000000..c07191d6 --- /dev/null +++ b/src/test/java/org/arkecosystem/crypto/transactions/serializers/UsernameRegistrationTest.java @@ -0,0 +1,25 @@ +package org.arkecosystem.crypto.transactions.serializers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.internal.LinkedTreeMap; +import org.arkecosystem.crypto.encoding.Hex; +import org.arkecosystem.crypto.transactions.Deserializer; +import org.arkecosystem.crypto.transactions.FixtureLoader; +import org.arkecosystem.crypto.transactions.Serializer; +import org.arkecosystem.crypto.transactions.types.Transaction; +import org.junit.jupiter.api.Test; + +class UsernameRegistrationTest { + @Test + void passphrase() { + LinkedTreeMap fixture = + FixtureLoader.load("transactions/username_registration/username-registration-sign"); + Transaction transaction = + new Deserializer(fixture.get("serialized").toString()).deserialize(); + + String actual = Hex.encode(Serializer.serialize(transaction)); + + assertEquals(fixture.get("serialized").toString(), actual); + } +} diff --git a/src/test/java/org/arkecosystem/crypto/transactions/serializers/UsernameResignationTest.java b/src/test/java/org/arkecosystem/crypto/transactions/serializers/UsernameResignationTest.java new file mode 100644 index 00000000..ec77bef7 --- /dev/null +++ b/src/test/java/org/arkecosystem/crypto/transactions/serializers/UsernameResignationTest.java @@ -0,0 +1,26 @@ +package org.arkecosystem.crypto.transactions.serializers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.internal.LinkedTreeMap; +import org.arkecosystem.crypto.encoding.Hex; +import org.arkecosystem.crypto.transactions.Deserializer; +import org.arkecosystem.crypto.transactions.FixtureLoader; +import org.arkecosystem.crypto.transactions.Serializer; +import org.arkecosystem.crypto.transactions.types.Transaction; +import org.junit.jupiter.api.Test; + +class UsernameResignationTest { + @Test + void passphrase() { + LinkedTreeMap fixture = + FixtureLoader.load("transactions/username_resignation/username-resignation-sign"); + + Transaction transaction = + new Deserializer(fixture.get("serialized").toString()).deserialize(); + + String actual = Hex.encode(Serializer.serialize(transaction)); + + assertEquals(fixture.get("serialized").toString(), actual); + } +}