Skip to content

Commit

Permalink
feat(𝔾ₜ exponentiation): Add benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim committed Jul 14, 2024
1 parent 55da57f commit bc2671e
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 4 deletions.
5 changes: 2 additions & 3 deletions benchmarks/bench_fields_template.nim
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,8 @@ proc powBench*(T: typedesc, iters: int) =
var r = x
r.pow(exponent)

proc powUnsafeBench*(T: typedesc, iters: int) =
proc powVartimeBench*(T: typedesc, iters: int) =
let x = rng.random_unsafe(T)
let exponent = rng.random_unsafe(BigInt[Fr[T.Name].bits()])
bench("Exp curve order (Leak exponent bits) - " & $exponent.bits & "-bit", T, iters):
var r = x
bench("Exp by curve order (vartime) - " & $exponent.bits & "-bit", T, iters):
r.pow_vartime(exponent)
2 changes: 1 addition & 1 deletion benchmarks/bench_fp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ proc main() =
sqrtRatioVartimeBench(Fp[curve], ExponentIters)
# Exponentiation by a "secret" of size ~the curve order
powBench(Fp[curve], ExponentIters)
powUnsafeBench(Fp[curve], ExponentIters)
powVartimeBench(Fp[curve], ExponentIters)
separator()

main()
Expand Down
64 changes: 64 additions & 0 deletions benchmarks/bench_gt.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# 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/named/algebras,
constantine/math/extension_fields,
# Helpers
./bench_gt_template

# ############################################################
#
# Benchmark of the 𝔾ₜ group of
# Pairing Friendly curves
#
# ############################################################

const Iters = 10000
const ExpIters = 1000
const AvailableCurves = [
# BN254_Nogami,
BN254_Snarks,
# BLS12_377,
BLS12_381,
]

proc main() =
separator()
staticFor i, 0, AvailableCurves.len:
const curve = AvailableCurves[i]
const bits = Fr[curve].bits()
separator()
mulBench(Fp12[curve], Iters)
sqrBench(Fp12[curve], Iters)
invBench(Fp12[curve], Iters)
separator()
cyclotomicSquare_Bench(Fp12[curve], Iters)
cyclotomicInv_Bench(Fp12[curve], Iters)
cyclotomicSquareCompressed_Bench(Fp12[curve], Iters)
cyclotomicDecompression_Bench(Fp12[curve], Iters)
separator()
powVartimeBench(Fp12[curve], window = 2, ExpIters)
powVartimeBench(Fp12[curve], window = 3, ExpIters)
powVartimeBench(Fp12[curve], window = 4, ExpIters)
separator()
gtExp_sqrmul_vartimeBench(Fp12[curve], ExpIters)
gtExp_minHammingWeight_vartimeBench(Fp12[curve], ExpIters)
separator()
gtExp_wNAF_vartimeBench(Fp12[curve], window = 2, ExpIters)
gtExp_wNAF_vartimeBench(Fp12[curve], window = 3, ExpIters)
gtExp_wNAF_vartimeBench(Fp12[curve], window = 4, ExpIters)
separator()
gtExp_endo_wNAF_vartimeBench(Fp12[curve], window = 2, ExpIters)
gtExp_endo_wNAF_vartimeBench(Fp12[curve], window = 3, ExpIters)
gtExp_endo_wNAF_vartimeBench(Fp12[curve], window = 4, ExpIters)
separator()

main()
notes()
167 changes: 167 additions & 0 deletions benchmarks/bench_gt_template.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# 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.

# ############################################################
#
# Summary of the performance of a curve
#
# ############################################################

import
# Internals
constantine/platforms/abstractions,
constantine/named/algebras,
constantine/math/[arithmetic, extension_fields],
constantine/math/pairings/[
pairings_generic,
cyclotomic_subgroups,
gt_exponentiations_vartime
],
# Helpers
helpers/prng_unsafe,
./bench_blueprint


export notes
export abstractions
proc separator*() = separator(168)

proc report(op, domain: string, start, stop: MonoTime, startClk, stopClk: int64, iters: int) =
let ns = inNanoseconds((stop-start) div iters)
let throughput = 1e9 / float64(ns)
when SupportsGetTicks:
echo &"{op:<68} {domain:<20} {throughput:>15.3f} ops/s {ns:>9} ns/op {(stopClk - startClk) div iters:>9} CPU cycles (approx)"
else:
echo &"{op:<68} {domain:<20} {throughput:>15.3f} ops/s {ns:>9} ns/op"

macro fixFieldDisplay(T: typedesc): untyped =
# At compile-time, enums are integers and their display is buggy
# we get the Curve ID instead of the curve name.
let instantiated = T.getTypeInst()
var name = $instantiated[1][0] # Fp
name.add "[" & $Algebra(instantiated[1][1].intVal) & "]"
result = newLit name

func fixDisplay(T: typedesc): string =
when T is (Fp or Fp2 or Fp4 or Fp6 or Fp12):
fixFieldDisplay(T)
else:
$T

func fixDisplay(T: Algebra): string =
$T

template bench(op: string, T: typed, iters: int, body: untyped): untyped =
measure(iters, startTime, stopTime, startClk, stopClk, body)
report(op, fixDisplay(T), startTime, stopTime, startClk, stopClk, iters)

func random_gt*(rng: var RngState, F: typedesc): F {.inline, noInit.} =
result = rng.random_unsafe(F)
result.finalExp()

proc mulBench*(T: typedesc, iters: int) =
var r: T
let x = rng.random_gt(T)
let y = rng.random_gt(T)
preventOptimAway(r)
bench("Multiplication", T, iters):
r.prod(x, y)

proc sqrBench*(T: typedesc, iters: int) =
var r: T
let x = rng.random_gt(T)
preventOptimAway(r)
bench("Squaring", T, iters):
r.square(x)

proc invBench*(T: typedesc, iters: int) =
var r: T
let x = rng.random_gt(T)
preventOptimAway(r)
bench("Inversion", T, iters):
r.inv(x)

proc cyclotomicSquare_Bench*(T: typedesc, iters: int) =
var f = rng.random_gt(T)

bench("Squaring in cyclotomic subgroup", T, iters):
f.cyclotomic_square()

proc cyclotomicInv_Bench*(T: typedesc, iters: int) =
var f = rng.random_gt(T)

bench("Inversion in cyclotomic subgroup", T, iters):
f.cyclotomic_inv()

proc cyclotomicSquareCompressed_Bench*(T: typedesc, iters: int) =
var f = rng.random_gt(T)

when T is Fp12:
type F = Fp2[T.Name]
else:
{.error: "Only compression of Fp12 extension is configured".}

var g: G2345[F]
g.fromFpk(f)

bench("Cyclotomic Compressed Squaring", T, iters):
g.cyclotomic_square_compressed()

proc cyclotomicDecompression_Bench*(T: typedesc, iters: int) =
var f = rng.random_gt(T)

when T is Fp12:
type F = Fp2[T.Name]
else:
{.error: "Only compression of Fp12 extension is configured".}

var gs: array[1, G2345[F]]
gs[0].fromFpk(f)

var g1s_ratio: array[1, tuple[g1_num, g1_den: F]]
var g0s, g1s: array[1, F]

bench("Cyclotomic Decompression", T, iters):
recover_g1(g1s_ratio[0].g1_num, g1s_ratio[0].g1_den, gs[0])
g1s.batch_ratio_g1s(g1s_ratio)
g0s[0].recover_g0(g1s[0], gs[0])

proc powVartimeBench*(T: typedesc, window: static int, iters: int) =
let x = rng.random_gt(T)
let exponent = rng.random_unsafe(BigInt[Fr[T.Name].bits()])
var r = x
bench("Field Exponentiation " & $exponent.bits & "-bit (window-" & $window & ", vartime)", T, iters):
r.pow_vartime(exponent, window)

proc gtExp_sqrmul_vartimeBench*(T: typedesc, iters: int) =
let x = rng.random_gt(T)
let exponent = rng.random_unsafe(BigInt[Fr[T.Name].bits()])
var r {.noInit.}: T
bench("𝔾ₜ Exponentiation " & $exponent.bits & "-bit (cyclotomic square-multiply, vartime)", T, iters):
r.gtExp_sqrmul_vartime(x, exponent)

proc gtExp_minHammingWeight_vartimeBench*(T: typedesc, iters: int) =
let x = rng.random_gt(T)
let exponent = rng.random_unsafe(BigInt[Fr[T.Name].bits()])
var r {.noInit.}: T
bench("𝔾ₜ Exponentiation " & $exponent.bits & "-bit (signed recoding, vartime)", T, iters):
r.gtExp_minHammingWeight_vartime(x, exponent)

proc gtExp_wNAF_vartimeBench*(T: typedesc, window: static int, iters: int) =
let x = rng.random_gt(T)
let exponent = rng.random_unsafe(BigInt[Fr[T.Name].bits()])
var r {.noInit.}: T
bench("𝔾ₜ Exponentiation " & $exponent.bits & "-bit (wNAF-" & $window & ", vartime)", T, iters):
r.gtExp_minHammingWeight_windowed_vartime(x, exponent, window)

proc gtExp_endo_wNAF_vartimeBench*(T: typedesc, window: static int, iters: int) =
let x = rng.random_gt(T)
let exponent = rng.random_unsafe(BigInt[Fr[T.Name].bits()])
var r {.noInit.}: T
bench("𝔾ₜ Exponentiation " & $exponent.bits & "-bit (endomorphism, wNAF-" & $window & ", vartime)", T, iters):
r.gtExpEndo_minHammingWeight_windowed_vartime(x, exponent, window)
8 changes: 8 additions & 0 deletions constantine.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[
# ("tests/math_pairings/t_pairing_bls12_381_optate.nim", false),

("tests/math_pairings/t_pairing_bn254_snarks_gt_exp.nim", false),
("tests/math_pairings/t_pairing_bls12_381_gt_exp.nim", false),

# Multi-Pairing
# ----------------------------------------------------------
Expand Down Expand Up @@ -652,6 +653,7 @@ const benchDesc = [
"bench_pairing_bls12_381",
"bench_pairing_bn254_nogami",
"bench_pairing_bn254_snarks",
"bench_gt",
"bench_summary_bls12_377",
"bench_summary_bls12_381",
"bench_summary_bn254_nogami",
Expand Down Expand Up @@ -1028,6 +1030,12 @@ task bench_ec_g2, "Run benchmark on Elliptic Curve group 𝔾2 - CC compiler":
task bench_ec_g2_scalar_mul, "Run benchmark on Elliptic Curve group 𝔾2 (Multi-Scalar-Mul) - CC compiler":
runBench("bench_ec_g2_scalar_mul")

# 𝔾ₜ
# ------------------------------------------

task bench_gt, "Run 𝔾ₜ benchmarks - CC compiler":
runBench("bench_gt")

# Pairings
# ------------------------------------------

Expand Down
15 changes: 15 additions & 0 deletions tests/math_pairings/t_pairing_bls12_381_gt_exp.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 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
# Test utilities
./t_pairing_template

runGTexponentiationTests(
Iters = 4,
GT = Fp12[BLS12_381])

0 comments on commit bc2671e

Please sign in to comment.