diff --git a/.gitignore b/.gitignore index 3917bb44679..66136d2be93 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ src/test/java/org/tron/consensus2 src/main/java/META-INF/ src/main/resources/META-INF/ /bin/ +bin # Eclipse IDE specific files and folders /.project diff --git a/build.gradle b/build.gradle index 8aad8910153..b98cfbda195 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,7 @@ subprojects { compile group: 'org.apache.commons', name: 'commons-math', version: '2.2' compile "org.apache.commons:commons-collections4:4.1" compile group: 'joda-time', name: 'joda-time', version: '2.3' + implementation 'javax.annotation:javax.annotation-api:1.3.2' } diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128.java index 705b8601cee..2d465bb7018 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128.java @@ -220,21 +220,6 @@ public boolean isZero() { return z.isZero(); } - protected boolean isValid() { - - // check whether coordinates belongs to the Field - if (!x.isValid() || !y.isValid() || !z.isValid()) { - return false; - } - - // check whether point is on the curve - if (!isOnCurve()) { - return false; - } - - return true; - } - @Override public String toString() { return String.format("(%s; %s; %s)", x.toString(), y.toString(), z.toString()); diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp.java index 4e3491759ab..ddfd1546972 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp.java @@ -47,6 +47,11 @@ public static BN128 create(byte[] xx, byte[] yy) { Fp x = Fp.create(xx); Fp y = Fp.create(yy); + if (x == null || y == null) { + // It means that one or both coordinates are not elements of Fp + return null; + } + // check for point at infinity if (x.isZero() && y.isZero()) { return ZERO; @@ -55,7 +60,7 @@ public static BN128 create(byte[] xx, byte[] yy) { BN128 p = new BN128Fp(x, y, Fp._1); // check whether point is a valid one - if (p.isValid()) { + if (p.isOnCurve()) { return p; } else { return null; diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp2.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp2.java index 4a8e5d34a24..ca5157110cd 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp2.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/BN128Fp2.java @@ -52,6 +52,11 @@ public static BN128 create(byte[] aa, byte[] bb, byte[] cc, byte[] dd) { Fp2 x = Fp2.create(aa, bb); Fp2 y = Fp2.create(cc, dd); + if (x == null || y == null) { + // It means that one or both coordinates are not elements of Fp + return null; + } + // check for point at infinity if (x.isZero() && y.isZero()) { return ZERO; @@ -60,7 +65,7 @@ public static BN128 create(byte[] aa, byte[] bb, byte[] cc, byte[] dd) { BN128 p = new BN128Fp2(x, y, Fp2._1); // check whether point is a valid one - if (p.isValid()) { + if (p.isOnCurve()) { return p; } else { return null; diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/Field.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/Field.java index e4e34c4a13a..27b16e1740b 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/Field.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/Field.java @@ -40,6 +40,4 @@ interface Field { T negate(); boolean isZero(); - - boolean isValid(); } diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp.java index 1498fd2cbd2..03ccbdfa045 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp.java @@ -17,24 +17,70 @@ */ package org.tron.common.crypto.zksnark; -import static org.tron.common.crypto.zksnark.Params.P; - import java.math.BigInteger; /** * Arithmetic in F_p, p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 - * + * This class stores elements of F_p in the Montgomery form: a*r mod p. + * * @author Mikhail Kalinin * @since 01.09.2017 */ public class Fp implements Field { + /** + * "p" field parameter of F_p, F_p2, F_p6 and F_p12 + */ + protected static final BigInteger P = new BigInteger( + "21888242871839275222246405745257275088696311157297823662689037894645226208583"); - static final Fp ZERO = new Fp(BigInteger.ZERO); - static final Fp _1 = new Fp(BigInteger.ONE); - static final Fp NON_RESIDUE = new Fp(new BigInteger( + /** + * This value is equal to 2^256. It should be greater than {@link #P} and coprime to it. + * Field elements are represented in Montgomery form as a*{@link #REDUCER} mod {@link #P}. + * This specific value of {@link #REDUCER} is selected to facilitate efficient division + * by {@link #REDUCER} through simple shifting. + * This field is not used in the code but can be helpful for understanding + */ + @SuppressWarnings("unused") + private static final BigInteger REDUCER = new BigInteger( + "115792089237316195423570985008687907853269984665640564039457584007913129639936"); + + /** + * The number of bits in the {@link #REDUCER} value. + */ + private static final int REDUCER_BITS = 256; + + /** + * A precomputed value of {@link #REDUCER}^2 mod {@link #P}. + */ + private static final BigInteger REDUCER_SQUARED = new BigInteger( + "3096616502983703923843567936837374451735540968419076528771170197431451843209"); + + /** + * A precomputed value of {@link #REDUCER}^3 mod {@link #P}. + */ + private static final BigInteger REDUCER_CUBED = new BigInteger( + "14921786541159648185948152738563080959093619838510245177710943249661917737183"); + + /** + * A precomputed value of -{@link #P}^{-1} mod {@link #REDUCER}. + */ + private static final BigInteger FACTOR = new BigInteger( + "111032442853175714102588374283752698368366046808579839647964533820976443843465"); + + /** + * The MASK value is set to 2^256 - 1 and is utilized to replace the operation % 2^256 + * with a bitwise AND using this value. This choice ensures that only the lower 256 bits + * of a result are retained, effectively simulating the modulus operation. + */ + private static final BigInteger MASK = new BigInteger( + "115792089237316195423570985008687907853269984665640564039457584007913129639935"); + + protected static final Fp ZERO = Fp.create(BigInteger.ZERO); + protected static final Fp _1 = Fp.create(BigInteger.ONE); + protected static final Fp NON_RESIDUE = Fp.create(new BigInteger( "21888242871839275222246405745257275088696311157297823662689037894645226208582")); - static final Fp _2_INV = new Fp(BigInteger.valueOf(2).modInverse(P)); + protected static final Fp _2_INV = Fp.create(BigInteger.valueOf(2).modInverse(P)); BigInteger v; @@ -43,41 +89,52 @@ public class Fp implements Field { } static Fp create(byte[] v) { - return new Fp(new BigInteger(1, v)); + BigInteger value = new BigInteger(1, v); + if (value.compareTo(P) >= 0) { + // Only the positive values less than P are valid + return null; + } + return new Fp(toMontgomery(value)); } static Fp create(BigInteger v) { - return new Fp(v); + if (v.compareTo(P) >= 0 || v.signum() == -1) { + // Only the positive values less than P are valid + return null; + } + return new Fp(toMontgomery(v)); } @Override public Fp add(Fp o) { - return new Fp(this.v.add(o.v).mod(P)); + BigInteger r = v.add(o.v); + return new Fp(r.compareTo(P) < 0 ? r : r.subtract(P)); } @Override public Fp mul(Fp o) { - return new Fp(this.v.multiply(o.v).mod(P)); + return new Fp(redc(v.multiply(o.v))); } @Override public Fp sub(Fp o) { - return new Fp(this.v.subtract(o.v).mod(P)); + BigInteger r = v.subtract(o.v); + return new Fp(r.compareTo(BigInteger.ZERO) < 0 ? r.add(P) : r); } @Override public Fp squared() { - return new Fp(v.multiply(v).mod(P)); + return new Fp(redc(v.multiply(v))); } @Override public Fp dbl() { - return new Fp(v.add(v).mod(P)); + return add(this); } @Override public Fp inverse() { - return new Fp(v.modInverse(P)); + return new Fp(redc(v.modInverse(P).multiply(REDUCER_CUBED))); } @Override @@ -90,20 +147,12 @@ public boolean isZero() { return v.compareTo(BigInteger.ZERO) == 0; } - /** - * Checks if provided value is a valid Fp member - */ - @Override - public boolean isValid() { - return v.compareTo(P) < 0; - } - Fp2 mul(Fp2 o) { return new Fp2(o.a.mul(this), o.b.mul(this)); } public byte[] bytes() { - return v.toByteArray(); + return fromMontgomery(v).toByteArray(); } @Override @@ -129,4 +178,36 @@ public int hashCode() { public String toString() { return v.toString(); } + + /** + * Converts a value in normal representation to Montgomery form. + * + * @param n value in normal form + * @return value in Montgomery form + */ + private static BigInteger toMontgomery(BigInteger n) { + return redc(n.multiply(REDUCER_SQUARED)); + } + + /** + * Converts a value in Montgomery form to a normal representation. + * + * @param n value in Montgomery form + * @return value in normal form + */ + private static BigInteger fromMontgomery(BigInteger n) { + return redc(n); + } + + /** + * Montgomery reduction; given a value x, computes x*{@link #REDUCER}^{-1} mod {@link #P} + * + * @param x value to reduce + * @return x*{@link #REDUCER}^{-1} mod {@link #P} + */ + private static BigInteger redc(BigInteger x) { + BigInteger temp = x.multiply(FACTOR).and(MASK); + BigInteger reduced = temp.multiply(P).add(x).shiftRight(REDUCER_BITS); + return reduced.compareTo(P) < 0 ? reduced : reduced.subtract(P); + } } diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp12.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp12.java index 26ea708fbe4..a09981c55ad 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp12.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp12.java @@ -36,53 +36,53 @@ class Fp12 implements Field { static final Fp12 _1 = new Fp12(Fp6._1, Fp6.ZERO); static final Fp2[] FROBENIUS_COEFFS_B = new Fp2[]{ - new Fp2(BigInteger.ONE, + Fp2.create(BigInteger.ONE, BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "8376118865763821496583973867626364092589906065868298776909617916018768340080"), new BigInteger( "16469823323077808223889137241176536799009286646108169935659301613961712198316")), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "21888242871839275220042445260109153167277707414472061641714758635765020556617"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "11697423496358154304825782922584725312912383441159505038794027105778954184319"), new BigInteger( "303847389135065887422783454877609941456349188919719272345083954437860409601")), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "21888242871839275220042445260109153167277707414472061641714758635765020556616"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "3321304630594332808241809054958361220322477375291206261884409189760185844239"), new BigInteger( "5722266937896532885780051958958348231143373700109372999374820235121374419868")), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "21888242871839275222246405745257275088696311157297823662689037894645226208582"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "13512124006075453725662431877630910996106405091429524885779419978626457868503"), new BigInteger( "5418419548761466998357268504080738289687024511189653727029736280683514010267")), - new Fp2(new BigInteger("2203960485148121921418603742825762020974279258880205651966"), + Fp2.create(new BigInteger("2203960485148121921418603742825762020974279258880205651966"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "10190819375481120917420622822672549775783927716138318623895010788866272024264"), new BigInteger( "21584395482704209334823622290379665147239961968378104390343953940207365798982")), - new Fp2(new BigInteger("2203960485148121921418603742825762020974279258880205651967"), + Fp2.create(new BigInteger("2203960485148121921418603742825762020974279258880205651967"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "18566938241244942414004596690298913868373833782006617400804628704885040364344"), new BigInteger( "16165975933942742336466353786298926857552937457188450663314217659523851788715")) @@ -233,11 +233,6 @@ public boolean isZero() { return this.equals(ZERO); } - @Override - public boolean isValid() { - return a.isValid() && b.isValid(); - } - Fp12 frobeniusMap(int power) { Fp6 ra = a.frobeniusMap(power); diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp2.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp2.java index ba2a1ceb477..957068f9f75 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp2.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp2.java @@ -36,11 +36,11 @@ class Fp2 implements Field { static final Fp2 ZERO = new Fp2(Fp.ZERO, Fp.ZERO); static final Fp2 _1 = new Fp2(Fp._1, Fp.ZERO); - static final Fp2 NON_RESIDUE = new Fp2(BigInteger.valueOf(9), BigInteger.ONE); + static final Fp2 NON_RESIDUE = Fp2.create(BigInteger.valueOf(9), BigInteger.ONE); static final Fp[] FROBENIUS_COEFFS_B = new Fp[]{ - new Fp(BigInteger.ONE), - new Fp(new BigInteger( + Fp.create(BigInteger.ONE), + Fp.create(new BigInteger( "21888242871839275222246405745257275088696311157297823662689037894645226208582")) }; @@ -60,6 +60,9 @@ static Fp2 create(BigInteger aa, BigInteger bb) { Fp a = Fp.create(aa); Fp b = Fp.create(bb); + if (a == null || b == null) { + return null; + } return new Fp2(a, b); } @@ -68,6 +71,9 @@ static Fp2 create(byte[] aa, byte[] bb) { Fp a = Fp.create(aa); Fp b = Fp.create(bb); + if (a == null || b == null) { + return null; + } return new Fp2(a, b); } @@ -139,11 +145,6 @@ public boolean isZero() { return this.equals(ZERO); } - @Override - public boolean isValid() { - return a.isValid() && b.isValid(); - } - @Override public boolean equals(Object o) { if (this == o) { diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp6.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp6.java index 0636cc334f1..0680f88cd7a 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp6.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/Fp6.java @@ -34,61 +34,62 @@ class Fp6 implements Field { static final Fp6 ZERO = new Fp6(Fp2.ZERO, Fp2.ZERO, Fp2.ZERO); static final Fp6 _1 = new Fp6(Fp2._1, Fp2.ZERO, Fp2.ZERO); - static final Fp2 NON_RESIDUE = new Fp2(BigInteger.valueOf(9), BigInteger.ONE); + static final Fp2 NON_RESIDUE = Fp2.create(BigInteger.valueOf(9), BigInteger.ONE); static final Fp2[] FROBENIUS_COEFFS_B = { - new Fp2(BigInteger.ONE, + Fp2.create(BigInteger.ONE, BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "21575463638280843010398324269430826099269044274347216827212613867836435027261"), new BigInteger( "10307601595873709700152284273816112264069230130616436755625194854815875713954")), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "21888242871839275220042445260109153167277707414472061641714758635765020556616"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "3772000881919853776433695186713858239009073593817195771773381919316419345261"), new BigInteger( "2236595495967245188281701248203181795121068902605861227855261137820944008926")), - new Fp2(new BigInteger("2203960485148121921418603742825762020974279258880205651966"), + Fp2.create(new BigInteger("2203960485148121921418603742825762020974279258880205651966"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "18429021223477853657660792034369865839114504446431234726392080002137598044644"), new BigInteger( "9344045779998320333812420223237981029506012124075525679208581902008406485703")) }; static final Fp2[] FROBENIUS_COEFFS_C = { - new Fp2(BigInteger.ONE, + Fp2.create(BigInteger.ONE, BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "2581911344467009335267311115468803099551665605076196740867805258568234346338"), new BigInteger( "19937756971775647987995932169929341994314640652964949448313374472400716661030")), - new Fp2(new BigInteger("2203960485148121921418603742825762020974279258880205651966"), + Fp2.create(new BigInteger("2203960485148121921418603742825762020974279258880205651966"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "5324479202449903542726783395506214481928257762400643279780343368557297135718"), new BigInteger( "16208900380737693084919495127334387981393726419856888799917914180988844123039")), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "21888242871839275220042445260109153167277707414472061641714758635765020556616"), BigInteger.ZERO), - new Fp2(new BigInteger( + Fp2.create(new BigInteger( "13981852324922362344252311234282257507216387789820983642040889267519694726527"), new BigInteger( "7629828391165209371577384193250820201684255241773809077146787135900891633097")) }; + Fp2 a; Fp2 b; Fp2 c; @@ -210,11 +211,6 @@ public boolean isZero() { return this.equals(ZERO); } - @Override - public boolean isValid() { - return a.isValid() && b.isValid() && c.isValid(); - } - Fp6 frobeniusMap(int power) { Fp2 ra = a.frobeniusMap(power); diff --git a/crypto/src/main/java/org/tron/common/crypto/zksnark/Params.java b/crypto/src/main/java/org/tron/common/crypto/zksnark/Params.java index 925b1154844..0386670a98a 100644 --- a/crypto/src/main/java/org/tron/common/crypto/zksnark/Params.java +++ b/crypto/src/main/java/org/tron/common/crypto/zksnark/Params.java @@ -26,13 +26,6 @@ * @since 31.08.2017 */ class Params { - - /** - * "p" field parameter of F_p, F_p2, F_p6 and F_p12 - */ - static final BigInteger P = new BigInteger( - "21888242871839275222246405745257275088696311157297823662689037894645226208583"); - /** * "r" order of {@link BN128G2} cyclic subgroup */ diff --git a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java index dce2cc7d105..0709d50e02d 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java @@ -1,13 +1,23 @@ package org.tron.common.runtime.vm; +import static org.junit.Assert.assertArrayEquals; import static org.tron.common.utils.ByteUtil.stripLeadingZeroes; import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.db.TransactionTrace.convertToTronAddress; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.Charsets; +import com.google.common.io.Files; import com.google.protobuf.Any; import com.google.protobuf.ByteString; + +import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.math.BigInteger; +import java.util.List; + import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; import org.bouncycastle.util.Arrays; @@ -40,6 +50,7 @@ import org.tron.core.vm.config.VMConfig; import org.tron.core.vm.repository.Repository; import org.tron.core.vm.repository.RepositoryImpl; +import org.tron.core.zksnark.SendCoinShieldTest; import org.tron.protos.Protocol; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Proposal.State; @@ -95,6 +106,14 @@ public class PrecompiledContractsTest extends BaseTest { private static final DataWord totalAcquiredResourceAddr = new DataWord( "0000000000000000000000000000000000000000000000000000000001000015"); + // bn128 + private static final DataWord altBN128AddAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000000006"); + private static final DataWord altBN128MulAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000000007"); + private static final DataWord altBN128PairingAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000000008"); + private static final String ACCOUNT_NAME = "account"; private static final String OWNER_ADDRESS; private static final String WITNESS_NAME = "witness"; @@ -1126,6 +1145,90 @@ public void totalAcquiredResourceTest() { Assert.assertEquals(0, ByteArray.toLong(res.getRight())); } + @Test + public void bn128Bench() throws Exception { + PrecompiledContract bn128Add = createPrecompiledContract(altBN128AddAddr, OWNER_ADDRESS); + JSONObject testCase = readJsonFile("bn256Add.json").getJSONObject(0); + byte[] input = Hex.decode(testCase.getString("Input")); + bench(bn128Add, input, 10000); + + PrecompiledContract bn128Mul = createPrecompiledContract(altBN128MulAddr, OWNER_ADDRESS); + testCase = readJsonFile("bn256ScalarMul.json").getJSONObject(1); + input = Hex.decode(testCase.getString("Input")); + bench(bn128Mul, input, 1000); + + PrecompiledContract bn128Pairing = + createPrecompiledContract(altBN128PairingAddr, OWNER_ADDRESS); + testCase = readJsonFile("bn256Pairing.json").getJSONObject(13); + input = Hex.decode(testCase.getString("Input")); + bench(bn128Pairing, input, 100); + } + + @Test + public void bn128AdditionTest() throws Exception { + PrecompiledContract bn128Add = createPrecompiledContract(altBN128AddAddr, OWNER_ADDRESS); + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/testdata/precompiles/bn256Add.json + JSONArray testCases = readJsonFile("bn256Add.json"); + for (int i = 0; i < testCases.size(); i++) { + JSONObject testCase = testCases.getJSONObject(i); + String name = testCase.getString("Name"); + byte[] input = Hex.decode(testCase.getString("Input")); + Boolean expectedResult = testCase.getBoolean("Result"); + byte[] expectedOutput = Hex.decode(testCase.getString("Expected")); + + Pair res = bn128Add.execute(input); + Boolean actualResult = res.getLeft(); + byte[] actualOutput = res.getRight(); + + Assert.assertEquals(String.format("test %s failed", name), expectedResult, actualResult); + assertArrayEquals(String.format("test %s failed", name), expectedOutput, actualOutput); + } + } + + @Test + public void bn128MultiplicationTest() throws Exception { + PrecompiledContract bn128Mul = createPrecompiledContract(altBN128MulAddr, OWNER_ADDRESS); + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/testdata/precompiles/bn256ScalarMul.json + JSONArray testCases = readJsonFile("bn256ScalarMul.json"); + for (int i = 0; i < testCases.size(); i++) { + JSONObject testCase = testCases.getJSONObject(i); + String name = testCase.getString("Name"); + byte[] input = Hex.decode(testCase.getString("Input")); + Boolean expectedResult = testCase.getBoolean("Result"); + byte[] expectedOutput = Hex.decode(testCase.getString("Expected")); + + Pair res = bn128Mul.execute(input); + Boolean actualResult = res.getLeft(); + byte[] actualOutput = res.getRight(); + + Assert.assertEquals(String.format("test %s failed", name), expectedResult, actualResult); + assertArrayEquals(String.format("test %s failed", name), expectedOutput, actualOutput); + } + } + + @Test + public void bn128PairingTest() throws Exception { + PrecompiledContract bn128Pairing = + createPrecompiledContract(altBN128PairingAddr, OWNER_ADDRESS); + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/testdata/precompiles/bn256Pairing.json + JSONArray testCases = readJsonFile("bn256Pairing.json"); + for (int i = 0; i < testCases.size(); i++) { + JSONObject testCase = testCases.getJSONObject(i); + String name = testCase.getString("Name"); + byte[] input = Hex.decode(testCase.getString("Input")); + Boolean expectedResult = testCase.getBoolean("Result"); + byte[] expectedOutput = Hex.decode(testCase.getString("Expected")); + + + Pair res = bn128Pairing.execute(input); + Boolean actualResult = res.getLeft(); + byte[] actualOutput = res.getRight(); + + Assert.assertEquals(String.format("test %s failed", name), expectedResult, actualResult); + assertArrayEquals(String.format("test %s failed", name), expectedOutput, actualOutput); + } + } + //@Test public void convertFromTronBase58AddressNative() { // 27WnTihwXsqCqpiNedWvtKCZHsLjDt4Hfmf TestNet address @@ -1165,4 +1268,23 @@ private static byte[] encodeMultiWord(byte[]... words) { return res; } + private JSONArray readJsonFile(String fileName) throws Exception { + String file1 = SendCoinShieldTest.class.getClassLoader() + .getResource("json" + File.separator + fileName).getFile(); + List readLines = Files.readLines(new File(file1), + Charsets.UTF_8); + + return JSONArray + .parseArray(readLines.stream().reduce((s, s2) -> s + s2).get()); + } + + private static void bench(PrecompiledContract contract, byte[] input, int itersCount) { + long start = System.nanoTime(); + for (int i = 0; i < itersCount; i++) { + contract.execute(input); + } + long end = System.nanoTime(); + System.out.println( + contract.getClass().getSimpleName() + " cost " + (end - start) / itersCount + "ns"); + } } diff --git a/framework/src/test/resources/json/bn256Add.json b/framework/src/test/resources/json/bn256Add.json new file mode 100644 index 00000000000..bd423efa85f --- /dev/null +++ b/framework/src/test/resources/json/bn256Add.json @@ -0,0 +1,110 @@ +[ + { + "Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726607c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7", + "Expected": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915", + "Result": true, + "Name": "chfast1" + }, + { + "Input": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c91518b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f37266", + "Expected": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204", + "Result": true, + "Name": "chfast2" + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "cdetrio1" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "cdetrio2" + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "cdetrio3" + }, + { + "Input": "", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "cdetrio4" + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "cdetrio5" + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Result": true, + "Name": "cdetrio6" + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Result": true, + "Name": "cdetrio7" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Result": true, + "Name": "cdetrio8" + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Result": true, + "Name": "cdetrio9" + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Result": true, + "Name": "cdetrio10" + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4", + "Result": true, + "Name": "cdetrio11" + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4", + "Result": true, + "Name": "cdetrio12" + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98", + "Expected": "15bf2bb17880144b5d1cd2b1f46eff9d617bffd1ca57c37fb5a49bd84e53cf66049c797f9ce0d17083deb32b5e36f2ea2a212ee036598dd7624c168993d1355f", + "Result": true, + "Name": "cdetrio13" + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "cdetrio14" + }, + { + "Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726707c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7", + "Expected": "", + "Result": false, + "Name": "invalid_first_point" + }, + { + "Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726607c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d8", + "Expected": "", + "Result": false, + "Name": "invalid_second_point" + } +] \ No newline at end of file diff --git a/framework/src/test/resources/json/bn256Pairing.json b/framework/src/test/resources/json/bn256Pairing.json new file mode 100644 index 00000000000..eef4eadb8a4 --- /dev/null +++ b/framework/src/test/resources/json/bn256Pairing.json @@ -0,0 +1,104 @@ +[ + { + "Input": "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "jeff1" + }, + { + "Input": "2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc0203d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db841213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f06967a1237ebfeca9aaae0d6d0bab8e28c198c5a339ef8a2407e31cdac516db922160fa257a5fd5b280642ff47b65eca77e626cb685c84fa6d3b6882a283ddd1198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "jeff2" + }, + { + "Input": "0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd216da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb314a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee245901b9e027bd5cfc2cb5db82d4dc9677ac795ec500ecd47deee3b5da006d6d049b811d7511c78158de484232fc68daf8a45cf217d1c2fae693ff5871e8752d73b21198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "jeff3" + }, + { + "Input": "2f2ea0b3da1e8ef11914acf8b2e1b32d99df51f5f4f206fc6b947eae860eddb6068134ddb33dc888ef446b648d72338684d678d2eb2371c61a50734d78da4b7225f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb122acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf6806d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb186bac5188a98c45e6016873d107f5cd131f3a3e339d0375e58bd6219347b008122ae2b09e539e152ec5364e7e2204b03d11d3caa038bfc7cd499f8176aacbee1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd415794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f211b88da1679b0b64a63b7e0e7bfe52aae524f73a55be7fe70c7e9bfc94b4cf0da1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "jeff4" + }, + { + "Input": "20a754d2071d4d53903e3b31a7e98ad6882d58aec240ef981fdf0a9d22c5926a29c853fcea789887315916bbeb89ca37edb355b4f980c9a12a94f30deeed30211213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f1abb4a25eb9379ae96c84fff9f0540abcfc0a0d11aeda02d4f37e4baf74cb0c11073b3ff2cdbb38755f8691ea59e9606696b3ff278acfc098fa8226470d03869217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac290a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a98552fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d70f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2198a1f162a73261f112401aa2db79c7dab1533c9935c77290a6ce3b191f2318d198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "jeff5" + }, + { + "Input": "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c103188585e2364128fe25c70558f1560f4f9350baf3959e603cc91486e110936198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "jeff6" + }, + { + "Input": "", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "empty_data" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "one_point" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "two_point_match_2" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "two_point_match_3" + }, + { + "Input": "105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "two_point_match_4" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "ten_point_match_1" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "ten_point_match_2" + }, + { + "Input": "105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Result": true, + "Name": "ten_point_match_3" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "", + "Result": false, + "Name": "g1_point_invalid" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7dab", + "Expected": "", + "Result": false, + "Name": "g2_point_invalid" + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7d", + "Expected": "", + "Result": false, + "Name": "input_length_is_not_valid" + } +] \ No newline at end of file diff --git a/framework/src/test/resources/json/bn256ScalarMul.json b/framework/src/test/resources/json/bn256ScalarMul.json new file mode 100644 index 00000000000..6c306b75c0f --- /dev/null +++ b/framework/src/test/resources/json/bn256ScalarMul.json @@ -0,0 +1,122 @@ +[ + { + "Input": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20400000000000000000000000000000000000000000000000011138ce750fa15c2", + "Expected": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc", + "Result": true, + "Name": "chfast1" + }, + { + "Input": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46", + "Expected": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e", + "Result": true, + "Name": "chfast2" + }, + { + "Input": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3", + "Expected": "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27", + "Result": true, + "Name": "chfast3" + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11", + "Result": true, + "Name": "cdetrio1" + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + "Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451", + "Result": true, + "Name": "cdetrio2" + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000", + "Expected": "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b", + "Result": true, + "Name": "cdetrio3" + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009", + "Expected": "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575", + "Result": true, + "Name": "cdetrio4" + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001", + "Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6", + "Result": true, + "Name": "cdetrio5" + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "29e587aadd7c06722aabba753017c093f70ba7eb1f1c0104ec0564e7e3e21f6022b1143f6a41008e7755c71c3d00b6b915d386de21783ef590486d8afa8453b1", + "Result": true, + "Name": "cdetrio6" + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + "Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb", + "Result": true, + "Name": "cdetrio7" + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000", + "Expected": "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15", + "Result": true, + "Name": "cdetrio8" + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009", + "Expected": "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a", + "Result": true, + "Name": "cdetrio9" + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001", + "Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c", + "Result": true, + "Name": "cdetrio10" + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "00a1a234d08efaa2616607e31eca1980128b00b415c845ff25bba3afcb81dc00242077290ed33906aeb8e42fd98c41bcb9057ba03421af3f2d08cfc441186024", + "Result": true, + "Name": "cdetrio11" + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + "Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf", + "Result": true, + "Name": "cdetrio12" + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000", + "Expected": "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434", + "Result": true, + "Name": "cdetrio13" + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009", + "Expected": "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f", + "Result": true, + "Name": "cdetrio14" + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001", + "Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98", + "Result": true, + "Name": "cdetrio15" + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Result": true, + "Name": "zeroScalar" + }, + { + "Input": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20500000000000000000000000000000000000000000000000011138ce750fa15c2", + "Expected": "", + "Result": false, + "Name": "invalid_point" + } +] \ No newline at end of file