From 0684aa070988acc237130ec934e0648c38046759 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Tue, 1 Oct 2024 15:47:28 -0700 Subject: [PATCH 1/6] benchmarkz Signed-off-by: garyschulte --- build.gradle | 2 + .../besu/evm/precompile/Benchmarkz.java | 704 ++++++++++++++++++ gradle.properties | 4 +- 3 files changed, 709 insertions(+), 1 deletion(-) create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java diff --git a/build.gradle b/build.gradle index 23908ad984f..c6c9dc8669b 100644 --- a/build.gradle +++ b/build.gradle @@ -166,6 +166,8 @@ allprojects { content { includeGroupByRegex('com\\.splunk\\..*') } } + mavenLocal() + mavenCentral() // ethereum execution spec tests fixtures. Exclusively for ethereum submodule to run ref tests diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java new file mode 100644 index 00000000000..2c5a1357e7a --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java @@ -0,0 +1,704 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.precompile; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hyperledger.besu.crypto.Hash.keccak256; + +import org.hyperledger.besu.crypto.Hash; +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SECPPrivateKey; +import org.hyperledger.besu.crypto.SECPSignature; +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.evm.code.CodeV0; +import org.hyperledger.besu.evm.fluent.SimpleBlockValues; +import org.hyperledger.besu.evm.fluent.SimpleWorld; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator; +import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; + +import java.math.BigInteger; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import com.google.common.base.Stopwatch; +import com.google.common.collect.ImmutableMap; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +@SuppressWarnings("UnusedMethod") +public class Benchmarkz { + + static final Random random = new Random(); + + static final long GAS_PER_SECOND_STANDARD = 35_000_000L; + + static final int HASH_WARMUP = 1_000_000; + static final int HASH_ITERATIONS = 10_000; + + static final int MATH_WARMUP = 10_000; + static final int MATH_ITERATIONS = 1_000; + static final MessageFrame fakeFrame = + MessageFrame.builder() + .type(MessageFrame.Type.CONTRACT_CREATION) + .contract(Address.ZERO) + .inputData(Bytes.EMPTY) + .sender(Address.ZERO) + .value(Wei.ZERO) + .apparentValue(Wei.ZERO) + .code(CodeV0.EMPTY_CODE) + .completer(__ -> {}) + .address(Address.ZERO) + .blockHashLookup(n -> null) + .blockValues(new SimpleBlockValues()) + .gasPrice(Wei.ZERO) + .miningBeneficiary(Address.ZERO) + .originator(Address.ZERO) + .initialGas(100_000L) + .worldUpdater(new SimpleWorld()) + .build(); + + private static void benchSecp256k1Recover() { + final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); + + final SECPPrivateKey privateKey = + signatureAlgorithm.createPrivateKey( + new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16)); + final KeyPair keyPair = signatureAlgorithm.createKeyPair(privateKey); + + final Bytes data = Bytes.wrap("This is an example of a signed message.".getBytes(UTF_8)); + final Bytes32 dataHash = keccak256(data); + final SECPSignature signature = signatureAlgorithm.sign(dataHash, keyPair); + for (int i = 0; i < MATH_WARMUP; i++) { + signatureAlgorithm.recoverPublicKeyFromSignature(dataHash, signature); + } + final Stopwatch timer = Stopwatch.createStarted(); + for (int i = 0; i < MATH_ITERATIONS; i++) { + signatureAlgorithm.recoverPublicKeyFromSignature(dataHash, signature); + } + timer.stop(); + + final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; + final double perCall = elapsed / MATH_ITERATIONS; + final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; + + System.out.printf("secp256k1 signature recovery for %,d gas.%n", (int) gasSpent); + } + + public static void benchSha256() { + final SHA256PrecompiledContract contract = + new SHA256PrecompiledContract(new IstanbulGasCalculator()); + final byte[] warmupData = new byte[240]; + final Bytes warmupBytes = Bytes.wrap(warmupData); + for (int i = 0; i < HASH_WARMUP; i++) { + contract.computePrecompile(warmupBytes, fakeFrame); + } + for (int len = 0; len <= 256; len += 8) { + final byte[] data = new byte[len]; + random.nextBytes(data); + final Bytes bytes = Bytes.wrap(data); + final Stopwatch timer = Stopwatch.createStarted(); + for (int i = 0; i < HASH_ITERATIONS; i++) { + contract.computePrecompile(bytes, fakeFrame); + } + timer.stop(); + + final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; + final double perCall = elapsed / HASH_ITERATIONS; + final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; + + System.out.printf( + "sha256 %,d bytes for %,d gas. Charging %,d gas.%n", + len, (int) gasSpent, contract.gasRequirement(bytes)); + } + } + + private static void benchKeccak256() { + fakeFrame.expandMemory(0, 1024); + var istanbulGasCalculator = new IstanbulGasCalculator(); + final byte[] warmupData = new byte[240]; + final Bytes warmupBytes = Bytes.wrap(warmupData); + for (int i = 0; i < HASH_WARMUP; i++) { + Hash.keccak256(warmupBytes); + } + for (int len = 0; len <= 512; len += 8) { + final byte[] data = new byte[len]; + random.nextBytes(data); + final Bytes bytes = Bytes.wrap(data); + final Stopwatch timer = Stopwatch.createStarted(); + for (int i = 0; i < HASH_ITERATIONS; i++) { + Hash.keccak256(bytes); + } + timer.stop(); + + final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; + final double perCall = elapsed / HASH_ITERATIONS; + final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; + + System.out.printf( + "keccak256 %,d bytes for %,d gas. Charing %d gas.%n", + len, (int) gasSpent, istanbulGasCalculator.keccak256OperationGasCost(fakeFrame, 0, len)); + } + } + + private static void benchRipeMD() { + final RIPEMD160PrecompiledContract contract = + new RIPEMD160PrecompiledContract(new IstanbulGasCalculator()); + final byte[] warmupData = new byte[240]; + final Bytes warmupBytes = Bytes.wrap(warmupData); + for (int i = 0; i < HASH_WARMUP; i++) { + contract.computePrecompile(warmupBytes, fakeFrame); + } + for (int len = 0; len <= 256; len += 8) { + final byte[] data = new byte[len]; + random.nextBytes(data); + final Bytes bytes = Bytes.wrap(data); + final Stopwatch timer = Stopwatch.createStarted(); + for (int i = 0; i < HASH_ITERATIONS; i++) { + contract.computePrecompile(bytes, fakeFrame); + } + timer.stop(); + + final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; + final double perCall = elapsed / HASH_ITERATIONS; + final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; + + System.out.printf( + "ripemd %,d bytes for %,d gas. Charging %,d gas.%n", + len, (int) gasSpent, contract.gasRequirement(bytes)); + } + } + + private static void benchModExp() { + final Map testcases = + new ImmutableMap.Builder() + .put( + "eip_example1", + Bytes.fromHexString( + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000020" + + "03" + + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e" + + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f")) + .put( + "eip_example2", + Bytes.fromHexString( + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000020" + + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e" + + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f")) + .put( + "even-modulus-1", + Bytes.fromHexString( + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003c2040160024518968061546464452029984405379963244433254832348165045983839181603600983245188119082741180552472823434126339186042653363989253518144015007104659260895861906540664936284389736130979465984263224400655133820675791338815252163142936101184074977707018635613728563507946963514079867296353079585444179075183175315953500862929638853495671020263166123912364061541662955981749424030252416330220564030645929402440479045589943839631409636357644094127401186503107365632233122371688639562179885062893961510897259834525401728081797411184820573804096446362924176080926052008070342876591822173915634645231182811305568049542955744148010693635112077769594038286419007643605441221736768092092706367136248982357930831050114862462054469804238839007660797444001134145988063087013657265067255538916788266246587774231646489345179567885975873995767749906187041937713976494258573504873269320274358396975658022816526738914029788471066595929777423497242252763504644221066495966982158816143636722736200299105017320500139589998102103536908651755056175006587609525845133254470473698921229697550145309121304642224273213418856615560961843245211567388930209839462064588566503446549415643465733541976019955544090933949692508519895293721888001835024288589127818157262958206047538648802179821901844091151603223229973835165715768557428338775055435040494382003663260090655173262271219880999454966135210800173588881197223814096778846598765822161982688788574265773201009190341430440400154076998270731076034021917712825351270109621323258567738829791704547404897555410847468529100600344699859551947494210268509149049419749744679372826553895949980386864014015247047775654329663958663391477680679444996526407026021137970100258833584773507489900747148344826790699325870056679710341571267983857125765234149331990149745571500943300684008078036054281629105618499442731182983775330888524074001975745730722737461725166625564316976464879780901853271273641654911641084141502464")) + .put( + "even-modulus-2", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d80000000000000000000000000000000000000000000000000000000000000010e0060000a921212121212121ff0000212b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf82828282828200ffff28ff2b218282000000000000000000")) + .put( + "nagydani-1-square", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb502fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b")) + .put( + "nagydani-1-qube", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb503fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b")) + .put( + "nagydani-1-pow0x10001", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5010001fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b")) + .put( + "nagydani-2-square", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf5102e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087")) + .put( + "nagydani-2-qube", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf5103e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087")) + .put( + "nagydani-2-pow0x10001", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51010001e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087")) + .put( + "nagydani-3-square", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb02d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d")) + .put( + "nagydani-3-qube", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb03d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d")) + .put( + "nagydani-3-pow0x10001", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb010001d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d")) + .put( + "nagydani-4-square", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b8102df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f")) + .put( + "nagydani-4-qube", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b8103df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f")) + .put( + "nagydani-4-pow0x10001", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81010001df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f")) + .put( + "nagydani-5-square", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf02e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad")) + .put( + "nagydani-5-qube", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf03e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad")) + .put( + "nagydani-5-pow0x10001", + Bytes.fromHexString( + "000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf010001e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad")) + .put( + "even-modulous2", + Bytes.fromHexString( + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003c2040160024518968061546464452029984405379963244433254832348165045983839181603600983245188119082741180552472823434126339186042653363989253518144015007104659260895861906540664936284389736130979465984263224400655133820675791338815252163142936101184074977707018635613728563507946963514079867296353079585444179075183175315953500862929638853495671020263166123912364061541662955981749424030252416330220564030645929402440479045589943839631409636357644094127401186503107365632233122371688639562179885062893961510897259834525401728081797411184820573804096446362924176080926052008070342876591822173915634645231182811305568049542955744148010693635112077769594038286419007643605441221736768092092706367136248982357930831050114862462054469804238839007660797444001134145988063087013657265067255538916788266246587774231646489345179567885975873995767749906187041937713976494258573504873269320274358396975658022816526738914029788471066595929777423497242252763504644221066495966982158816143636722736200299105017320500139589998102103536908651755056175006587609525845133254470473698921229697550145309121304642224273213418856615560961843245211567388930209839462064588566503446549415643465733541976019955544090933949692508519895293721888001835024288589127818157262958206047538648802179821901844091151603223229973835165715768557428338775055435040494382003663260090655173262271219880999454966135210800173588881197223814096778846598765822161982688788574265773201009190341430440400154076998270731076034021917712825351270109621323258567738829791704547404897555410847468529100600344699859551947494210268509149049419749744679372826553895949980386864014015247047775654329663958663391477680679444996526407026021137970100258833584773507489900747148344826790699325870056679710341571267983857125765234149331990149745571500943300684008078036054281629105618499442731182983775330888524074001975745730722737461725166625564316976464879780901853271273641654911641084141502464")) + .build(); + final BigIntegerModularExponentiationPrecompiledContract contract = + new BigIntegerModularExponentiationPrecompiledContract(new BerlinGasCalculator()); + + for (final Map.Entry testCase : testcases.entrySet()) { + final double gasSpent = runBenchmark(testCase.getValue(), contract); + + long gasCost = contract.gasRequirement(testCase.getValue()); + System.out.printf( + "ModEXP %s for \t%,d gas. Charging %,d gas. \t@ %,.3f MGps%n", + testCase.getKey(), + (int) gasSpent, + gasCost, + gasCost / gasSpent * GAS_PER_SECOND_STANDARD / 1_000_000); + } + + System.getProperties().forEach((k, v) -> System.out.println(k + " = " + v)); + } + + private static void benchBNADD() { + final Bytes g1Point0 = + Bytes.concatenate( + Bytes.fromHexString( + "0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"), + Bytes.fromHexString( + "0x01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c")); + + final Bytes g1Point1 = + Bytes.concatenate( + Bytes.fromHexString( + "0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"), + Bytes.fromHexString( + "0x2e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb")); + final Bytes arg = Bytes.concatenate(g1Point0, g1Point1); + + final AltBN128AddPrecompiledContract contract = + AltBN128AddPrecompiledContract.istanbul(new IstanbulGasCalculator()); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "BNADD for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); + } + + private static void benchBNMUL() { + final Bytes g1Point1 = + Bytes.concatenate( + Bytes.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000001"), + Bytes.fromHexString( + "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45")); + final Bytes scalar = + Bytes.fromHexString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + final Bytes arg = Bytes.concatenate(g1Point1, scalar); + + final AltBN128MulPrecompiledContract contract = + AltBN128MulPrecompiledContract.istanbul(new IstanbulGasCalculator()); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "BNMUL for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); + } + + private static void benchBNPairing() { + final Bytes[] args = { + Bytes.fromHexString( + "0x0fc6ebd1758207e311a99674dc77d28128643c057fb9ca2c92b4205b6bf57ed2" + + "1e50042f97b7a1f2768fa15f6683eca9ee7fa8ee655d94246ab85fb1da3f0b90" + + "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" + + "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" + + "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" + + "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"), + Bytes.fromHexString( + "0x2b101be01b2f064cba109e065dc0b5e5bf6b64ed4054b82af3a7e6e34c1e2005" + + "1a4d9ceecf9115a98efd147c4abb2684102d3e925938989153b9ff330523cdb4" + + "08d554bf59102bbb961ba81107ec71785ef9ce6638e5332b6c1a58b87447d181" + + "01cf7cc93bfbf7b2c5f04a3bc9cb8b72bbcf2defcabdceb09860c493bdf1588d" + + "02cb2a424885c9e412b94c40905b359e3043275cd29f5b557f008cd0a3e0c0dc" + + "204e5d81d86c561f9344ad5f122a625f259996b065b80cbbe74a9ad97b6d7cc2" + + "07402fdc3bc28a434909f24695adea3e9418d9857efc8c71f67a470a17f3cf12" + + "255dbc3a8b5c2c1a7a3f8c59e2f5b6e04bc4d7b7bb82fcbe18b2294305c8473b" + + "19156e854972d656d1020003e5781972d84081309cdf71baacf6c6e29272f5ff" + + "2acded377df8902b7a75de6c0f53c161f3a2ff3f374470b78d5b3c4d826d84d5" + + "1731ef3b84913296c30a649461b2ca35e3fcc2e3031ea2386d32f885ff096559" + + "0919e7685f6ea605db14f311dede6e83f21937f05cfc53ac1dbe45891c47bf2a"), + Bytes.fromHexString( + "0x1a3fabea802788c8aa88741c6a68f271b221eb75838bb1079381f3f1ae414f40" + + "126308d6cdb6b7efceb1ec0016b99cf7a1e5780f5a9a775d43bc7f2b6fd510e2" + + "11b35cf2c85531eab64b96eb2eef487e0eb60fb9207fe4763e7f6e02dcead646" + + "2cbea52f3417b398aed9e355ed16934a81b72d2646e3bf90dbc2dcba294b631d" + + "2c6518cd26310e541a799357d1ae8bc477b162f2040407b965ecd777e26d31f7" + + "125170b5860fb8f8da2c43e00ea4a83bcc1a974e47e59fcd657851d2b0dd1655" + + "130a2183533392b5fd031857eb4c199a19382f39fcb666d6133b3a6e5784d6a5" + + "2cca76f2bc625d2e61a41b5f382eadf1df1756dd392f639c3d9f3513099e63f9" + + "07ecba8131b3fb354272c86d01577e228c5bd5fb6404bbaf106d7f4858dc2996" + + "1c5d49a9ae291a2a2213da57a76653391fa1fc0fa7c534afa124ad71b7fdd719" + + "10f1a73f94a8f077f478d069d7cf1c49444f64cd20ed75d4f6de3d8986147cf8" + + "0d5816f2f116c5cc0be7dfc4c0b4c592204864acb70ad5f789013389a0092ce4" + + "2650b89e5540eea1375b27dfd9081a0622e03352e5c6a7593df72e2113328e64" + + "21991b3e5100845cd9b8f0fa16c7fe5f40152e702e61f4cdf0d98e7f213b1a47" + + "10520008be7609bdb92145596ac6bf37da0269f7460e04e8e4701c3afbae0e52" + + "0664e736b2af7bf9125f69fe5c3706cd893cd769b1dae8a6e3d639e2d76e66e2" + + "1cacce8776f5ada6b35036f9343faab26c91b9aea83d3cb59cf5628ffe18ab1b" + + "03b48ca7e6d84fca619aaf81745fbf9c30e5a78ed4766cc62b0f12aea5044f56") + }; + final AltBN128PairingPrecompiledContract contract = + AltBN128PairingPrecompiledContract.istanbul(new IstanbulGasCalculator()); + + for (int i = 0; i < args.length; i++) { + final double gasSpent = runBenchmark(args[i], contract); + + System.out.printf( + "BNPairings %d pairs for %,d gas. Charging %,d gas.%n", + i * 2 + 2, (int) gasSpent, contract.gasRequirement(args[i])); + } + } + + public static void benchBLS12G1Add() { + final Bytes arg = + Bytes.fromHexString( + "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f56" + + "0000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee" + + "000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac" + + "0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7"); + + final BLS12G1AddPrecompiledContract contract = new BLS12G1AddPrecompiledContract(); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "G1ADD for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); + } + + private static void benchBLS12G1Mul() { + final Bytes arg = + Bytes.fromHexString( + "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" + + "0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1" + + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + + final BLS12G1MulPrecompiledContract contract = new BLS12G1MulPrecompiledContract(); + contract.computePrecompile(arg, fakeFrame); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "G1MUL for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); + } + + private static void benchBLS12G1MultiExp32Pairs() { + final Bytes[] warmupargs = {Bytes.fromHexString("0000000000000000000000000000000007664256b807eaa3a2345380f94ffc73803fe1d1f66748a6b815971c20f6e03ad1cbdb77f1d4b6cbb1a4a6ee05db9d310000000000000000000000000000000009067b299e5bfd669035fd4bcf9b301b8d1ca0fc37c4208f4da51e2ef5326c2accf8f878508fabc8a235305090ff53dfaa80b53cf0fdd235808f25062ab0f2a53e2013bbe7fa1d9b5b2232ad430315ad0000000000000000000000000000000019b0feda6576be667b8e6bba34dbecfe16a18405df5d8ad8d3ae3c0f9e51dbe83f52d4a55ebad88dbfb10f8094872b700000000000000000000000000000000012f4ddaeb1d20cfd904dd234f02012b034b36dc68e7f87b1358159580271096ff3c67b913b49b99c1816e84d4ff85c651ce12a1ae3f16e26e6fc3e226a4cd3226e35673f6e5aa3e93e150acc915f3a8a0000000000000000000000000000000017a25f415c4667f133c8e0686778c4fff788de4ccf5de941a34ac2231e3c4e4467bde96eb0bbc843e84b294965e2ca950000000000000000000000000000000004262f32154f54a180459d368b07c56cd74b3806964810c43ec93aa206cd3c50c8b69e4847ce32381f671005339273666ed4fcaaa748173954236ad5414292899af572a25ee8f50c4267944af28b0349000000000000000000000000000000000ffb3d452b67876d201735f58b12ed95f1ad8a559f327402fac12aaa12f8fb3d2228a878df7343acf35c39aa300af0480000000000000000000000000000000008d16105c8a1209f89689c7727d774c8c49fd4fdfb615f8873ce1542282e49c174f1782b77de0e837f00331a0138e853e7e793bc6cb21a063e1157268ef28ad2fb30f7cffb45cd20c86370b0722468e8000000000000000000000000000000000290388bce9bd1139e20d8eec9366cbbbe4a9dc685a4f22efef3b8417c9eade6694b5e5e2cd5e934695c448c62e4a9fa000000000000000000000000000000001923a61e55953813ff71c54c2288dcbe1ab43e09d048abb1078a1775fc8789d2d16cb5dfd363c490a72df379f55aebf9996a13510cfbcc5bb10b0bc4e71616c7fc79eb804b366358fa3ef46a1d70516a0000000000000000000000000000000015b4e1e8d4afd65d347c3fb7294726c4fcf6df1318088a1ddffb8b47891097032076a362ffbe02585837119acc170463000000000000000000000000000000000824cdb59b5ef867e5c09652b5a600d3199301116237a2de101d06a5c60d8bb383e8b506b42445f3aa8d61f85150bda5ab6157e88065eabfc77894321021a26e9d88a05c5530bb841f52a20655f417df0000000000000000000000000000000009d9f36237628378ed04e28b251b9c3859bf728f9a65a01fa20e2220d4370d21127ce6db522664081db93662201bca6400000000000000000000000000000000189d5b721a75b746e175c0801ab23ce20ed2c0ac3d2ab58421e9a1f0cbf126d5117a225d2de1257cee1f0717b79f520412b782bd6a26a3471e05401dd24a0477c38402b622e36a7c7a7c6ef10b1dc5a200000000000000000000000000000000154f98971e27f0b6ac04ad8b63bda2497bb80124620f23f07eeb14b5736e38b33502890fdb9abc43ba203c911668127000000000000000000000000000000000024e9ddca8aaa87a0784c9a70fdd9cdb4683f16019543e0314d37ee70d5346290d5d8068496feaa9d5495e679c24b61900a3ade342e302fef0c63a938bbe483f782501082565ae178403cbc1397a4c8f00000000000000000000000000000000131120da9c879429226bd8a342470153bb8e65464ee8903a276ab4ba0657009edd7eb50c20d4948d5550ea97e777be22000000000000000000000000000000000ac267e400c460352cb5a807470932d76796c284c1b85215d0c095d432b9860903143f342aab76eb9069dffe67f353a253fe4009eff5f1d7d3981827f51259170dce200f6a363cda507476d9039a8f16000000000000000000000000000000001708e97f405b46df5cd9c4177d0ed58d83f29466d8abdffd1f4e3876ec3475db8e8de73a91ff58fef5a8370f206f14740000000000000000000000000000000002238b6ebb0df26edb27f5b61748b4bd554824faf433360b77cdac8579fcdb4584203dc4dbb008df67e37f867e06ac39fa97ad23cc242b08dc250e74abb82c9495c9d0f1d2b8935aceba35d8a04db2af0000000000000000000000000000000017d352210c2b627af5b3cd22ad1663387e686b5a8cc6683f8f5b689248bb132cd558928a07b79427b96d002f77c880cb0000000000000000000000000000000004a332585204830bcb8e8a191ee8251d5f1fc66d47108f11b0785d9014eb8696cc54f9b6ccaa73e43cece2be0dcc526ef33dc7fe948356238e3f70c0d1e711f5b0b73a5eca18dd3473796c5cbdc19ea60000000000000000000000000000000016801aa4c72270b52bfc97ef15d6b110183ecd882cbf55989140725f626b16431989058862855e41cbcb81180bbd6ca50000000000000000000000000000000011a18e6aed38703430d0a34236e26055db71e3ac18a8f5a5fa9dc6894d4eb1644d0bb28093902fc64416d66a7f8ae935bd0a03df615b35da5b0304748126a52f7516574989dbaac881aae9396ab16d99000000000000000000000000000000000af7826515ef482e139ab6e180d83200f54b92f2ff1b834cd174e6b965ea8a986b4f39550721a9896e98b708e9b35a430000000000000000000000000000000009268dcbad65048807941ffb7bddf5f1dcdf93006e6aa1a51c4dbd9fa65b2598f0d639d489967b3953d390adc7fe31f20cbcaf531eae209c4a1a794148a3a09e08b461f3fc3b7f964197ec7a6d370c71000000000000000000000000000000001970b65d23f1e7015585ab101b4221e41f8a16a04edd27bdc522898467281a475779b9c05025c56f3cd6708d0baa53c7000000000000000000000000000000000727dbab812703b5098d9992264472e35c96a9c46bdc14ca7f7472826cded859f4c98e969dd7662fbf14d5abdd2179cbe4d409f29475a9ef826263b28ac024b3d16c411932ff1e97a4b878fa5ba6b0820000000000000000000000000000000011e818d54ef5a9fa5683da7eebd36b7abd202459dc55dfd496f84a1083eae6571d609c92dc9928fc4ce2e21e88999070000000000000000000000000000000000692eb691f4a2eb097f0cf554d631b22dd445b21dc80c198c57313ad358b4581bf41ef9e60d7a102d92c69bf49853a34ed47fd3aef867b1c18dab6cc526a49e9c006e7661c1a4388aea83cdd47161d8900000000000000000000000000000000159bdb894d55db8b26cb3a2780d437ed3b8146d63db29da48abb1d2fcac90b83e72f401625cdb988666ad17f3b01c8d900000000000000000000000000000000019f92e9e567a8c2b7ffc5af96038d620f6a6608bb7de4486345396abc09115b326777a1e6ed6f080498c4f762349ce3bd8c301dba98b3af6a515db49bad427a691006328a7f5d8948633cee33090efd0000000000000000000000000000000002240edc25a6b20963fa0912a93ccd25cc94112188bc1cf10f8280488f365fedf47b13d05308f65891f55be75d6a546e000000000000000000000000000000000bc17f8e45e7733a5e3d6efdb8001111782210fbf9b4fbaaea67acab77516d89ad1b271f841631c58becb3e3ff6506ec174341f19e73d59a34d1655265d109633b6023bc166d4b1195185dc3fa35d6690000000000000000000000000000000008161a348271c629255ad9712c5811e75fdefada8573c00ba493dc865042b7790b2a4612ddc6846a535d0e7de61ed8ad00000000000000000000000000000000005b1d8aa7076d1ead706bb149b4d2066ddecbff265415101495141cf87b9527b4eb3d1e1018d5a11ed9ad31735b86ef730a08a15eb5e12b98cec6266c6918827e27d6129f6316758f726aec42d4c0bb00000000000000000000000000000000016562da4cc2df48bbebeda74be9ef19b440beaddd7c05e048dd9ef5a8b65384f70f72476cd3dad180dcee853fa59193000000000000000000000000000000000f99180611eae16e07c4742552baa010c3c256331ba4a0377cb533de012f6a55024f83800bfcc59ead74608e8f0eeabade569312e27ef078dfe70c29edc01d3eb937745ef766d7117a2b8eeda878992e000000000000000000000000000000001728d7d6cac8e82b958bd4f7f5e917659d4b401e3d86ebf4794694ddd4d5d0e1a971ce6139a3b55289c4a4d6a0ee92c70000000000000000000000000000000012fc239cd5d58f66f1078106e32808d90472541112544344c9161cd54c8d196f69963c275536352bd305c0bdcb1fef66e7c36a44be028e0226ffaf00aa83ec29ff6de3b9e54c62a21d522a80e3237abe0000000000000000000000000000000008e716795594276c6f9f241fb0c0b8b57b891e0fd1516eb31d29bd0ad40844bb45cefaeec535180a7f41f7f62ed1a0c40000000000000000000000000000000009ccb5ee63c13c4d81bea4e0cf9a1f196a99ef4df81b71f4b7a4d674c0e714a071633d7bf9e0c73109d393c7044ccae8b7d521ce97d681276990af474d3b1112bfa3810277204b4dc8532ec302cddc8600000000000000000000000000000000018c571437c067d42983c22f51498ea3b922178c5bcbcf3a26646408a3cb764fd08555ab6d7ce2179d6e88e8764b9d5900000000000000000000000000000000048828bd14a480dbd5755105178c519840bfc36a3d8ad902b03d6a4a91f18b6dbef3276a102981cce3b300a38a10cf4055ee41337625eda81c2afe1213fe87ec7a03b9fdd093be58c3a5345be8e4425c00000000000000000000000000000000169a952e4750f32f8be59115098323b8a8335ff29f4928d802cc81ab0311a208df66a1fa21f4f06a3dac003fbff3afe20000000000000000000000000000000012258ae4eee13ff5fbb9653e13239b2675ddb1a82718a5d9598129cfcacea0bff98053aca600939421b38d4736cea3e6ad681fdc185147f10c30c0f875af683fb588456373eef40d246adc493bed6579000000000000000000000000000000000282cb07d118142878ed40ba125c652651b75096cde9b0b79e1752ae73f504b281dbcb7d0a8ea88e78b15a5b0610d306000000000000000000000000000000000831a67a63cbcd46cd3644de8fc8ca8a0342f9736325ea99ce3ebd350cb142865cce149f121cfd7f338d138d518c9046dc4a555322320eeb7f68830df56fc7d7a134f41f19c87c29a1321fbcc36f95e900000000000000000000000000000000116b877ed25c603b77084f97e9fb7c3465b00176751f9ec77e8c283ff38f601906efd0a848632299e667743fccc9e9c200000000000000000000000000000000075fd02aadd0076af212b1b1819e7c22fe7889f4a99ac865c1df73b6e673697852631a9e2033bacd81bb90942f0d53390af8a1cecefa59c5734c8b7566045cc375857a72da0849aa33c2a4b16feb3a130000000000000000000000000000000013528207baf1edfb2370f73640009d1268d0f9ea02035392418f809bcc8ee06ab5d2b8d361805305f37e1669e521be13000000000000000000000000000000000ed65d4a7b11db4cdc68fb10ef35e7e8a290c8cf1022d3ca5db12c3284ee19a7220fda17fead5b4c3b8e266b9f37e70e2bfe92cfecd8cde0b798e4d84481c125c4a40983e1575b3789c7e57a2966dbb400000000000000000000000000000000011b44f3f1446d884a50270e98478f2f1180ff1aece24836a4e1cb085b25e9506ef2c2bc48c07c07c87189ad21b6c1b40000000000000000000000000000000000913cd2fcc40789101c31cbbb2e9f3446c9840e67f1b7f455fa71a5af12b1c62bb4921f0513ed653009c3edc190b9eaeda2905fbd7a90e86bbfa7a7a3ec6feb952c74e0043781976bb755f79260502c00000000000000000000000000000000064357258c8c86dda11a0eec88cfb1a0f1916119c2515fb26861992f70a37eced19b92721b5274e531c2def77dcfb2e30000000000000000000000000000000010061891593da3d189f26413325f1ec966f52a8d565b644e18b9d90918fb932b387c7389408fc41bc158f95d3c7e05c60537aace274ce26c827bcaf96344be095389c963eb96ea8cfdf9607b4f2b7b4d00000000000000000000000000000000069d648fb44e554b510eb364bf81dfcfb7692afb612f40a1bb7fa7e4666d92ca95c2c67196c3fcac92126782a2cf0f430000000000000000000000000000000008bc56e8879e330cf0a88d55838c68deeca45ba70e7df47b5f743569014d9e2aaa0dcbcfcf3c0227e94eef6b1fc56e2557c32d94c592251f6e04d66401fbb4cd0204881bad7e6fd8e5922290944a9cf500000000000000000000000000000000071fd55782b2bfc0353034dc3d756cff43db5c55fb09f60746a7ef7121028795a318e6030a4f71f723f72375f317c610000000000000000000000000000000001036bbbd1a2b39aec610e0fd488080ba1ab477487480a55b860f9c7c507f0703c1bfa8add16c1686f3021c780d37aadff9299de37ab22ac1c427d854933ed59e66e16e034aed011f795f3629b21921550000000000000000000000000000000011c587c0d81c454c99b02d87fb89f081dd7217ba92c3f9158bd913fd9fab6afc8ee7d7011c58ba8a6c36121189a16af70000000000000000000000000000000004dfb0b3e90477e730bbb8cf07cef522c86b54772076bc2209f1928206957ed5653be93f6008d33b9e6d545aa5a5b600926d04008431f57a215217a80304b0a35fea4a3fb83c9cee546c4f5b2c38d47e000000000000000000000000000000000a9e5f4e93fe429c8ad492db1ebb366123a538d0518c8f0ec203f7f27b759dc2c88764e0e8cbad4a09f2e803d76859c3000000000000000000000000000000000a4863bae62f85c7ab6b717a5fc54a71f125270053775fa107787fa49d1372b900b0684d9156424eb5c60be63f293647cf6950ec19f6c0877085a9af6d457dc16b8c4697d48acd5e31baf9a9cfd0c5ae")}; + final Bytes[] args = {Bytes.fromHexString("0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb807257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146dd291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba400000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a48090000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fdcdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf00000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb34dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b810b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb351e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc780000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b6036b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a040000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf62399320000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a3025ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac410978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab10000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef6491d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d428700000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b20000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d400000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e37d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed2450000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b28d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f83511073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c800000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ecea558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb09b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c9400000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c00000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe08b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080")}; + + final BLS12G1MultiExpPrecompiledContract contract = new BLS12G1MultiExpPrecompiledContract(); + + for (int i = 0; i < args.length; i++) { + final double gasSpent = runBenchmark(warmupargs[i], args[i], contract); + + System.out.printf("G1MULTIEXP %d for %,d gas. Charging %,d gas.%n", i + 1, (int) gasSpent, + contract.gasRequirement(args[i])); + } + } + + private static void benchBLS12G2MultiExp32Pairs() { + final Bytes[] warmupargs = {Bytes.fromHexString("00000000000000000000000000000000188f0ed533923d52663d42b8ff1034105aa494104bfcae76e8c35914e9483546056cf7b40049f3d01ebc9c7501933fa60000000000000000000000000000000014acda4c3a536c82dd799ab1e67e951b161dc8225e68b1c8a8ede0f47954ae908939957d8c2a45fa1c32fc7bbc25573c0000000000000000000000000000000005d7e403f13fd451a751baa1937ee1184a74cea61b36316ed5752d2b9afd4b19aedf76fa04221524fc847b69d3441a300000000000000000000000000000000011451f2fc4a2a189cc181e4df02d200f0608105a49279e36aeb8238dc7270a8eed01317b139cba78796d4b518a2cda240b9b40957ebce0ae2cdfb25693b86d03fbd9572b61e5dc9dd7be9b0a242d90c20000000000000000000000000000000015c254a6f11ddcf83b5e08d0aaf46c82b964c48405c3708f7b735a8092a59a3195e8ecea2c37cd40cf2c4694d15660910000000000000000000000000000000018aa81b024791f5872ef1518b790d120011f0f45d59ed4a8a351b246301e88a0de6a0aae141b04740f943013c6ad1e4c000000000000000000000000000000000610fb96f6ef4bf9e176d6bf3e2834b901d9f7eae8e9a0217534d2e2a50cf91709a62b1da914a64c24fcdf0a06c6c1d90000000000000000000000000000000011fa15ebc6a4ea237a02758e7bef8ef6f4734a15cb506738832c5f47234f78f2823eac6ee3a8272a9261991bd7791e8c59c55cf825f4711d4bb841d252b972e163722781b5a20cc8b8c71311028aa0a70000000000000000000000000000000006641858b2f93295589d53902136dfd7b907d6e5667ddb0df3d8d79f53a1e8905f7a20e7c3d3987b6ed202edd41bba590000000000000000000000000000000010e565024d72c2a1e381416e42ebb8877a2563766f21171b8571b966f25f3ac34b5178ee23efc3051ed7795949cfff14000000000000000000000000000000000eda8c88f3433b3bc92ab1bbe783dfb34b2d39e78d5c6ca3ab6df37d2fa040ae6eb04fc20a04f927e19dc8d3697b43a5000000000000000000000000000000000f4df0831d760310cd112d0f54d51c630544a59a9f0e27aa70ec06221f7df55f747ac54f67aa46a59967e9fdb7e870dd0f993d797779e8c03a0e8241016e9acb57bebb93400c7e162f87ac9f04c9330f0000000000000000000000000000000000c25a16f1a906ac0bebe4be099b1618cdc096c6b4550a8abb505d2f0510b397ab85129b2e2f88ca59cb8ba464b59e9a0000000000000000000000000000000016b800325a811b23f3c6546e8bfb4c2f0ccfd675cc0b1b06cf38c069c77c3e2844102943f393d2b806a3f283120c071b0000000000000000000000000000000007af1731e525fa3538bdbb4227c665aeb9538a2098db0ef30cd9bcac486fe16b5d31c2ea63d4855cc4e70093388dcccb000000000000000000000000000000000d08a0e55753497c12a12b32bbe6a0f9946eaf9330258b4ca58d0418f075c4a7e374ba47d278349752250ca43695a9911f591f7b58dfc781b7c059e62291fc79cf27c40d5e8038e2b674b66476a365d40000000000000000000000000000000015cbaf607c81adecaf4a3c50395e9ae05c71c49ce8d0e52df9f7c78a690f79de53aeed701879e23694ccde9bfdaa8fa10000000000000000000000000000000001d72c4cf66f49f5705ca20b57a39ffe2c50ac60e46661bfb7515cf030d0c8211204ec033632b5329b8686f4a3a7b47d0000000000000000000000000000000002956318f0905d98b3f830e833eefb49331ba2f9c180cc43c33e9aafa5b7f8d51aed30d4fbd767dee85ee8332345faa9000000000000000000000000000000000393de667ab77f12f6d14146e2cdb38fd9676c6ec42e5cb11bc3f8d601aec2ec085d087a4a89508cd59902e64cc5c37e4374b1a801d55e360347bde069d6bf9041d0ce23d0756ba6b6049cd630eebea4000000000000000000000000000000000a1685e598fbd658c9af1898152a1fa056befa105856d76d835a3bf029c1206897b5ea065f1bdab99928aee50f36ec58000000000000000000000000000000001204dd0ad42d5182a57874ebd0b85d3c1717736ac548ad5bce3618d86c5aabae9f481c1df56c4b58c32024ec2e9a78f800000000000000000000000000000000199e8594d05c7899c2969006e3c068ffa2e85fd18fa507ec141b4e8bb80545f3a800183ad60e91f52bd14fe2a64da6db00000000000000000000000000000000027d91a9e88af8742dd96e067d1aaea93b6f2be3f72146d71d257061dc6e3dfb12a682f38d75df3974210626b76b8001a18b4d5f4f17ad0c1985817232ef324a7065892033c3f1aa6dad01115db037d8000000000000000000000000000000000e189eae7c173a91a5ac085d149bc31a94f6a772d09b55fdecef2cf43fa46c71cdef79391c69e948f1076d3f4146dc88000000000000000000000000000000001090889d2e1f3491d3f567ae33d8cf5f52d268c3d3517e33f908b8ac9d85e3688d91a69261c97fe353609e3fa13a19470000000000000000000000000000000016a1c443da338ebe5b1cd23532e435f029badd9b6c11688f8d7e9bf3726fc1a2279245ae60ec72170e3bf95e67a6f7a6000000000000000000000000000000001708271b2c70a9c8da3f02054dbc3bb7874bee25581a96338f49f6b35f5f9cae1d4094fd8028cf46da064633ae0e22bd95e20ef92082e1a1ec58dfdb1a4fd1296864f34f6f00903ed04ca62a89655ea00000000000000000000000000000000010bc94fedb42c4b42cb0e3ee09e102aed0fea61152118714606e3a52da75531c1acf863284736c7f8b0986c6ffd12508000000000000000000000000000000000bf6f0d53e25be8c950f6f020cde9eee09978b8f6ee3a34c45882fd7c21b0db1d673482571cceec26affea4cb849c67d00000000000000000000000000000000031bc2b2cb039744be4b1bd33d120783e5c47e1333a02ae76b2744f895a2acc6fc3a68eaa78bd7e018591c5e7f41502f000000000000000000000000000000000ab02378267bf8bee96fd3012f8960d64d2d9158ddeec3d882231c258ab1b4ca0f9a1743066da160a02236213e9d90979bbf871d126a56956556f385cdf7fb80c2637a863ff2e93453863c1eb1d3054b0000000000000000000000000000000015828208b747373d7582a8cec9551791fdba44cfafe4dabd27ac3500f1f01ad414f77f0ae02023732573eb2543795ef3000000000000000000000000000000000e54f402578a8f9105ee45759d7969bb45756bba251e1b42d397b04f8727c742199406fd4a061ab68971003ec70d63e90000000000000000000000000000000017b1fc332708941a522e8d9298ebfdb30284e928462512679206b6eefc20fe8b79964ef7b75b836add0774e7e5c7a3ca00000000000000000000000000000000072adb5d5c951200e40dd896eacad43d05651ca8437e06674a3254a0e854fb357a481f993ca3d8fe3ee41557b529417c0d7df4d20aca9f94b0c3e4ee565bd992165c2b0697f941de8b8f53b09c1f35ef000000000000000000000000000000000a9f57cc0c46addc7f42366a14a29a654e5652f697c156cc190677556c1925f1fbc278ba40705289b903ac33963b6c8d000000000000000000000000000000000a77dfd78a8879850dba365deeb1945fb4d98125eb6d16b0daf62b8d23a5a9887b45f86c2e4e7990a010e3cda31039cf0000000000000000000000000000000005159c436bb8521ea68dbab7cdb237c5515bc34618e8fad6f75e0e190dc5574446d0c4b6e43ae46daa248a388bbe38df00000000000000000000000000000000095810096d80f5917a06eb404fd0fad83633ab12097deb3204ce6065ec462e34150840edcdc0bf9ab45636a02d777cd00e19cc686068548e9fc1a3eb39af71cbecae2ef4bd659aa2ccc67a87e343f3240000000000000000000000000000000007230c1f2951000536261aeebf2eed777626e05aab5b726812f68bcd3147b4884e615c0353995d55117ca002ccd9a97b0000000000000000000000000000000007d2c8ca78123f05e659fc205984d0d2c38ec2a985def4db47af1b9ed506de020c0bbc59d9ee80ed8cf493ba0c329b52000000000000000000000000000000000ad6399c2b7479f058ab02cda02e124a094a64d567f9d9e47bb1d7fdb700383dd73a644eeea752327dd09378fc8868bd0000000000000000000000000000000009daffa5ebf6655983566abacafa696b5816668cadf21af3036eb03eabfa2aa4026beefe4405c4c308039dec8846feb9707c2584dd81179e70d22a5fc402d2b9a8103b9ff6a9e79a48a201ae3df2bccf00000000000000000000000000000000091fac3f5853d7255da59ce2d70c3e8d644a9ff6be3b5d509350b50bc37c5b6b6bfa2d627ae3b9fd5e88d6c4cc837bfb0000000000000000000000000000000017394485415f012098e36e727145f6c9b80d021669ec097e862eeb2ff93bd2631950e49e68e1f95957de2a34eab670c60000000000000000000000000000000006ca148d11c2802eba709b7d97d1bda2a268ea1df615f716e9c4c0e2045f5af7179196d364b86dcf1ce5285909dd03740000000000000000000000000000000000b17c3f47edd9424b8404a301f439fc1dde3eb7eb59c454e51d6d649e2f998d585487e88f25d4f1f642cfbb5166afb81c8dd840a920b82ad18b0d10988bf08665f88d6d83f3f78acf9b6763ba5da1340000000000000000000000000000000017e6b72e82759b5adde10ef6ee13f59d45a012dd1f58395e8d5ac81e5087ba6968b056d59faf5d7701906d95c46e2a45000000000000000000000000000000000f376f1c12b55fb0d010204cbfe4678811208e37d01c173dca295c034d5f37e6daaeb36c9662e0dc6c0cbaa303c812c4000000000000000000000000000000000bdd08c4b9a02c7dc0c1008e69a40bb7df3d78faea9556c9614bbd014d77b537c10d90a2c8393a5aaafbd0151dafc54200000000000000000000000000000000047fd77392129274352b20b95e8928dc030f8d6751bd5e974942328d37daac373df8a7595d7ecfbfa31df9cd6f6d28a4566294ee07bc3797c3c106b614a77d74dae8920ec5674417cc1811498a1c6fa6000000000000000000000000000000000af3da28daacb9b6969569a80ad3e74217b591f27011b5c22fbdf3040396b2612692cb6266e996d01a1e0d84aef2837f000000000000000000000000000000001138efd32ccea9112bc47652c35298699db1bb10f9bb3a88add16a53592ffb538cd76545e9dc30fab0e1849987ccc52f000000000000000000000000000000000a7f68b7ddca4b5106e18f6e600e969f65ac0d24755613d810c49b1463ec946dfac27003ff5d963e31443ac2c10fe409000000000000000000000000000000001226047190acfec2486a1faa6150a64e0eb19020938621ae64e2a135b15a85d9de3690e29655dbee2248cbc9054af7cfc2a2a3e6314c35d8ded36364e63b939fb209e669776b4e462e24b714dfc0a0ce0000000000000000000000000000000011bd10b220803704a8e85fa96639dbecc90dbc343661756876cefc5b9e3023d56d7003aaa3f64165c19fcfe86a926e3b0000000000000000000000000000000011dc64c9609e7809c1cbe573bb54759bcfafd364ada70f5c866d762e981698af26acea16e823ca84f84efb9b7acaf9a7000000000000000000000000000000000fce053a5e86ba0850365b907635f655d1104952d1428d3b831757860ba768f20552812c0145b328a196e1b789daec7d00000000000000000000000000000000043271158dc0cf59a227e53fc00dcba2de9f8bac4d7c8c50bd4097e1188716e2a33cb8027786c7c4f142b64a3e9990c26b136c62452eb60bf1137a838fb229959af217b8d292c83c9bea5fc4dd2043f600000000000000000000000000000000001652ab647d2d2bc5fce9309a676cd95005d3beab03b775c3fdc892ed84ec13fcffb5d0fd9d7a24e058f49293607ede000000000000000000000000000000000b676401571f804ad3b64b893121234d8639a37749559b7b5fe7fda34b6a67d973586f9686573f690787f7d576c4593500000000000000000000000000000000196596e51755124653733f4e42c94d195d79b418bd907c3f70f8469e70d4923784b8881482cd1ff9f8bbd30a0c31de300000000000000000000000000000000002eed3d4212c1e31ad59cbf0c31838a054d80c01c9f98f33c331fe6e9005bbbaf5cbbaa6ffb2be3f00c3323efaef6a5bbc0496ceadc4b7db1fefbdd102f64abe295fbd8278e08cf0c0af895efbec733f000000000000000000000000000000000c95644726db9ed64ae44b919bb1bb0ad65efc10bbc0ea31b240a0c77c088599f0ad18e68805e9d40a381d39adc11b9e00000000000000000000000000000000089dd201e2d5c37b3df60ab6e14eecabb78aea8fba85394431aa8f17b931e411069ba286537d8979a3f761f68be80cb0000000000000000000000000000000000ee9271dee9c0afc5b68be899951ddd7732f66a4f19353377b0218e0ce72b2de3c4b0b254eb2f956b1415bbfd8a877f70000000000000000000000000000000000f0f9db21df709a7843796618af2dd6d0738c7d423db16a864ff5ad7e37998a794ce23c00a113888006dd868c23f7db2b295eb3ebad32c19ef056c2d84acc4dc5362182c0908cd12eb5810d311ebe2c0000000000000000000000000000000009d6be799b26bbf89a24d285a3be40162c7182cdd2790c4338e53d2500582564a1ed81328af02470c1eaa87fff5acea4000000000000000000000000000000000816b4ba02217cb1c0428fac9a091916188ed9729083feacabf525ec53a7a665ca8e8b9f4e7a5c42e641bce4ed6bf9b1000000000000000000000000000000000dd1fccfea4f2fa592b7d13ad33b021473a37689dc488ba7424f32ca332c03158fbb996c09538f37224465cbdd40f1a8000000000000000000000000000000000d725c382abd00f31e3caeb84f9a7f8917387da004c7e6d6a2587a541f0c91149a6b297c1b1aeb59e7d0bf49f82ddaa7a15ab9ef4b3dfef6c1cc3110af2f114c6b0725e7e61dcbc6168b4b8f2347574a00000000000000000000000000000000150a25e38c580220c1721054cfd3bc25bf5b9840484ad8593a8177fabce406158290c94f110b1613acb41dfd3603744d000000000000000000000000000000000296b5725f102180b6ebda4d239b132a1aa0ad420a407f574831891552b2dc735b3f832b7c91f965c8a21ad7e02ec5a20000000000000000000000000000000008cba3cb8ae244bb91297cad82737bb6606cdf9930e425fa45e1b73bcbfa2196d29e533c114197280782c953d303675f0000000000000000000000000000000013da6ddc0404d72d63914948a05a0921f1575dbbf11e93bd04d9d38c637faf09e2da795340d2f9033d4ba57a5c778f4272acb7e6eccf25efd392fe0b0cb66ec51c64296a597e29b9669db6291e2181e800000000000000000000000000000000193de5c8c223779f3d8c81a48dca3b6eb72c1eec095d52a1ff0940c7cf240a037f6225752c5e7197af9fdd2fa0d3977b000000000000000000000000000000000b49139f74cf1ba6805a785db8df8293032f98701bee591013dae4a73cb406fd6ed1dfd625e23e063bc743c0c4b8c1cc000000000000000000000000000000000edda5a33c5d35c79005e3725a11d6fe925b9474ee745bb0e6b219ed2b406adc19b0c67c155d687ac5d65a2e8171f29e0000000000000000000000000000000013f039cdf25f58f6995952541d27fada4f10ae655b5d461036a140340225fcb5461a378ee01ab644f43d97349faefbbbc407a4b18cc4e68d9bd5c2d3c895a5acb7368f8f0a79e49b9b40edffc48b68ca000000000000000000000000000000000b1fd0b16eb5fad718981f9b46fca568c56f3a0481e44dd568c3708940b02077773aae986cc38204616a8a0c167d28da00000000000000000000000000000000152f443527d9ef5e63662758f21020970ffd70aab5e92e331ef7888ccf72e7f5dc56276ef6c66fcb3976f909d3d0ba480000000000000000000000000000000005b7d5c7221b7073011c86dfaa563f394562695995dcd9ff57929f4e15f3adfcd0352fdb95dad61fca2e36746e296df30000000000000000000000000000000007de2176223fc6871f2f648a49044f9ecf005488a8598dae85c53ceb1a2e7e136c775738f5f4166836e47f5da97f2635e0aeb9f6e72951c91564007bafdb6aef495293dd3d13f9ef5c2744fbea2408c1000000000000000000000000000000000d45fe6b2e258d7bdd62a06b895e63638c2cd126feb64cd3e1076cd29596ae7e08e8b3312f5d40a2ce0a695f993aeaaa0000000000000000000000000000000011e2fc0023878114585f48f681f40ac5af68863369eb58c017940331ec7d3c0e86ce2f65e931f875f570f97691c19ea70000000000000000000000000000000014006f95d7b667a7ad8c8b2551a4c10bb4fccf4d2d829595bcb7e4eaa9f7caeef12836571fe3d4d13082e58486cdf00f000000000000000000000000000000001331a1a6bede57f8a1cd3406b1ee8df4dda5e6dcf39eec6eff369bdb2ceb9a1bc4e5f0f91776e8a3d80920c28d77c93c58d3a70c495d90fd9ffa6fa22178f8dc8c37d8e9f260d2275c34d33998baccb000000000000000000000000000000000000b9c84a0c5cea0a80c01e2af19f0d164def421b5ced49bc35f6ba4ecb75920da0797d7d85d56de6ad21a00a51403ac0000000000000000000000000000000012137797dca543979864663d292ee40900208b7d58cce1cf68dca7b7ec1b022f3015a652984c0e81bf929c81c9320f6800000000000000000000000000000000141e5987903a920c5ed88e51708803cd95e8ace73c6d4507bda45b01477fe15aaf5673c56ad9c86a63c691a965db8e5800000000000000000000000000000000168a7a068f30e8fedb5e86be8c418484bdb722260af8fe274d9f341f8893b6bcdf4c89f3dd9a9c1a38ba45406ed9aac6d079470404e36d535ba79d178988c6b5a2cf40953183475a340f5649488635ea00000000000000000000000000000000179989bb4a3e1c98d14fce8f9596d6e1dace6efa75afeebf366bb2a62a7ed92f90e94289aad542861110369584863db8000000000000000000000000000000000432c73984e564bedc7a6f532f05bf8b8cec73d75cc046a2f001401397e9f5a9808635a8ac402d0aa7800a7eace81d1900000000000000000000000000000000084869f18177bbba633aa3714ff3ec36d1cf4548d4e3d2ac90e2dd9bff191e28ae36b6ad5030d0fe6f14167763014293000000000000000000000000000000000d1d18c38ede2a5570feba47c086124690bc53fb799a99c2d6fa3c2c9ca7967346d5a8bc8ec90846fd90dee2220c9508396d275d82cc3950aebd1d0cc4bdece0a06284a10b61998dfce6582043f1d669000000000000000000000000000000001188406db269a686292fceb9b4d63001d40a9e54f229a0efdcda5317e779baddde885451599014ecb21a477fef94fb730000000000000000000000000000000013abf0ec56e8da6b874ef9154ed3265ccfacf426003484abd5eb179c92d94eda52c6adcf2e0f4b30ec08aaf68501367d0000000000000000000000000000000018570c750d8eea7e3e13d8a77fb5de9ee0d3a4f4fc952f93d5b1f1eb9d75ace90619173fae00e7d904936d6b071475530000000000000000000000000000000008842e857399b8d509a5fdf749db4ca6cebdd99703f7740d5dfee84cbde53c6023054fe83013381cffaffbf6467b9c3be93096be26c02ccdca748f82873127286fb900c309862f3e3b4e51c40e8ca0480000000000000000000000000000000008b6a73cf4ff199054cf3c15d3f9cfc2a1292864f1b3ce8fe016c7a75182650b6e10840a33ce6a101efd0a138db341910000000000000000000000000000000005d27b953b8d6abf9908bb7506394bbb4dd7fdd5e99e6950c12319d6cd8bc912faaebfa47516a7e185223c7f45d8f97e000000000000000000000000000000000dca7de717ce6bea3d0dab6e996a1a99493eb739c00df14d51c030173e58c233d544d750013bfa1f8d7313ef2e76555e0000000000000000000000000000000019a0af34ff5a8430c83d93ae619b30783e007bd9fc9eaf9bdc59114bb767ad59705584e01cb14fcf64a057667c039bde61c06721cc9dc6738ca8d2b164007af54fbd1e652e2fc6ac16d3361d4b29505f000000000000000000000000000000001166d3fb438a8ad3c461e9cc2a2d551f654291fba6c6daa66d0805c76abe6bf3592dfba5bb4e662267c190ac93d84d3b000000000000000000000000000000001596ff334e90f5af580494e275566431cf297d4f1c9396e0ac9bf08fb0395f0bebbf2714ce5eee82ad2010c09d3dfc270000000000000000000000000000000008f3e3bd6c54a47395a5898faded4378fb17852fc3b0f173c1f463b8547d776097021987c37363cd65f3e2602e782a4600000000000000000000000000000000179eeb50a3edea2627cee9f573d285a27c2ffbf260d4d5efa70bab8a52d0efa03a18c07dbd96d3871107af653d8eb7cd84d062c49fb2fb65d0179685f6ee29f964fe646e823076274f1d29a4e6fe051a0000000000000000000000000000000017fb3531a4d2431cea98c6f124b46efc303caccae1b731db2dce505c7af42054e92b41e7385826b5fc2f15fe902f940a000000000000000000000000000000000535c50770db6b6805f86b2c0cd90015dc3fe8465faf8b5ad2935ac56829d476492f574e9979b5a5b53ce8b06149c74b000000000000000000000000000000000058e3fe4bdede871def9c79754954aaa7948ebbff7b1490a0577563d66ac257620f4b1e3d44ed847ed065789c22a429000000000000000000000000000000000e95cd7e9ede52613437af323898f0541348646fbb5fac1ea8dfdaff37f1655ffa8861bebd44752850be426399ed042b19794f7b5300f29cd1c1a724761992365430a06726982690a0bb8bc663f6309b00000000000000000000000000000000075ae04db44850b10c0bd93d8e9f98101c0f319575590e481ed70ab46f600e4d60811a9267efd154d2e0a7b2e4213a4c00000000000000000000000000000000026b6fa0f68b7a81a6d2a3d0c3ec17aed11814c0f9d490684317745e76801b0920eab176616853fc26a160cad23d80a60000000000000000000000000000000015e4747db8097ec674206e69658e03af9ba685e344cad84330d3d1f274bafe9e3d6c733828999a550073ee829b505bae0000000000000000000000000000000006e079f71a5cc76ea9b8a1f4c112f4244f72f32193b575b08afce8aa8bec7662b7fffb0d8b8a3cc41828511cb457a2bc688678dc754580c619f286402ce54011f71bd6ee0a5b692570b55b273a3907af00000000000000000000000000000000096ae6860debd6c707b938e3aa3e56e74af570f811e949fcdbbc08653d66141bd0ae12cd93c6d91ea59792ad87f04ba50000000000000000000000000000000007eaa9ed1244ae2b1af86aaa3aba8d0c30cb7a1a33df26a2df295a3af573931ffad1a4411c7ec78e2bcf60ed7251520d000000000000000000000000000000000552d7f5bdf90df6b6eb41b3a3a69d2d0eed0bc5aff6e56564d19fcf410427a7b85d9d6adc38e73da3c77d39a12ed15e000000000000000000000000000000001975980e75458936ef89d7c6930d6cc29eee05bc2dd3b16db731240c9321673994bf11829b9804679de69f2c947de5227f7c48af4aef5e07567bddbd20c4907f79af0e974a8714f9588e7b8a65cd293300000000000000000000000000000000074fd3d8145c7fc925a32a9d58f2ac1091cfcc1de6c97943adeb2ec25044d50c624cf7e08b146f0abc199c0175e2b3090000000000000000000000000000000012bc51a42c89496bbccdc8b5f2733a754acc4709208474544eeb0e5bf2aad6d1009d288b7b3df248d7398e08d1be8be200000000000000000000000000000000183516577e7dfdb7844ffa2177c5c22adcd5fd4ff5391d2fb5708313eb73986c511457f49ded49c84b970342dd6582d900000000000000000000000000000000086fdf965b9c0586efb0b475aca124dae876df12fb66ade5fc06cab2f3c7849ba4f48e53fc17f1ec4a1cb5a5d76581b98358065d32fa521f619158d090ddb075a02b5b499c279985d3f64f8c6b52c39400000000000000000000000000000000077d3b1148b25fab4256d28d18ca214d0c2950dab19c048ab293efb9aff03b5ccad3d0ad4068f101dfbbc2f84e954ecd0000000000000000000000000000000001ed80bd1d6de030fc807d0f49cf4c2e9dca2b76b75ab391251a6f41af79bf11ee496e1294f171445dee4d77c7e70cd6000000000000000000000000000000000e08ebd51454a391b4795d53058b823789f48a1e508046d9e960bef2000e96da2936693689fa6f33ac32e1e4196337820000000000000000000000000000000004acf1c78f78c40e572c3326e451735d3f3c6dbbb622f2def266c36d4fce8822c1ff86899dd0e6617d775a2bf9bdb181d62e15762d9fa3afa8ee9d65c7436739cb29cf26f3e01af82196ef6f4fbeca5f")}; + final Bytes[] args = {Bytes.fromHexString("000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e01400b97e1211ea91ba027896f711b96062118bcfa5515c7880679b5849e545000000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a9808c85140e6eca6cfd8510261183d479a443f0629e33dc470c3f7d930c2defa00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294533aae2894034cc6c5278a4bd4daec46e6c08e7fdd6550fe1fa6e2d4d1adf57b00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e331fb26e72247c9cb76eb258094d3fcc9a294180d4106ee3930d0a3fb519b65ee0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79dc6516d7a44f93eebf1bc1fc084c7d0e9b92b3f5be754df31be1b8d8a3415c8100000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba74b614fd3f867cf44fce6e2b91427dbed22190091891b6c02973ca1a5cef6a35d000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b847556700fa1fdfe4e101eb1fb436608a377eb8f4a49a0e99a4d208a19b830967dd65000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc003a8881d042f3242a48d781773832f2d7d93314b215643a23abbdb5e8b7d9a15000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb3febc1ada758ad9a5ab3e93b8a40813c79abfc88abe7e53c94462a36fbac41c80000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0bff7a5e41be99c4d598551e42492169cf09083886c5abfccaab6a064840e6176000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22bc44b57817b2848936bae5cb561ee0d4a71bf32c1f7d39f1e28b849a8b41b5a5d000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1c151847b7b5854158831995014961865238cfe36fd2ee66b26ae013a52c5a6100000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c45581819385fc49c771164342eb70a34b88629a93a4a73fd947b01184803cbb91f49f2b000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29abd7987f7a0e32086552fdff94c5e8791ef142e6a4285ae0f02f1ea7805b52b0000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e0d896153b7293f871e7d1dd50a18ec88a117acc95a95185799f2521b9aa137ef0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f7ee8ca85ad1e179596c12492061c3489a3ea4684e290d50f8ed310320c89678e0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064254f8b95a217dc00f0e069b2fcfbe9acd684642aa0dc754c9520e700d9e1ea28000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad175e4a25b77e39aef40131e0dc7548a7a8d11cfba650aa88a6007622d5a904790000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5de1cff4f165f49342d6e7ffea6aa2199d7af7290c13403b44abcdd56f168b88300000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d4e50f2ac7deaeaf1a85fbfdbd822984eb091eb07d855001c390f88ad0ba96a6f00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437bb836f0c479fbb44d5981c113546ea36e434945eee7b8681790aaac1e776f2405000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89a7d6b59c8a696805893be4249e4fe58609d3608f6dd63b6d8f335a45919da39e0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296026563275db4f9b8b4db071ecde75ae98de14ca3929a6e4a9b992a6743c5254a0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f8fe0d4e218c204ff3db6c9e0e428c9d851ad90c3f126f345d1cbd0aff255bb220000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69bf5b0a443239846ac6afec05fa2a1cc3b102499fa2cbb54d07a1c0920733021ad000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d5cd219b7cf86550b75ca2e2195b00565be311dde9404d9a9207dadd55fa5740c0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53864630c026cf0e096af5910ecc7bcd105febd2544df3a232fee6df97281335dc000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0168acab37c5e0c6b1f12a58e0da2cf9807608cb95ff410189ef552f5fd25c12500000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368ae900998d5e03a6134f6a73872e7788e94216888aec7a98ad72c3db9d090c1bfc00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d057a95d3f2326dba2cf0949f743d407d3027459d796ae89d93fc1cac19fd93b170000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921bef9dbe0487b733954d8ee50ad812774474437436f4630927d61f82f1e46f4151000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da9d2e89d33fa35cb41e398bf41ef89dde8948c75edef997e60ebee61515b542fa")}; + + final BLS12G2MultiExpPrecompiledContract contract = new BLS12G2MultiExpPrecompiledContract(); + + for (int i = 0; i < args.length; i++) { + final double gasSpent = runBenchmark(warmupargs[i], args[i], contract); + + System.out.printf("G2MULTIEXP %d for %,d gas. Charging %,d gas.%n", i + 1, (int) gasSpent, + contract.gasRequirement(args[i])); + } + } + + + private static void benchBLS12G1MultiExp() { + final Bytes[] args = { + Bytes.fromHexString( + "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee" + + "b3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e"), + Bytes.fromHexString( + "00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed2" + + "4d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d" + + "0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f" + + "973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1"), + Bytes.fromHexString( + "0000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e4" + + "4c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a" + + "0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d3" + + "8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89" + + "000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90" + + "787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944"), + Bytes.fromHexString( + "000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1b" + + "aaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1" + + "0000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442a" + + "dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c" + + "0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795" + + "bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108" + + "0000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190" + + "fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f8187672"), + Bytes.fromHexString( + "0000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943" + + "b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea" + + "000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e" + + "3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76" + + "0000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276b" + + "dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c" + + "00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a5787681" + + "7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a" + + "0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f768" + + "94c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a659054") + }; + + final BLS12G1MultiExpPrecompiledContract contract = new BLS12G1MultiExpPrecompiledContract(); + + for (int i = 0; i < args.length; i++) { + final double gasSpent = runBenchmark(args[i], contract); + + System.out.printf( + "G1MULTIEXP %d for %,d gas. Charging %,d gas.%n", + i + 1, (int) gasSpent, contract.gasRequirement(args[i])); + } + } + + public static void benchBLS12G2Add() { + final Bytes arg = + Bytes.fromHexString( + "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d2090324" + + "0000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d9388" + + "00000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae22" + + "0000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633"); + + final BLS12G2AddPrecompiledContract contract = new BLS12G2AddPrecompiledContract(); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "G2ADD for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); + } + + private static void benchBLS12G2Mul() { + final Bytes arg = + Bytes.fromHexString( + "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e" + + "000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be" + + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + + final BLS12G2MulPrecompiledContract contract = new BLS12G2MulPrecompiledContract(); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "G2MUL for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); + } + + private static void benchBLS12G2MultiExp() { + final Bytes[] args = { + Bytes.fromHexString( + "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df" + + "b3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e"), + Bytes.fromHexString( + "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d9388" + + "4d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d" + + "0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc" + + "973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1"), + Bytes.fromHexString( + "000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf49" + + "4c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a" + + "000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e" + + "8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89" + + "0000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2" + + "787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944"), + Bytes.fromHexString( + "00000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46e" + + "aaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1" + + "000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12" + + "dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c" + + "0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5b" + + "bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108" + + "000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596" + + "fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f8187672"), + Bytes.fromHexString( + "00000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196" + + "b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea" + + "000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a9" + + "3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76" + + "000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836" + + "dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c" + + "000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b" + + "7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a" + + "0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd3" + + "94c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a659054") + }; + + final BLS12G2MultiExpPrecompiledContract contract = new BLS12G2MultiExpPrecompiledContract(); + + for (int i = 0; i < args.length; i++) { + final double gasSpent = runBenchmark(args[i], contract); + + System.out.printf( + "G2MULTIEXP %d for %,d gas. Charging %,d gas.%n", + i + 1, (int) gasSpent, contract.gasRequirement(args[i])); + } + } + + public static void benchBLS12Pair() { + final Bytes[] args = { + Bytes.fromHexString( + "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f56" + + "0000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f" + + "0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624" + + "000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40"), + Bytes.fromHexString( + "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80" + + "000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e" + + "000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834" + + "000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e" + + "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80" + + "00000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e" + + "000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834" + + "000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e"), + Bytes.fromHexString( + "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6" + + "000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086" + + "000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f" + + "0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce" + + "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6" + + "000000000000000000000000000000000cbcd06a1c576af16d0d77ff8bcc3669a486d044cc7b85db03661a92f4c5c44a28d028521dfcfc292d8ecd05aed6ab940000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086" + + "000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f" + + "0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce" + + "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6" + + "000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086" + + "000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f" + + "00000000000000000000000000000000153ba4ab4fecc724c843b8f78db2db1943e91051b8cb9be2eb7e610a570f1f5925b7981334951b505cce1a3992ff05c9000000000000000000000000000000000c1e79925e9ebfd99e5d11489c56a994e0f855a759f0652cc9bb5151877cfea5c37896f56b949167b9cd2226f14333dd"), + }; + final BLS12PairingPrecompiledContract contract = new BLS12PairingPrecompiledContract(); + + for (int i = 0; i < args.length; i++) { + final double gasSpent = runBenchmark(args[i], contract); + + System.out.printf( + "BLS pairings %d pairs for %,d gas. Charging %,d gas.%n", + i * 2 + 2, (int) gasSpent, contract.gasRequirement(args[i])); + } + } + + private static void benchBLS12MapFPTOG1() { + final Bytes arg = + Bytes.fromHexString( + "0000000000000000000000000000000014406e5bfb9209256a3820879a29ac2f62d6aca82324bf3ae2aa7d3c54792043bd8c791fccdb080c1a52dc68b8b69350"); + + final BLS12MapFpToG1PrecompiledContract contract = new BLS12MapFpToG1PrecompiledContract(); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "MAPFPTOG1 for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); + } + + private static void benchBLS12MapFP2TOG2() { + final Bytes arg = + Bytes.fromHexString( + "0000000000000000000000000000000014406e5bfb9209256a3820879a29ac2f62d6aca82324bf3ae2aa7d3c54792043bd8c791fccdb080c1a52dc68b8b69350000000000000000000000000000000000e885bb33996e12f07da69073e2c0cc880bc8eff26d2a724299eb12d54f4bcf26f4748bb020e80a7e3794a7b0e47a641"); + + final BLS12MapFp2ToG2PrecompiledContract contract = new BLS12MapFp2ToG2PrecompiledContract(); + + final double gasSpent = runBenchmark(arg, contract); + + System.out.printf( + "MAPFP2TOG2 for %,d gas. Charging %,d gas.%n", + (int) gasSpent, contract.gasRequirement(arg)); + } + + // just use the actual arg as the warmup arg. not great for true perf + private static double runBenchmark(final Bytes arg, final PrecompiledContract contract) { + return runBenchmark(arg, arg, contract); + } + private static double runBenchmark(final Bytes warmupArg, final Bytes arg, final PrecompiledContract contract) { + if (contract.computePrecompile(arg, fakeFrame).getOutput() == null) { + throw new RuntimeException("Input is Invalid"); + } + + for (int i = 0; i < MATH_WARMUP; i++) { + contract.computePrecompile(warmupArg, fakeFrame); + } + final Stopwatch timer = Stopwatch.createStarted(); + for (int i = 0; i < MATH_ITERATIONS; i++) { + contract.computePrecompile(arg, fakeFrame); + } + timer.stop(); + + final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; + final double perCall = elapsed / MATH_ITERATIONS; + System.out.printf("\telapsed in nanos %f\n", elapsed); + System.out.printf("\tper call %f\n", perCall); + return perCall * GAS_PER_SECOND_STANDARD; + } + + public static void main(final String[] args) { + benchBLS12G1MultiExp32Pairs(); + benchBLS12G2MultiExp32Pairs(); + benchSecp256k1Recover(); +// benchSha256(); +// benchKeccak256(); +// benchRipeMD(); +// benchBNADD(); +// benchBNMUL(); +// benchBNPairing(); +// benchModExp(); +// benchBLS12G1Add(); +// benchBLS12G1Mul(); +// benchBLS12G1MultiExp(); +// benchBLS12G2Add(); +// benchBLS12G2Mul(); +// benchBLS12G2MultiExp(); +// benchBLS12Pair(); +// benchBLS12MapFPTOG1(); +// benchBLS12MapFP2TOG2(); + } +} diff --git a/gradle.properties b/gradle.properties index 93f56e01379..a8b2e95a2af 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,6 +3,8 @@ org.gradle.welcome=never # Optional - set custom build version # version=24.5.6-acme # versionappendcommit=true +org.gradle.dependency.verification=lenient + # Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396) org.gradle.jvmargs=-Xmx4g \ @@ -18,4 +20,4 @@ org.gradle.jvmargs=-Xmx4g \ --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \ --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED # Could be moved to sonar properties after https://sonarsource.atlassian.net/browse/SONARGRADL-134 -systemProp.sonar.gradle.skipCompile=true \ No newline at end of file +systemProp.sonar.gradle.skipCompile=true From de92780fa76ce2aa893db3659573cfde20a6856b Mon Sep 17 00:00:00 2001 From: garyschulte Date: Tue, 1 Oct 2024 16:12:33 -0700 Subject: [PATCH 2/6] mgas/sec output Signed-off-by: garyschulte --- .../org/hyperledger/besu/evm/precompile/Benchmarkz.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java index 2c5a1357e7a..dc7d1cab3ab 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java @@ -97,7 +97,7 @@ private static void benchSecp256k1Recover() { final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; final double perCall = elapsed / MATH_ITERATIONS; final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; - + System.out.printf("\tsecp256k1 %f seconds, %f ,mgas/sec", elapsed, (MATH_ITERATIONS * 3000L / 1_000_000 / elapsed)); System.out.printf("secp256k1 signature recovery for %,d gas.%n", (int) gasSpent); } @@ -675,8 +675,10 @@ private static double runBenchmark(final Bytes warmupArg, final Bytes arg, final final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; final double perCall = elapsed / MATH_ITERATIONS; - System.out.printf("\telapsed in nanos %f\n", elapsed); - System.out.printf("\tper call %f\n", perCall); + System.out.printf("\t%s %f seconds, %f ,mgas/sec", + contract.getName(), + elapsed, + (MATH_ITERATIONS * contract.gasRequirement(arg) / 1_000_000d / elapsed)); return perCall * GAS_PER_SECOND_STANDARD; } From 50c1f23e9f60eb3a7019af47fedc775101386451 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Tue, 1 Oct 2024 16:54:12 -0700 Subject: [PATCH 3/6] add bls12 g1/g2 msm to evmtool benchmark subcommand Signed-off-by: garyschulte --- .../besu/evmtool/BenchmarkSubCommand.java | 5 +- .../evmtool/benchmarks/BLS12Benchmark.java | 108 +++ .../AbstractBLS12PrecompiledContract.java | 16 + .../besu/evm/precompile/Benchmarkz.java | 706 ------------------ 4 files changed, 128 insertions(+), 707 deletions(-) create mode 100644 ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java delete mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java index 829bf2d58e7..5b20912ca14 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.evmtool.benchmarks.AltBN128Benchmark; +import org.hyperledger.besu.evmtool.benchmarks.BLS12Benchmark; import org.hyperledger.besu.evmtool.benchmarks.BenchmarkExecutor; import org.hyperledger.besu.evmtool.benchmarks.ECRecoverBenchmark; import org.hyperledger.besu.evmtool.benchmarks.ModExpBenchmark; @@ -56,7 +57,9 @@ enum Benchmark { // blake2f EcRecover(new ECRecoverBenchmark()), ModExp(new ModExpBenchmark()), - Secp256k1(new Secp256k1Benchmark()); + Secp256k1(new Secp256k1Benchmark()), + // bls12 + Bls12(new BLS12Benchmark()); final BenchmarkExecutor benchmarkExecutor; diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java new file mode 100644 index 00000000000..b11e6a60654 --- /dev/null +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java @@ -0,0 +1,108 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evmtool.benchmarks; + +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.evm.EvmSpecVersion; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; +import org.hyperledger.besu.evm.precompile.AbstractBLS12PrecompiledContract; +import org.hyperledger.besu.evm.precompile.AltBN128AddPrecompiledContract; +import org.hyperledger.besu.evm.precompile.AltBN128MulPrecompiledContract; +import org.hyperledger.besu.evm.precompile.AltBN128PairingPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1MultiExpPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2MultiExpPrecompiledContract; + +import java.io.PrintStream; +import java.util.LinkedHashMap; +import java.util.Map; + +/** Benchmark BLS12-381 G1 and G2 MSM */ +public class BLS12Benchmark extends BenchmarkExecutor { + + /** Benchmark BLS12-381 G1 and G2 MSM with default warmup and iterations */ + public BLS12Benchmark() { + super(MATH_WARMUP, MATH_ITERATIONS); + } + + @Override + public void runBenchmark( + final PrintStream output, final Boolean attemptNative, final String fork) { + + EvmSpecVersion forkVersion = EvmSpecVersion.fromName(fork); + + if (forkVersion.compareTo(EvmSpecVersion.PRAGUE) < 0) { + output.printf("EIP2537 is not available before Prague\n"); + return; + } + + if (!AbstractBLS12PrecompiledContract.isAvailable()) { + output.printf("BLS12-381 not available on this platform %s %s %s\n", + System.getProperty("os.name"), + System.getProperty("os.version"), + System.getProperty("os.arch")); + return; + } + + benchmarkG1MultiExp32Pairs(output); + benchmarkG2MultiExp32Pairs(output); + } + + private void benchmarkG1MultiExp32Pairs( + final PrintStream output) { + final Map addTestCases = new LinkedHashMap<>(); + addTestCases.put( + "G1 MSM", + Bytes.fromHexString("0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb807257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146dd291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba400000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a48090000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fdcdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf00000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb34dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b810b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb351e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc780000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b6036b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a040000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf62399320000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a3025ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac410978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab10000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef6491d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d428700000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b20000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d400000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e37d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed2450000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b28d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f83511073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c800000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ecea558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb09b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c9400000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c00000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe08b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080")); + + BLS12G1MultiExpPrecompiledContract g1msmContract = new BLS12G1MultiExpPrecompiledContract(); + warmup = MATH_WARMUP / addTestCases.size(); + iterations = MATH_ITERATIONS / addTestCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : addTestCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1msmContract); + gasCost += g1msmContract.gasRequirement(testCase.getValue()); + } + execTime /= addTestCases.size(); + gasCost /= addTestCases.size(); + output.printf( + "Bls12 G1 MSM %,6d gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2MultiExp32Pairs( + final PrintStream output) { + final Map addTestCases = new LinkedHashMap<>(); + addTestCases.put( + "G2 MSM", + Bytes.fromHexString("000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e01400b97e1211ea91ba027896f711b96062118bcfa5515c7880679b5849e545000000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a9808c85140e6eca6cfd8510261183d479a443f0629e33dc470c3f7d930c2defa00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294533aae2894034cc6c5278a4bd4daec46e6c08e7fdd6550fe1fa6e2d4d1adf57b00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e331fb26e72247c9cb76eb258094d3fcc9a294180d4106ee3930d0a3fb519b65ee0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79dc6516d7a44f93eebf1bc1fc084c7d0e9b92b3f5be754df31be1b8d8a3415c8100000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba74b614fd3f867cf44fce6e2b91427dbed22190091891b6c02973ca1a5cef6a35d000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b847556700fa1fdfe4e101eb1fb436608a377eb8f4a49a0e99a4d208a19b830967dd65000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc003a8881d042f3242a48d781773832f2d7d93314b215643a23abbdb5e8b7d9a15000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb3febc1ada758ad9a5ab3e93b8a40813c79abfc88abe7e53c94462a36fbac41c80000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0bff7a5e41be99c4d598551e42492169cf09083886c5abfccaab6a064840e6176000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22bc44b57817b2848936bae5cb561ee0d4a71bf32c1f7d39f1e28b849a8b41b5a5d000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1c151847b7b5854158831995014961865238cfe36fd2ee66b26ae013a52c5a6100000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c45581819385fc49c771164342eb70a34b88629a93a4a73fd947b01184803cbb91f49f2b000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29abd7987f7a0e32086552fdff94c5e8791ef142e6a4285ae0f02f1ea7805b52b0000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e0d896153b7293f871e7d1dd50a18ec88a117acc95a95185799f2521b9aa137ef0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f7ee8ca85ad1e179596c12492061c3489a3ea4684e290d50f8ed310320c89678e0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064254f8b95a217dc00f0e069b2fcfbe9acd684642aa0dc754c9520e700d9e1ea28000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad175e4a25b77e39aef40131e0dc7548a7a8d11cfba650aa88a6007622d5a904790000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5de1cff4f165f49342d6e7ffea6aa2199d7af7290c13403b44abcdd56f168b88300000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d4e50f2ac7deaeaf1a85fbfdbd822984eb091eb07d855001c390f88ad0ba96a6f00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437bb836f0c479fbb44d5981c113546ea36e434945eee7b8681790aaac1e776f2405000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89a7d6b59c8a696805893be4249e4fe58609d3608f6dd63b6d8f335a45919da39e0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296026563275db4f9b8b4db071ecde75ae98de14ca3929a6e4a9b992a6743c5254a0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f8fe0d4e218c204ff3db6c9e0e428c9d851ad90c3f126f345d1cbd0aff255bb220000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69bf5b0a443239846ac6afec05fa2a1cc3b102499fa2cbb54d07a1c0920733021ad000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d5cd219b7cf86550b75ca2e2195b00565be311dde9404d9a9207dadd55fa5740c0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53864630c026cf0e096af5910ecc7bcd105febd2544df3a232fee6df97281335dc000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0168acab37c5e0c6b1f12a58e0da2cf9807608cb95ff410189ef552f5fd25c12500000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368ae900998d5e03a6134f6a73872e7788e94216888aec7a98ad72c3db9d090c1bfc00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d057a95d3f2326dba2cf0949f743d407d3027459d796ae89d93fc1cac19fd93b170000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921bef9dbe0487b733954d8ee50ad812774474437436f4630927d61f82f1e46f4151000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da9d2e89d33fa35cb41e398bf41ef89dde8948c75edef997e60ebee61515b542fa")); + + BLS12G2MultiExpPrecompiledContract g2msmContract = new BLS12G2MultiExpPrecompiledContract(); + warmup = MATH_WARMUP / addTestCases.size(); + iterations = MATH_ITERATIONS / addTestCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : addTestCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g2msmContract); + gasCost += g2msmContract.gasRequirement(testCase.getValue()); + } + execTime /= addTestCases.size(); + gasCost /= addTestCases.size(); + output.printf( + "Bls12 G2 MSM %,6d gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java index 67fecb92aa7..ad1e30bdca4 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import java.util.Optional; @@ -67,6 +68,21 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon this.inputLimit = inputLen + 1; } + /** + * Is bls12 supported on this platform + * + * @return true if the native library was loaded. + */ + public static boolean isAvailable() { + try { + return LibGnarkEIP2537.ENABLED; + } catch (UnsatisfiedLinkError | NoClassDefFoundError ule) { + LOG.info("bls12-381 native precompile not available: {}", ule.getMessage()); + } + return false; + } + + @Override public String getName() { return name; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java deleted file mode 100644 index dc7d1cab3ab..00000000000 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/Benchmarkz.java +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.evm.precompile; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hyperledger.besu.crypto.Hash.keccak256; - -import org.hyperledger.besu.crypto.Hash; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SECPPrivateKey; -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.code.CodeV0; -import org.hyperledger.besu.evm.fluent.SimpleBlockValues; -import org.hyperledger.besu.evm.fluent.SimpleWorld; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator; -import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; - -import java.math.BigInteger; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.TimeUnit; - -import com.google.common.base.Stopwatch; -import com.google.common.collect.ImmutableMap; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; - -@SuppressWarnings("UnusedMethod") -public class Benchmarkz { - - static final Random random = new Random(); - - static final long GAS_PER_SECOND_STANDARD = 35_000_000L; - - static final int HASH_WARMUP = 1_000_000; - static final int HASH_ITERATIONS = 10_000; - - static final int MATH_WARMUP = 10_000; - static final int MATH_ITERATIONS = 1_000; - static final MessageFrame fakeFrame = - MessageFrame.builder() - .type(MessageFrame.Type.CONTRACT_CREATION) - .contract(Address.ZERO) - .inputData(Bytes.EMPTY) - .sender(Address.ZERO) - .value(Wei.ZERO) - .apparentValue(Wei.ZERO) - .code(CodeV0.EMPTY_CODE) - .completer(__ -> {}) - .address(Address.ZERO) - .blockHashLookup(n -> null) - .blockValues(new SimpleBlockValues()) - .gasPrice(Wei.ZERO) - .miningBeneficiary(Address.ZERO) - .originator(Address.ZERO) - .initialGas(100_000L) - .worldUpdater(new SimpleWorld()) - .build(); - - private static void benchSecp256k1Recover() { - final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); - - final SECPPrivateKey privateKey = - signatureAlgorithm.createPrivateKey( - new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16)); - final KeyPair keyPair = signatureAlgorithm.createKeyPair(privateKey); - - final Bytes data = Bytes.wrap("This is an example of a signed message.".getBytes(UTF_8)); - final Bytes32 dataHash = keccak256(data); - final SECPSignature signature = signatureAlgorithm.sign(dataHash, keyPair); - for (int i = 0; i < MATH_WARMUP; i++) { - signatureAlgorithm.recoverPublicKeyFromSignature(dataHash, signature); - } - final Stopwatch timer = Stopwatch.createStarted(); - for (int i = 0; i < MATH_ITERATIONS; i++) { - signatureAlgorithm.recoverPublicKeyFromSignature(dataHash, signature); - } - timer.stop(); - - final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; - final double perCall = elapsed / MATH_ITERATIONS; - final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; - System.out.printf("\tsecp256k1 %f seconds, %f ,mgas/sec", elapsed, (MATH_ITERATIONS * 3000L / 1_000_000 / elapsed)); - System.out.printf("secp256k1 signature recovery for %,d gas.%n", (int) gasSpent); - } - - public static void benchSha256() { - final SHA256PrecompiledContract contract = - new SHA256PrecompiledContract(new IstanbulGasCalculator()); - final byte[] warmupData = new byte[240]; - final Bytes warmupBytes = Bytes.wrap(warmupData); - for (int i = 0; i < HASH_WARMUP; i++) { - contract.computePrecompile(warmupBytes, fakeFrame); - } - for (int len = 0; len <= 256; len += 8) { - final byte[] data = new byte[len]; - random.nextBytes(data); - final Bytes bytes = Bytes.wrap(data); - final Stopwatch timer = Stopwatch.createStarted(); - for (int i = 0; i < HASH_ITERATIONS; i++) { - contract.computePrecompile(bytes, fakeFrame); - } - timer.stop(); - - final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; - final double perCall = elapsed / HASH_ITERATIONS; - final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; - - System.out.printf( - "sha256 %,d bytes for %,d gas. Charging %,d gas.%n", - len, (int) gasSpent, contract.gasRequirement(bytes)); - } - } - - private static void benchKeccak256() { - fakeFrame.expandMemory(0, 1024); - var istanbulGasCalculator = new IstanbulGasCalculator(); - final byte[] warmupData = new byte[240]; - final Bytes warmupBytes = Bytes.wrap(warmupData); - for (int i = 0; i < HASH_WARMUP; i++) { - Hash.keccak256(warmupBytes); - } - for (int len = 0; len <= 512; len += 8) { - final byte[] data = new byte[len]; - random.nextBytes(data); - final Bytes bytes = Bytes.wrap(data); - final Stopwatch timer = Stopwatch.createStarted(); - for (int i = 0; i < HASH_ITERATIONS; i++) { - Hash.keccak256(bytes); - } - timer.stop(); - - final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; - final double perCall = elapsed / HASH_ITERATIONS; - final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; - - System.out.printf( - "keccak256 %,d bytes for %,d gas. Charing %d gas.%n", - len, (int) gasSpent, istanbulGasCalculator.keccak256OperationGasCost(fakeFrame, 0, len)); - } - } - - private static void benchRipeMD() { - final RIPEMD160PrecompiledContract contract = - new RIPEMD160PrecompiledContract(new IstanbulGasCalculator()); - final byte[] warmupData = new byte[240]; - final Bytes warmupBytes = Bytes.wrap(warmupData); - for (int i = 0; i < HASH_WARMUP; i++) { - contract.computePrecompile(warmupBytes, fakeFrame); - } - for (int len = 0; len <= 256; len += 8) { - final byte[] data = new byte[len]; - random.nextBytes(data); - final Bytes bytes = Bytes.wrap(data); - final Stopwatch timer = Stopwatch.createStarted(); - for (int i = 0; i < HASH_ITERATIONS; i++) { - contract.computePrecompile(bytes, fakeFrame); - } - timer.stop(); - - final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; - final double perCall = elapsed / HASH_ITERATIONS; - final double gasSpent = perCall * GAS_PER_SECOND_STANDARD; - - System.out.printf( - "ripemd %,d bytes for %,d gas. Charging %,d gas.%n", - len, (int) gasSpent, contract.gasRequirement(bytes)); - } - } - - private static void benchModExp() { - final Map testcases = - new ImmutableMap.Builder() - .put( - "eip_example1", - Bytes.fromHexString( - "0000000000000000000000000000000000000000000000000000000000000001" - + "0000000000000000000000000000000000000000000000000000000000000020" - + "0000000000000000000000000000000000000000000000000000000000000020" - + "03" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f")) - .put( - "eip_example2", - Bytes.fromHexString( - "0000000000000000000000000000000000000000000000000000000000000000" - + "0000000000000000000000000000000000000000000000000000000000000020" - + "0000000000000000000000000000000000000000000000000000000000000020" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e" - + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f")) - .put( - "even-modulus-1", - Bytes.fromHexString( - "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003c2040160024518968061546464452029984405379963244433254832348165045983839181603600983245188119082741180552472823434126339186042653363989253518144015007104659260895861906540664936284389736130979465984263224400655133820675791338815252163142936101184074977707018635613728563507946963514079867296353079585444179075183175315953500862929638853495671020263166123912364061541662955981749424030252416330220564030645929402440479045589943839631409636357644094127401186503107365632233122371688639562179885062893961510897259834525401728081797411184820573804096446362924176080926052008070342876591822173915634645231182811305568049542955744148010693635112077769594038286419007643605441221736768092092706367136248982357930831050114862462054469804238839007660797444001134145988063087013657265067255538916788266246587774231646489345179567885975873995767749906187041937713976494258573504873269320274358396975658022816526738914029788471066595929777423497242252763504644221066495966982158816143636722736200299105017320500139589998102103536908651755056175006587609525845133254470473698921229697550145309121304642224273213418856615560961843245211567388930209839462064588566503446549415643465733541976019955544090933949692508519895293721888001835024288589127818157262958206047538648802179821901844091151603223229973835165715768557428338775055435040494382003663260090655173262271219880999454966135210800173588881197223814096778846598765822161982688788574265773201009190341430440400154076998270731076034021917712825351270109621323258567738829791704547404897555410847468529100600344699859551947494210268509149049419749744679372826553895949980386864014015247047775654329663958663391477680679444996526407026021137970100258833584773507489900747148344826790699325870056679710341571267983857125765234149331990149745571500943300684008078036054281629105618499442731182983775330888524074001975745730722737461725166625564316976464879780901853271273641654911641084141502464")) - .put( - "even-modulus-2", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d80000000000000000000000000000000000000000000000000000000000000010e0060000a921212121212121ff0000212b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf82828282828200ffff28ff2b218282000000000000000000")) - .put( - "nagydani-1-square", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb502fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b")) - .put( - "nagydani-1-qube", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb503fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b")) - .put( - "nagydani-1-pow0x10001", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000040e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5010001fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b")) - .put( - "nagydani-2-square", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf5102e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087")) - .put( - "nagydani-2-qube", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf5103e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087")) - .put( - "nagydani-2-pow0x10001", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000080cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51010001e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087")) - .put( - "nagydani-3-square", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb02d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d")) - .put( - "nagydani-3-qube", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb03d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d")) - .put( - "nagydani-3-pow0x10001", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000100c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb010001d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d")) - .put( - "nagydani-4-square", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b8102df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f")) - .put( - "nagydani-4-qube", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b8103df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f")) - .put( - "nagydani-4-pow0x10001", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000200db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81010001df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f")) - .put( - "nagydani-5-square", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf02e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad")) - .put( - "nagydani-5-qube", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf03e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad")) - .put( - "nagydani-5-pow0x10001", - Bytes.fromHexString( - "000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000400c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf010001e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad")) - .put( - "even-modulous2", - Bytes.fromHexString( - "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003c2040160024518968061546464452029984405379963244433254832348165045983839181603600983245188119082741180552472823434126339186042653363989253518144015007104659260895861906540664936284389736130979465984263224400655133820675791338815252163142936101184074977707018635613728563507946963514079867296353079585444179075183175315953500862929638853495671020263166123912364061541662955981749424030252416330220564030645929402440479045589943839631409636357644094127401186503107365632233122371688639562179885062893961510897259834525401728081797411184820573804096446362924176080926052008070342876591822173915634645231182811305568049542955744148010693635112077769594038286419007643605441221736768092092706367136248982357930831050114862462054469804238839007660797444001134145988063087013657265067255538916788266246587774231646489345179567885975873995767749906187041937713976494258573504873269320274358396975658022816526738914029788471066595929777423497242252763504644221066495966982158816143636722736200299105017320500139589998102103536908651755056175006587609525845133254470473698921229697550145309121304642224273213418856615560961843245211567388930209839462064588566503446549415643465733541976019955544090933949692508519895293721888001835024288589127818157262958206047538648802179821901844091151603223229973835165715768557428338775055435040494382003663260090655173262271219880999454966135210800173588881197223814096778846598765822161982688788574265773201009190341430440400154076998270731076034021917712825351270109621323258567738829791704547404897555410847468529100600344699859551947494210268509149049419749744679372826553895949980386864014015247047775654329663958663391477680679444996526407026021137970100258833584773507489900747148344826790699325870056679710341571267983857125765234149331990149745571500943300684008078036054281629105618499442731182983775330888524074001975745730722737461725166625564316976464879780901853271273641654911641084141502464")) - .build(); - final BigIntegerModularExponentiationPrecompiledContract contract = - new BigIntegerModularExponentiationPrecompiledContract(new BerlinGasCalculator()); - - for (final Map.Entry testCase : testcases.entrySet()) { - final double gasSpent = runBenchmark(testCase.getValue(), contract); - - long gasCost = contract.gasRequirement(testCase.getValue()); - System.out.printf( - "ModEXP %s for \t%,d gas. Charging %,d gas. \t@ %,.3f MGps%n", - testCase.getKey(), - (int) gasSpent, - gasCost, - gasCost / gasSpent * GAS_PER_SECOND_STANDARD / 1_000_000); - } - - System.getProperties().forEach((k, v) -> System.out.println(k + " = " + v)); - } - - private static void benchBNADD() { - final Bytes g1Point0 = - Bytes.concatenate( - Bytes.fromHexString( - "0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"), - Bytes.fromHexString( - "0x01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c")); - - final Bytes g1Point1 = - Bytes.concatenate( - Bytes.fromHexString( - "0x17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9"), - Bytes.fromHexString( - "0x2e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb")); - final Bytes arg = Bytes.concatenate(g1Point0, g1Point1); - - final AltBN128AddPrecompiledContract contract = - AltBN128AddPrecompiledContract.istanbul(new IstanbulGasCalculator()); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "BNADD for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); - } - - private static void benchBNMUL() { - final Bytes g1Point1 = - Bytes.concatenate( - Bytes.fromHexString( - "0x0000000000000000000000000000000000000000000000000000000000000001"), - Bytes.fromHexString( - "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45")); - final Bytes scalar = - Bytes.fromHexString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - final Bytes arg = Bytes.concatenate(g1Point1, scalar); - - final AltBN128MulPrecompiledContract contract = - AltBN128MulPrecompiledContract.istanbul(new IstanbulGasCalculator()); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "BNMUL for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); - } - - private static void benchBNPairing() { - final Bytes[] args = { - Bytes.fromHexString( - "0x0fc6ebd1758207e311a99674dc77d28128643c057fb9ca2c92b4205b6bf57ed2" - + "1e50042f97b7a1f2768fa15f6683eca9ee7fa8ee655d94246ab85fb1da3f0b90" - + "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2" - + "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed" - + "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b" - + "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"), - Bytes.fromHexString( - "0x2b101be01b2f064cba109e065dc0b5e5bf6b64ed4054b82af3a7e6e34c1e2005" - + "1a4d9ceecf9115a98efd147c4abb2684102d3e925938989153b9ff330523cdb4" - + "08d554bf59102bbb961ba81107ec71785ef9ce6638e5332b6c1a58b87447d181" - + "01cf7cc93bfbf7b2c5f04a3bc9cb8b72bbcf2defcabdceb09860c493bdf1588d" - + "02cb2a424885c9e412b94c40905b359e3043275cd29f5b557f008cd0a3e0c0dc" - + "204e5d81d86c561f9344ad5f122a625f259996b065b80cbbe74a9ad97b6d7cc2" - + "07402fdc3bc28a434909f24695adea3e9418d9857efc8c71f67a470a17f3cf12" - + "255dbc3a8b5c2c1a7a3f8c59e2f5b6e04bc4d7b7bb82fcbe18b2294305c8473b" - + "19156e854972d656d1020003e5781972d84081309cdf71baacf6c6e29272f5ff" - + "2acded377df8902b7a75de6c0f53c161f3a2ff3f374470b78d5b3c4d826d84d5" - + "1731ef3b84913296c30a649461b2ca35e3fcc2e3031ea2386d32f885ff096559" - + "0919e7685f6ea605db14f311dede6e83f21937f05cfc53ac1dbe45891c47bf2a"), - Bytes.fromHexString( - "0x1a3fabea802788c8aa88741c6a68f271b221eb75838bb1079381f3f1ae414f40" - + "126308d6cdb6b7efceb1ec0016b99cf7a1e5780f5a9a775d43bc7f2b6fd510e2" - + "11b35cf2c85531eab64b96eb2eef487e0eb60fb9207fe4763e7f6e02dcead646" - + "2cbea52f3417b398aed9e355ed16934a81b72d2646e3bf90dbc2dcba294b631d" - + "2c6518cd26310e541a799357d1ae8bc477b162f2040407b965ecd777e26d31f7" - + "125170b5860fb8f8da2c43e00ea4a83bcc1a974e47e59fcd657851d2b0dd1655" - + "130a2183533392b5fd031857eb4c199a19382f39fcb666d6133b3a6e5784d6a5" - + "2cca76f2bc625d2e61a41b5f382eadf1df1756dd392f639c3d9f3513099e63f9" - + "07ecba8131b3fb354272c86d01577e228c5bd5fb6404bbaf106d7f4858dc2996" - + "1c5d49a9ae291a2a2213da57a76653391fa1fc0fa7c534afa124ad71b7fdd719" - + "10f1a73f94a8f077f478d069d7cf1c49444f64cd20ed75d4f6de3d8986147cf8" - + "0d5816f2f116c5cc0be7dfc4c0b4c592204864acb70ad5f789013389a0092ce4" - + "2650b89e5540eea1375b27dfd9081a0622e03352e5c6a7593df72e2113328e64" - + "21991b3e5100845cd9b8f0fa16c7fe5f40152e702e61f4cdf0d98e7f213b1a47" - + "10520008be7609bdb92145596ac6bf37da0269f7460e04e8e4701c3afbae0e52" - + "0664e736b2af7bf9125f69fe5c3706cd893cd769b1dae8a6e3d639e2d76e66e2" - + "1cacce8776f5ada6b35036f9343faab26c91b9aea83d3cb59cf5628ffe18ab1b" - + "03b48ca7e6d84fca619aaf81745fbf9c30e5a78ed4766cc62b0f12aea5044f56") - }; - final AltBN128PairingPrecompiledContract contract = - AltBN128PairingPrecompiledContract.istanbul(new IstanbulGasCalculator()); - - for (int i = 0; i < args.length; i++) { - final double gasSpent = runBenchmark(args[i], contract); - - System.out.printf( - "BNPairings %d pairs for %,d gas. Charging %,d gas.%n", - i * 2 + 2, (int) gasSpent, contract.gasRequirement(args[i])); - } - } - - public static void benchBLS12G1Add() { - final Bytes arg = - Bytes.fromHexString( - "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f56" - + "0000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee" - + "000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac" - + "0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7"); - - final BLS12G1AddPrecompiledContract contract = new BLS12G1AddPrecompiledContract(); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "G1ADD for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); - } - - private static void benchBLS12G1Mul() { - final Bytes arg = - Bytes.fromHexString( - "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" - + "0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1" - + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - - final BLS12G1MulPrecompiledContract contract = new BLS12G1MulPrecompiledContract(); - contract.computePrecompile(arg, fakeFrame); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "G1MUL for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); - } - - private static void benchBLS12G1MultiExp32Pairs() { - final Bytes[] warmupargs = {Bytes.fromHexString("0000000000000000000000000000000007664256b807eaa3a2345380f94ffc73803fe1d1f66748a6b815971c20f6e03ad1cbdb77f1d4b6cbb1a4a6ee05db9d310000000000000000000000000000000009067b299e5bfd669035fd4bcf9b301b8d1ca0fc37c4208f4da51e2ef5326c2accf8f878508fabc8a235305090ff53dfaa80b53cf0fdd235808f25062ab0f2a53e2013bbe7fa1d9b5b2232ad430315ad0000000000000000000000000000000019b0feda6576be667b8e6bba34dbecfe16a18405df5d8ad8d3ae3c0f9e51dbe83f52d4a55ebad88dbfb10f8094872b700000000000000000000000000000000012f4ddaeb1d20cfd904dd234f02012b034b36dc68e7f87b1358159580271096ff3c67b913b49b99c1816e84d4ff85c651ce12a1ae3f16e26e6fc3e226a4cd3226e35673f6e5aa3e93e150acc915f3a8a0000000000000000000000000000000017a25f415c4667f133c8e0686778c4fff788de4ccf5de941a34ac2231e3c4e4467bde96eb0bbc843e84b294965e2ca950000000000000000000000000000000004262f32154f54a180459d368b07c56cd74b3806964810c43ec93aa206cd3c50c8b69e4847ce32381f671005339273666ed4fcaaa748173954236ad5414292899af572a25ee8f50c4267944af28b0349000000000000000000000000000000000ffb3d452b67876d201735f58b12ed95f1ad8a559f327402fac12aaa12f8fb3d2228a878df7343acf35c39aa300af0480000000000000000000000000000000008d16105c8a1209f89689c7727d774c8c49fd4fdfb615f8873ce1542282e49c174f1782b77de0e837f00331a0138e853e7e793bc6cb21a063e1157268ef28ad2fb30f7cffb45cd20c86370b0722468e8000000000000000000000000000000000290388bce9bd1139e20d8eec9366cbbbe4a9dc685a4f22efef3b8417c9eade6694b5e5e2cd5e934695c448c62e4a9fa000000000000000000000000000000001923a61e55953813ff71c54c2288dcbe1ab43e09d048abb1078a1775fc8789d2d16cb5dfd363c490a72df379f55aebf9996a13510cfbcc5bb10b0bc4e71616c7fc79eb804b366358fa3ef46a1d70516a0000000000000000000000000000000015b4e1e8d4afd65d347c3fb7294726c4fcf6df1318088a1ddffb8b47891097032076a362ffbe02585837119acc170463000000000000000000000000000000000824cdb59b5ef867e5c09652b5a600d3199301116237a2de101d06a5c60d8bb383e8b506b42445f3aa8d61f85150bda5ab6157e88065eabfc77894321021a26e9d88a05c5530bb841f52a20655f417df0000000000000000000000000000000009d9f36237628378ed04e28b251b9c3859bf728f9a65a01fa20e2220d4370d21127ce6db522664081db93662201bca6400000000000000000000000000000000189d5b721a75b746e175c0801ab23ce20ed2c0ac3d2ab58421e9a1f0cbf126d5117a225d2de1257cee1f0717b79f520412b782bd6a26a3471e05401dd24a0477c38402b622e36a7c7a7c6ef10b1dc5a200000000000000000000000000000000154f98971e27f0b6ac04ad8b63bda2497bb80124620f23f07eeb14b5736e38b33502890fdb9abc43ba203c911668127000000000000000000000000000000000024e9ddca8aaa87a0784c9a70fdd9cdb4683f16019543e0314d37ee70d5346290d5d8068496feaa9d5495e679c24b61900a3ade342e302fef0c63a938bbe483f782501082565ae178403cbc1397a4c8f00000000000000000000000000000000131120da9c879429226bd8a342470153bb8e65464ee8903a276ab4ba0657009edd7eb50c20d4948d5550ea97e777be22000000000000000000000000000000000ac267e400c460352cb5a807470932d76796c284c1b85215d0c095d432b9860903143f342aab76eb9069dffe67f353a253fe4009eff5f1d7d3981827f51259170dce200f6a363cda507476d9039a8f16000000000000000000000000000000001708e97f405b46df5cd9c4177d0ed58d83f29466d8abdffd1f4e3876ec3475db8e8de73a91ff58fef5a8370f206f14740000000000000000000000000000000002238b6ebb0df26edb27f5b61748b4bd554824faf433360b77cdac8579fcdb4584203dc4dbb008df67e37f867e06ac39fa97ad23cc242b08dc250e74abb82c9495c9d0f1d2b8935aceba35d8a04db2af0000000000000000000000000000000017d352210c2b627af5b3cd22ad1663387e686b5a8cc6683f8f5b689248bb132cd558928a07b79427b96d002f77c880cb0000000000000000000000000000000004a332585204830bcb8e8a191ee8251d5f1fc66d47108f11b0785d9014eb8696cc54f9b6ccaa73e43cece2be0dcc526ef33dc7fe948356238e3f70c0d1e711f5b0b73a5eca18dd3473796c5cbdc19ea60000000000000000000000000000000016801aa4c72270b52bfc97ef15d6b110183ecd882cbf55989140725f626b16431989058862855e41cbcb81180bbd6ca50000000000000000000000000000000011a18e6aed38703430d0a34236e26055db71e3ac18a8f5a5fa9dc6894d4eb1644d0bb28093902fc64416d66a7f8ae935bd0a03df615b35da5b0304748126a52f7516574989dbaac881aae9396ab16d99000000000000000000000000000000000af7826515ef482e139ab6e180d83200f54b92f2ff1b834cd174e6b965ea8a986b4f39550721a9896e98b708e9b35a430000000000000000000000000000000009268dcbad65048807941ffb7bddf5f1dcdf93006e6aa1a51c4dbd9fa65b2598f0d639d489967b3953d390adc7fe31f20cbcaf531eae209c4a1a794148a3a09e08b461f3fc3b7f964197ec7a6d370c71000000000000000000000000000000001970b65d23f1e7015585ab101b4221e41f8a16a04edd27bdc522898467281a475779b9c05025c56f3cd6708d0baa53c7000000000000000000000000000000000727dbab812703b5098d9992264472e35c96a9c46bdc14ca7f7472826cded859f4c98e969dd7662fbf14d5abdd2179cbe4d409f29475a9ef826263b28ac024b3d16c411932ff1e97a4b878fa5ba6b0820000000000000000000000000000000011e818d54ef5a9fa5683da7eebd36b7abd202459dc55dfd496f84a1083eae6571d609c92dc9928fc4ce2e21e88999070000000000000000000000000000000000692eb691f4a2eb097f0cf554d631b22dd445b21dc80c198c57313ad358b4581bf41ef9e60d7a102d92c69bf49853a34ed47fd3aef867b1c18dab6cc526a49e9c006e7661c1a4388aea83cdd47161d8900000000000000000000000000000000159bdb894d55db8b26cb3a2780d437ed3b8146d63db29da48abb1d2fcac90b83e72f401625cdb988666ad17f3b01c8d900000000000000000000000000000000019f92e9e567a8c2b7ffc5af96038d620f6a6608bb7de4486345396abc09115b326777a1e6ed6f080498c4f762349ce3bd8c301dba98b3af6a515db49bad427a691006328a7f5d8948633cee33090efd0000000000000000000000000000000002240edc25a6b20963fa0912a93ccd25cc94112188bc1cf10f8280488f365fedf47b13d05308f65891f55be75d6a546e000000000000000000000000000000000bc17f8e45e7733a5e3d6efdb8001111782210fbf9b4fbaaea67acab77516d89ad1b271f841631c58becb3e3ff6506ec174341f19e73d59a34d1655265d109633b6023bc166d4b1195185dc3fa35d6690000000000000000000000000000000008161a348271c629255ad9712c5811e75fdefada8573c00ba493dc865042b7790b2a4612ddc6846a535d0e7de61ed8ad00000000000000000000000000000000005b1d8aa7076d1ead706bb149b4d2066ddecbff265415101495141cf87b9527b4eb3d1e1018d5a11ed9ad31735b86ef730a08a15eb5e12b98cec6266c6918827e27d6129f6316758f726aec42d4c0bb00000000000000000000000000000000016562da4cc2df48bbebeda74be9ef19b440beaddd7c05e048dd9ef5a8b65384f70f72476cd3dad180dcee853fa59193000000000000000000000000000000000f99180611eae16e07c4742552baa010c3c256331ba4a0377cb533de012f6a55024f83800bfcc59ead74608e8f0eeabade569312e27ef078dfe70c29edc01d3eb937745ef766d7117a2b8eeda878992e000000000000000000000000000000001728d7d6cac8e82b958bd4f7f5e917659d4b401e3d86ebf4794694ddd4d5d0e1a971ce6139a3b55289c4a4d6a0ee92c70000000000000000000000000000000012fc239cd5d58f66f1078106e32808d90472541112544344c9161cd54c8d196f69963c275536352bd305c0bdcb1fef66e7c36a44be028e0226ffaf00aa83ec29ff6de3b9e54c62a21d522a80e3237abe0000000000000000000000000000000008e716795594276c6f9f241fb0c0b8b57b891e0fd1516eb31d29bd0ad40844bb45cefaeec535180a7f41f7f62ed1a0c40000000000000000000000000000000009ccb5ee63c13c4d81bea4e0cf9a1f196a99ef4df81b71f4b7a4d674c0e714a071633d7bf9e0c73109d393c7044ccae8b7d521ce97d681276990af474d3b1112bfa3810277204b4dc8532ec302cddc8600000000000000000000000000000000018c571437c067d42983c22f51498ea3b922178c5bcbcf3a26646408a3cb764fd08555ab6d7ce2179d6e88e8764b9d5900000000000000000000000000000000048828bd14a480dbd5755105178c519840bfc36a3d8ad902b03d6a4a91f18b6dbef3276a102981cce3b300a38a10cf4055ee41337625eda81c2afe1213fe87ec7a03b9fdd093be58c3a5345be8e4425c00000000000000000000000000000000169a952e4750f32f8be59115098323b8a8335ff29f4928d802cc81ab0311a208df66a1fa21f4f06a3dac003fbff3afe20000000000000000000000000000000012258ae4eee13ff5fbb9653e13239b2675ddb1a82718a5d9598129cfcacea0bff98053aca600939421b38d4736cea3e6ad681fdc185147f10c30c0f875af683fb588456373eef40d246adc493bed6579000000000000000000000000000000000282cb07d118142878ed40ba125c652651b75096cde9b0b79e1752ae73f504b281dbcb7d0a8ea88e78b15a5b0610d306000000000000000000000000000000000831a67a63cbcd46cd3644de8fc8ca8a0342f9736325ea99ce3ebd350cb142865cce149f121cfd7f338d138d518c9046dc4a555322320eeb7f68830df56fc7d7a134f41f19c87c29a1321fbcc36f95e900000000000000000000000000000000116b877ed25c603b77084f97e9fb7c3465b00176751f9ec77e8c283ff38f601906efd0a848632299e667743fccc9e9c200000000000000000000000000000000075fd02aadd0076af212b1b1819e7c22fe7889f4a99ac865c1df73b6e673697852631a9e2033bacd81bb90942f0d53390af8a1cecefa59c5734c8b7566045cc375857a72da0849aa33c2a4b16feb3a130000000000000000000000000000000013528207baf1edfb2370f73640009d1268d0f9ea02035392418f809bcc8ee06ab5d2b8d361805305f37e1669e521be13000000000000000000000000000000000ed65d4a7b11db4cdc68fb10ef35e7e8a290c8cf1022d3ca5db12c3284ee19a7220fda17fead5b4c3b8e266b9f37e70e2bfe92cfecd8cde0b798e4d84481c125c4a40983e1575b3789c7e57a2966dbb400000000000000000000000000000000011b44f3f1446d884a50270e98478f2f1180ff1aece24836a4e1cb085b25e9506ef2c2bc48c07c07c87189ad21b6c1b40000000000000000000000000000000000913cd2fcc40789101c31cbbb2e9f3446c9840e67f1b7f455fa71a5af12b1c62bb4921f0513ed653009c3edc190b9eaeda2905fbd7a90e86bbfa7a7a3ec6feb952c74e0043781976bb755f79260502c00000000000000000000000000000000064357258c8c86dda11a0eec88cfb1a0f1916119c2515fb26861992f70a37eced19b92721b5274e531c2def77dcfb2e30000000000000000000000000000000010061891593da3d189f26413325f1ec966f52a8d565b644e18b9d90918fb932b387c7389408fc41bc158f95d3c7e05c60537aace274ce26c827bcaf96344be095389c963eb96ea8cfdf9607b4f2b7b4d00000000000000000000000000000000069d648fb44e554b510eb364bf81dfcfb7692afb612f40a1bb7fa7e4666d92ca95c2c67196c3fcac92126782a2cf0f430000000000000000000000000000000008bc56e8879e330cf0a88d55838c68deeca45ba70e7df47b5f743569014d9e2aaa0dcbcfcf3c0227e94eef6b1fc56e2557c32d94c592251f6e04d66401fbb4cd0204881bad7e6fd8e5922290944a9cf500000000000000000000000000000000071fd55782b2bfc0353034dc3d756cff43db5c55fb09f60746a7ef7121028795a318e6030a4f71f723f72375f317c610000000000000000000000000000000001036bbbd1a2b39aec610e0fd488080ba1ab477487480a55b860f9c7c507f0703c1bfa8add16c1686f3021c780d37aadff9299de37ab22ac1c427d854933ed59e66e16e034aed011f795f3629b21921550000000000000000000000000000000011c587c0d81c454c99b02d87fb89f081dd7217ba92c3f9158bd913fd9fab6afc8ee7d7011c58ba8a6c36121189a16af70000000000000000000000000000000004dfb0b3e90477e730bbb8cf07cef522c86b54772076bc2209f1928206957ed5653be93f6008d33b9e6d545aa5a5b600926d04008431f57a215217a80304b0a35fea4a3fb83c9cee546c4f5b2c38d47e000000000000000000000000000000000a9e5f4e93fe429c8ad492db1ebb366123a538d0518c8f0ec203f7f27b759dc2c88764e0e8cbad4a09f2e803d76859c3000000000000000000000000000000000a4863bae62f85c7ab6b717a5fc54a71f125270053775fa107787fa49d1372b900b0684d9156424eb5c60be63f293647cf6950ec19f6c0877085a9af6d457dc16b8c4697d48acd5e31baf9a9cfd0c5ae")}; - final Bytes[] args = {Bytes.fromHexString("0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb807257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146dd291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba400000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a48090000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fdcdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf00000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb34dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b810b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb351e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc780000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b6036b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a040000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf62399320000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a3025ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac410978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab10000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef6491d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d428700000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b20000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d400000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e37d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed2450000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b28d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f83511073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c800000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ecea558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb09b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c9400000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c00000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe08b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080")}; - - final BLS12G1MultiExpPrecompiledContract contract = new BLS12G1MultiExpPrecompiledContract(); - - for (int i = 0; i < args.length; i++) { - final double gasSpent = runBenchmark(warmupargs[i], args[i], contract); - - System.out.printf("G1MULTIEXP %d for %,d gas. Charging %,d gas.%n", i + 1, (int) gasSpent, - contract.gasRequirement(args[i])); - } - } - - private static void benchBLS12G2MultiExp32Pairs() { - final Bytes[] warmupargs = {Bytes.fromHexString("00000000000000000000000000000000188f0ed533923d52663d42b8ff1034105aa494104bfcae76e8c35914e9483546056cf7b40049f3d01ebc9c7501933fa60000000000000000000000000000000014acda4c3a536c82dd799ab1e67e951b161dc8225e68b1c8a8ede0f47954ae908939957d8c2a45fa1c32fc7bbc25573c0000000000000000000000000000000005d7e403f13fd451a751baa1937ee1184a74cea61b36316ed5752d2b9afd4b19aedf76fa04221524fc847b69d3441a300000000000000000000000000000000011451f2fc4a2a189cc181e4df02d200f0608105a49279e36aeb8238dc7270a8eed01317b139cba78796d4b518a2cda240b9b40957ebce0ae2cdfb25693b86d03fbd9572b61e5dc9dd7be9b0a242d90c20000000000000000000000000000000015c254a6f11ddcf83b5e08d0aaf46c82b964c48405c3708f7b735a8092a59a3195e8ecea2c37cd40cf2c4694d15660910000000000000000000000000000000018aa81b024791f5872ef1518b790d120011f0f45d59ed4a8a351b246301e88a0de6a0aae141b04740f943013c6ad1e4c000000000000000000000000000000000610fb96f6ef4bf9e176d6bf3e2834b901d9f7eae8e9a0217534d2e2a50cf91709a62b1da914a64c24fcdf0a06c6c1d90000000000000000000000000000000011fa15ebc6a4ea237a02758e7bef8ef6f4734a15cb506738832c5f47234f78f2823eac6ee3a8272a9261991bd7791e8c59c55cf825f4711d4bb841d252b972e163722781b5a20cc8b8c71311028aa0a70000000000000000000000000000000006641858b2f93295589d53902136dfd7b907d6e5667ddb0df3d8d79f53a1e8905f7a20e7c3d3987b6ed202edd41bba590000000000000000000000000000000010e565024d72c2a1e381416e42ebb8877a2563766f21171b8571b966f25f3ac34b5178ee23efc3051ed7795949cfff14000000000000000000000000000000000eda8c88f3433b3bc92ab1bbe783dfb34b2d39e78d5c6ca3ab6df37d2fa040ae6eb04fc20a04f927e19dc8d3697b43a5000000000000000000000000000000000f4df0831d760310cd112d0f54d51c630544a59a9f0e27aa70ec06221f7df55f747ac54f67aa46a59967e9fdb7e870dd0f993d797779e8c03a0e8241016e9acb57bebb93400c7e162f87ac9f04c9330f0000000000000000000000000000000000c25a16f1a906ac0bebe4be099b1618cdc096c6b4550a8abb505d2f0510b397ab85129b2e2f88ca59cb8ba464b59e9a0000000000000000000000000000000016b800325a811b23f3c6546e8bfb4c2f0ccfd675cc0b1b06cf38c069c77c3e2844102943f393d2b806a3f283120c071b0000000000000000000000000000000007af1731e525fa3538bdbb4227c665aeb9538a2098db0ef30cd9bcac486fe16b5d31c2ea63d4855cc4e70093388dcccb000000000000000000000000000000000d08a0e55753497c12a12b32bbe6a0f9946eaf9330258b4ca58d0418f075c4a7e374ba47d278349752250ca43695a9911f591f7b58dfc781b7c059e62291fc79cf27c40d5e8038e2b674b66476a365d40000000000000000000000000000000015cbaf607c81adecaf4a3c50395e9ae05c71c49ce8d0e52df9f7c78a690f79de53aeed701879e23694ccde9bfdaa8fa10000000000000000000000000000000001d72c4cf66f49f5705ca20b57a39ffe2c50ac60e46661bfb7515cf030d0c8211204ec033632b5329b8686f4a3a7b47d0000000000000000000000000000000002956318f0905d98b3f830e833eefb49331ba2f9c180cc43c33e9aafa5b7f8d51aed30d4fbd767dee85ee8332345faa9000000000000000000000000000000000393de667ab77f12f6d14146e2cdb38fd9676c6ec42e5cb11bc3f8d601aec2ec085d087a4a89508cd59902e64cc5c37e4374b1a801d55e360347bde069d6bf9041d0ce23d0756ba6b6049cd630eebea4000000000000000000000000000000000a1685e598fbd658c9af1898152a1fa056befa105856d76d835a3bf029c1206897b5ea065f1bdab99928aee50f36ec58000000000000000000000000000000001204dd0ad42d5182a57874ebd0b85d3c1717736ac548ad5bce3618d86c5aabae9f481c1df56c4b58c32024ec2e9a78f800000000000000000000000000000000199e8594d05c7899c2969006e3c068ffa2e85fd18fa507ec141b4e8bb80545f3a800183ad60e91f52bd14fe2a64da6db00000000000000000000000000000000027d91a9e88af8742dd96e067d1aaea93b6f2be3f72146d71d257061dc6e3dfb12a682f38d75df3974210626b76b8001a18b4d5f4f17ad0c1985817232ef324a7065892033c3f1aa6dad01115db037d8000000000000000000000000000000000e189eae7c173a91a5ac085d149bc31a94f6a772d09b55fdecef2cf43fa46c71cdef79391c69e948f1076d3f4146dc88000000000000000000000000000000001090889d2e1f3491d3f567ae33d8cf5f52d268c3d3517e33f908b8ac9d85e3688d91a69261c97fe353609e3fa13a19470000000000000000000000000000000016a1c443da338ebe5b1cd23532e435f029badd9b6c11688f8d7e9bf3726fc1a2279245ae60ec72170e3bf95e67a6f7a6000000000000000000000000000000001708271b2c70a9c8da3f02054dbc3bb7874bee25581a96338f49f6b35f5f9cae1d4094fd8028cf46da064633ae0e22bd95e20ef92082e1a1ec58dfdb1a4fd1296864f34f6f00903ed04ca62a89655ea00000000000000000000000000000000010bc94fedb42c4b42cb0e3ee09e102aed0fea61152118714606e3a52da75531c1acf863284736c7f8b0986c6ffd12508000000000000000000000000000000000bf6f0d53e25be8c950f6f020cde9eee09978b8f6ee3a34c45882fd7c21b0db1d673482571cceec26affea4cb849c67d00000000000000000000000000000000031bc2b2cb039744be4b1bd33d120783e5c47e1333a02ae76b2744f895a2acc6fc3a68eaa78bd7e018591c5e7f41502f000000000000000000000000000000000ab02378267bf8bee96fd3012f8960d64d2d9158ddeec3d882231c258ab1b4ca0f9a1743066da160a02236213e9d90979bbf871d126a56956556f385cdf7fb80c2637a863ff2e93453863c1eb1d3054b0000000000000000000000000000000015828208b747373d7582a8cec9551791fdba44cfafe4dabd27ac3500f1f01ad414f77f0ae02023732573eb2543795ef3000000000000000000000000000000000e54f402578a8f9105ee45759d7969bb45756bba251e1b42d397b04f8727c742199406fd4a061ab68971003ec70d63e90000000000000000000000000000000017b1fc332708941a522e8d9298ebfdb30284e928462512679206b6eefc20fe8b79964ef7b75b836add0774e7e5c7a3ca00000000000000000000000000000000072adb5d5c951200e40dd896eacad43d05651ca8437e06674a3254a0e854fb357a481f993ca3d8fe3ee41557b529417c0d7df4d20aca9f94b0c3e4ee565bd992165c2b0697f941de8b8f53b09c1f35ef000000000000000000000000000000000a9f57cc0c46addc7f42366a14a29a654e5652f697c156cc190677556c1925f1fbc278ba40705289b903ac33963b6c8d000000000000000000000000000000000a77dfd78a8879850dba365deeb1945fb4d98125eb6d16b0daf62b8d23a5a9887b45f86c2e4e7990a010e3cda31039cf0000000000000000000000000000000005159c436bb8521ea68dbab7cdb237c5515bc34618e8fad6f75e0e190dc5574446d0c4b6e43ae46daa248a388bbe38df00000000000000000000000000000000095810096d80f5917a06eb404fd0fad83633ab12097deb3204ce6065ec462e34150840edcdc0bf9ab45636a02d777cd00e19cc686068548e9fc1a3eb39af71cbecae2ef4bd659aa2ccc67a87e343f3240000000000000000000000000000000007230c1f2951000536261aeebf2eed777626e05aab5b726812f68bcd3147b4884e615c0353995d55117ca002ccd9a97b0000000000000000000000000000000007d2c8ca78123f05e659fc205984d0d2c38ec2a985def4db47af1b9ed506de020c0bbc59d9ee80ed8cf493ba0c329b52000000000000000000000000000000000ad6399c2b7479f058ab02cda02e124a094a64d567f9d9e47bb1d7fdb700383dd73a644eeea752327dd09378fc8868bd0000000000000000000000000000000009daffa5ebf6655983566abacafa696b5816668cadf21af3036eb03eabfa2aa4026beefe4405c4c308039dec8846feb9707c2584dd81179e70d22a5fc402d2b9a8103b9ff6a9e79a48a201ae3df2bccf00000000000000000000000000000000091fac3f5853d7255da59ce2d70c3e8d644a9ff6be3b5d509350b50bc37c5b6b6bfa2d627ae3b9fd5e88d6c4cc837bfb0000000000000000000000000000000017394485415f012098e36e727145f6c9b80d021669ec097e862eeb2ff93bd2631950e49e68e1f95957de2a34eab670c60000000000000000000000000000000006ca148d11c2802eba709b7d97d1bda2a268ea1df615f716e9c4c0e2045f5af7179196d364b86dcf1ce5285909dd03740000000000000000000000000000000000b17c3f47edd9424b8404a301f439fc1dde3eb7eb59c454e51d6d649e2f998d585487e88f25d4f1f642cfbb5166afb81c8dd840a920b82ad18b0d10988bf08665f88d6d83f3f78acf9b6763ba5da1340000000000000000000000000000000017e6b72e82759b5adde10ef6ee13f59d45a012dd1f58395e8d5ac81e5087ba6968b056d59faf5d7701906d95c46e2a45000000000000000000000000000000000f376f1c12b55fb0d010204cbfe4678811208e37d01c173dca295c034d5f37e6daaeb36c9662e0dc6c0cbaa303c812c4000000000000000000000000000000000bdd08c4b9a02c7dc0c1008e69a40bb7df3d78faea9556c9614bbd014d77b537c10d90a2c8393a5aaafbd0151dafc54200000000000000000000000000000000047fd77392129274352b20b95e8928dc030f8d6751bd5e974942328d37daac373df8a7595d7ecfbfa31df9cd6f6d28a4566294ee07bc3797c3c106b614a77d74dae8920ec5674417cc1811498a1c6fa6000000000000000000000000000000000af3da28daacb9b6969569a80ad3e74217b591f27011b5c22fbdf3040396b2612692cb6266e996d01a1e0d84aef2837f000000000000000000000000000000001138efd32ccea9112bc47652c35298699db1bb10f9bb3a88add16a53592ffb538cd76545e9dc30fab0e1849987ccc52f000000000000000000000000000000000a7f68b7ddca4b5106e18f6e600e969f65ac0d24755613d810c49b1463ec946dfac27003ff5d963e31443ac2c10fe409000000000000000000000000000000001226047190acfec2486a1faa6150a64e0eb19020938621ae64e2a135b15a85d9de3690e29655dbee2248cbc9054af7cfc2a2a3e6314c35d8ded36364e63b939fb209e669776b4e462e24b714dfc0a0ce0000000000000000000000000000000011bd10b220803704a8e85fa96639dbecc90dbc343661756876cefc5b9e3023d56d7003aaa3f64165c19fcfe86a926e3b0000000000000000000000000000000011dc64c9609e7809c1cbe573bb54759bcfafd364ada70f5c866d762e981698af26acea16e823ca84f84efb9b7acaf9a7000000000000000000000000000000000fce053a5e86ba0850365b907635f655d1104952d1428d3b831757860ba768f20552812c0145b328a196e1b789daec7d00000000000000000000000000000000043271158dc0cf59a227e53fc00dcba2de9f8bac4d7c8c50bd4097e1188716e2a33cb8027786c7c4f142b64a3e9990c26b136c62452eb60bf1137a838fb229959af217b8d292c83c9bea5fc4dd2043f600000000000000000000000000000000001652ab647d2d2bc5fce9309a676cd95005d3beab03b775c3fdc892ed84ec13fcffb5d0fd9d7a24e058f49293607ede000000000000000000000000000000000b676401571f804ad3b64b893121234d8639a37749559b7b5fe7fda34b6a67d973586f9686573f690787f7d576c4593500000000000000000000000000000000196596e51755124653733f4e42c94d195d79b418bd907c3f70f8469e70d4923784b8881482cd1ff9f8bbd30a0c31de300000000000000000000000000000000002eed3d4212c1e31ad59cbf0c31838a054d80c01c9f98f33c331fe6e9005bbbaf5cbbaa6ffb2be3f00c3323efaef6a5bbc0496ceadc4b7db1fefbdd102f64abe295fbd8278e08cf0c0af895efbec733f000000000000000000000000000000000c95644726db9ed64ae44b919bb1bb0ad65efc10bbc0ea31b240a0c77c088599f0ad18e68805e9d40a381d39adc11b9e00000000000000000000000000000000089dd201e2d5c37b3df60ab6e14eecabb78aea8fba85394431aa8f17b931e411069ba286537d8979a3f761f68be80cb0000000000000000000000000000000000ee9271dee9c0afc5b68be899951ddd7732f66a4f19353377b0218e0ce72b2de3c4b0b254eb2f956b1415bbfd8a877f70000000000000000000000000000000000f0f9db21df709a7843796618af2dd6d0738c7d423db16a864ff5ad7e37998a794ce23c00a113888006dd868c23f7db2b295eb3ebad32c19ef056c2d84acc4dc5362182c0908cd12eb5810d311ebe2c0000000000000000000000000000000009d6be799b26bbf89a24d285a3be40162c7182cdd2790c4338e53d2500582564a1ed81328af02470c1eaa87fff5acea4000000000000000000000000000000000816b4ba02217cb1c0428fac9a091916188ed9729083feacabf525ec53a7a665ca8e8b9f4e7a5c42e641bce4ed6bf9b1000000000000000000000000000000000dd1fccfea4f2fa592b7d13ad33b021473a37689dc488ba7424f32ca332c03158fbb996c09538f37224465cbdd40f1a8000000000000000000000000000000000d725c382abd00f31e3caeb84f9a7f8917387da004c7e6d6a2587a541f0c91149a6b297c1b1aeb59e7d0bf49f82ddaa7a15ab9ef4b3dfef6c1cc3110af2f114c6b0725e7e61dcbc6168b4b8f2347574a00000000000000000000000000000000150a25e38c580220c1721054cfd3bc25bf5b9840484ad8593a8177fabce406158290c94f110b1613acb41dfd3603744d000000000000000000000000000000000296b5725f102180b6ebda4d239b132a1aa0ad420a407f574831891552b2dc735b3f832b7c91f965c8a21ad7e02ec5a20000000000000000000000000000000008cba3cb8ae244bb91297cad82737bb6606cdf9930e425fa45e1b73bcbfa2196d29e533c114197280782c953d303675f0000000000000000000000000000000013da6ddc0404d72d63914948a05a0921f1575dbbf11e93bd04d9d38c637faf09e2da795340d2f9033d4ba57a5c778f4272acb7e6eccf25efd392fe0b0cb66ec51c64296a597e29b9669db6291e2181e800000000000000000000000000000000193de5c8c223779f3d8c81a48dca3b6eb72c1eec095d52a1ff0940c7cf240a037f6225752c5e7197af9fdd2fa0d3977b000000000000000000000000000000000b49139f74cf1ba6805a785db8df8293032f98701bee591013dae4a73cb406fd6ed1dfd625e23e063bc743c0c4b8c1cc000000000000000000000000000000000edda5a33c5d35c79005e3725a11d6fe925b9474ee745bb0e6b219ed2b406adc19b0c67c155d687ac5d65a2e8171f29e0000000000000000000000000000000013f039cdf25f58f6995952541d27fada4f10ae655b5d461036a140340225fcb5461a378ee01ab644f43d97349faefbbbc407a4b18cc4e68d9bd5c2d3c895a5acb7368f8f0a79e49b9b40edffc48b68ca000000000000000000000000000000000b1fd0b16eb5fad718981f9b46fca568c56f3a0481e44dd568c3708940b02077773aae986cc38204616a8a0c167d28da00000000000000000000000000000000152f443527d9ef5e63662758f21020970ffd70aab5e92e331ef7888ccf72e7f5dc56276ef6c66fcb3976f909d3d0ba480000000000000000000000000000000005b7d5c7221b7073011c86dfaa563f394562695995dcd9ff57929f4e15f3adfcd0352fdb95dad61fca2e36746e296df30000000000000000000000000000000007de2176223fc6871f2f648a49044f9ecf005488a8598dae85c53ceb1a2e7e136c775738f5f4166836e47f5da97f2635e0aeb9f6e72951c91564007bafdb6aef495293dd3d13f9ef5c2744fbea2408c1000000000000000000000000000000000d45fe6b2e258d7bdd62a06b895e63638c2cd126feb64cd3e1076cd29596ae7e08e8b3312f5d40a2ce0a695f993aeaaa0000000000000000000000000000000011e2fc0023878114585f48f681f40ac5af68863369eb58c017940331ec7d3c0e86ce2f65e931f875f570f97691c19ea70000000000000000000000000000000014006f95d7b667a7ad8c8b2551a4c10bb4fccf4d2d829595bcb7e4eaa9f7caeef12836571fe3d4d13082e58486cdf00f000000000000000000000000000000001331a1a6bede57f8a1cd3406b1ee8df4dda5e6dcf39eec6eff369bdb2ceb9a1bc4e5f0f91776e8a3d80920c28d77c93c58d3a70c495d90fd9ffa6fa22178f8dc8c37d8e9f260d2275c34d33998baccb000000000000000000000000000000000000b9c84a0c5cea0a80c01e2af19f0d164def421b5ced49bc35f6ba4ecb75920da0797d7d85d56de6ad21a00a51403ac0000000000000000000000000000000012137797dca543979864663d292ee40900208b7d58cce1cf68dca7b7ec1b022f3015a652984c0e81bf929c81c9320f6800000000000000000000000000000000141e5987903a920c5ed88e51708803cd95e8ace73c6d4507bda45b01477fe15aaf5673c56ad9c86a63c691a965db8e5800000000000000000000000000000000168a7a068f30e8fedb5e86be8c418484bdb722260af8fe274d9f341f8893b6bcdf4c89f3dd9a9c1a38ba45406ed9aac6d079470404e36d535ba79d178988c6b5a2cf40953183475a340f5649488635ea00000000000000000000000000000000179989bb4a3e1c98d14fce8f9596d6e1dace6efa75afeebf366bb2a62a7ed92f90e94289aad542861110369584863db8000000000000000000000000000000000432c73984e564bedc7a6f532f05bf8b8cec73d75cc046a2f001401397e9f5a9808635a8ac402d0aa7800a7eace81d1900000000000000000000000000000000084869f18177bbba633aa3714ff3ec36d1cf4548d4e3d2ac90e2dd9bff191e28ae36b6ad5030d0fe6f14167763014293000000000000000000000000000000000d1d18c38ede2a5570feba47c086124690bc53fb799a99c2d6fa3c2c9ca7967346d5a8bc8ec90846fd90dee2220c9508396d275d82cc3950aebd1d0cc4bdece0a06284a10b61998dfce6582043f1d669000000000000000000000000000000001188406db269a686292fceb9b4d63001d40a9e54f229a0efdcda5317e779baddde885451599014ecb21a477fef94fb730000000000000000000000000000000013abf0ec56e8da6b874ef9154ed3265ccfacf426003484abd5eb179c92d94eda52c6adcf2e0f4b30ec08aaf68501367d0000000000000000000000000000000018570c750d8eea7e3e13d8a77fb5de9ee0d3a4f4fc952f93d5b1f1eb9d75ace90619173fae00e7d904936d6b071475530000000000000000000000000000000008842e857399b8d509a5fdf749db4ca6cebdd99703f7740d5dfee84cbde53c6023054fe83013381cffaffbf6467b9c3be93096be26c02ccdca748f82873127286fb900c309862f3e3b4e51c40e8ca0480000000000000000000000000000000008b6a73cf4ff199054cf3c15d3f9cfc2a1292864f1b3ce8fe016c7a75182650b6e10840a33ce6a101efd0a138db341910000000000000000000000000000000005d27b953b8d6abf9908bb7506394bbb4dd7fdd5e99e6950c12319d6cd8bc912faaebfa47516a7e185223c7f45d8f97e000000000000000000000000000000000dca7de717ce6bea3d0dab6e996a1a99493eb739c00df14d51c030173e58c233d544d750013bfa1f8d7313ef2e76555e0000000000000000000000000000000019a0af34ff5a8430c83d93ae619b30783e007bd9fc9eaf9bdc59114bb767ad59705584e01cb14fcf64a057667c039bde61c06721cc9dc6738ca8d2b164007af54fbd1e652e2fc6ac16d3361d4b29505f000000000000000000000000000000001166d3fb438a8ad3c461e9cc2a2d551f654291fba6c6daa66d0805c76abe6bf3592dfba5bb4e662267c190ac93d84d3b000000000000000000000000000000001596ff334e90f5af580494e275566431cf297d4f1c9396e0ac9bf08fb0395f0bebbf2714ce5eee82ad2010c09d3dfc270000000000000000000000000000000008f3e3bd6c54a47395a5898faded4378fb17852fc3b0f173c1f463b8547d776097021987c37363cd65f3e2602e782a4600000000000000000000000000000000179eeb50a3edea2627cee9f573d285a27c2ffbf260d4d5efa70bab8a52d0efa03a18c07dbd96d3871107af653d8eb7cd84d062c49fb2fb65d0179685f6ee29f964fe646e823076274f1d29a4e6fe051a0000000000000000000000000000000017fb3531a4d2431cea98c6f124b46efc303caccae1b731db2dce505c7af42054e92b41e7385826b5fc2f15fe902f940a000000000000000000000000000000000535c50770db6b6805f86b2c0cd90015dc3fe8465faf8b5ad2935ac56829d476492f574e9979b5a5b53ce8b06149c74b000000000000000000000000000000000058e3fe4bdede871def9c79754954aaa7948ebbff7b1490a0577563d66ac257620f4b1e3d44ed847ed065789c22a429000000000000000000000000000000000e95cd7e9ede52613437af323898f0541348646fbb5fac1ea8dfdaff37f1655ffa8861bebd44752850be426399ed042b19794f7b5300f29cd1c1a724761992365430a06726982690a0bb8bc663f6309b00000000000000000000000000000000075ae04db44850b10c0bd93d8e9f98101c0f319575590e481ed70ab46f600e4d60811a9267efd154d2e0a7b2e4213a4c00000000000000000000000000000000026b6fa0f68b7a81a6d2a3d0c3ec17aed11814c0f9d490684317745e76801b0920eab176616853fc26a160cad23d80a60000000000000000000000000000000015e4747db8097ec674206e69658e03af9ba685e344cad84330d3d1f274bafe9e3d6c733828999a550073ee829b505bae0000000000000000000000000000000006e079f71a5cc76ea9b8a1f4c112f4244f72f32193b575b08afce8aa8bec7662b7fffb0d8b8a3cc41828511cb457a2bc688678dc754580c619f286402ce54011f71bd6ee0a5b692570b55b273a3907af00000000000000000000000000000000096ae6860debd6c707b938e3aa3e56e74af570f811e949fcdbbc08653d66141bd0ae12cd93c6d91ea59792ad87f04ba50000000000000000000000000000000007eaa9ed1244ae2b1af86aaa3aba8d0c30cb7a1a33df26a2df295a3af573931ffad1a4411c7ec78e2bcf60ed7251520d000000000000000000000000000000000552d7f5bdf90df6b6eb41b3a3a69d2d0eed0bc5aff6e56564d19fcf410427a7b85d9d6adc38e73da3c77d39a12ed15e000000000000000000000000000000001975980e75458936ef89d7c6930d6cc29eee05bc2dd3b16db731240c9321673994bf11829b9804679de69f2c947de5227f7c48af4aef5e07567bddbd20c4907f79af0e974a8714f9588e7b8a65cd293300000000000000000000000000000000074fd3d8145c7fc925a32a9d58f2ac1091cfcc1de6c97943adeb2ec25044d50c624cf7e08b146f0abc199c0175e2b3090000000000000000000000000000000012bc51a42c89496bbccdc8b5f2733a754acc4709208474544eeb0e5bf2aad6d1009d288b7b3df248d7398e08d1be8be200000000000000000000000000000000183516577e7dfdb7844ffa2177c5c22adcd5fd4ff5391d2fb5708313eb73986c511457f49ded49c84b970342dd6582d900000000000000000000000000000000086fdf965b9c0586efb0b475aca124dae876df12fb66ade5fc06cab2f3c7849ba4f48e53fc17f1ec4a1cb5a5d76581b98358065d32fa521f619158d090ddb075a02b5b499c279985d3f64f8c6b52c39400000000000000000000000000000000077d3b1148b25fab4256d28d18ca214d0c2950dab19c048ab293efb9aff03b5ccad3d0ad4068f101dfbbc2f84e954ecd0000000000000000000000000000000001ed80bd1d6de030fc807d0f49cf4c2e9dca2b76b75ab391251a6f41af79bf11ee496e1294f171445dee4d77c7e70cd6000000000000000000000000000000000e08ebd51454a391b4795d53058b823789f48a1e508046d9e960bef2000e96da2936693689fa6f33ac32e1e4196337820000000000000000000000000000000004acf1c78f78c40e572c3326e451735d3f3c6dbbb622f2def266c36d4fce8822c1ff86899dd0e6617d775a2bf9bdb181d62e15762d9fa3afa8ee9d65c7436739cb29cf26f3e01af82196ef6f4fbeca5f")}; - final Bytes[] args = {Bytes.fromHexString("000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e01400b97e1211ea91ba027896f711b96062118bcfa5515c7880679b5849e545000000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a9808c85140e6eca6cfd8510261183d479a443f0629e33dc470c3f7d930c2defa00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294533aae2894034cc6c5278a4bd4daec46e6c08e7fdd6550fe1fa6e2d4d1adf57b00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e331fb26e72247c9cb76eb258094d3fcc9a294180d4106ee3930d0a3fb519b65ee0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79dc6516d7a44f93eebf1bc1fc084c7d0e9b92b3f5be754df31be1b8d8a3415c8100000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba74b614fd3f867cf44fce6e2b91427dbed22190091891b6c02973ca1a5cef6a35d000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b847556700fa1fdfe4e101eb1fb436608a377eb8f4a49a0e99a4d208a19b830967dd65000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc003a8881d042f3242a48d781773832f2d7d93314b215643a23abbdb5e8b7d9a15000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb3febc1ada758ad9a5ab3e93b8a40813c79abfc88abe7e53c94462a36fbac41c80000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0bff7a5e41be99c4d598551e42492169cf09083886c5abfccaab6a064840e6176000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22bc44b57817b2848936bae5cb561ee0d4a71bf32c1f7d39f1e28b849a8b41b5a5d000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1c151847b7b5854158831995014961865238cfe36fd2ee66b26ae013a52c5a6100000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c45581819385fc49c771164342eb70a34b88629a93a4a73fd947b01184803cbb91f49f2b000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29abd7987f7a0e32086552fdff94c5e8791ef142e6a4285ae0f02f1ea7805b52b0000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e0d896153b7293f871e7d1dd50a18ec88a117acc95a95185799f2521b9aa137ef0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f7ee8ca85ad1e179596c12492061c3489a3ea4684e290d50f8ed310320c89678e0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064254f8b95a217dc00f0e069b2fcfbe9acd684642aa0dc754c9520e700d9e1ea28000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad175e4a25b77e39aef40131e0dc7548a7a8d11cfba650aa88a6007622d5a904790000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5de1cff4f165f49342d6e7ffea6aa2199d7af7290c13403b44abcdd56f168b88300000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d4e50f2ac7deaeaf1a85fbfdbd822984eb091eb07d855001c390f88ad0ba96a6f00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437bb836f0c479fbb44d5981c113546ea36e434945eee7b8681790aaac1e776f2405000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89a7d6b59c8a696805893be4249e4fe58609d3608f6dd63b6d8f335a45919da39e0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296026563275db4f9b8b4db071ecde75ae98de14ca3929a6e4a9b992a6743c5254a0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f8fe0d4e218c204ff3db6c9e0e428c9d851ad90c3f126f345d1cbd0aff255bb220000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69bf5b0a443239846ac6afec05fa2a1cc3b102499fa2cbb54d07a1c0920733021ad000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d5cd219b7cf86550b75ca2e2195b00565be311dde9404d9a9207dadd55fa5740c0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53864630c026cf0e096af5910ecc7bcd105febd2544df3a232fee6df97281335dc000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0168acab37c5e0c6b1f12a58e0da2cf9807608cb95ff410189ef552f5fd25c12500000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368ae900998d5e03a6134f6a73872e7788e94216888aec7a98ad72c3db9d090c1bfc00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d057a95d3f2326dba2cf0949f743d407d3027459d796ae89d93fc1cac19fd93b170000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921bef9dbe0487b733954d8ee50ad812774474437436f4630927d61f82f1e46f4151000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da9d2e89d33fa35cb41e398bf41ef89dde8948c75edef997e60ebee61515b542fa")}; - - final BLS12G2MultiExpPrecompiledContract contract = new BLS12G2MultiExpPrecompiledContract(); - - for (int i = 0; i < args.length; i++) { - final double gasSpent = runBenchmark(warmupargs[i], args[i], contract); - - System.out.printf("G2MULTIEXP %d for %,d gas. Charging %,d gas.%n", i + 1, (int) gasSpent, - contract.gasRequirement(args[i])); - } - } - - - private static void benchBLS12G1MultiExp() { - final Bytes[] args = { - Bytes.fromHexString( - "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee" - + "b3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e"), - Bytes.fromHexString( - "00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed2" - + "4d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d" - + "0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f" - + "973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1"), - Bytes.fromHexString( - "0000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e4" - + "4c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a" - + "0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d3" - + "8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89" - + "000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90" - + "787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944"), - Bytes.fromHexString( - "000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1b" - + "aaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1" - + "0000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442a" - + "dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c" - + "0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795" - + "bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108" - + "0000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190" - + "fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f8187672"), - Bytes.fromHexString( - "0000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943" - + "b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea" - + "000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e" - + "3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76" - + "0000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276b" - + "dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c" - + "00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a5787681" - + "7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a" - + "0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f768" - + "94c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a659054") - }; - - final BLS12G1MultiExpPrecompiledContract contract = new BLS12G1MultiExpPrecompiledContract(); - - for (int i = 0; i < args.length; i++) { - final double gasSpent = runBenchmark(args[i], contract); - - System.out.printf( - "G1MULTIEXP %d for %,d gas. Charging %,d gas.%n", - i + 1, (int) gasSpent, contract.gasRequirement(args[i])); - } - } - - public static void benchBLS12G2Add() { - final Bytes arg = - Bytes.fromHexString( - "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d2090324" - + "0000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d9388" - + "00000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae22" - + "0000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633"); - - final BLS12G2AddPrecompiledContract contract = new BLS12G2AddPrecompiledContract(); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "G2ADD for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); - } - - private static void benchBLS12G2Mul() { - final Bytes arg = - Bytes.fromHexString( - "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e" - + "000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be" - + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - - final BLS12G2MulPrecompiledContract contract = new BLS12G2MulPrecompiledContract(); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "G2MUL for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); - } - - private static void benchBLS12G2MultiExp() { - final Bytes[] args = { - Bytes.fromHexString( - "00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df" - + "b3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e"), - Bytes.fromHexString( - "0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d9388" - + "4d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d" - + "0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc" - + "973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1"), - Bytes.fromHexString( - "000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf49" - + "4c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a" - + "000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e" - + "8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89" - + "0000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2" - + "787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944"), - Bytes.fromHexString( - "00000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46e" - + "aaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1" - + "000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12" - + "dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c" - + "0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5b" - + "bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108" - + "000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596" - + "fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f8187672"), - Bytes.fromHexString( - "00000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196" - + "b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea" - + "000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a9" - + "3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76" - + "000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836" - + "dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c" - + "000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b" - + "7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a" - + "0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd3" - + "94c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a659054") - }; - - final BLS12G2MultiExpPrecompiledContract contract = new BLS12G2MultiExpPrecompiledContract(); - - for (int i = 0; i < args.length; i++) { - final double gasSpent = runBenchmark(args[i], contract); - - System.out.printf( - "G2MULTIEXP %d for %,d gas. Charging %,d gas.%n", - i + 1, (int) gasSpent, contract.gasRequirement(args[i])); - } - } - - public static void benchBLS12Pair() { - final Bytes[] args = { - Bytes.fromHexString( - "0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f56" - + "0000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f" - + "0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624" - + "000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40"), - Bytes.fromHexString( - "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80" - + "000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e" - + "000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834" - + "000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e" - + "000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80" - + "00000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e" - + "000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834" - + "000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e"), - Bytes.fromHexString( - "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6" - + "000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086" - + "000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f" - + "0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce" - + "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6" - + "000000000000000000000000000000000cbcd06a1c576af16d0d77ff8bcc3669a486d044cc7b85db03661a92f4c5c44a28d028521dfcfc292d8ecd05aed6ab940000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086" - + "000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f" - + "0000000000000000000000000000000004c56d3ee9931f7582d7eebeb598d1be208e3b333ab976dc7bb271969fa1d6caf8f467eb7cbee4af5d30e5c66d00a4e2000000000000000000000000000000000de29857dae126c0acbe966da6f50342837ef5dd9994ad929d75814f6f33f77e5b33690945bf6e980031ddd90ebc76ce" - + "00000000000000000000000000000000189bf269a72de2872706983835afcbd09f6f4dfcabe0241b4e9fe1965a250d230d6f793ab17ce7cac456af7be4376be6" - + "000000000000000000000000000000000d4441801d287ba8de0e2fb6b77f766dbff07b4027098ce463cab80e01eb31d9f5dbd7ac935703d68c7032fa5128ff170000000000000000000000000000000011798ea9c137acf6ef9483b489c0273d4f69296959922a352b079857953263372b8d339115f0576cfabedc185abf2086" - + "000000000000000000000000000000001498b1412f52b07a0e4f91cbf5e1852ea38fc111613523f1e61b97ebf1fd7fd2cdf36d7f73f1e33719c0b63d7bf66b8f" - + "00000000000000000000000000000000153ba4ab4fecc724c843b8f78db2db1943e91051b8cb9be2eb7e610a570f1f5925b7981334951b505cce1a3992ff05c9000000000000000000000000000000000c1e79925e9ebfd99e5d11489c56a994e0f855a759f0652cc9bb5151877cfea5c37896f56b949167b9cd2226f14333dd"), - }; - final BLS12PairingPrecompiledContract contract = new BLS12PairingPrecompiledContract(); - - for (int i = 0; i < args.length; i++) { - final double gasSpent = runBenchmark(args[i], contract); - - System.out.printf( - "BLS pairings %d pairs for %,d gas. Charging %,d gas.%n", - i * 2 + 2, (int) gasSpent, contract.gasRequirement(args[i])); - } - } - - private static void benchBLS12MapFPTOG1() { - final Bytes arg = - Bytes.fromHexString( - "0000000000000000000000000000000014406e5bfb9209256a3820879a29ac2f62d6aca82324bf3ae2aa7d3c54792043bd8c791fccdb080c1a52dc68b8b69350"); - - final BLS12MapFpToG1PrecompiledContract contract = new BLS12MapFpToG1PrecompiledContract(); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "MAPFPTOG1 for %,d gas. Charging %,d gas.%n", (int) gasSpent, contract.gasRequirement(arg)); - } - - private static void benchBLS12MapFP2TOG2() { - final Bytes arg = - Bytes.fromHexString( - "0000000000000000000000000000000014406e5bfb9209256a3820879a29ac2f62d6aca82324bf3ae2aa7d3c54792043bd8c791fccdb080c1a52dc68b8b69350000000000000000000000000000000000e885bb33996e12f07da69073e2c0cc880bc8eff26d2a724299eb12d54f4bcf26f4748bb020e80a7e3794a7b0e47a641"); - - final BLS12MapFp2ToG2PrecompiledContract contract = new BLS12MapFp2ToG2PrecompiledContract(); - - final double gasSpent = runBenchmark(arg, contract); - - System.out.printf( - "MAPFP2TOG2 for %,d gas. Charging %,d gas.%n", - (int) gasSpent, contract.gasRequirement(arg)); - } - - // just use the actual arg as the warmup arg. not great for true perf - private static double runBenchmark(final Bytes arg, final PrecompiledContract contract) { - return runBenchmark(arg, arg, contract); - } - private static double runBenchmark(final Bytes warmupArg, final Bytes arg, final PrecompiledContract contract) { - if (contract.computePrecompile(arg, fakeFrame).getOutput() == null) { - throw new RuntimeException("Input is Invalid"); - } - - for (int i = 0; i < MATH_WARMUP; i++) { - contract.computePrecompile(warmupArg, fakeFrame); - } - final Stopwatch timer = Stopwatch.createStarted(); - for (int i = 0; i < MATH_ITERATIONS; i++) { - contract.computePrecompile(arg, fakeFrame); - } - timer.stop(); - - final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; - final double perCall = elapsed / MATH_ITERATIONS; - System.out.printf("\t%s %f seconds, %f ,mgas/sec", - contract.getName(), - elapsed, - (MATH_ITERATIONS * contract.gasRequirement(arg) / 1_000_000d / elapsed)); - return perCall * GAS_PER_SECOND_STANDARD; - } - - public static void main(final String[] args) { - benchBLS12G1MultiExp32Pairs(); - benchBLS12G2MultiExp32Pairs(); - benchSecp256k1Recover(); -// benchSha256(); -// benchKeccak256(); -// benchRipeMD(); -// benchBNADD(); -// benchBNMUL(); -// benchBNPairing(); -// benchModExp(); -// benchBLS12G1Add(); -// benchBLS12G1Mul(); -// benchBLS12G1MultiExp(); -// benchBLS12G2Add(); -// benchBLS12G2Mul(); -// benchBLS12G2MultiExp(); -// benchBLS12Pair(); -// benchBLS12MapFPTOG1(); -// benchBLS12MapFP2TOG2(); - } -} From dcccad520491720ae025f273f17cd8eb080534d4 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Thu, 10 Oct 2024 18:04:24 -0700 Subject: [PATCH 4/6] add the rest of the bls precompiles to the bls12 benchmark subcommand Signed-off-by: garyschulte --- .../evmtool/benchmarks/BLS12Benchmark.java | 352 +++++++++++++++++- 1 file changed, 332 insertions(+), 20 deletions(-) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java index b11e6a60654..818216422d9 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java @@ -21,12 +21,21 @@ import org.hyperledger.besu.evm.precompile.AltBN128AddPrecompiledContract; import org.hyperledger.besu.evm.precompile.AltBN128MulPrecompiledContract; import org.hyperledger.besu.evm.precompile.AltBN128PairingPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1AddPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1MulPrecompiledContract; import org.hyperledger.besu.evm.precompile.BLS12G1MultiExpPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2AddPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2MulPrecompiledContract; import org.hyperledger.besu.evm.precompile.BLS12G2MultiExpPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12MapFp2ToG2PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12MapFpToG1PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12PairingPrecompiledContract; import java.io.PrintStream; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; +import java.util.stream.Collectors; /** Benchmark BLS12-381 G1 and G2 MSM */ public class BLS12Benchmark extends BenchmarkExecutor { @@ -36,6 +45,110 @@ public BLS12Benchmark() { super(MATH_WARMUP, MATH_ITERATIONS); } + static final String[] scalars = { + "4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34", + "7257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede", + "d291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba4", + "b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a4809", + "cdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3", + "d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf0", + "4dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326", + "0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393", + "2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304", + "0b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd", + "1e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc78", + "36b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a04", + "e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf6239932", + "25ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b", + "450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976", + "f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883", + "9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1", + "0978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b", + "387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab1", + "1d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d4287", + "cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b2", + "d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d4", + "7d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed245", + "8d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd", + "f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074", + "b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d", + "11073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c8", + "fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f", + "a558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e", + "9b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c94", + "c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c0", + "8b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080", + }; + + static final String[] g1PointPairs = { + "0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e", + "000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb80", + "0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146d", + "00000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51", + "0000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fd", + "000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4", + "0000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb3", + "000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a", + "000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada", + "000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b81", + "00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb35", + "0000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b60", + "0000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578", + "0000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a30", + "00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b", + "000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82", + "000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f", + "000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac41", + "00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d", + "0000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef649", + "00000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7", + "0000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24", + "00000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e3", + "0000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b2", + "0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583", + "000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435", + "00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f835", + "00000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804", + "00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ece", + "00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb0", + "00000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263", + "0000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe0" }; + + String [] g2PointPairs = { + "000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e", + "00000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a", + "00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294", + "00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e3", + "0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79", + "00000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba7", + "000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b84755", + "000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc0", + "000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb", + "0000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0", + "000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22b", + "000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1", + "0000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c4558181", + "000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29", + "000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e", + "0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f", + "0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064", + "000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad", + "0000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5", + "00000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d", + "00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437b", + "000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89", + "0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296", + "0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f", + "0000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69b", + "000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d", + "0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53", + "000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0", + "00000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368a", + "00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d0", + "0000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921b", + "000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da", + }; + @Override public void runBenchmark( final PrintStream output, final Boolean attemptNative, final String fork) { @@ -55,54 +168,253 @@ public void runBenchmark( return; } + benchmarkG1Add(output); + benchmarkG1Mul(output); benchmarkG1MultiExp32Pairs(output); + benchmarkMapFpToG1(output); + benchmarkG2Add(output); + benchmarkG2Mul(output); benchmarkG2MultiExp32Pairs(output); + benchmarkMapFp2ToG2(output); + benchmarkBlsPairing(output); + } + + private void benchmarkG1Add( + final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length -1; i++) { + testCases.put( + "G1 Add " + i, + Bytes.fromHexString(g1PointPairs[i] + g1PointPairs[i+1])); + } + + BLS12G1AddPrecompiledContract g1addContract = new BLS12G1AddPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G1 Add %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + + private void benchmarkG1Mul( + final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length; i++) { + testCases.put( + "G1 Mul " + i, + Bytes.fromHexString(g1PointPairs[i] + scalars[i])); + } + + BLS12G1MulPrecompiledContract g1addContract = new BLS12G1MulPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G1 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } private void benchmarkG1MultiExp32Pairs( final PrintStream output) { - final Map addTestCases = new LinkedHashMap<>(); - addTestCases.put( - "G1 MSM", - Bytes.fromHexString("0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb807257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146dd291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba400000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a48090000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fdcdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf00000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb34dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b810b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb351e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc780000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b6036b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a040000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf62399320000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a3025ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac410978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab10000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef6491d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d428700000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b20000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d400000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e37d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed2450000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b28d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f83511073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c800000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ecea558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb09b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c9400000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c00000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe08b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080")); + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1 ; i <= 5 ; i++) { + StringBuilder g1msmPairs= new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + g1msmPairs.append(g1PointPairs[j]).append(scalars[j]); + } + testCases.put( + "G1 MSM, " + (1 << i) + " pairs", + Bytes.fromHexString(g1msmPairs.toString())); + } BLS12G1MultiExpPrecompiledContract g1msmContract = new BLS12G1MultiExpPrecompiledContract(); - warmup = MATH_WARMUP / addTestCases.size(); - iterations = MATH_ITERATIONS / addTestCases.size(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); double execTime = Double.MIN_VALUE; // a way to dodge divide by zero long gasCost = 0; - for (final Map.Entry testCase : addTestCases.entrySet()) { + for (final Map.Entry testCase : testCases.entrySet()) { execTime += runPrecompileBenchmark(testCase.getValue(), g1msmContract); gasCost += g1msmContract.gasRequirement(testCase.getValue()); } - execTime /= addTestCases.size(); - gasCost /= addTestCases.size(); output.printf( - "Bls12 G1 MSM %,6d gas @%,7.1f µs /%,8.1f MGps%n", + "Bls12 G1 MSM %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkMapFpToG1( + final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length; i++) { + testCases.put( + "Map Fp to G1 " + i, + Bytes.fromHexString(g1PointPairs[i].substring(0, 128))); + } + + BLS12MapFpToG1PrecompiledContract g1MapFpToG1Contract = new BLS12MapFpToG1PrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1MapFpToG1Contract); + gasCost += g1MapFpToG1Contract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 MapFpToG1 %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2Add( + final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length -1; i++) { + testCases.put( + "G2 Add " + i, + Bytes.fromHexString(g2PointPairs[i] + g2PointPairs[i+1])); + } + + BLS12G2AddPrecompiledContract g1addContract = new BLS12G2AddPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G2 Add %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2Mul( + final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length; i++) { + testCases.put( + "G2 Mul " + i, + Bytes.fromHexString(g2PointPairs[i] + scalars[i])); + } + + BLS12G2MulPrecompiledContract g1addContract = new BLS12G2MulPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G2 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } private void benchmarkG2MultiExp32Pairs( final PrintStream output) { - final Map addTestCases = new LinkedHashMap<>(); - addTestCases.put( - "G2 MSM", - Bytes.fromHexString("000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e01400b97e1211ea91ba027896f711b96062118bcfa5515c7880679b5849e545000000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a9808c85140e6eca6cfd8510261183d479a443f0629e33dc470c3f7d930c2defa00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294533aae2894034cc6c5278a4bd4daec46e6c08e7fdd6550fe1fa6e2d4d1adf57b00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e331fb26e72247c9cb76eb258094d3fcc9a294180d4106ee3930d0a3fb519b65ee0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79dc6516d7a44f93eebf1bc1fc084c7d0e9b92b3f5be754df31be1b8d8a3415c8100000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba74b614fd3f867cf44fce6e2b91427dbed22190091891b6c02973ca1a5cef6a35d000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b847556700fa1fdfe4e101eb1fb436608a377eb8f4a49a0e99a4d208a19b830967dd65000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc003a8881d042f3242a48d781773832f2d7d93314b215643a23abbdb5e8b7d9a15000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb3febc1ada758ad9a5ab3e93b8a40813c79abfc88abe7e53c94462a36fbac41c80000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0bff7a5e41be99c4d598551e42492169cf09083886c5abfccaab6a064840e6176000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22bc44b57817b2848936bae5cb561ee0d4a71bf32c1f7d39f1e28b849a8b41b5a5d000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1c151847b7b5854158831995014961865238cfe36fd2ee66b26ae013a52c5a6100000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c45581819385fc49c771164342eb70a34b88629a93a4a73fd947b01184803cbb91f49f2b000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29abd7987f7a0e32086552fdff94c5e8791ef142e6a4285ae0f02f1ea7805b52b0000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e0d896153b7293f871e7d1dd50a18ec88a117acc95a95185799f2521b9aa137ef0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f7ee8ca85ad1e179596c12492061c3489a3ea4684e290d50f8ed310320c89678e0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064254f8b95a217dc00f0e069b2fcfbe9acd684642aa0dc754c9520e700d9e1ea28000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad175e4a25b77e39aef40131e0dc7548a7a8d11cfba650aa88a6007622d5a904790000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5de1cff4f165f49342d6e7ffea6aa2199d7af7290c13403b44abcdd56f168b88300000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d4e50f2ac7deaeaf1a85fbfdbd822984eb091eb07d855001c390f88ad0ba96a6f00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437bb836f0c479fbb44d5981c113546ea36e434945eee7b8681790aaac1e776f2405000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89a7d6b59c8a696805893be4249e4fe58609d3608f6dd63b6d8f335a45919da39e0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296026563275db4f9b8b4db071ecde75ae98de14ca3929a6e4a9b992a6743c5254a0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f8fe0d4e218c204ff3db6c9e0e428c9d851ad90c3f126f345d1cbd0aff255bb220000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69bf5b0a443239846ac6afec05fa2a1cc3b102499fa2cbb54d07a1c0920733021ad000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d5cd219b7cf86550b75ca2e2195b00565be311dde9404d9a9207dadd55fa5740c0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53864630c026cf0e096af5910ecc7bcd105febd2544df3a232fee6df97281335dc000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0168acab37c5e0c6b1f12a58e0da2cf9807608cb95ff410189ef552f5fd25c12500000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368ae900998d5e03a6134f6a73872e7788e94216888aec7a98ad72c3db9d090c1bfc00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d057a95d3f2326dba2cf0949f743d407d3027459d796ae89d93fc1cac19fd93b170000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921bef9dbe0487b733954d8ee50ad812774474437436f4630927d61f82f1e46f4151000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da9d2e89d33fa35cb41e398bf41ef89dde8948c75edef997e60ebee61515b542fa")); + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1 ; i <= 5 ; i++) { + StringBuilder g2msmPairs= new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + g2msmPairs.append(g2PointPairs[j]).append(scalars[j]); + } + testCases.put( + "G2 MSM, " + (1 << i) + " pairs", + Bytes.fromHexString(g2msmPairs.toString())); + } BLS12G2MultiExpPrecompiledContract g2msmContract = new BLS12G2MultiExpPrecompiledContract(); - warmup = MATH_WARMUP / addTestCases.size(); - iterations = MATH_ITERATIONS / addTestCases.size(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); double execTime = Double.MIN_VALUE; // a way to dodge divide by zero long gasCost = 0; - for (final Map.Entry testCase : addTestCases.entrySet()) { + for (final Map.Entry testCase : testCases.entrySet()) { execTime += runPrecompileBenchmark(testCase.getValue(), g2msmContract); gasCost += g2msmContract.gasRequirement(testCase.getValue()); } - execTime /= addTestCases.size(); - gasCost /= addTestCases.size(); output.printf( - "Bls12 G2 MSM %,6d gas @%,7.1f µs /%,8.1f MGps%n", + "Bls12 G2 MSM %,9d total gas @%,7.1f µs /%,8.1f MGps%n", gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } + private void benchmarkMapFp2ToG2( + final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length; i++) { + testCases.put( + "Map Fp2 to G2 " + i, + Bytes.fromHexString(g2PointPairs[i].substring(0, 256))); + } + + BLS12MapFp2ToG2PrecompiledContract g1MapFp2ToG2Contract = new BLS12MapFp2ToG2PrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1MapFp2ToG2Contract); + gasCost += g1MapFp2ToG2Contract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 MapFp2G1 %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkBlsPairing( + final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1 ; i <= 5 ; i++) { + StringBuilder pairs= new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + pairs.append(g1PointPairs[j]).append(g2PointPairs[j]); + } + testCases.put( + "BLS Pairing, " + (1 << i) + " pairs", + Bytes.fromHexString(pairs.toString())); + } + + BLS12PairingPrecompiledContract blsPairingContract = new BLS12PairingPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), blsPairingContract); + gasCost += blsPairingContract.gasRequirement(testCase.getValue()); + } + + output.printf( + "Bls12 Pairing %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } } From d8e0d97dc60fa325b2953d4d3f54773ab83b92aa Mon Sep 17 00:00:00 2001 From: garyschulte Date: Thu, 10 Oct 2024 18:07:50 -0700 Subject: [PATCH 5/6] remove local testing tweaks Signed-off-by: garyschulte --- build.gradle | 2 -- gradle.properties | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index c6c9dc8669b..23908ad984f 100644 --- a/build.gradle +++ b/build.gradle @@ -166,8 +166,6 @@ allprojects { content { includeGroupByRegex('com\\.splunk\\..*') } } - mavenLocal() - mavenCentral() // ethereum execution spec tests fixtures. Exclusively for ethereum submodule to run ref tests diff --git a/gradle.properties b/gradle.properties index a8b2e95a2af..2a983e1d80e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.welcome=never # Optional - set custom build version # version=24.5.6-acme # versionappendcommit=true -org.gradle.dependency.verification=lenient +#org.gradle.dependency.verification=lenient # Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396) From f335cefc4eaeabfc117bfc1c02d9bfa6c397010f Mon Sep 17 00:00:00 2001 From: garyschulte Date: Thu, 10 Oct 2024 18:37:13 -0700 Subject: [PATCH 6/6] spotless Signed-off-by: garyschulte --- .../evmtool/benchmarks/BLS12Benchmark.java | 292 ++++++++---------- .../AbstractBLS12PrecompiledContract.java | 2 - 2 files changed, 131 insertions(+), 163 deletions(-) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java index 818216422d9..a95f48c0dfb 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java @@ -14,13 +14,8 @@ */ package org.hyperledger.besu.evmtool.benchmarks; -import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.evm.EvmSpecVersion; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.precompile.AbstractBLS12PrecompiledContract; -import org.hyperledger.besu.evm.precompile.AltBN128AddPrecompiledContract; -import org.hyperledger.besu.evm.precompile.AltBN128MulPrecompiledContract; -import org.hyperledger.besu.evm.precompile.AltBN128PairingPrecompiledContract; import org.hyperledger.besu.evm.precompile.BLS12G1AddPrecompiledContract; import org.hyperledger.besu.evm.precompile.BLS12G1MulPrecompiledContract; import org.hyperledger.besu.evm.precompile.BLS12G1MultiExpPrecompiledContract; @@ -32,10 +27,10 @@ import org.hyperledger.besu.evm.precompile.BLS12PairingPrecompiledContract; import java.io.PrintStream; -import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; -import java.util.stream.Collectors; + +import org.apache.tuweni.bytes.Bytes; /** Benchmark BLS12-381 G1 and G2 MSM */ public class BLS12Benchmark extends BenchmarkExecutor { @@ -46,107 +41,108 @@ public BLS12Benchmark() { } static final String[] scalars = { - "4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34", - "7257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede", - "d291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba4", - "b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a4809", - "cdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3", - "d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf0", - "4dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326", - "0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393", - "2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304", - "0b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd", - "1e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc78", - "36b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a04", - "e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf6239932", - "25ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b", - "450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976", - "f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883", - "9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1", - "0978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b", - "387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab1", - "1d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d4287", - "cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b2", - "d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d4", - "7d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed245", - "8d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd", - "f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074", - "b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d", - "11073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c8", - "fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f", - "a558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e", - "9b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c94", - "c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c0", - "8b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080", + "4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34", + "7257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede", + "d291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba4", + "b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a4809", + "cdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3", + "d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf0", + "4dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326", + "0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393", + "2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304", + "0b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd", + "1e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc78", + "36b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a04", + "e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf6239932", + "25ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b", + "450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976", + "f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883", + "9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1", + "0978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b", + "387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab1", + "1d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d4287", + "cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b2", + "d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d4", + "7d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed245", + "8d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd", + "f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074", + "b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d", + "11073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c8", + "fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f", + "a558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e", + "9b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c94", + "c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c0", + "8b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080", }; static final String[] g1PointPairs = { - "0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e", - "000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb80", - "0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146d", - "00000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51", - "0000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fd", - "000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4", - "0000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb3", - "000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a", - "000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada", - "000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b81", - "00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb35", - "0000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b60", - "0000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578", - "0000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a30", - "00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b", - "000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82", - "000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f", - "000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac41", - "00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d", - "0000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef649", - "00000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7", - "0000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24", - "00000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e3", - "0000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b2", - "0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583", - "000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435", - "00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f835", - "00000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804", - "00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ece", - "00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb0", - "00000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263", - "0000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe0" }; - - String [] g2PointPairs = { - "000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e", - "00000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a", - "00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294", - "00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e3", - "0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79", - "00000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba7", - "000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b84755", - "000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc0", - "000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb", - "0000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0", - "000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22b", - "000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1", - "0000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c4558181", - "000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29", - "000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e", - "0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f", - "0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064", - "000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad", - "0000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5", - "00000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d", - "00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437b", - "000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89", - "0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296", - "0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f", - "0000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69b", - "000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d", - "0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53", - "000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0", - "00000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368a", - "00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d0", - "0000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921b", - "000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da", + "0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e", + "000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb80", + "0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146d", + "00000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51", + "0000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fd", + "000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4", + "0000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb3", + "000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a", + "000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada", + "000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b81", + "00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb35", + "0000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b60", + "0000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578", + "0000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a30", + "00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b", + "000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82", + "000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f", + "000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac41", + "00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d", + "0000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef649", + "00000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7", + "0000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24", + "00000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e3", + "0000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b2", + "0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583", + "000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435", + "00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f835", + "00000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804", + "00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ece", + "00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb0", + "00000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263", + "0000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe0" + }; + + String[] g2PointPairs = { + "000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e", + "00000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a", + "00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294", + "00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e3", + "0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79", + "00000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba7", + "000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b84755", + "000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc0", + "000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb", + "0000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0", + "000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22b", + "000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1", + "0000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c4558181", + "000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29", + "000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e", + "0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f", + "0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064", + "000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad", + "0000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5", + "00000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d", + "00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437b", + "000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89", + "0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296", + "0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f", + "0000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69b", + "000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d", + "0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53", + "000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0", + "00000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368a", + "00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d0", + "0000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921b", + "000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da", }; @Override @@ -161,7 +157,8 @@ public void runBenchmark( } if (!AbstractBLS12PrecompiledContract.isAvailable()) { - output.printf("BLS12-381 not available on this platform %s %s %s\n", + output.printf( + "BLS12-381 not available on this platform %s %s %s\n", System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")); @@ -179,13 +176,10 @@ public void runBenchmark( benchmarkBlsPairing(output); } - private void benchmarkG1Add( - final PrintStream output) { + private void benchmarkG1Add(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); - for (int i = 0; i < g1PointPairs.length -1; i++) { - testCases.put( - "G1 Add " + i, - Bytes.fromHexString(g1PointPairs[i] + g1PointPairs[i+1])); + for (int i = 0; i < g1PointPairs.length - 1; i++) { + testCases.put("G1 Add " + i, Bytes.fromHexString(g1PointPairs[i] + g1PointPairs[i + 1])); } BLS12G1AddPrecompiledContract g1addContract = new BLS12G1AddPrecompiledContract(); @@ -204,14 +198,10 @@ private void benchmarkG1Add( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - - private void benchmarkG1Mul( - final PrintStream output) { + private void benchmarkG1Mul(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); for (int i = 0; i < g1PointPairs.length; i++) { - testCases.put( - "G1 Mul " + i, - Bytes.fromHexString(g1PointPairs[i] + scalars[i])); + testCases.put("G1 Mul " + i, Bytes.fromHexString(g1PointPairs[i] + scalars[i])); } BLS12G1MulPrecompiledContract g1addContract = new BLS12G1MulPrecompiledContract(); @@ -230,19 +220,16 @@ private void benchmarkG1Mul( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - private void benchmarkG1MultiExp32Pairs( - final PrintStream output) { + private void benchmarkG1MultiExp32Pairs(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs - for (int i = 1 ; i <= 5 ; i++) { - StringBuilder g1msmPairs= new StringBuilder(); + for (int i = 1; i <= 5; i++) { + StringBuilder g1msmPairs = new StringBuilder(); for (int j = 0; j < 1 << i; j++) { g1msmPairs.append(g1PointPairs[j]).append(scalars[j]); } - testCases.put( - "G1 MSM, " + (1 << i) + " pairs", - Bytes.fromHexString(g1msmPairs.toString())); + testCases.put("G1 MSM, " + (1 << i) + " pairs", Bytes.fromHexString(g1msmPairs.toString())); } BLS12G1MultiExpPrecompiledContract g1msmContract = new BLS12G1MultiExpPrecompiledContract(); @@ -259,13 +246,10 @@ private void benchmarkG1MultiExp32Pairs( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - private void benchmarkMapFpToG1( - final PrintStream output) { + private void benchmarkMapFpToG1(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); for (int i = 0; i < g1PointPairs.length; i++) { - testCases.put( - "Map Fp to G1 " + i, - Bytes.fromHexString(g1PointPairs[i].substring(0, 128))); + testCases.put("Map Fp to G1 " + i, Bytes.fromHexString(g1PointPairs[i].substring(0, 128))); } BLS12MapFpToG1PrecompiledContract g1MapFpToG1Contract = new BLS12MapFpToG1PrecompiledContract(); @@ -284,13 +268,10 @@ private void benchmarkMapFpToG1( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - private void benchmarkG2Add( - final PrintStream output) { + private void benchmarkG2Add(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); - for (int i = 0; i < g2PointPairs.length -1; i++) { - testCases.put( - "G2 Add " + i, - Bytes.fromHexString(g2PointPairs[i] + g2PointPairs[i+1])); + for (int i = 0; i < g2PointPairs.length - 1; i++) { + testCases.put("G2 Add " + i, Bytes.fromHexString(g2PointPairs[i] + g2PointPairs[i + 1])); } BLS12G2AddPrecompiledContract g1addContract = new BLS12G2AddPrecompiledContract(); @@ -309,13 +290,10 @@ private void benchmarkG2Add( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - private void benchmarkG2Mul( - final PrintStream output) { + private void benchmarkG2Mul(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); for (int i = 0; i < g2PointPairs.length; i++) { - testCases.put( - "G2 Mul " + i, - Bytes.fromHexString(g2PointPairs[i] + scalars[i])); + testCases.put("G2 Mul " + i, Bytes.fromHexString(g2PointPairs[i] + scalars[i])); } BLS12G2MulPrecompiledContract g1addContract = new BLS12G2MulPrecompiledContract(); @@ -334,19 +312,16 @@ private void benchmarkG2Mul( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - private void benchmarkG2MultiExp32Pairs( - final PrintStream output) { + private void benchmarkG2MultiExp32Pairs(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs - for (int i = 1 ; i <= 5 ; i++) { - StringBuilder g2msmPairs= new StringBuilder(); + for (int i = 1; i <= 5; i++) { + StringBuilder g2msmPairs = new StringBuilder(); for (int j = 0; j < 1 << i; j++) { g2msmPairs.append(g2PointPairs[j]).append(scalars[j]); } - testCases.put( - "G2 MSM, " + (1 << i) + " pairs", - Bytes.fromHexString(g2msmPairs.toString())); + testCases.put("G2 MSM, " + (1 << i) + " pairs", Bytes.fromHexString(g2msmPairs.toString())); } BLS12G2MultiExpPrecompiledContract g2msmContract = new BLS12G2MultiExpPrecompiledContract(); @@ -363,16 +338,14 @@ private void benchmarkG2MultiExp32Pairs( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - private void benchmarkMapFp2ToG2( - final PrintStream output) { + private void benchmarkMapFp2ToG2(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); for (int i = 0; i < g2PointPairs.length; i++) { - testCases.put( - "Map Fp2 to G2 " + i, - Bytes.fromHexString(g2PointPairs[i].substring(0, 256))); + testCases.put("Map Fp2 to G2 " + i, Bytes.fromHexString(g2PointPairs[i].substring(0, 256))); } - BLS12MapFp2ToG2PrecompiledContract g1MapFp2ToG2Contract = new BLS12MapFp2ToG2PrecompiledContract(); + BLS12MapFp2ToG2PrecompiledContract g1MapFp2ToG2Contract = + new BLS12MapFp2ToG2PrecompiledContract(); warmup = MATH_WARMUP / testCases.size(); iterations = MATH_ITERATIONS / testCases.size(); double execTime = Double.MIN_VALUE; // a way to dodge divide by zero @@ -388,19 +361,16 @@ private void benchmarkMapFp2ToG2( gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); } - private void benchmarkBlsPairing( - final PrintStream output) { + private void benchmarkBlsPairing(final PrintStream output) { final Map testCases = new LinkedHashMap<>(); // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs - for (int i = 1 ; i <= 5 ; i++) { - StringBuilder pairs= new StringBuilder(); + for (int i = 1; i <= 5; i++) { + StringBuilder pairs = new StringBuilder(); for (int j = 0; j < 1 << i; j++) { pairs.append(g1PointPairs[j]).append(g2PointPairs[j]); } - testCases.put( - "BLS Pairing, " + (1 << i) + " pairs", - Bytes.fromHexString(pairs.toString())); + testCases.put("BLS Pairing, " + (1 << i) + " pairs", Bytes.fromHexString(pairs.toString())); } BLS12PairingPrecompiledContract blsPairingContract = new BLS12PairingPrecompiledContract(); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java index ad1e30bdca4..3f0f5bc4cc2 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import java.util.Optional; @@ -82,7 +81,6 @@ public static boolean isAvailable() { return false; } - @Override public String getName() { return name;