From 38563a2f69ece5d924f349f5d7c49621a65a6fb4 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Tue, 2 Jul 2024 11:11:18 +0200 Subject: [PATCH] Add some util function code docs --- .../evm/src/precompiles/bls12_381/util.ts | 55 +++++++++++++++++++ packages/evm/src/types.ts | 12 +++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/packages/evm/src/precompiles/bls12_381/util.ts b/packages/evm/src/precompiles/bls12_381/util.ts index 78baa99ec0f..9ee9d92a181 100644 --- a/packages/evm/src/precompiles/bls12_381/util.ts +++ b/packages/evm/src/precompiles/bls12_381/util.ts @@ -6,6 +6,14 @@ import type { PrecompileInput } from '../types' const ZERO_BYTES_16 = new Uint8Array(16) +/** + * Checks that the gas used remain under the gas limit. + * + * @param opts + * @param gasUsed + * @param pName + * @returns + */ export const gasCheck = (opts: PrecompileInput, gasUsed: bigint, pName: string) => { if (opts._debug !== undefined) { opts._debug( @@ -23,6 +31,14 @@ export const gasCheck = (opts: PrecompileInput, gasUsed: bigint, pName: string) return true } +/** + * Calculates the gas used for the MSM precompiles based on the number of pairs and + * calculating in some discount in relation to the number of pairs. + * + * @param numPairs + * @param gasUsedPerPair + * @returns + */ export const msmGasUsed = (numPairs: number, gasUsedPerPair: bigint) => { const gasDiscountMax = BLS_GAS_DISCOUNT_PAIRS[BLS_GAS_DISCOUNT_PAIRS.length - 1][1] let gasDiscountMultiplier @@ -40,6 +56,14 @@ export const msmGasUsed = (numPairs: number, gasUsedPerPair: bigint) => { return (BigInt(numPairs) * gasUsedPerPair * BigInt(gasDiscountMultiplier)) / BigInt(1000) } +/** + * Checks that the length of the provided data is equal to `length`. + * + * @param opts + * @param length + * @param pName + * @returns + */ export const equalityLengthCheck = (opts: PrecompileInput, length: number, pName: string) => { if (opts.data.length !== length) { if (opts._debug !== undefined) { @@ -52,6 +76,15 @@ export const equalityLengthCheck = (opts: PrecompileInput, length: number, pName return true } +/** + * Checks that the total length of the provided data input can be subdivided into k equal parts + * with `length` (without leaving some remainder bytes). + * + * @param opts + * @param length + * @param pName + * @returns + */ export const moduloLengthCheck = (opts: PrecompileInput, length: number, pName: string) => { if (opts.data.length % length !== 0) { if (opts._debug !== undefined) { @@ -64,6 +97,28 @@ export const moduloLengthCheck = (opts: PrecompileInput, length: number, pName: return true } +/** + * BLS-specific zero check to check that the top 16 bytes of a 64 byte field element provided + * are always zero (see EIP notes on field element encoding). + * + * Zero byte ranges are expected to be passed in the following format (and so each referencing + * 16-byte ranges): + * + * ```ts + * const zeroByteRanges = [ + * [0, 16], + * [64, 80], + * [128, 144] + * + * ] + * ``` + * + * @param opts + * @param zeroByteRanges + * @param pName + * @param pairStart + * @returns + */ export const zeroByteCheck = ( opts: PrecompileInput, zeroByteRanges: number[][], diff --git a/packages/evm/src/types.ts b/packages/evm/src/types.ts index 3177e7f232d..8c3f0d5e6ba 100644 --- a/packages/evm/src/types.ts +++ b/packages/evm/src/types.ts @@ -266,9 +266,15 @@ export interface EVMOpts { * to the `EVMBLSInterface` specification. * * An interface for the MCL WASM implementation https://github.com/herumi/mcl-wasm - * is shipped with this library, see the following test file for an example on - * how to use: - * https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/evm/test/precompiles/eip-2537-bls.spec.ts + * is shipped with this library which can be used as follows (with `mcl-wasm` being + * explicitly added to the set of dependencies): + * + * ```ts + * import * as mcl from 'mcl-wasm' + * + * await mcl.init(mcl.BLS12_381) + * const evm = await EVM.create({ mcl: new MCLBLS(mcl) }) + * ``` */ bls?: EVMBLSInterface