diff --git a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java index d7e2f1c0949..e74e497e2bc 100644 --- a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java +++ b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java @@ -871,6 +871,21 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore, } break; } + case ALLOW_OPTIMIZED_BN128: { + if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_2)) { + throw new ContractValidateException( + "Bad chain parameter id [ALLOW_OPTIMIZED_BN128]"); + } + if (dynamicPropertiesStore.getAllowOptimizedBN128() == 1) { + throw new ContractValidateException( + "[ALLOW_OPTIMIZED_BN128] has been valid, no need to propose again"); + } + if (value != 1) { + throw new ContractValidateException( + "This value[ALLOW_OPTIMIZED_BN128] is only allowed to be 1"); + } + break; + } default: break; } @@ -955,7 +970,8 @@ public enum ProposalType { // current value, value range CONSENSUS_LOGIC_OPTIMIZATION(88), // 0, 1 ALLOW_TVM_BLOB(89), // 0, 1 PROPOSAL_EXPIRE_TIME(92), // (0, 31536003000) - ALLOW_TVM_SELFDESTRUCT_RESTRICTION(94); // 0, 1 + ALLOW_TVM_SELFDESTRUCT_RESTRICTION(94), // 0, 1 + ALLOW_OPTIMIZED_BN128(95); // 0, 1 private long code; diff --git a/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java b/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java index 654a76db33b..38b96be5574 100644 --- a/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java +++ b/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java @@ -45,6 +45,8 @@ import org.tron.common.crypto.Rsv; import org.tron.common.crypto.SignUtils; import org.tron.common.crypto.SignatureInterface; +import org.tron.common.crypto.bn128.BN128Service; +import org.tron.common.crypto.bn128.SocketBN128Client; import org.tron.common.crypto.zksnark.BN128; import org.tron.common.crypto.zksnark.BN128Fp; import org.tron.common.crypto.zksnark.BN128G1; @@ -426,6 +428,39 @@ public abstract static class PrecompiledContract { @Getter @Setter private long vmShouldEndInUs; + protected static BN128Service client; + // BN128 client connection pool size + private static final int BN128_CLIENT_POOL_SIZE = 8; + + static { + if (VMConfig.allowOptimizedBn128()) { + try { + int bn128Port = VMConfig.getBN128ClientPort(); + int bn128Timeout = VMConfig.getBN128SocketTimeout(); + client = new SocketBN128Client(BN128_CLIENT_POOL_SIZE, bn128Port, bn128Timeout); + logger.info("SocketBn128Client initialized with pool size={}, port={}, timeout={}ms", + BN128_CLIENT_POOL_SIZE, bn128Port, bn128Timeout); + + // Register shutdown hook for graceful cleanup + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + if (client != null) { + logger.info("Closing SocketBn128Client..."); + client.close(); + logger.info("SocketBn128Client closed successfully"); + } + } catch (Exception e) { + logger.error("Error occurred while closing SocketBn128Client", e); + } + })); + } catch (Exception e) { + logger.warn( + "Failed to initialize SocketBn128Client, falling back to non-optimized mode: {}", + e.getMessage()); + client = null; + } + } + } public abstract long getEnergyForData(byte[] data); @@ -757,6 +792,18 @@ public Pair execute(byte[] data) { data = EMPTY_BYTE_ARRAY; } + if (VMConfig.allowOptimizedBn128() && client != null) { + byte[] input = data.length > 128 ? Arrays.copyOfRange(data, 0, 128) : data; + try { + return client.bn128Add(input); + } catch (Exception e) { + logger.warn( + "Optimized BN128 add failed for input length {}, falling back to non-optimized " + + "implementation: {}", + data.length, e.getMessage()); + } + } + byte[] x1 = parseWord(data, 0); byte[] y1 = parseWord(data, 1); @@ -811,6 +858,18 @@ public Pair execute(byte[] data) { data = EMPTY_BYTE_ARRAY; } + if (VMConfig.allowOptimizedBn128() && client != null) { + byte[] input = data.length > 96 ? Arrays.copyOfRange(data, 0, 96) : data; + try { + return client.bn128Mul(input); + } catch (Exception e) { + logger.warn( + "Optimized BN128 multiplication failed for input length {}, falling back to " + + "non-optimized implementation: {}", + data.length, e.getMessage()); + } + } + byte[] x = parseWord(data, 0); byte[] y = parseWord(data, 1); @@ -844,7 +903,8 @@ public Pair execute(byte[] data) { public static class BN128Pairing extends PrecompiledContract { private static final int PAIR_SIZE = 192; - + // Limit to 100 pairs (19,200 bytes) in optimized mode to guarantee security + private static final int MAX_PAIR_SIZE_LIMIT = 192 * 100; @Override public long getEnergyForData(byte[] data) { if (VMConfig.allowTvmIstanbul()) { @@ -875,6 +935,17 @@ public Pair execute(byte[] data) { return Pair.of(false, EMPTY_BYTE_ARRAY); } + if (VMConfig.allowOptimizedBn128() && client != null && data.length <= MAX_PAIR_SIZE_LIMIT) { + try { + return client.bn128Pairing(data); + } catch (Exception e) { + logger.warn( + "Optimized BN128 pairing failed for input length {}, falling back to " + + "non-optimized implementation: {}", + data.length, e.getMessage()); + } + } + PairingCheck check = PairingCheck.create(); // iterating over all pairs diff --git a/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java b/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java index e0ebca329cd..d1cd0f3ca12 100644 --- a/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java +++ b/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java @@ -45,6 +45,9 @@ public static void load(StoreFactory storeFactory) { VMConfig.initDisableJavaLangMath(ds.getConsensusLogicOptimization()); VMConfig.initAllowTvmBlob(ds.getAllowTvmBlob()); VMConfig.initAllowTvmSelfdestructRestriction(ds.getAllowTvmSelfdestructRestriction()); + VMConfig.initAllowOptimizedBN128(ds.getAllowOptimizedBN128()); + VMConfig.initBN128Port(ds.getBN128Port()); + VMConfig.initBN128SocketTimeout(ds.getBN128SocketTimeout()); } } } diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java index 89c5ba18e59..822944cef5d 100644 --- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java @@ -238,6 +238,9 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking private static final byte[] ALLOW_TVM_SELFDESTRUCT_RESTRICTION = "ALLOW_TVM_SELFDESTRUCT_RESTRICTION".getBytes(); + private static final byte[] ALLOW_OPTIMIZED_BN128 = + "ALLOW_OPTIMIZED_BN128".getBytes(); + @Autowired private DynamicPropertiesStore(@Value("properties") String dbName) { super(dbName); @@ -2967,7 +2970,32 @@ public void saveAllowTvmSelfdestructRestriction(long value) { public boolean allowTvmSelfdestructRestriction() { return getAllowTvmSelfdestructRestriction() == 1L; } - + + public void saveAllowOptimizedBn128(long allowOptimizedBn128) { + this.put(ALLOW_OPTIMIZED_BN128, + new BytesCapsule(ByteArray.fromLong(allowOptimizedBn128))); + } + + public long getAllowOptimizedBN128() { + return Optional.ofNullable(getUnchecked(ALLOW_OPTIMIZED_BN128)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElse(CommonParameter.getInstance() + .getAllowOptimizedBN128()); + } + + public boolean allowOptimizedBN128() { + return getAllowOptimizedBN128() == 1L; + } + + public int getBN128Port() { + return CommonParameter.getInstance().getBn128ServerPort(); + } + + public int getBN128SocketTimeout() { + return CommonParameter.getInstance().getBn128SocketTimeout(); + } + public void saveProposalExpireTime(long proposalExpireTime) { this.put(PROPOSAL_EXPIRE_TIME, new BytesCapsule(ByteArray.fromLong(proposalExpireTime))); } diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index fbb39a13288..96af871c09a 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -632,6 +632,18 @@ public class CommonParameter { @Getter @Setter public long allowTvmBlob; + @Getter + @Setter + public long allowOptimizedBN128; + @Getter + @Setter + public boolean launchBN128Server = false; + @Getter + @Setter + public int bn128ServerPort = 9001; + @Getter + @Setter + public int bn128SocketTimeout = 30; private static double calcMaxTimeRatio() { return 5.0; diff --git a/common/src/main/java/org/tron/core/config/Parameter.java b/common/src/main/java/org/tron/core/config/Parameter.java index 8ec27ed3eb5..db88ab5e047 100644 --- a/common/src/main/java/org/tron/core/config/Parameter.java +++ b/common/src/main/java/org/tron/core/config/Parameter.java @@ -28,7 +28,8 @@ public enum ForkBlockVersionEnum { VERSION_4_7_7(31, 1596780000000L, 80), VERSION_4_8_0(32, 1596780000000L, 80), VERSION_4_8_0_1(33, 1596780000000L, 70), - VERSION_4_8_1(34, 1596780000000L, 80); + VERSION_4_8_1(34, 1596780000000L, 80), + VERSION_4_8_2(35, 1596780000000L, 80); // if add a version, modify BLOCK_VERSION simultaneously @Getter @@ -77,7 +78,7 @@ public class ChainConstant { public static final int SINGLE_REPEAT = 1; public static final int BLOCK_FILLED_SLOTS_NUMBER = 128; public static final int MAX_FROZEN_NUMBER = 1; - public static final int BLOCK_VERSION = 34; + public static final int BLOCK_VERSION = 35; public static final long FROZEN_PERIOD = 86_400_000L; public static final long DELEGATE_PERIOD = 3 * 86_400_000L; public static final long TRX_PRECISION = 1000_000L; diff --git a/common/src/main/java/org/tron/core/vm/config/VMConfig.java b/common/src/main/java/org/tron/core/vm/config/VMConfig.java index 578827b2f8c..08c0e7b6559 100644 --- a/common/src/main/java/org/tron/core/vm/config/VMConfig.java +++ b/common/src/main/java/org/tron/core/vm/config/VMConfig.java @@ -61,6 +61,12 @@ public class VMConfig { private static boolean ALLOW_TVM_SELFDESTRUCT_RESTRICTION = false; + private static boolean ALLOW_OPTIMIZED_BN128 = false; + + private static int BN128_CLIENT_PORT = 9001; + + private static int BN128_SOCKET_TIMEOUT = 30; + private VMConfig() { } @@ -172,6 +178,18 @@ public static void initAllowTvmSelfdestructRestriction(long allow) { ALLOW_TVM_SELFDESTRUCT_RESTRICTION = allow == 1; } + public static void initAllowOptimizedBN128(long allow) { + ALLOW_OPTIMIZED_BN128 = allow == 1; + } + + public static void initBN128Port(int port) { + BN128_CLIENT_PORT = port; + } + + public static void initBN128SocketTimeout(int timeout) { + BN128_SOCKET_TIMEOUT = timeout; + } + public static boolean getEnergyLimitHardFork() { return CommonParameter.ENERGY_LIMIT_HARD_FORK; } @@ -271,4 +289,16 @@ public static boolean allowTvmBlob() { public static boolean allowTvmSelfdestructRestriction() { return ALLOW_TVM_SELFDESTRUCT_RESTRICTION; } + + public static boolean allowOptimizedBn128() { + return ALLOW_OPTIMIZED_BN128; + } + + public static int getBN128ClientPort() { + return BN128_CLIENT_PORT; + } + + public static int getBN128SocketTimeout() { + return BN128_SOCKET_TIMEOUT; + } } diff --git a/crypto/build.gradle b/crypto/build.gradle index 82814af49e6..75dc0418ed9 100644 --- a/crypto/build.gradle +++ b/crypto/build.gradle @@ -12,6 +12,8 @@ repositories { dependencies { api project(":common") + api 'net.java.dev.jna:jna:5.12.1' + api 'com.github.federico2014.besu-native:gnark:1.3.11' } jacocoTestReport { diff --git a/crypto/src/main/java/org/tron/common/crypto/bn128/BN128Executor.java b/crypto/src/main/java/org/tron/common/crypto/bn128/BN128Executor.java new file mode 100644 index 00000000000..36ddb830571 --- /dev/null +++ b/crypto/src/main/java/org/tron/common/crypto/bn128/BN128Executor.java @@ -0,0 +1,92 @@ +package org.tron.common.crypto.bn128; + +import com.sun.jna.ptr.IntByReference; +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; + +@Slf4j(topic = "crypto") +public class BN128Executor { + + public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + private static final int PAIR_SIZE = 192; + + // Limit to 100 pairs (19,200 bytes) in optimized mode to prevent timeout attacks + private static final int MAX_PAIR_SIZE_LIMIT = 192 * 100; + + public static Pair add(byte[] data) { + if (data == null) { + data = EMPTY_BYTE_ARRAY; + } + + byte[] input = data.length > 128 + ? Arrays.copyOfRange(data, 0, 128) : data; + Pair result = executeEIP196Operation( + LibGnarkEIP196.EIP196_ADD_OPERATION_RAW_VALUE, input); + return result; + } + + public static Pair mul(byte[] data) { + if (data == null) { + data = EMPTY_BYTE_ARRAY; + } + + byte[] input = data.length > 96 + ? Arrays.copyOfRange(data, 0, 96) : data; + Pair result = executeEIP196Operation( + LibGnarkEIP196.EIP196_MUL_OPERATION_RAW_VALUE, input); + return result; + } + + public static Pair pairing(byte[] data) { + if (data == null) { + data = EMPTY_BYTE_ARRAY; + } + + if (data.length > MAX_PAIR_SIZE_LIMIT + || data.length % PAIR_SIZE > 0) { + return Pair.of(false, EMPTY_BYTE_ARRAY); + } + Pair result = executeEIP196Operation( + LibGnarkEIP196.EIP196_PAIR_OPERATION_RAW_VALUE, data); + return result; + + } + + + private static Pair executeEIP196Operation( + byte operation, byte[] data) { + if (!LibGnarkEIP196.ENABLED) { + logger.warn("Native BN128 library not available, " + + "cannot execute optimized path"); + return null; + } + + final byte[] output = + new byte[LibGnarkEIP196.EIP196_PREALLOCATE_FOR_RESULT_BYTES]; + final IntByReference outputLength = new IntByReference(); + final byte[] error = + new byte[LibGnarkEIP196.EIP196_PREALLOCATE_FOR_ERROR_BYTES]; + final IntByReference errorLength = new IntByReference(); + + int ret = LibGnarkEIP196.eip196_perform_operation( + operation, data, data.length, + output, outputLength, error, errorLength); + + if (ret == 0) { + return Pair.of(true, + subArray(output, 0, outputLength.getValue())); + } else { + return Pair.of(false, EMPTY_BYTE_ARRAY); + } + } + + public static byte[] subArray(byte[] input, int start, int end) { + byte[] result = new byte[end - start]; + System.arraycopy(input, start, result, 0, end - start); + return result; + } + +} diff --git a/crypto/src/main/java/org/tron/common/crypto/bn128/BN128Service.java b/crypto/src/main/java/org/tron/common/crypto/bn128/BN128Service.java new file mode 100644 index 00000000000..808dc8a97e2 --- /dev/null +++ b/crypto/src/main/java/org/tron/common/crypto/bn128/BN128Service.java @@ -0,0 +1,38 @@ +package org.tron.common.crypto.bn128; + +import org.apache.commons.lang3.tuple.Pair; + +/** + * Common interface for BN128 elliptic curve operations via IPC. + */ +public interface BN128Service { + + /** + * Performs BN128 point addition. + * + * @param input 128 bytes (two compressed G1 points) + * @return Pair of (success, result bytes) + */ + Pair bn128Add(byte[] input) throws Exception; + + /** + * Performs BN128 scalar multiplication. + * + * @param input 96 bytes (one compressed G1 point + scalar) + * @return Pair of (success, result bytes) + */ + Pair bn128Mul(byte[] input) throws Exception; + + /** + * Performs BN128 pairing check. + * + * @param input 192 bytes (pairing inputs) + * @return Pair of (success, result bytes) - result is {1} if true, {0} if false + */ + Pair bn128Pairing(byte[] input) throws Exception; + + /** + * Closes the service and releases resources. + */ + void close() throws Exception; +} diff --git a/crypto/src/main/java/org/tron/common/crypto/bn128/SocketBN128Client.java b/crypto/src/main/java/org/tron/common/crypto/bn128/SocketBN128Client.java new file mode 100644 index 00000000000..5292934921b --- /dev/null +++ b/crypto/src/main/java/org/tron/common/crypto/bn128/SocketBN128Client.java @@ -0,0 +1,95 @@ +package org.tron.common.crypto.bn128; + +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; +import java.util.concurrent.ArrayBlockingQueue; +import org.apache.commons.lang3.tuple.Pair; + +/** + * Socket-based implementation of Bn128Service. Connects to a remote BN128 worker server via TCP + * socket. + */ +public class SocketBN128Client implements BN128Service { + + private ArrayBlockingQueue pool; + private final int port; + private final int socketTimeout; + + public SocketBN128Client(String host, int port, int poolSize, int socketTimeout) throws Exception { + this.port = port; + this.socketTimeout = socketTimeout; + pool = new ArrayBlockingQueue<>(poolSize); + for (int i = 0; i < poolSize; i++) { + SocketChannel ch = SocketChannel.open(); + ch.connect(new InetSocketAddress(host, port)); + pool.add(ch); + } + } + + public SocketBN128Client( int poolSize, int port, int socketTimeout) throws Exception { + this("127.0.0.1", port, poolSize, socketTimeout); + } + + public SocketBN128Client(int poolSize, int socketTimeout) throws Exception { + this("127.0.0.1", 9001, poolSize, socketTimeout); + } + + private Pair call(byte opcode, byte[] input) throws Exception { + SocketChannel ch = pool.take(); + try { + // Set timeout for socket operations + ch.socket().setSoTimeout(socketTimeout); + + ByteBuffer req = ByteBuffer.allocate(5 + input.length); + req.put(opcode); + req.putInt(input.length); + req.put(input); + req.flip(); + ch.write(req); + + ByteBuffer header = ByteBuffer.allocate(5); + ch.read(header); + header.flip(); + boolean success = header.get() == 0; // status byte: 0=success + int len = header.getInt(); + + ByteBuffer body = ByteBuffer.allocate(len); + ch.read(body); + body.flip(); + byte[] result = new byte[len]; + body.get(result); + return Pair.of(success, result); + } catch (java.net.SocketTimeoutException e) { + throw new RuntimeException("BN128 operation timed out after " + socketTimeout + "ms", e); + } finally { + pool.put(ch); + } + } + + @Override + public Pair bn128Add(byte[] input) throws Exception { + return call((byte) 1, input); + } + + @Override + public Pair bn128Mul(byte[] input) throws Exception { + return call((byte) 2, input); + } + + @Override + public Pair bn128Pairing(byte[] input) throws Exception { + return call((byte) 3, input); + } + + @Override + public void close() throws Exception { + for (SocketChannel ch : pool) { + try { + ch.close(); + } catch (Exception e) { + // Ignore + } + } + } +} diff --git a/crypto/src/main/java/org/tron/common/crypto/bn128/SocketBn128Server.java b/crypto/src/main/java/org/tron/common/crypto/bn128/SocketBn128Server.java new file mode 100644 index 00000000000..4c9d9df93c1 --- /dev/null +++ b/crypto/src/main/java/org/tron/common/crypto/bn128/SocketBn128Server.java @@ -0,0 +1,196 @@ +package org.tron.common.crypto.bn128; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.commons.lang3.tuple.Pair; + +/** + * Socket-based BN128 worker server. Listens on TCP port and processes BN128 operations using a + * thread pool. + */ +public class SocketBn128Server { + + private static final int DEFAULT_PORT = 9001; + private static final int DEFAULT_QUEUE_SIZE = 1000; + + private final int port; + private final BlockingQueue queue; + private final ExecutorService workers; + private volatile boolean running = false; + private Selector selector; + private ServerSocketChannel server; + + private static final int MAX_PAYLOAD = 100 * 196; + private static final int BUFFER_SIZE = 5 + MAX_PAYLOAD; + + public SocketBn128Server() { + this(DEFAULT_PORT); + } + + public SocketBn128Server(int port) { + this.port = port; + this.queue = new ArrayBlockingQueue<>(DEFAULT_QUEUE_SIZE); + this.workers = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + } + + public void start() throws Exception { + if (running) { + return; + } + running = true; + + startWorkers(); + + selector = Selector.open(); + server = ServerSocketChannel.open(); + server.socket().bind(new InetSocketAddress(port)); + server.configureBlocking(false); + server.register(selector, SelectionKey.OP_ACCEPT); + + System.out.println("BN128 Socket Worker started on port " + port); + + while (running) { + selector.select(); + Iterator it = selector.selectedKeys().iterator(); + + while (it.hasNext()) { + SelectionKey key = it.next(); + it.remove(); + + if (key.isAcceptable()) { + SocketChannel client = server.accept(); + client.configureBlocking(false); + client.register(selector, SelectionKey.OP_READ, + ByteBuffer.allocateDirect(BUFFER_SIZE)); + } + + if (key.isReadable()) { + SocketChannel ch = (SocketChannel) key.channel(); + ByteBuffer buffer = (ByteBuffer) key.attachment(); + int read = ch.read(buffer); + if (read == -1) { + ch.close(); + continue; + } + + if (buffer.position() >= 5) { + buffer.flip(); + byte opcode = buffer.get(); + int len = buffer.getInt(); + if (buffer.remaining() >= len) { + byte[] payload = new byte[len]; + buffer.get(payload); + SocketRequest req = new SocketRequest(ch, opcode, payload); + if (!queue.offer(req)) { + ch.close(); + } + buffer.clear(); + } else { + buffer.compact(); + } + } + } + } + } + } + + public void stop() throws IOException { + running = false; + if (server != null) { + server.close(); + } + if (selector != null) { + selector.close(); + } + workers.shutdown(); + } + + private void startWorkers() { + for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { + workers.submit(() -> { + while (true) { + try { + SocketRequest req = queue.take(); + Pair resultPair; + byte[] result; + byte status = 0; + switch (req.opcode) { + case 1: + resultPair = bn128Add(req.payload); + result = resultPair != null ? resultPair.getRight() : new byte[]{0}; + status = (resultPair != null && resultPair.getLeft()) ? (byte) 0 : (byte) 1; + break; + case 2: + resultPair = bn128Mul(req.payload); + result = resultPair != null ? resultPair.getRight() : new byte[]{0}; + status = (resultPair != null && resultPair.getLeft()) ? (byte) 0 : (byte) 1; + break; + case 3: + resultPair = bn128Pairing(req.payload); + result = resultPair != null ? resultPair.getRight() : new byte[]{0}; + status = (resultPair != null && resultPair.getLeft()) ? (byte) 0 : (byte) 1; + break; + default: + result = new byte[]{0}; + status = 1; + } + sendResponse(req.channel, status, result); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + } + + // BN128 operations using GNark library + private Pair bn128Add(byte[] input) { + return BN128Executor.add(input); + } + + private Pair bn128Mul(byte[] input) { + return BN128Executor.mul(input); + } + + private Pair bn128Pairing(byte[] input) { + return BN128Executor.pairing(input); + } + + private void sendResponse(SocketChannel ch, byte status, byte[] result) throws IOException { + ByteBuffer resp = ByteBuffer.allocateDirect(5 + result.length); + resp.put(status); + resp.putInt(result.length); + resp.put(result); + resp.flip(); + ch.write(resp); + } + + // Request holder class + static class SocketRequest { + + SocketChannel channel; + byte opcode; + byte[] payload; + + SocketRequest(SocketChannel ch, byte op, byte[] data) { + channel = ch; + opcode = op; + payload = data; + } + } + + public static void main(String[] args) throws Exception { + SocketBn128Server server = new SocketBn128Server(); + server.start(); + } +} diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 8c86f2f66ac..28ec76e8f56 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -780,7 +780,7 @@ public WitnessList getPaginatedNowWitnessList(long offset, long limit) throws if (limit > WITNESS_COUNT_LIMIT_MAX) { limit = WITNESS_COUNT_LIMIT_MAX; } - + /* In the maintenance period, the VoteStores will be cleared. To avoid the race condition of VoteStores deleted but Witness vote counts not updated, @@ -1502,12 +1502,16 @@ public Protocol.ChainParameters getChainParameters() { builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder() .setKey("getAllowTvmSelfdestructRestriction") .setValue(dbManager.getDynamicPropertiesStore().getAllowTvmSelfdestructRestriction()) - .build()); - + .build()); + builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder() .setKey("getProposalExpireTime") .setValue(dbManager.getDynamicPropertiesStore().getProposalExpireTime()) .build()); + builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder() + .setKey("getAllowOptimizedBn128") + .setValue(dbManager.getDynamicPropertiesStore().getAllowOptimizedBN128()) + .build()); return builder.build(); } diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 0e71294d786..01942d95065 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -36,7 +36,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.concurrent.BlockingQueue; @@ -985,6 +984,17 @@ public static void applyConfigParams( config.hasPath(ConfigKey.COMMITTEE_ALLOW_TVM_BLOB) ? config .getInt(ConfigKey.COMMITTEE_ALLOW_TVM_BLOB) : 0; + PARAMETER.allowOptimizedBN128 = + config.hasPath(ConfigKey.COMMITTEE_ALLOW_OPTIMIZED_BN128) + ? config.getInt( + ConfigKey.COMMITTEE_ALLOW_OPTIMIZED_BN128) : 0; + + // BN128 Socket configuration + PARAMETER.bn128ServerPort = config.hasPath(ConfigKey.BN128_SERVER_PORT) + ? config.getInt(ConfigKey.BN128_SERVER_PORT) : 9001; + PARAMETER.bn128SocketTimeout = config.hasPath(ConfigKey.BN128_SOCKET_TIMEOUT) + ? config.getInt(ConfigKey.BN128_SOCKET_TIMEOUT) : 30; + logConfig(); } @@ -1098,6 +1108,9 @@ private static void applyCLIParams(CLIParameter cmd, JCommander jc) { } PARAMETER.seedNode.setAddressList(seeds); } + if (assigned.contains("--bn128-server")) { + PARAMETER.launchBN128Server = cmd.launchBN128Server; + } } private static void initLocalWitnesses(Config config, CLIParameter cmd) { diff --git a/framework/src/main/java/org/tron/core/config/args/CLIParameter.java b/framework/src/main/java/org/tron/core/config/args/CLIParameter.java index b5bd0e2e85a..91f9b69b043 100644 --- a/framework/src/main/java/org/tron/core/config/args/CLIParameter.java +++ b/framework/src/main/java/org/tron/core/config/args/CLIParameter.java @@ -153,4 +153,7 @@ public class CLIParameter { @Parameter(names = {"--history-balance-lookup"}) public boolean historyBalanceLookup; + + @Parameter(names = {"--bn128-server"}, description = "Launch BN128 IPC server") + public boolean launchBN128Server; } diff --git a/framework/src/main/java/org/tron/core/config/args/ConfigKey.java b/framework/src/main/java/org/tron/core/config/args/ConfigKey.java index dbb872febce..d35e0a8e20f 100644 --- a/framework/src/main/java/org/tron/core/config/args/ConfigKey.java +++ b/framework/src/main/java/org/tron/core/config/args/ConfigKey.java @@ -246,6 +246,7 @@ private ConfigKey() { "committee.consensusLogicOptimization"; public static final String COMMITTEE_ALLOW_TVM_CANCUN = "committee.allowTvmCancun"; public static final String COMMITTEE_ALLOW_TVM_BLOB = "committee.allowTvmBlob"; + public static final String COMMITTEE_ALLOW_OPTIMIZED_BN128 = "committee.allowOptimizedBn128"; public static final String COMMITTEE_PROPOSAL_EXPIRE_TIME = "committee.proposalExpireTime"; public static final String ALLOW_ACCOUNT_ASSET_OPTIMIZATION = "committee.allowAccountAssetOptimization"; @@ -312,6 +313,8 @@ private ConfigKey() { "node.metrics.influxdb.metricsReportInterval"; public static final String METRICS_PROMETHEUS_ENABLE = "node.metrics.prometheus.enable"; public static final String METRICS_PROMETHEUS_PORT = "node.metrics.prometheus.port"; + public static final String BN128_SERVER_PORT = "node.bn128.serverPort"; + public static final String BN128_SOCKET_TIMEOUT = "node.bn128.socketTimeout"; // seed public static final String SEED_NODE_IP_LIST = "seed.node.ip.list"; diff --git a/framework/src/main/java/org/tron/core/consensus/ProposalService.java b/framework/src/main/java/org/tron/core/consensus/ProposalService.java index 51d53f6a59e..f1f2c43903a 100644 --- a/framework/src/main/java/org/tron/core/consensus/ProposalService.java +++ b/framework/src/main/java/org/tron/core/consensus/ProposalService.java @@ -392,6 +392,10 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule) manager.getDynamicPropertiesStore().saveProposalExpireTime(entry.getValue()); break; } + case ALLOW_OPTIMIZED_BN128: { + manager.getDynamicPropertiesStore().saveAllowOptimizedBn128(entry.getValue()); + break; + } default: find = false; break; diff --git a/framework/src/main/java/org/tron/program/FullNode.java b/framework/src/main/java/org/tron/program/FullNode.java index 95257d77f8e..600227bf544 100644 --- a/framework/src/main/java/org/tron/program/FullNode.java +++ b/framework/src/main/java/org/tron/program/FullNode.java @@ -6,6 +6,7 @@ import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; import org.tron.common.arch.Arch; +import org.tron.common.crypto.bn128.SocketBn128Server; import org.tron.common.exit.ExitManager; import org.tron.common.log.LogService; import org.tron.common.parameter.CommonParameter; @@ -36,6 +37,33 @@ public static void main(String[] args) { KeystoreFactory.start(); return; } + if (parameter.launchBN128Server) { + logger.info("Starting BN128 Server..."); + int bn128Port = Args.getInstance().getBn128ServerPort(); + logger.info("BN128 Server config: port={}", bn128Port); + SocketBn128Server server = new SocketBn128Server(bn128Port); + try { + server.start(); + logger.info("BN128 Socket Server started successfully"); + + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + logger.info("Shutting down BN128 Socket Server..."); + server.stop(); + logger.info("BN128 Socket Server stopped successfully"); + } catch (Exception e) { + logger.error("Error occurred while stopping BN128 Socket Server", e); + } + })); + + Thread.currentThread().join(); + } catch (Exception e) { + logger.error("Failed to start BN128 Socket Server", e); + System.exit(1); + } + return; + } + logger.info("Full node running."); if (Args.getInstance().isDebug()) { logger.info("in debug mode, it won't check energy time"); diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 661a592e431..c5250af1fb1 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -267,6 +267,14 @@ node { reflectionService = false } + # BN128 Socket Server configuration + bn128 { + # Server listen port, default 9001 + serverPort = 9001 + # Socket timeout in milliseconds for client operations, default 30ms + socketTimeout = 30 + } + # number of solidity thread in the FullNode. # If accessing solidity rpc and http interface timeout, could increase the number of threads, # The default value is the number of cpu cores of the machine. @@ -759,6 +767,7 @@ committee = { # allowTvmBlob = 0 # consensusLogicOptimization = 0 # allowOptimizedReturnValueOfChainId = 0 + # allowOptimizedBn128 = 0 } event.subscribe = { diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BN128PrecompiledContratsTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BN128PrecompiledContratsTest.java new file mode 100644 index 00000000000..8664c38a5ad --- /dev/null +++ b/framework/src/test/java/org/tron/common/runtime/vm/BN128PrecompiledContratsTest.java @@ -0,0 +1,436 @@ +package org.tron.common.runtime.vm; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertTrue; +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 java.io.File; +import java.security.SecureRandom; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.bouncycastle.util.encoders.Hex; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.runtime.ProgramResult; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.ByteUtil; +import org.tron.core.Wallet; +import org.tron.core.config.args.Args; +import org.tron.core.store.StoreFactory; +import org.tron.core.vm.PrecompiledContracts; +import org.tron.core.vm.PrecompiledContracts.PrecompiledContract; +import org.tron.core.vm.config.VMConfig; +import org.tron.core.vm.repository.RepositoryImpl; +import org.tron.core.zksnark.SendCoinShieldTest; + +@Slf4j +public class BN128PrecompiledContratsTest extends BaseTest { + + // 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 OWNER_ADDRESS; + + static { + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, "config-test.conf"); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + } + + @Before + public void setUp() { + VMConfig.initAllowOptimizedBN128(1); + } + + @After + public void tearDown() { + VMConfig.initAllowOptimizedBN128(0); + } + + @Test + public void testLibraryLoading() { + assertTrue("Native LibGnarkEIP196 library should be loaded", LibGnarkEIP196.ENABLED); + } + + @Test + public void bn128AdditionTest() throws Exception { + PrecompiledContract bn128Add = createPrecompiledContract(altBN128AddAddr, OWNER_ADDRESS); + JSONArray testCases = readJsonFile("bn256Add.json"); + for (int i = 0; i < testCases.size(); i++) { + JSONObject testCase = testCases.getJSONObject(i); + String name = testCase.getString("Name"); + Boolean ret = testCase.getBoolean("Result"); + byte[] input = Hex.decode(testCase.getString("Input")); + byte[] expected = Hex.decode(testCase.getString("Expected")); + Pair result = bn128Add.execute(input); + if (result.getLeft()) { + assertArrayEquals(String.format("BN128Add test %s failed", name), expected, + result.getRight()); + Assert.assertNull(ret); + } else { + Assert.assertFalse(ret); + } + } + } + + @Test + public void bn128MultiplicationTest() throws Exception { + PrecompiledContract bn128Mul = createPrecompiledContract(altBN128MulAddr, OWNER_ADDRESS); + JSONArray testCases = readJsonFile("bn256ScalarMul.json"); + for (int i = 0; i < testCases.size(); i++) { + JSONObject testCase = testCases.getJSONObject(i); + String name = testCase.getString("Name"); + Boolean ret = testCase.getBoolean("Result"); + byte[] input = Hex.decode(testCase.getString("Input")); + byte[] expected = Hex.decode(testCase.getString("Expected")); + Pair result = bn128Mul.execute(input); + if (result.getLeft()) { + assertArrayEquals(String.format("bn128Mul test %s failed", name), expected, + result.getRight()); + Assert.assertNull(ret); + } else { + Assert.assertFalse(ret); + } + } + } + + @Test + public void bn128PairingTest() throws Exception { + PrecompiledContract bn128Pairing = + createPrecompiledContract(altBN128PairingAddr, OWNER_ADDRESS); + JSONArray testCases = readJsonFile("bn256Pairing.json"); + for (int i = 0; i < testCases.size(); i++) { + JSONObject testCase = testCases.getJSONObject(i); + String name = testCase.getString("Name"); + Boolean ret = testCase.getBoolean("Result"); + byte[] input = Hex.decode(testCase.getString("Input")); + byte[] expected = Hex.decode(testCase.getString("Expected")); + Pair result = bn128Pairing.execute(input); + if (result.getLeft()) { + assertArrayEquals(String.format("bn128Pairing test %s failed", name), expected, + result.getRight()); + Assert.assertNull(ret); + } else { + Assert.assertFalse(ret); + } + } + } + + private byte[] validPointsByte() { + byte[] g1Point0 = ByteUtil.merge(ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), + ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000002")); + + byte[] g2Point0 = ByteUtil.merge(ByteArray.fromHexString( + "0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2"), + ByteArray.fromHexString( + "0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed"), + ByteArray.fromHexString( + "0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b"), + ByteArray.fromHexString( + "0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa") + ); + + byte[] g1Point1 = ByteUtil.merge(ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), + ByteArray.fromHexString( + "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45")); + + byte[] g2Point1 = ByteUtil.merge(ByteArray.fromHexString( + "0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2"), + ByteArray.fromHexString( + "0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed"), + ByteArray.fromHexString( + "0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b"), + ByteArray.fromHexString( + "0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa") + ); + + return ByteUtil.merge(g1Point0, g2Point0, g1Point1, g2Point1); + } + + private byte[] inValidPointsOutsideSubgroupG2() { + byte[] g1Point0 = ByteUtil.merge(ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), + ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000002")); + + byte[] g2Point0 = ByteUtil.merge(ByteArray.fromHexString( + "0x1382cd45e5674247f9c900b5c6f6cabbc189c2fabe2df0bf5acd84c97818f508"), + ByteArray.fromHexString( + "0x1246178655ab8f2f26956b189894b7eb93cd4215b9937e7969e44305f80f521e"), + ByteArray.fromHexString( + "0x08331c0a261a74e7e75db1232956663cbc88110f726159c5cba1857ecd03fa64"), + ByteArray.fromHexString( + "0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa") + ); + + byte[] g1Point1 = ByteUtil.merge(ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), + ByteArray.fromHexString( + "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45")); + + byte[] g2Point1 = ByteUtil.merge(ByteArray.fromHexString( + "0x1382cd45e5674247f9c900b5c6f6cabbc189c2fabe2df0bf5acd84c97818f508"), + ByteArray.fromHexString( + "0x1246178655ab8f2f26956b189894b7eb93cd4215b9937e7969e44305f80f521e"), + ByteArray.fromHexString( + "0x08331c0a261a74e7e75db1232956663cbc88110f726159c5cba1857ecd03fa64"), + ByteArray.fromHexString( + "0x1fbf8045ce3e79b5cde4112d38bcd0efbdb1295d2eefdf58151ae309d7ded7db") + ); + + return ByteUtil.merge(g1Point0, g2Point0, g1Point1, g2Point1); + } + + @Test + public void bn128CorrectionTest() { + PrecompiledContract bn128Pairing = createPrecompiledContract(altBN128PairingAddr, + OWNER_ADDRESS); + byte[] intput = validPointsByte(); + Pair result = bn128Pairing.execute(intput); + + assertTrue(result.getLeft()); + Assert.assertArrayEquals(ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), result.getRight()); + + intput = inValidPointsOutsideSubgroupG2(); + result = bn128Pairing.execute(intput); + Assert.assertFalse(result.getLeft()); + Assert.assertEquals(0, result.getRight().length); + } + + @Test + public void bn128AdditionRandomTest() { + PrecompiledContract bn128Add = createPrecompiledContract(altBN128AddAddr, OWNER_ADDRESS); + + SecureRandom random = new SecureRandom(); + byte[] randomInput; + Pair result; + result = bn128Add.execute(null); + assertTrue(result.getLeft()); + result = bn128Add.execute(new byte[0]); + assertTrue(result.getLeft()); + + for (int i = 5; i < 200; i++) { + randomInput = new byte[i]; + random.nextBytes(randomInput); + result = bn128Add.execute(randomInput); + Assert.assertFalse(result.getLeft()); + } + } + + @Test + public void bn128MulRandomTest() { + PrecompiledContract bn128Mul = createPrecompiledContract(altBN128MulAddr, OWNER_ADDRESS); + + SecureRandom random = new SecureRandom(); + byte[] randomInput; + Pair result; + result = bn128Mul.execute(null); + assertTrue(result.getLeft()); + result = bn128Mul.execute(new byte[0]); + assertTrue(result.getLeft()); + + for (int i = 5; i < 200; i++) { + randomInput = new byte[i]; + random.nextBytes(randomInput); + result = bn128Mul.execute(randomInput); + Assert.assertFalse(result.getLeft()); + } + } + + @Test + public void bn128PairingRandomTest() { + PrecompiledContract bn128Pairing = createPrecompiledContract(altBN128PairingAddr, + OWNER_ADDRESS); + SecureRandom random = new SecureRandom(); + byte[] randomInput; + Pair result; + result = bn128Pairing.execute(null); + assertTrue(result.getLeft()); + result = bn128Pairing.execute(new byte[0]); + assertTrue(result.getLeft()); + + for (int i = 5; i <= 110 * 192; i++) { + randomInput = new byte[i]; + random.nextBytes(randomInput); + result = bn128Pairing.execute(randomInput); + Assert.assertFalse(result.getLeft()); + } + } + + @Ignore + @Test + public void bn128BenchOptimized() 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); + } + + @Ignore + @Test + public void bn128BenchUnoptimized() throws Exception { + VMConfig.initAllowOptimizedBN128(0); + 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); + VMConfig.initAllowOptimizedBN128(1); + } + + private PrecompiledContract createPrecompiledContract(DataWord addr, String ownerAddress) { + PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr); + contract.setCallerAddress(convertToTronAddress(Hex.decode(ownerAddress))); + contract.setRepository(RepositoryImpl.createRoot(StoreFactory.getInstance())); + ProgramResult programResult = new ProgramResult(); + contract.setResult(programResult); + return contract; + } + + 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) { + int MATH_WARMUP = 1000; + for (int i = 0; i < MATH_WARMUP; i++) { + contract.execute(input); + } + long start = System.nanoTime(); + for (int i = 0; i < itersCount; i++) { + contract.execute(input); + } + long end = System.nanoTime(); + // Convert nanoseconds to milliseconds + double avgMs = ((double) (end - start)) / itersCount / 1_000_000.0; + logger.info("{} cost {} ms/op average over {} iterations", + contract.getClass().getSimpleName(), String.format("%.3f", avgMs), itersCount); + } + + @Ignore + @Test + public void bn128PairingMaxPairsTest() { + PrecompiledContract bn128Pairing = createPrecompiledContract(altBN128PairingAddr, + OWNER_ADDRESS); + + byte[] twoValidPairs = validPointsByte(); // length is 192 * 2 = 384 + + // Construct 100 pairs (50 * 2 pairs) + byte[] hundredPairs = new byte[192 * 100]; + for (int i = 0; i < 50; i++) { + System.arraycopy(twoValidPairs, 0, hundredPairs, i * 384, 384); + } + + // Default tearDown sets VMConfig.allowOptimizedBn128 back to 0, but setup sets it to 1. + // 1. In optimized mode, test that exactly 100 pairs execute successfully + Pair result = bn128Pairing.execute(hundredPairs); + assertTrue("100 pairs passed optimized verification", result.getLeft()); + Assert.assertArrayEquals(ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), + result.getRight()); + + // 2. In optimized mode, test that 102 pairs will fall back to unoptimized mode + byte[] hundredTwoPairs = new byte[192 * 102]; + System.arraycopy(hundredPairs, 0, hundredTwoPairs, 0, 192 * 100); + System.arraycopy(twoValidPairs, 0, hundredTwoPairs, 192 * 100, 384); + result = bn128Pairing.execute(hundredTwoPairs); + Assert.assertTrue("102 pairs should fall back in unoptimized mode", result.getLeft()); + + // 3. Fallback/Unoptimized mode does not have the max size constraint + VMConfig.initAllowOptimizedBN128(0); + result = bn128Pairing.execute(hundredTwoPairs); + assertTrue("102 pairs should pass in unoptimized mode", result.getLeft()); + Assert.assertArrayEquals(ByteArray.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), + result.getRight()); + + VMConfig.initAllowOptimizedBN128(1); + } + + @Test + public void bn128Pairing100PairsBenchTest() { + PrecompiledContract bn128Pairing = createPrecompiledContract(altBN128PairingAddr, + OWNER_ADDRESS); + + byte[] twoValidPairs = validPointsByte(); + byte[] hundredPairs = new byte[192 * 100]; + for (int i = 0; i < 50; i++) { + System.arraycopy(twoValidPairs, 0, hundredPairs, i * 384, 384); + } + + // Warmup + for (int i = 0; i < 5; i++) { + bn128Pairing.execute(hundredPairs); + } + + int iters = 50; + long start = System.nanoTime(); + for (int i = 0; i < iters; i++) { + bn128Pairing.execute(hundredPairs); + } + long end = System.nanoTime(); + + double avgMs = (end - start) / 1_000_000.0 / iters; + logger.info("BN128 Pairing (100 pairs) optimized execution time: {} ms/op " + + "average over {} iterations", String.format("%.2f", avgMs), iters); + + // Unoptimized + VMConfig.initAllowOptimizedBN128(0); + start = System.nanoTime(); + for (int i = 0; i < iters; i++) { + bn128Pairing.execute(hundredPairs); + } + end = System.nanoTime(); + double unoptimizedMs = (end - start) / 1_000_000.0 / iters; + logger.info("BN128 Pairing (100 pairs) UNoptimized execution time: {} ms/op", + String.format("%.3f", unoptimizedMs)); + + // Restore optimization setting + VMConfig.initAllowOptimizedBN128(1); + } +} diff --git a/framework/src/test/resources/json/bn256Add.json b/framework/src/test/resources/json/bn256Add.json new file mode 100644 index 00000000000..fdef753efc9 --- /dev/null +++ b/framework/src/test/resources/json/bn256Add.json @@ -0,0 +1,126 @@ +[ + { + "Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726607c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7", + "Expected": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915", + "Name": "chfast1", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c91518b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f37266", + "Expected": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204", + "Name": "chfast2", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "cdetrio1", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "cdetrio2", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "cdetrio3", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "cdetrio4", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "cdetrio5", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Name": "cdetrio6", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Name": "cdetrio7", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Name": "cdetrio8", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Gas": 150, + "Name": "cdetrio9", + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Gas": 150, + "Name": "cdetrio10", + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + "Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4", + "Name": "cdetrio11", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4", + "Name": "cdetrio12", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98", + "Expected": "15bf2bb17880144b5d1cd2b1f46eff9d617bffd1ca57c37fb5a49bd84e53cf66049c797f9ce0d17083deb32b5e36f2ea2a212ee036598dd7624c168993d1355f", + "Name": "cdetrio13", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "cdetrio14", + "Gas": 150, + "NoBenchmark": false + }, + { + "Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726707c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7", + "Expected": "696e76616c696420696e70757420706172616d65746572732c20706f696e74206973206e6f74206f6e206375727665", + "Result": false, + "Name": "invalid_first_point" + }, + { + "Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726607c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d8", + "Expected": "696e76616c696420696e70757420706172616d65746572732c20706f696e74206973206e6f74206f6e206375727665", + "Result": false, + "Name": "invalid_second_point" + } +] diff --git a/framework/src/test/resources/json/bn256Pairing.json b/framework/src/test/resources/json/bn256Pairing.json new file mode 100644 index 00000000000..58cdb393d92 --- /dev/null +++ b/framework/src/test/resources/json/bn256Pairing.json @@ -0,0 +1,118 @@ +[ + { + "Input": "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "jeff1", + "Gas": 113000, + "NoBenchmark": false + }, + { + "Input": "2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc0203d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db841213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f06967a1237ebfeca9aaae0d6d0bab8e28c198c5a339ef8a2407e31cdac516db922160fa257a5fd5b280642ff47b65eca77e626cb685c84fa6d3b6882a283ddd1198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "jeff2", + "Gas": 113000, + "NoBenchmark": false + }, + { + "Input": "0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd216da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb314a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee245901b9e027bd5cfc2cb5db82d4dc9677ac795ec500ecd47deee3b5da006d6d049b811d7511c78158de484232fc68daf8a45cf217d1c2fae693ff5871e8752d73b21198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "jeff3", + "Gas": 113000, + "NoBenchmark": false + }, + { + "Input": "2f2ea0b3da1e8ef11914acf8b2e1b32d99df51f5f4f206fc6b947eae860eddb6068134ddb33dc888ef446b648d72338684d678d2eb2371c61a50734d78da4b7225f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb122acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf6806d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb186bac5188a98c45e6016873d107f5cd131f3a3e339d0375e58bd6219347b008122ae2b09e539e152ec5364e7e2204b03d11d3caa038bfc7cd499f8176aacbee1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd415794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f211b88da1679b0b64a63b7e0e7bfe52aae524f73a55be7fe70c7e9bfc94b4cf0da1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "jeff4", + "Gas": 147000, + "NoBenchmark": false + }, + { + "Input": "20a754d2071d4d53903e3b31a7e98ad6882d58aec240ef981fdf0a9d22c5926a29c853fcea789887315916bbeb89ca37edb355b4f980c9a12a94f30deeed30211213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f1abb4a25eb9379ae96c84fff9f0540abcfc0a0d11aeda02d4f37e4baf74cb0c11073b3ff2cdbb38755f8691ea59e9606696b3ff278acfc098fa8226470d03869217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac290a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a98552fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d70f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2198a1f162a73261f112401aa2db79c7dab1533c9935c77290a6ce3b191f2318d198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "jeff5", + "Gas": 147000, + "NoBenchmark": false + }, + { + "Input": "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c103188585e2364128fe25c70558f1560f4f9350baf3959e603cc91486e110936198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Name": "jeff6", + "Gas": 113000, + "NoBenchmark": false + }, + { + "Input": "", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "empty_data", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Name": "one_point", + "Gas": 79000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "two_point_match_2", + "Gas": 113000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "two_point_match_3", + "Gas": 113000, + "NoBenchmark": false + }, + { + "Input": "105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "two_point_match_4", + "Gas": 113000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "ten_point_match_1", + "Gas": 385000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "ten_point_match_2", + "Gas": 385000, + "NoBenchmark": false + }, + { + "Input": "105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "ten_point_match_3", + "Gas": 113000, + "NoBenchmark": false + }, + { + "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" + } +] diff --git a/framework/src/test/resources/json/bn256ScalarMul.json b/framework/src/test/resources/json/bn256ScalarMul.json new file mode 100644 index 00000000000..19985a6b513 --- /dev/null +++ b/framework/src/test/resources/json/bn256ScalarMul.json @@ -0,0 +1,145 @@ +[ + { + "Input": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20400000000000000000000000000000000000000000000000011138ce750fa15c2", + "Expected": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc", + "Name": "chfast1", + "Gas": 6000, + "NoBenchmark": false + }, + { + "Input": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46", + "Expected": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e", + "Name": "chfast2", + "Gas": 6000, + "NoBenchmark": false + }, + { + "Input": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3", + "Expected": "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27", + "Name": "chfast3", + "Gas": 6000, + "NoBenchmark": false + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11", + "Name": "cdetrio1", + "Gas": 6000, + "NoBenchmark": false + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + "Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451", + "Name": "cdetrio2", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000", + "Expected": "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b", + "Name": "cdetrio3", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009", + "Expected": "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575", + "Name": "cdetrio4", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001", + "Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6", + "Name": "cdetrio5", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "29e587aadd7c06722aabba753017c093f70ba7eb1f1c0104ec0564e7e3e21f6022b1143f6a41008e7755c71c3d00b6b915d386de21783ef590486d8afa8453b1", + "Name": "cdetrio6", + "Gas": 6000, + "NoBenchmark": false + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + "Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb", + "Name": "cdetrio7", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000", + "Expected": "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15", + "Name": "cdetrio8", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009", + "Expected": "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a", + "Name": "cdetrio9", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001", + "Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c", + "Name": "cdetrio10", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "00a1a234d08efaa2616607e31eca1980128b00b415c845ff25bba3afcb81dc00242077290ed33906aeb8e42fd98c41bcb9057ba03421af3f2d08cfc441186024", + "Name": "cdetrio11", + "Gas": 6000, + "NoBenchmark": false + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + "Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf", + "Name": "cdetrio12", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000", + "Expected": "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434", + "Name": "cdetrio13", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009", + "Expected": "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f", + "Name": "cdetrio14", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001", + "Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98", + "Name": "cdetrio15", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000000", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "zeroScalar", + "Gas": 6000, + "NoBenchmark": true + }, + { + "Input": "", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "Input": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20500000000000000000000000000000000000000000000000011138ce750fa15c2", + "Expected": "", + "Result": false, + "Name": "invalid_point" + } +] diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 4d0bf1013d6..4f878772e68 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -258,6 +258,22 @@ + + + + + + + + + + + + + + + + @@ -1280,6 +1296,14 @@ + + + + + + + +