UNPKG

@polygon-hermez/vm

Version:
91 lines 3.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ethereumjs_util_1 = require("ethereumjs-util"); const evm_1 = require("../evm"); const exceptions_1 = require("../../exceptions"); const assert = require('assert'); const { BLS12_381_ToG1Point, BLS12_381_ToG2Point } = require('./util/bls12_381'); const zeroBuffer = Buffer.alloc(32, 0); const oneBuffer = Buffer.concat([Buffer.alloc(31, 0), Buffer.from('01', 'hex')]); async function default_1(opts) { assert(opts.data); const mcl = opts._VM._mcl; const inputData = opts.data; const baseGas = new ethereumjs_util_1.BN(opts._common.paramByEIP('gasPrices', 'Bls12381PairingBaseGas', 2537)); if (inputData.length == 0) { return (0, evm_1.VmErrorResult)(new exceptions_1.VmError(exceptions_1.ERROR.BLS_12_381_INPUT_EMPTY), opts.gasLimit); } const gasUsedPerPair = new ethereumjs_util_1.BN(opts._common.paramByEIP('gasPrices', 'Bls12381PairingPerPairGas', 2537)); const gasUsed = baseGas.iadd(gasUsedPerPair.imul(new ethereumjs_util_1.BN(Math.floor(inputData.length / 384)))); if (inputData.length % 384 != 0) { return (0, evm_1.VmErrorResult)(new exceptions_1.VmError(exceptions_1.ERROR.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit); } if (opts.gasLimit.lt(gasUsed)) { return (0, evm_1.OOGResult)(opts.gasLimit); } // prepare pairing list and check for mandatory zero bytes const pairs = []; const zeroBytes16 = Buffer.alloc(16, 0); const zeroByteCheck = [ [0, 16], [64, 80], [128, 144], [192, 208], [256, 272], [320, 336], ]; for (let k = 0; k < inputData.length / 384; k++) { // zero bytes check const pairStart = 384 * k; for (const index in zeroByteCheck) { const slicedBuffer = opts.data.slice(zeroByteCheck[index][0] + pairStart, zeroByteCheck[index][1] + pairStart); if (!slicedBuffer.equals(zeroBytes16)) { return (0, evm_1.VmErrorResult)(new exceptions_1.VmError(exceptions_1.ERROR.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit); } } let G1; try { G1 = BLS12_381_ToG1Point(opts.data.slice(pairStart, pairStart + 128), mcl); } catch (e) { return (0, evm_1.VmErrorResult)(e, opts.gasLimit); } const g2start = pairStart + 128; let G2; try { G2 = BLS12_381_ToG2Point(opts.data.slice(g2start, g2start + 256), mcl); } catch (e) { return (0, evm_1.VmErrorResult)(e, opts.gasLimit); } pairs.push([G1, G2]); } // run the pairing check // reference (Nethermind): https://github.com/NethermindEth/nethermind/blob/374b036414722b9c8ad27e93d64840b8f63931b9/src/Nethermind/Nethermind.Evm/Precompiles/Bls/Mcl/PairingPrecompile.cs#L93 let GT; for (let index = 0; index < pairs.length; index++) { const pair = pairs[index]; const G1 = pair[0]; const G2 = pair[1]; if (index == 0) { GT = mcl.millerLoop(G1, G2); } else { GT = mcl.mul(GT, mcl.millerLoop(G1, G2)); } } GT = mcl.finalExp(GT); let returnValue; if (GT.isOne()) { returnValue = oneBuffer; } else { returnValue = zeroBuffer; } return { gasUsed, returnValue: returnValue, }; } exports.default = default_1; //# sourceMappingURL=10-bls12-pairing.js.map