Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-2537 - BLS12-381 precompiles for the EVM #368

Merged
merged 27 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2aed92e
eip2537: initial metering
mratsim Apr 1, 2024
c3b720c
eip2537: improve markdown reporting
mratsim Apr 1, 2024
65316b2
eip2537: iterate on reporting
mratsim Apr 1, 2024
e919c38
eip2537: iterate on reporting 2
mratsim Apr 1, 2024
c1c64eb
eip2537: fix constant-time scalar mul
mratsim Apr 1, 2024
b8ef636
eip2537: add projective coordinates
mratsim Apr 1, 2024
3227e0c
eip2537: more comprehensive metering
mratsim Apr 1, 2024
834bc2b
eip2537: use Clang and also add benchmarks
mratsim Apr 1, 2024
51003bd
eip2537: fix bench table
mratsim Apr 1, 2024
b58c24e
eip2537: add pic
mratsim Apr 1, 2024
3b810ef
eip2537: add vartime benches
mratsim Apr 1, 2024
110140b
eip2537: benches for rollcall and https://ethereum-magicians.org/t/ei…
mratsim Apr 10, 2024
80366e6
eip2537: create bench with subgroup checks
mratsim Apr 10, 2024
ec864eb
eip2537: fix import of MSM on G2 - frobenius endomorphism
mratsim Apr 10, 2024
3590439
commit subgroup check benches from https://github.com/mratsim/constan…
mratsim Apr 27, 2024
522ad03
EVM: move modexp precompiles above the rest of elliptic precompiles
mratsim Apr 27, 2024
5301601
EVM: implement BLS12381_G1ADD and BLS12381_G2ADD
mratsim Apr 27, 2024
5755f72
eip2537: bn254 tests properly call renamed procedure
mratsim Apr 30, 2024
d732e47
EVM: implement BLS12381_G1MUL and BLS12381_G2MUL
mratsim Apr 30, 2024
0cf1e9d
EVM: implement BLS12381_G1MSM and BLS12381_G2MSM
mratsim Apr 30, 2024
b968756
EVM: Pass geth and EIP-2537 precompiles test suite
mratsim Apr 30, 2024
4acf9d7
MSM: fix types for field coefficients
mratsim Apr 30, 2024
f64b48f
EVM: implement map to field and pass all tests
mratsim Apr 30, 2024
228e706
bench: consistent use of eth prefix for Ethereum benches
mratsim May 1, 2024
4272438
EVM: add precompiles benchmark
mratsim May 1, 2024
3199d6a
EVM: add BLS12 pairings
mratsim May 1, 2024
c89118f
EVM: fix bench bls sig
mratsim May 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions benchmarks/bench_ec_g2_scalar_mul.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ import
ec_shortweierstrass_projective,
ec_shortweierstrass_jacobian],
# Helpers
./bench_elliptic_template,
# Standard library
std/strutils
./bench_elliptic_template

# ############################################################
#
Expand All @@ -29,7 +27,7 @@ import


const Iters = 10_000
const MulIters = 500
const MulIters = 100
const AvailableCurves = [
# P224,
BN254_Nogami,
Expand Down
50 changes: 50 additions & 0 deletions benchmarks/bench_ec_msm_bls12_381_g2.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Constantine
# Copyright (c) 2018-2019 Status Research & Development GmbH
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.

import
# Internals
../constantine/math/config/curves,
../constantine/math/extension_fields,
../constantine/math/elliptic/[
ec_shortweierstrass_projective,
ec_shortweierstrass_jacobian],
# Helpers
../helpers/prng_unsafe,
./bench_elliptic_parallel_template

# ############################################################
#
# Benchmark of the G1 group of
# Short Weierstrass elliptic curves
# in (homogeneous) projective coordinates
#
# ############################################################


const Iters = 10_000
const AvailableCurves = [
BLS12_381,
]

# const testNumPoints = [10, 100, 1000, 10000, 100000]
const testNumPoints = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]

proc main() =
separator()
staticFor i, 0, AvailableCurves.len:
const curve = AvailableCurves[i]
var ctx = createBenchMsmContext(ECP_ShortW_Jac[Fp2[curve], G2], testNumPoints)
separator()
for numPoints in testNumPoints:
let batchIters = max(1, Iters div numPoints)
ctx.msmParallelBench(numPoints, batchIters)
separator()
separator()

main()
notes()
32 changes: 28 additions & 4 deletions benchmarks/bench_elliptic_template.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ macro fixEllipticDisplay(EC: typedesc): untyped =
var name = $instantiated[1][0] # EllipticEquationFormCoordinates
let fieldName = $instantiated[1][1][0]
let curveName = $Curve(instantiated[1][1][1].intVal)
name.add "[" & fieldName & "[" & curveName & "]]"
name.add "[" &
fieldName & "[" & curveName & "]" &
(if family(Curve(instantiated[1][1][1].intVal)) != NoFamily:
", " & $Subgroup(instantiated[1][2].intVal)
else: "") &
"]"
result = newLit name

proc report(op, elliptic: string, start, stop: MonoTime, startClk, stopClk: int64, iters: int) =
Expand Down Expand Up @@ -155,7 +160,7 @@ proc scalarMulGenericBench*(EC: typedesc, bits, window: static int, iters: int)

let exponent = rng.random_unsafe(BigInt[bits])

bench("EC ScalarMul " & $bits & "-bit " & $EC.G & " (window-" & $window & ", generic)", EC, iters):
bench("EC ScalarMul " & $bits & "-bit " & $EC.G & " (window-" & $window & ", constant-time)", EC, iters):
r = P
r.scalarMulGeneric(exponent, window)

Expand All @@ -166,7 +171,7 @@ proc scalarMulEndo*(EC: typedesc, bits: static int, iters: int) =

let exponent = rng.random_unsafe(BigInt[bits])

bench("EC ScalarMul " & $bits & "-bit " & $EC.G & " (endomorphism accelerated)", EC, iters):
bench("EC ScalarMul " & $bits & "-bit " & $EC.G & " (constant-time, endomorphism)", EC, iters):
r = P
r.scalarMulEndo(exponent)

Expand All @@ -177,7 +182,7 @@ proc scalarMulEndoWindow*(EC: typedesc, bits: static int, iters: int) =

let exponent = rng.random_unsafe(BigInt[bits])

bench("EC ScalarMul " & $bits & "-bit " & $EC.G & " (window-2, endomorphism accelerated)", EC, iters):
bench("EC ScalarMul " & $bits & "-bit " & $EC.G & " (constant-time, window-2, endomorphism)", EC, iters):
r = P
when EC.F is Fp:
r.scalarMulGLV_m2w2(exponent)
Expand Down Expand Up @@ -228,6 +233,25 @@ proc scalarMulVartimeEndoWNAFBench*(EC: typedesc, bits, window: static int, iter
r = P
r.scalarMulEndo_minHammingWeight_windowed_vartime(exponent, window)

proc subgroupCheckBench*(EC: typedesc, iters: int) =
var P = rng.random_unsafe(EC)
P.clearCofactor()

bench("Subgroup check", EC, iters):
discard P.isInSubgroup()

proc subgroupCheckScalarMulVartimeEndoWNAFBench*(EC: typedesc, bits, window: static int, iters: int) =
var r {.noInit.}: EC
var P = rng.random_unsafe(EC)
P.clearCofactor()

let exponent = rng.random_unsafe(BigInt[bits])

bench("EC subgroup check + ScalarMul " & $bits & "-bit " & $EC.G & " (vartime endo + wNAF-" & $window & ")", EC, iters):
r = P
discard r.isInSubgroup()
r.scalarMulEndo_minHammingWeight_windowed_vartime(exponent, window)

proc multiAddBench*(EC: typedesc, numPoints: int, useBatching: bool, iters: int) =
var points = newSeq[ECP_ShortW_Aff[EC.F, EC.G]](numPoints)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ proc separator*() = separator(180)
proc report(op, curve: string, startTime, stopTime: MonoTime, startClk, stopClk: int64, iters: int) =
let ns = inNanoseconds((stopTime-startTime) div iters)
let throughput = 1e9 / float64(ns)
let cycles = (stopClk - startClk) div iters
when SupportsGetTicks:
echo &"{op:<88} {curve:<15} {throughput:>15.3f} ops/s {ns:>9} ns/op {(stopClk - startClk) div iters:>9} CPU cycles (approx)"
echo &"{op:<88} {curve:<15} {throughput:>15.3f} ops/s {ns:>9} ns/op {cycles:>9} CPU cycles (approx)"
else:
echo &"{op:<8} {curve:<15} {throughput:>15.3f} ops/s {ns:>9} ns/op"
echo &"{op:<88} {curve:<15} {throughput:>15.3f} ops/s {ns:>9} ns/op"

template bench(op: string, curve: string, iters: int, body: untyped): untyped =
measure(iters, startTime, stopTime, startClk, stopClk, body)
Expand Down Expand Up @@ -156,7 +157,7 @@ proc benchVerifyMulti*(numSigs, iters: int) =
sig.sign(sk, hashedMsg)
triplets.add (pk, hashedMsg, sig)

bench("BLS verif of " & $numSigs & " msgs by "& $numSigs & " pubkeys", "BLS12_381", iters):
bench("BLS verif of " & $numSigs & " msgs by " & $numSigs & " pubkeys", "BLS12_381", iters):
for i in 0 ..< triplets.len:
let ok = triplets[i].pubkey.verify(triplets[i].msg, triplets[i].sig)
doAssert ok == cttEthBls_Success
Expand Down
77 changes: 77 additions & 0 deletions benchmarks/bench_eth_eip2537_subgroup_checks_impact.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Constantine
# Copyright (c) 2018-2019 Status Research & Development GmbH
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.

import
# Internals
../constantine/math/config/curves,
../constantine/math/arithmetic,
../constantine/math/extension_fields,
../constantine/math/elliptic/ec_shortweierstrass_jacobian,
# Helpers
./bench_elliptic_template

# ############################################################
#
# EIP-2537 benchmarks for
# subgroup checks discussion
#
# ############################################################


const Iters = 10_000
const MulIters = 100
const AvailableCurves = [
BLS12_381,
]

proc main() =
separator()
staticFor i, 0, AvailableCurves.len:
const curve = AvailableCurves[i]
const bits = curve.getCurveOrderBitwidth()

# G1
separator()
scalarMulVartimeDoubleAddBench(ECP_ShortW_Jac[Fp[curve], G1], bits, MulIters)
separator()
scalarMulVartimeWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 3, MulIters)
scalarMulVartimeWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 4, MulIters)
scalarMulVartimeWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 5, MulIters)
separator()
scalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 3, MulIters)
scalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 4, MulIters)
scalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 5, MulIters)
separator()
scalarMulEndo( ECP_ShortW_Jac[Fp[curve], G1], bits, MulIters)
scalarMulEndoWindow(ECP_ShortW_Jac[Fp[curve], G1], bits, MulIters)
separator()
subgroupCheckBench(ECP_ShortW_Jac[Fp[curve], G1], MulIters)
subgroupCheckScalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 3, MulIters)
subgroupCheckScalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 4, MulIters)
subgroupCheckScalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp[curve], G1], bits, window = 5, MulIters)
separator()

# G2
separator()
scalarMulVartimeDoubleAddBench(ECP_ShortW_Jac[Fp2[curve], G2], bits, MulIters)
separator()
scalarMulVartimeWNAFBench(ECP_ShortW_Jac[Fp2[curve], G2], bits, window = 3, MulIters)
scalarMulVartimeWNAFBench(ECP_ShortW_Jac[Fp2[curve], G2], bits, window = 4, MulIters)
separator()
scalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp2[curve], G2], bits, window = 3, MulIters)
scalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp2[curve], G2], bits, window = 4, MulIters)
separator()
scalarMulEndo(ECP_ShortW_Jac[Fp2[curve], G2], bits, MulIters)
separator()
subgroupCheckBench(ECP_ShortW_Jac[Fp2[curve], G2], MulIters)
subgroupCheckScalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp2[curve], G2], bits, window = 3, MulIters)
subgroupCheckScalarMulVartimeEndoWNAFBench(ECP_ShortW_Jac[Fp2[curve], G2], bits, window = 4, MulIters)
separator()

main()
notes()
1 change: 1 addition & 0 deletions benchmarks/bench_eth_eip4844_kzg.nim.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--threads:on
Loading
Loading