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

Bandersnatch/banderwagon endomorphism acceleration v2 #405

Merged
merged 4 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions constantine.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,12 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[
("tests/math_elliptic_curves/t_ec_twedw_prj_mul_sanity", false),
("tests/math_elliptic_curves/t_ec_twedw_prj_mul_distri", false),

# ("tests/math_elliptic_curves/t_ec_shortw_jac_g1_mul_endomorphism_bls12_381", false),
# ("tests/math_elliptic_curves/t_ec_shortw_prj_g1_mul_endomorphism_bls12_381", false),
# ("tests/math_elliptic_curves/t_ec_shortw_jac_g1_mul_endomorphism_bn254_snarks", false),
# ("tests/math_elliptic_curves/t_ec_shortw_prj_g1_mul_endomorphism_bn254_snarks", false),
# ("tests/math_elliptic_curves/t_ec_twedwards_mul_endomorphism_bandersnatch", false),


# Elliptic curve arithmetic G2
# ----------------------------------------------------------
Expand Down Expand Up @@ -476,6 +482,11 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[
("tests/math_elliptic_curves/t_ec_shortw_jac_g2_mul_vs_ref_bw6_761.nim", false),
# ("tests/math_elliptic_curves/t_ec_shortw_jac_g2_mixed_add_bw6_761.nim", false),

# ("tests/math_elliptic_curves/t_ec_shortw_jac_g2_mul_endomorphism_bls12_381", false),
# ("tests/math_elliptic_curves/t_ec_shortw_prj_g2_mul_endomorphism_bls12_381", false),
# ("tests/math_elliptic_curves/t_ec_shortw_jac_g2_mul_endomorphism_bn254_snarks", false),
# ("tests/math_elliptic_curves/t_ec_shortw_prj_g2_mul_endomorphism_bn254_snarks", false),

# Elliptic curve arithmetic vs Sagemath
# ----------------------------------------------------------
("tests/math_elliptic_curves/t_ec_frobenius.nim", false),
Expand Down
43 changes: 14 additions & 29 deletions constantine/math/elliptic/ec_endomorphism_accel.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import
constantine/named/zoo_endomorphisms,
constantine/math/arithmetic,
constantine/math/extension_fields,
constantine/math/isogenies/frobenius,
./ec_shortweierstrass_affine,
./ec_shortweierstrass_projective,
./ec_shortweierstrass_jacobian,
./ec_twistededwards_affine,
./ec_twistededwards_projective,
./ec_shortweierstrass_batch_ops
./ec_shortweierstrass_batch_ops,
./ec_twistededwards_batch_ops

# ############################################################
#
Expand Down Expand Up @@ -332,25 +332,14 @@ func scalarMulEndo*[scalBits; EC](
mixin affine
const C = P.F.Name # curve
static: doAssert scalBits <= EC.getScalarField().bits(), "Do not use endomorphism to multiply beyond the curve order"
when P.F is Fp:
const M = 2
# 1. Compute endomorphisms
var endomorphisms {.noInit.}: array[M-1, EC]
when P.G == G1:
endomorphisms[0] = P
endomorphisms[0].x *= C.getCubicRootOfUnity_mod_p()
else:
endomorphisms[0].frobenius_psi(P, 2)

elif P.F is Fp2:
const M = 4
# 1. Compute endomorphisms
var endomorphisms {.noInit.}: array[M-1, EC]
endomorphisms[0].frobenius_psi(P)
endomorphisms[1].frobenius_psi(P, 2)
endomorphisms[2].frobenius_psi(P, 3)
else:
{.error: "Unconfigured".}

# 1. Compute endomorphisms
const M = when P.F is Fp: 2
elif P.F is Fp2: 4
else: {.error: "Unconfigured".}

var endos {.noInit.}: array[M-1, EC]
endos.computeEndomorphisms(P)

# 2. Decompose scalar into mini-scalars
const L = scalBits.ceilDiv_vartime(M) + 1
Expand All @@ -366,11 +355,11 @@ func scalarMulEndo*[scalBits; EC](
block:
P.cneg(negatePoints[0])
staticFor i, 1, M:
endomorphisms[i-1].cneg(negatePoints[i])
endos[i-1].cneg(negatePoints[i])

# 4. Precompute lookup table
var lut {.noInit.}: array[1 shl (M-1), affine(EC)]
buildLookupTable(P, endomorphisms, lut)
buildLookupTable(P, endos, lut)

# 5. Recode the miniscalars
# we need the base miniscalar (that encodes the sign)
Expand Down Expand Up @@ -521,12 +510,8 @@ func scalarMulGLV_m2w2*[scalBits; EC](P0: var EC, scalar: BigInt[scalBits]) {.me
static: doAssert: scalBits <= EC.getScalarField().bits()

# 1. Compute endomorphisms
when P0.G == G1:
var P1 = P0
P1.x *= C.getCubicRootOfUnity_mod_p()
else:
var P1 {.noInit.}: EC
P1.frobenius_psi(P0, 2)
var P1 {.noInit.}: EC
P1.computeEndomorphism(P0)

# 2. Decompose scalar into mini-scalars
const L = computeRecodedLength(EC.getScalarField().bits(), 2)
Expand Down
16 changes: 4 additions & 12 deletions constantine/math/elliptic/ec_multi_scalar_mul.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import constantine/named/algebras,
./ec_multi_scalar_mul_scheduler,
./ec_endomorphism_accel,
constantine/math/extension_fields,
constantine/math/isogenies/frobenius,
constantine/named/zoo_endomorphisms
export bestBucketBitSize

Expand Down Expand Up @@ -411,17 +410,10 @@ proc applyEndomorphism[bits: static int, ECaff](
else:
endoBasis[i][0] = points[i]

when ECaff.F is Fp:
endoBasis[i][1].x.prod(points[i].x, ECaff.F.Name.getCubicRootOfUnity_mod_p())
if negatePoints[1].bool:
endoBasis[i][1].y.neg(points[i].y)
else:
endoBasis[i][1].y = points[i].y
else:
staticFor m, 1, M:
endoBasis[i][m].frobenius_psi(points[i], m)
if negatePoints[m].bool:
endoBasis[i][m].neg()
cast[ptr array[M-1, ECaff]](endoBasis[i][1].addr)[].computeEndomorphisms(points[i])
for m in 1 ..< M:
if negatePoints[m].bool:
endoBasis[i][m].neg()

let endoCoefs = cast[ptr UncheckedArray[BigInt[L]]](splitCoefs)
let endoPoints = cast[ptr UncheckedArray[ECaff]](endoBasis)
Expand Down
16 changes: 4 additions & 12 deletions constantine/math/elliptic/ec_multi_scalar_mul_parallel.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import constantine/named/algebras,
./ec_multi_scalar_mul,
./ec_endomorphism_accel,
constantine/math/extension_fields,
constantine/math/isogenies/frobenius,
constantine/named/zoo_endomorphisms,
../../threadpool/[threadpool, partitioners]
export bestBucketBitSize
Expand Down Expand Up @@ -477,17 +476,10 @@ proc applyEndomorphism_parallel[bits: static int, ECaff](
else:
endoBasis[i][0] = points[i]

when ECaff.F is Fp:
endoBasis[i][1].x.prod(points[i].x, ECaff.F.Name.getCubicRootOfUnity_mod_p())
if negatePoints[1].bool:
endoBasis[i][1].y.neg(points[i].y)
else:
endoBasis[i][1].y = points[i].y
else:
staticFor m, 1, M:
endoBasis[i][m].frobenius_psi(points[i], m)
if negatePoints[m].bool:
endoBasis[i][m].neg()
cast[ptr array[M-1, ECaff]](endoBasis[i][1].addr)[].computeEndomorphisms(points[i])
for m in 1 ..< M:
if negatePoints[m].bool:
endoBasis[i][m].neg()

let endoCoefs = cast[ptr UncheckedArray[BigInt[L]]](splitCoefs)
let endoPoints = cast[ptr UncheckedArray[ECaff]](endoBasis)
Expand Down
35 changes: 11 additions & 24 deletions constantine/math/elliptic/ec_scalar_mul_vartime.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ import
constantine/math/arithmetic,
constantine/math/extension_fields,
constantine/math/io/io_bigints,
constantine/named/zoo_endomorphisms,
constantine/math/isogenies/frobenius,
constantine/platforms/abstractions,
constantine/math_arbitrary_precision/arithmetic/limbs_views
constantine/math_arbitrary_precision/arithmetic/limbs_views,
constantine/named/zoo_endomorphisms

{.push raises: [].} # No exceptions allowed in core cryptographic operations
{.push checks: off.} # No defects due to array bound checking or signed integer overflow allowed
Expand Down Expand Up @@ -252,25 +251,13 @@ func scalarMulEndo_minHammingWeight_windowed_vartime*[scalBits: static int; EC](
const precompSize = 1 shl (window - 2)
static: doAssert window < 8, "Window is too large and precomputation would use " & $(precompSize * sizeof(EC)) & " stack space."

when P.F is Fp:
const M = 2
# 1. Compute endomorphisms
var endomorphisms {.noInit.}: array[M-1, EC]
when P.G == G1:
endomorphisms[0] = P
endomorphisms[0].x *= EC.F.Name.getCubicRootOfUnity_mod_p()
else:
endomorphisms[0].frobenius_psi(P, 2)
# 1. Compute endomorphisms
const M = when P.F is Fp: 2
elif P.F is Fp2: 4
else: {.error: "Unconfigured".}

elif P.F is Fp2:
const M = 4
# 1. Compute endomorphisms
var endomorphisms {.noInit.}: array[M-1, EC]
endomorphisms[0].frobenius_psi(P)
endomorphisms[1].frobenius_psi(P, 2)
endomorphisms[2].frobenius_psi(P, 3)
else:
{.error: "Unconfigured".}
var endos {.noInit.}: array[M-1, EC]
endos.computeEndomorphisms(P)

# 2. Decompose scalar into mini-scalars
const L = scalBits.ceilDiv_vartime(M) + 1
Expand All @@ -283,7 +270,7 @@ func scalarMulEndo_minHammingWeight_windowed_vartime*[scalBits: static int; EC](
P.neg()
for m in 1 ..< M:
if negatePoints[m].bool:
endomorphisms[m-1].neg()
endos[m-1].neg()

# 4. EC precomputed table
var tabEC {.noinit.}: array[M, array[precompSize, EC]]
Expand All @@ -293,8 +280,8 @@ func scalarMulEndo_minHammingWeight_windowed_vartime*[scalBits: static int; EC](
tabEC[0][0] = P
P2.double(P)
else:
tabEC[m][0] = endomorphisms[m-1]
P2.double(endomorphisms[m-1])
tabEC[m][0] = endos[m-1]
P2.double(endos[m-1])
for i in 1 ..< tabEC[m].len:
tabEC[m][i].sum_vartime(tabEC[m][i-1], P2)

Expand Down
7 changes: 7 additions & 0 deletions constantine/math/elliptic/ec_twistededwards_affine.nim
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ func setNeutral*(P: var EC_TwEdw_Aff) {.inline.} =
P.x.setZero()
P.y.setOne()

func ccopy*(P: var EC_TwEdw_Aff, Q: EC_TwEdw_Aff, ctl: SecretBool) {.inline.} =
## Constant-time conditional copy
## If ctl is true: Q is copied into P
## if ctl is false: Q is not copied and P is unmodified
## Time and memory accesses are the same whether a copy occurs or not
for fP, fQ in fields(P, Q):
ccopy(fP, fQ, ctl)

func isOnCurve*[F](x, y: F): SecretBool =
## Returns true if the (x, y) coordinates
Expand Down
27 changes: 27 additions & 0 deletions constantine/named/constants/bandersnatch_endomorphisms.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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
constantine/math/io/io_bigints

# Bandersnatch
# ------------------------------------------------------------

const Bandersnatch_Lattice_G1* = (
# (BigInt, isNeg)
((BigInt[127].fromHex"0x555fe2004be6928e4b02f94a9789181f", false),
(BigInt[124].fromHex"0x814b3eee55e8f5df8e2591a23d61f44", false)),
((BigInt[125].fromHex"0x102967ddcabd1ebbf1c4b23447ac3e88", false),
(BigInt[127].fromHex"0x555fe2004be6928e4b02f94a9789181f", true))
)

const Bandersnatch_Babai_G1* = (
# (BigInt, isNeg)
(BigInt[130].fromHex"0x2f21df5b0541cf632debac77a3f4747c1", false),
(BigInt[127].fromHex"0x4760f127d8767bde993b75e7547768aa", false)
)
27 changes: 27 additions & 0 deletions constantine/named/constants/banderwagon_endomorphisms.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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
constantine/math/io/io_bigints

# Banderwagon
# ------------------------------------------------------------

const Banderwagon_Lattice_G1* = (
# (BigInt, isNeg)
((BigInt[127].fromHex"0x555fe2004be6928e4b02f94a9789181f", false),
(BigInt[124].fromHex"0x814b3eee55e8f5df8e2591a23d61f44", false)),
((BigInt[125].fromHex"0x102967ddcabd1ebbf1c4b23447ac3e88", false),
(BigInt[127].fromHex"0x555fe2004be6928e4b02f94a9789181f", true))
)

const Banderwagon_Babai_G1* = (
# (BigInt, isNeg)
(BigInt[130].fromHex"0x2f21df5b0541cf632debac77a3f4747c1", false),
(BigInt[127].fromHex"0x4760f127d8767bde993b75e7547768aa", false)
)
1 change: 1 addition & 0 deletions constantine/named/constants/bls12_377_subgroups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import
constantine/math/arithmetic,
constantine/math/extension_fields,
constantine/math/ec_shortweierstrass,
constantine/math/elliptic/ec_scalar_mul,
constantine/math/io/io_bigints,
constantine/math/isogenies/frobenius,
constantine/named/zoo_endomorphisms
Expand Down
1 change: 1 addition & 0 deletions constantine/named/constants/bls12_381_subgroups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import
constantine/math/arithmetic,
constantine/math/extension_fields,
constantine/math/ec_shortweierstrass,
constantine/math/elliptic/ec_scalar_mul,
constantine/math/io/io_bigints,
constantine/math/isogenies/frobenius,
constantine/named/zoo_endomorphisms
Expand Down
1 change: 1 addition & 0 deletions constantine/named/constants/bn254_nogami_subgroups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import
constantine/math/arithmetic,
constantine/math/extension_fields,
constantine/math/ec_shortweierstrass,
constantine/math/elliptic/ec_scalar_mul,
constantine/math/io/io_bigints,
constantine/math/isogenies/frobenius

Expand Down
1 change: 1 addition & 0 deletions constantine/named/constants/bn254_snarks_subgroups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import
constantine/math/arithmetic,
constantine/math/extension_fields,
constantine/math/ec_shortweierstrass,
constantine/math/elliptic/ec_scalar_mul,
constantine/math/io/io_bigints,
constantine/math/isogenies/frobenius

Expand Down
1 change: 1 addition & 0 deletions constantine/named/constants/bw6_761_subgroups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import
constantine/math/arithmetic,
constantine/math/extension_fields,
constantine/math/ec_shortweierstrass,
constantine/math/elliptic/ec_scalar_mul,
constantine/math/io/io_bigints
# constantine/math/isogenies/frobenius

Expand Down
4 changes: 2 additions & 2 deletions constantine/named/properties_fields.nim
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ debug:

{.experimental: "dynamicBindSym".}

macro baseFieldModulus(Name: static Algebra): untyped =
macro baseFieldModulus*(Name: static Algebra): untyped =
result = bindSym($Name & "_Modulus")

macro scalarFieldModulus(Name: static Algebra): untyped =
macro scalarFieldModulus*(Name: static Algebra): untyped =
result = bindSym($Name & "_Order")

template getModulus*[Name: static Algebra](F: type FF[Name]): untyped =
Expand Down
Loading
Loading