diff --git a/.gitignore b/.gitignore index b4994e1..340330e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ Captures/ .externalNativeBuild/ temp erl_crash.dump +*.class diff --git a/gajumaru-core/bin/compile b/bin/compile similarity index 91% rename from gajumaru-core/bin/compile rename to bin/compile index 6bc3d64..ccd245c 100755 --- a/gajumaru-core/bin/compile +++ b/bin/compile @@ -18,6 +18,6 @@ find "$project_dir/src/main/java" -name "*.java" | xargs javac \ -d "$project_dir/build/classes" # Build the Testinator thingy -javac -cp "build/classes" -d build src/Testinator.java +javac -cp "build/classes" -d build test/Testinator.java echo "Bytecode in $project_dir/build/classes/" diff --git a/gajumaru-core/bin/run b/bin/run similarity index 100% rename from gajumaru-core/bin/run rename to bin/run diff --git a/gajumaru-core/test/TestRunner.java b/gajumaru-core/test/TestRunner.java deleted file mode 100644 index 8d8b1db..0000000 --- a/gajumaru-core/test/TestRunner.java +++ /dev/null @@ -1,47 +0,0 @@ -import swiss.qpq.gajumaru.core.crypto.*; -import swiss.qpq.gajumaru.core.encoding.*; -import swiss.qpq.gajumaru.core.data.*; -import swiss.qpq.gajumaru.core.tools.*; -import java.util.Arrays; - -public class TestRunner { - public static void main(String[] args) { - try { - if (args.length == 0) { - System.out.println("Usage: java TestRunner "); - return; - } - - String cmd = args[0]; - switch (cmd) { - case "keccak": - byte[] kInput = CryptoUtils.hexToBin(args[1]); - System.out.println(CryptoUtils.binToHex(Keccak256.hash(kInput))); - break; - case "blake2b": - byte[] bInput = CryptoUtils.hexToBin(args[1]); - System.out.println(CryptoUtils.binToHex(Blake2b.hash(bInput))); - break; - case "ak_encode": - byte[] akInput = CryptoUtils.hexToBin(args[1]); - System.out.println(ApiEncoder.encode(ApiEncoder.Type.ACCOUNT_PUBKEY, akInput)); - break; - case "ed25519_pub": - byte[] seed = CryptoUtils.hexToBin(args[1]); - System.out.println(CryptoUtils.binToHex(Ed25519.publicKey(seed))); - break; - case "id_serialize": - int tag = Integer.parseInt(args[1]); - byte[] val = CryptoUtils.hexToBin(args[2]); - Id id = new Id(Id.Tag.fromValue(tag), val); - System.out.println(CryptoUtils.binToHex(id.serialize())); - break; - default: - System.out.println("Unknown command: " + cmd); - } - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - } -} diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/crypto/Blake2b.java b/src/main/java/swiss/qpq/gajumaru/core/crypto/Blake2b.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/crypto/Blake2b.java rename to src/main/java/swiss/qpq/gajumaru/core/crypto/Blake2b.java diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/crypto/Ed25519.java b/src/main/java/swiss/qpq/gajumaru/core/crypto/Ed25519.java similarity index 93% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/crypto/Ed25519.java rename to src/main/java/swiss/qpq/gajumaru/core/crypto/Ed25519.java index ac89269..59ee8eb 100644 --- a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/crypto/Ed25519.java +++ b/src/main/java/swiss/qpq/gajumaru/core/crypto/Ed25519.java @@ -204,7 +204,7 @@ public final class Ed25519 { return res; } - private static void ge_add(Ge r, Ge p1, Ge p2, Scratch s) { + public static void ge_add(Ge r, Ge p1, Ge p2, Scratch s) { long[] yMinusX1 = s.stack[0], yPlusX1 = s.stack[1], yMinusX2 = s.stack[2], yPlusX2 = s.stack[3]; long[] A = s.stack[4], B = s.stack[5], C = s.stack[6], D = s.stack[7]; long[] E = s.stack[8], F = s.stack[9], G = s.a, H = s.b; @@ -228,7 +228,7 @@ public final class Ed25519 { fe_mul(r.T, E, H, s.t19); } - private static void ge_double(Ge r, Ge p, Scratch s) { + public static void ge_double(Ge r, Ge p, Scratch s) { long[] A = s.stack[0], B = s.stack[1], C = s.stack[2], D = s.stack[3]; long[] E = s.stack[4], F = s.stack[5], G = s.stack[6], H = s.stack[7]; fe_sq(A, p.X, s.t19); @@ -264,7 +264,7 @@ public final class Ed25519 { } } - private static Ge decompress(byte[] b, Scratch s) { + public static Ge decompress(byte[] b, Scratch s) { if (b.length != 32) return null; Ge p = new Ge(); fe_frombytes(p.Y, b); @@ -290,7 +290,7 @@ public final class Ed25519 { return p; } - private static byte[] compress(Ge p, Scratch s) { + public static byte[] compress(Ge p, Scratch s) { fe_invert(s.a, p.Z, s); fe_mul(s.b, p.X, s.a, s.t19); fe_mul(s.c, p.Y, s.a, s.t19); @@ -324,7 +324,7 @@ public final class Ed25519 { for (int i = 0; i < 10; i++) h[i] = -f[i]; } - private static void fe_mul(long[] out, long[] f, long[] g, long[] t) { + public static void fe_mul(long[] out, long[] f, long[] g, long[] t) { t[0] = f[0] * g[0]; t[1] = f[0] * g[1] + f[1] * g[0]; t[2] = f[0] * g[2] + f[2] * g[0] + 2 * f[1] * g[1]; @@ -347,7 +347,7 @@ public final class Ed25519 { fe_reduce(out, t); } - private static void fe_sq(long[] out, long[] f, long[] t) { + public static void fe_sq(long[] out, long[] f, long[] t) { t[0] = f[0] * f[0]; t[1] = 2 * f[0] * f[1]; t[2] = 2 * f[0] * f[2] + 2 * f[1] * f[1]; @@ -370,7 +370,7 @@ public final class Ed25519 { fe_reduce(out, t); } - private static void fe_reduce(long[] h, long[] t) { + public static void fe_reduce(long[] h, long[] t) { t[0] += t[10] * 19; t[1] += t[11] * 19; t[2] += t[12] * 19; @@ -393,7 +393,7 @@ public final class Ed25519 { for (int i = 0; i < 10; i++) h[i] = t[i]; } - private static void fe_frombytes(long[] h, byte[] s) { + public static void fe_frombytes(long[] h, byte[] s) { for (int i = 0; i < 10; i++) h[i] = 0; int bitIdx = 0; for (int i = 0; i < 10; i++) { @@ -407,7 +407,7 @@ public final class Ed25519 { } } - private static byte[] fe_contract(long[] h) { + public static byte[] fe_contract(long[] h) { long[] val = Arrays.copyOf(h, 10); for (int p = 0; p < 3; p++) { for (int i = 0; i < 9; i++) { @@ -540,7 +540,7 @@ public final class Ed25519 { return s[0] & 1; } - private static void reduceScalar(byte[] s) { + public static void reduceScalar(byte[] s) { long s0 = 2097151 & load3(s, 0); long s1 = 2097151 & (load4(s, 2) >> 5); long s2 = 2097151 & (load3(s, 5) >> 2); @@ -812,54 +812,6 @@ public final class Ed25519 { System.arraycopy(buffer, 0, S, 0, 32); } - public static void testFromBytes(long[] h, byte[] s) { - fe_frombytes(h, s); - } - - public static byte[] testFeParity(byte[] in) { - long[] h = new long[10]; - fe_frombytes(h, in); - return fe_contract(h); - } - - public static byte[] testReduce(byte[] in) { - byte[] s = Arrays.copyOf(in, 64); - reduceScalar(s); - return Arrays.copyOf(s, 32); - } - - public static byte[] testSmb(byte[] in) { - Scratch sc = new Scratch(); - Ge p = scalarMulBase(in, sc); - byte[] out = compress(p, sc); - p.wipe(); - sc.wipe(); - return out; - } - - public static byte[] testGeAdd(byte[] a, byte[] b) { - Scratch sc = new Scratch(); - Ge p1 = scalarMulBase(a, sc); - Ge p2 = scalarMulBase(b, sc); - Ge p3 = new Ge(); - ge_add(p3, p1, p2, sc); - byte[] out = compress(p3, sc); - p1.wipe(); - p2.wipe(); - p3.wipe(); - sc.wipe(); - return out; - } - - public static byte[] testFeMul(byte[] a, byte[] b) { - long[] ha = new long[10], hb = new long[10]; - fe_frombytes(ha, a); - fe_frombytes(hb, b); - long[] hr = new long[10]; - fe_mul(hr, ha, hb, new long[19]); - return fe_contract(hr); - } - private static byte[] sha512(byte[]... parts) { try { MessageDigest md = MessageDigest.getInstance("SHA-512"); diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/crypto/Keccak256.java b/src/main/java/swiss/qpq/gajumaru/core/crypto/Keccak256.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/crypto/Keccak256.java rename to src/main/java/swiss/qpq/gajumaru/core/crypto/Keccak256.java diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/data/Id.java b/src/main/java/swiss/qpq/gajumaru/core/data/Id.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/data/Id.java rename to src/main/java/swiss/qpq/gajumaru/core/data/Id.java diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/encoding/ApiEncoder.java b/src/main/java/swiss/qpq/gajumaru/core/encoding/ApiEncoder.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/encoding/ApiEncoder.java rename to src/main/java/swiss/qpq/gajumaru/core/encoding/ApiEncoder.java diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/encoding/Base58.java b/src/main/java/swiss/qpq/gajumaru/core/encoding/Base58.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/encoding/Base58.java rename to src/main/java/swiss/qpq/gajumaru/core/encoding/Base58.java diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/encoding/RLP.java b/src/main/java/swiss/qpq/gajumaru/core/encoding/RLP.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/encoding/RLP.java rename to src/main/java/swiss/qpq/gajumaru/core/encoding/RLP.java diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/formatting/GajuFormat.java b/src/main/java/swiss/qpq/gajumaru/core/formatting/GajuFormat.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/formatting/GajuFormat.java rename to src/main/java/swiss/qpq/gajumaru/core/formatting/GajuFormat.java diff --git a/gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/tools/CryptoUtils.java b/src/main/java/swiss/qpq/gajumaru/core/tools/CryptoUtils.java similarity index 100% rename from gajumaru-core/src/main/java/swiss/qpq/gajumaru/core/tools/CryptoUtils.java rename to src/main/java/swiss/qpq/gajumaru/core/tools/CryptoUtils.java diff --git a/gajumaru-core/test/.gitignore b/test/.gitignore similarity index 100% rename from gajumaru-core/test/.gitignore rename to test/.gitignore diff --git a/gajumaru-core/test/Emakefile b/test/Emakefile similarity index 100% rename from gajumaru-core/test/Emakefile rename to test/Emakefile diff --git a/gajumaru-core/test/LICENSE b/test/LICENSE similarity index 100% rename from gajumaru-core/test/LICENSE rename to test/LICENSE diff --git a/gajumaru-core/test/README.md b/test/README.md similarity index 100% rename from gajumaru-core/test/README.md rename to test/README.md diff --git a/gajumaru-core/src/Testinator.java b/test/Testinator.java similarity index 76% rename from gajumaru-core/src/Testinator.java rename to test/Testinator.java index 31f7f79..e1f8aca 100644 --- a/gajumaru-core/src/Testinator.java +++ b/test/Testinator.java @@ -4,6 +4,7 @@ import java.nio.file.Path; import java.util.Base64; import java.util.ArrayList; import java.util.List; +import java.util.Arrays; import java.math.BigInteger; import swiss.qpq.gajumaru.core.encoding.Base58; @@ -18,73 +19,64 @@ import swiss.qpq.gajumaru.core.tools.CryptoUtils; public class Testinator { public static void main(String[] args) { - if (args.length != 2) { - System.out.println("Error: Provide the test suite name and the working dir path."); + if (args.length < 2) { + System.out.println("Error: Provide the test suite name and the required arguments."); System.exit(1); } try { switch (args[0]) { - case "base64" -> { - System.out.print(base64(args[1])); + case "base64" -> { System.out.print(base64(args[1])); } + case "base58" -> { System.out.print(base58(args[1])); } + case "base58_check" -> { System.out.print(base58_check(args[1])); } + case "rlp" -> { System.out.print(rlp(args[1])); } + case "rlp_stream" -> { System.out.print(rlp_stream(args[1])); } + case "rlp_fail" -> { System.out.print(rlp_fail(args[1])); } + case "gaju_format" -> { System.out.print(gaju_format(args[1])); } + case "keccak256" -> { System.out.print(keccak256(args[1])); } + case "blake2b" -> { System.out.print(blake2b(args[1])); } + case "ed25519" -> { System.out.print(ed25519(args[1])); } + case "ed25519_verify" -> { System.out.print(ed25519_verify(args[1])); } + case "api_encode" -> { System.out.print(api_encode(args[1])); } + case "id_serialization" -> { System.out.print(id_serialization(args[1])); } + case "fe_parity" -> { System.out.print(fe_parity(args[1])); } + case "reduce_parity" -> { System.out.print(reduce_parity(args[1])); } + case "smb_parity" -> { System.out.print(smb_parity(args[1])); } + case "femul_parity" -> { System.out.print(femul_parity(args[1])); } + case "frombytes_parity" -> { System.out.print(frombytes_parity(args[1])); } + case "ge_parity" -> { System.out.print(ge_parity(args[1], args[2])); } + + // Direct commands from TestRunner + case "keccak" -> { + byte[] in = CryptoUtils.hexToBin(args[1]); + System.out.println(CryptoUtils.binToHex(Keccak256.hash(in))); } - case "base58" -> { - System.out.print(base58(args[1])); + case "blake2b_direct" -> { + byte[] in = CryptoUtils.hexToBin(args[1]); + System.out.println(CryptoUtils.binToHex(Blake2b.hash(in))); } - case "base58_check" -> { - System.out.print(base58_check(args[1])); + case "ak_encode" -> { + byte[] in = CryptoUtils.hexToBin(args[1]); + System.out.println(ApiEncoder.encode(ApiEncoder.Type.ACCOUNT_PUBKEY, in)); } - case "rlp" -> { - System.out.print(rlp(args[1])); + case "ed25519_pub" -> { + byte[] seed = CryptoUtils.hexToBin(args[1]); + System.out.println(CryptoUtils.binToHex(Ed25519.publicKey(seed))); } - case "rlp_stream" -> { - System.out.print(rlp_stream(args[1])); + case "id_serialize" -> { + int tag = Integer.parseInt(args[1]); + byte[] val = CryptoUtils.hexToBin(args[2]); + Id id = new Id(Id.Tag.fromValue(tag), val); + System.out.println(CryptoUtils.binToHex(id.serialize())); } - case "rlp_fail" -> { - System.out.print(rlp_fail(args[1])); - } - case "gaju_format" -> { - System.out.print(gaju_format(args[1])); - } - case "keccak256" -> { - System.out.print(keccak256(args[1])); - } - case "blake2b" -> { - System.out.print(blake2b(args[1])); - } - case "ed25519" -> { - System.out.print(ed25519(args[1])); - } - case "ed25519_verify" -> { - System.out.print(ed25519_verify(args[1])); - } - case "api_encode" -> { - System.out.print(api_encode(args[1])); - } - case "id_serialization" -> { - System.out.print(id_serialization(args[1])); - } - case "fe_parity" -> { - System.out.print(fe_parity(args[1])); - } - case "reduce_parity" -> { - System.out.print(reduce_parity(args[1])); - } - case "smb_parity" -> { - System.out.print(smb_parity(args[1])); - } - case "femul_parity" -> { - System.out.print(femul_parity(args[1])); - } - case "frombytes_parity" -> { - System.out.print(frombytes_parity(args[1])); - } - case "ge_parity" -> { - System.out.print(ge_parity(args[1], args[2])); + default -> { + System.out.println("Error: Unknown test suite or command: " + args[0]); + System.exit(1); } } } catch (Exception e) { System.err.println("Error: " + e.getMessage()); + e.printStackTrace(); System.exit(1); } } @@ -92,7 +84,15 @@ public class Testinator { private static String ge_parity(String aHex, String bHex) throws IOException { byte[] a = CryptoUtils.hexToBin(aHex); byte[] b = CryptoUtils.hexToBin(bHex); - byte[] res = Ed25519.testGeAdd(a, b); + + Ed25519.Scratch sc = new Ed25519.Scratch(); + Ed25519.Ge p1 = Ed25519.scalarMulBase(a, sc); + Ed25519.Ge p2 = Ed25519.scalarMulBase(b, sc); + Ed25519.Ge p3 = new Ed25519.Ge(); + Ed25519.ge_add(p3, p1, p2, sc); + byte[] res = Ed25519.compress(p3, sc); + p1.wipe(); p2.wipe(); p3.wipe(); sc.wipe(); + return CryptoUtils.binToHex(res) + "|||"; } @@ -105,7 +105,7 @@ public class Testinator { if (hex.trim().isEmpty()) continue; byte[] in = CryptoUtils.hexToBin(hex); long[] h = new long[10]; - Ed25519.testFromBytes(h, in); + Ed25519.fe_frombytes(h, in); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) { if (i > 0) sb.append(","); @@ -127,7 +127,14 @@ public class Testinator { String[] parts = line.split("\\|"); byte[] a = CryptoUtils.hexToBin(parts[0]); byte[] b = CryptoUtils.hexToBin(parts[1]); - byte[] out = Ed25519.testFeMul(a, b); + + long[] ha = new long[10], hb = new long[10]; + Ed25519.fe_frombytes(ha, a); + Ed25519.fe_frombytes(hb, b); + long[] hr = new long[10]; + Ed25519.fe_mul(hr, ha, hb, new long[19]); + byte[] out = Ed25519.fe_contract(hr); + results.add(CryptoUtils.binToHex(out)); } Files.write(resPath, results); @@ -142,7 +149,12 @@ public class Testinator { for (String hex : lines) { if (hex.trim().isEmpty()) continue; byte[] in = CryptoUtils.hexToBin(hex); - byte[] out = Ed25519.testSmb(in); + + Ed25519.Scratch sc = new Ed25519.Scratch(); + Ed25519.Ge p = Ed25519.scalarMulBase(in, sc); + byte[] out = Ed25519.compress(p, sc); + p.wipe(); sc.wipe(); + results.add(CryptoUtils.binToHex(out)); } Files.write(resPath, results); @@ -157,7 +169,11 @@ public class Testinator { for (String hex : lines) { if (hex.trim().isEmpty()) continue; byte[] in = CryptoUtils.hexToBin(hex); - byte[] out = Ed25519.testReduce(in); + + byte[] s = Arrays.copyOf(in, 64); + Ed25519.reduceScalar(s); + byte[] out = Arrays.copyOf(s, 32); + results.add(CryptoUtils.binToHex(out)); } Files.write(resPath, results); @@ -172,7 +188,11 @@ public class Testinator { for (String hex : lines) { if (hex.trim().isEmpty()) continue; byte[] in = CryptoUtils.hexToBin(hex); - byte[] out = Ed25519.testFeParity(in); + + long[] h = new long[10]; + Ed25519.fe_frombytes(h, in); + byte[] out = Ed25519.fe_contract(h); + results.add(CryptoUtils.binToHex(out)); } Files.write(resPath, results); diff --git a/gajumaru-core/test/ebin/gm_libtester.app b/test/ebin/gm_libtester.app similarity index 100% rename from gajumaru-core/test/ebin/gm_libtester.app rename to test/ebin/gm_libtester.app diff --git a/gajumaru-core/test/src/gmt.erl b/test/src/gmt.erl similarity index 100% rename from gajumaru-core/test/src/gmt.erl rename to test/src/gmt.erl diff --git a/gajumaru-core/test/zomp.meta b/test/zomp.meta similarity index 100% rename from gajumaru-core/test/zomp.meta rename to test/zomp.meta