Serialization and Ed25519 #2
@@ -14,3 +14,4 @@ Captures/
|
||||
.externalNativeBuild/
|
||||
temp
|
||||
erl_crash.dump
|
||||
*.class
|
||||
|
||||
@@ -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/"
|
||||
@@ -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 <command> <input>");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-58
@@ -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");
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user