mirror of
https://github.com/codex-storage/constantine.git
synced 2025-01-13 12:34:31 +00:00
Implement 𝔽p12 inversion, enable 𝔽p12 tests and bench
This commit is contained in:
parent
3a1a5f8847
commit
a6e4517be2
54
benchmarks/bench_fp12.nim
Normal file
54
benchmarks/bench_fp12.nim
Normal file
@ -0,0 +1,54 @@
|
||||
# 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/config/curves,
|
||||
../constantine/tower_field_extensions/[abelian_groups, fp12_quad_fp6],
|
||||
# Helpers
|
||||
../helpers/static_for,
|
||||
./bench_fields_template,
|
||||
# Standard library
|
||||
std/strutils
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Benchmark of 𝔽p12
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
|
||||
const Iters = 10_000
|
||||
const InvIters = 1000
|
||||
const AvailableCurves = [
|
||||
# Pairing-Friendly curves
|
||||
BN254,
|
||||
BLS12_377,
|
||||
BLS12_381,
|
||||
BN446,
|
||||
FKM12_447,
|
||||
BLS12_461,
|
||||
BN462
|
||||
]
|
||||
|
||||
proc main() =
|
||||
echo "-".repeat(80)
|
||||
staticFor i, 0, AvailableCurves.len:
|
||||
const curve = AvailableCurves[i]
|
||||
addBench(Fp12[curve], Iters)
|
||||
subBench(Fp12[curve], Iters)
|
||||
negBench(Fp12[curve], Iters)
|
||||
mulBench(Fp12[curve], Iters)
|
||||
sqrBench(Fp12[curve], Iters)
|
||||
invBench(Fp12[curve], InvIters)
|
||||
echo "-".repeat(80)
|
||||
|
||||
main()
|
||||
|
||||
echo "Notes:"
|
||||
echo " GCC is significantly slower than Clang on multiprecision arithmetic."
|
@ -18,7 +18,7 @@ import
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Benchmark of 𝔽p2 = 𝔽p[𝑖]
|
||||
# Benchmark of 𝔽p6
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
|
@ -51,6 +51,7 @@ task test, "Run all tests":
|
||||
# Towers of extension fields
|
||||
test "", "tests/test_fp2.nim"
|
||||
test "", "tests/test_fp6.nim"
|
||||
test "", "tests/test_fp12.nim"
|
||||
|
||||
if sizeof(int) == 8: # 32-bit tests
|
||||
# Primitives
|
||||
@ -74,6 +75,7 @@ task test, "Run all tests":
|
||||
# Towers of extension fields
|
||||
test "-d:Constantine32", "tests/test_fp2.nim"
|
||||
test "-d:Constantine32", "tests/test_fp6.nim"
|
||||
test "-d:Constantine32", "tests/test_fp12.nim"
|
||||
|
||||
task test_no_gmp, "Run tests that don't require GMP":
|
||||
# -d:testingCurves is configured in a *.nim.cfg for convenience
|
||||
@ -95,6 +97,7 @@ task test_no_gmp, "Run tests that don't require GMP":
|
||||
# Towers of extension fields
|
||||
test "", "tests/test_fp2.nim"
|
||||
test "", "tests/test_fp6.nim"
|
||||
test "", "tests/test_fp12.nim"
|
||||
|
||||
if sizeof(int) == 8: # 32-bit tests
|
||||
# Primitives
|
||||
@ -114,6 +117,7 @@ task test_no_gmp, "Run tests that don't require GMP":
|
||||
# Towers of extension fields
|
||||
test "-d:Constantine32", "tests/test_fp2.nim"
|
||||
test "-d:Constantine32", "tests/test_fp6.nim"
|
||||
test "-d:Constantine32", "tests/test_fp12.nim"
|
||||
|
||||
proc runBench(benchName: string, compiler = "") =
|
||||
if not dirExists "build":
|
||||
@ -152,3 +156,12 @@ task bench_fp6_gcc, "Run benchmark 𝔽p6 with gcc":
|
||||
|
||||
task bench_fp6_clang, "Run benchmark 𝔽p6 with clang":
|
||||
runBench("bench_fp6", "clang")
|
||||
|
||||
task bench_fp12, "Run benchmark with 𝔽p12 your default compiler":
|
||||
runBench("bench_fp12")
|
||||
|
||||
task bench_fp12_gcc, "Run benchmark 𝔽p12 with gcc":
|
||||
runBench("bench_fp12", "gcc")
|
||||
|
||||
task bench_fp12_clang, "Run benchmark 𝔽p12 with clang":
|
||||
runBench("bench_fp12", "clang")
|
||||
|
@ -127,3 +127,27 @@ func prod*[C](r: var Fp12[C], a, b: Fp12[C]) =
|
||||
|
||||
# r0 <- a0 b0 + γ a1 b1
|
||||
r.c0 += Gamma * t
|
||||
|
||||
func inv*[C](r: var Fp12[C], a: Fp12[C]) =
|
||||
## Compute the multiplicative inverse of ``a``
|
||||
#
|
||||
# Algorithm: (the inverse exist if a != 0 which might cause constant-time issue)
|
||||
#
|
||||
# 1 / (a0 + a1 w) <=> (a0 - a1 w) / (a0 + a1 w)(a0 - a1 w)
|
||||
# <=> (a0 - a1 w) / (a0² - a1² w²)
|
||||
# In our case 𝔽p12 = 𝔽p6[γ], we have w² = γ
|
||||
# So the inverse is (a0 - a1 w) / (a0² - γ a1²)
|
||||
|
||||
# [2 Sqr, 1 Add]
|
||||
var v0 {.noInit.}, v1 {.noInit.}: Fp6[C]
|
||||
v0.square(a.c0)
|
||||
v1.square(a.c1)
|
||||
v0 -= Gamma * v1 # v0 = a0² - γ a1² (the norm / squared magnitude of a)
|
||||
|
||||
# [1 Inv, 2 Sqr, 1 Add]
|
||||
v1.inv(v0) # v1 = 1 / (a0² - γ a1²)
|
||||
|
||||
# [1 Inv, 2 Mul, 2 Sqr, 1 Add, 1 Neg]
|
||||
r.c0.prod(a.c0, v1) # r0 = a0 / (a0² - γ a1²)
|
||||
v0.neg(v1) # v0 = -1 / (a0² - γ a1²)
|
||||
r.c1.prod(a.c1, v0) # r1 = -a1 / (a0² - γ a1²)
|
||||
|
@ -418,3 +418,33 @@ suite "𝔽p12 = 𝔽p6[√∛(1+𝑖)]":
|
||||
commutativeRing(FKM12_447)
|
||||
commutativeRing(BLS12_461)
|
||||
commutativeRing(BN462)
|
||||
|
||||
test "𝔽p6 = 𝔽p2[∛(1+𝑖)] extension field multiplicative inverse":
|
||||
proc mulInvOne(curve: static Curve) =
|
||||
var one: Fp12[curve]
|
||||
one.setOne()
|
||||
|
||||
block: # Inverse of 1 is 1
|
||||
var r {.noInit.}: Fp12[curve]
|
||||
r.inv(one)
|
||||
check: bool(r == one)
|
||||
|
||||
var aInv, r{.noInit.}: Fp12[curve]
|
||||
|
||||
for _ in 0 ..< Iters:
|
||||
let a = rng.random(Fp12[curve])
|
||||
|
||||
aInv.inv(a)
|
||||
r.prod(a, aInv)
|
||||
check: bool(r == one)
|
||||
|
||||
r.prod(aInv, a)
|
||||
check: bool(r == one)
|
||||
|
||||
mulInvOne(BN254)
|
||||
mulInvOne(BLS12_377)
|
||||
mulInvOne(BLS12_381)
|
||||
mulInvOne(BN446)
|
||||
mulInvOne(FKM12_447)
|
||||
mulInvOne(BLS12_461)
|
||||
mulInvOne(BN462)
|
||||
|
@ -431,7 +431,7 @@ suite "𝔽p6 = 𝔽p2[∛(1+𝑖)] (irreducible polynomial x³ - (1+𝑖))":
|
||||
|
||||
var aInv, r{.noInit.}: Fp6[curve]
|
||||
|
||||
for _ in 0 ..< 1: # Iters:
|
||||
for _ in 0 ..< Iters:
|
||||
let a = rng.random(Fp6[curve])
|
||||
|
||||
aInv.inv(a)
|
||||
|
Loading…
x
Reference in New Issue
Block a user