Skip to content

Commit

Permalink
gt: fix aliasing issue in mixed torus multiplication
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim committed Oct 23, 2024
1 parent 987080e commit 45bac91
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 8 deletions.
13 changes: 9 additions & 4 deletions constantine/math/pairings/gt_prj.nim
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ proc fromTorus2_vartime*[F](r: var QuadraticExt[F], a: T2Aff[F]) =

# Special case identity element
if bool a.isNeutral():
r.setNeutral()
r.setOne()
return

var num {.noInit.}, den {.noInit.}: typeof(r)
Expand Down Expand Up @@ -380,13 +380,14 @@ proc mixedProd_vartime*[F](r: var T2Prj[F], a: T2Prj[F], b: T2Aff[F]) =
r = a
return

var u0 {.noInit.}, u1 {.noInit.}: F
var u0 {.noInit.}, u1 {.noInit.}, t{.noInit.}: F
u0.prod(a.x, F b)
u1.prod(a.z, F b)
t.prod(a.z, NonResidue)

r.x.prod(a.z, NonResidue)
r.x += u0
# Aliasing: a.x must be read before r.x is written to
r.z.sum(u1, a.x)
r.x.sum(u0, t)

proc affineProd_vartime*[F](r: var T2Prj[F], a, b: T2Aff[F]) =

Expand Down Expand Up @@ -535,6 +536,10 @@ proc batchFromTorus2_vartime*[F](dst: var openArray[QuadraticExt[F]],
t.conj(QF src[0])
dst[0] *= t

func toHex*[F](a: T2Aff[F] or T2Prj[F], indent = 0, order: static Endianness = bigEndian): string =
var t {.noInit.}: QuadraticExt[F]
t.fromTorus2_vartime(a)
t.toHex(indent, order)

when isMainModule:
var a, c: QuadraticExt[Fp6[BLS12_381]]
Expand Down
85 changes: 82 additions & 3 deletions tests/math_pairings/t_gt_prj.nim
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ suite "Torus-based Cryptography for 𝔾ₜ, T₂(𝔽p6) compression":
var r_tprj: T2Prj[Fp6[Name]]
a_taff.fromGT_vartime(a)
b_taff.fromGT_vartime(b)
r_tprj.affineProd(a_taff, b_taff)
r_tprj.affineProd_vartime(a_taff, b_taff)

var r_gt: MyFp12
r_gt.prod(a, b)
Expand All @@ -207,7 +207,34 @@ suite "Torus-based Cryptography for 𝔾ₜ, T₂(𝔽p6) compression":
var a_tprj, r_tprj: T2Prj[Fp6[Name]]
a_tprj.fromGT_vartime(a)
b_taff.fromGT_vartime(b)
r_tprj.mixedProd(a_tprj, b_taff)
r_tprj.mixedProd_vartime(a_tprj, b_taff)

var r_gt: MyFp12
r_gt.prod(a, b)

var r: MyFp12
r.fromTorus2_vartime(r_tprj)

doAssert bool r == r_gt

test(BN254_Nogami)
# test(BN254_Snarks)
test(BLS12_381)

test "T₂prj(𝔽p6) <- T₂prj(𝔽p6) * T₂aff(𝔽p6) - with aliasing":
proc test(Name: static Algebra) =
for i in 0 ..< Fp6iters:
type MyFp12 = QuadraticExt[Fp6[Name]] # Even if we choose to Fp2 -> Fp4 -> Fp12
# we want this test to pass
let a = rng.random_gt(MyFp12)
let b = rng.random_gt(MyFp12)

var b_taff: T2Aff[Fp6[Name]]
var a_tprj, r_tprj: T2Prj[Fp6[Name]]
a_tprj.fromGT_vartime(a)
b_taff.fromGT_vartime(b)
r_tprj = a_tprj
r_tprj.mixedProd_vartime(r_tprj, b_taff)

var r_gt: MyFp12
r_gt.prod(a, b)
Expand Down Expand Up @@ -246,6 +273,58 @@ suite "Torus-based Cryptography for 𝔾ₜ, T₂(𝔽p6) compression":
# test(BN254_Snarks)
test(BLS12_381)

test "T₂prj(𝔽p6) <- T₂prj(𝔽p6) * T₂prj(𝔽p6) - with aliasing of lhs":
proc test(Name: static Algebra) =
for i in 0 ..< Fp6iters:
type MyFp12 = QuadraticExt[Fp6[Name]] # Even if we choose to Fp2 -> Fp4 -> Fp12
# we want this test to pass
let a = rng.random_gt(MyFp12)
let b = rng.random_gt(MyFp12)

var a_tprj, b_tprj, r_tprj: T2Prj[Fp6[Name]]
a_tprj.fromGT_vartime(a)
b_tprj.fromGT_vartime(b)
r_tprj = a_tprj
r_tprj.prod(r_tprj, b_tprj)

var r_gt: MyFp12
r_gt.prod(a, b)

var r: MyFp12
r.fromTorus2_vartime(r_tprj)

doAssert bool r == r_gt

test(BN254_Nogami)
# test(BN254_Snarks)
test(BLS12_381)

test "T₂prj(𝔽p6) <- T₂prj(𝔽p6) * T₂prj(𝔽p6) - with aliasing of rhs":
proc test(Name: static Algebra) =
for i in 0 ..< Fp6iters:
type MyFp12 = QuadraticExt[Fp6[Name]] # Even if we choose to Fp2 -> Fp4 -> Fp12
# we want this test to pass
let a = rng.random_gt(MyFp12)
let b = rng.random_gt(MyFp12)

var a_tprj, b_tprj, r_tprj: T2Prj[Fp6[Name]]
a_tprj.fromGT_vartime(a)
b_tprj.fromGT_vartime(b)
r_tprj = b_tprj
r_tprj.prod(a_tprj, r_tprj)

var r_gt: MyFp12
r_gt.prod(a, b)

var r: MyFp12
r.fromTorus2_vartime(r_tprj)

doAssert bool r == r_gt

test(BN254_Nogami)
# test(BN254_Snarks)
test(BLS12_381)

# ====================================================================================

test "T₂prj(𝔽p6) <- T₂aff(𝔽p6)²":
Expand All @@ -258,7 +337,7 @@ suite "Torus-based Cryptography for 𝔾ₜ, T₂(𝔽p6) compression":
var a_taff: T2Aff[Fp6[Name]]
var r_tprj: T2Prj[Fp6[Name]]
a_taff.fromGT_vartime(a)
r_tprj.affineSquare(a_taff)
r_tprj.affineSquare_vartime(a_taff)

var r_gt: MyFp12
r_gt.square(a)
Expand Down
3 changes: 2 additions & 1 deletion tests/math_pairings/t_pairing_template.nim
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ proc runGTsubgroupTests*(GT: typedesc, iters: int) =
func random_gt(rng: var RngState, F: typedesc, gen: RandomGen): F {.noInit.} =
result = rng.random_elem(F, gen)
result.finalExp()
debug: doAssert bool result.isInPairingSubgroup()

proc runGTexponentiationTests*(GT: typedesc, iters: int) =
var rng: RngState
Expand Down Expand Up @@ -217,7 +218,7 @@ proc runGTexponentiationTests*(GT: typedesc, iters: int) =

proc runGTmultiexpTests*[N: static int](GT: typedesc, num_points: array[N, int], iters: int) =
var rng: RngState
let timeseed = 1727299797 # uint32(toUnix(getTime()) and (1'i64 shl 32 - 1)) # unixTime mod 2^32
let timeseed = uint32(toUnix(getTime()) and (1'i64 shl 32 - 1)) # unixTime mod 2^32
seed(rng, timeseed)
echo "\n------------------------------------------------------\n"
echo "test_pairing_",$GT.Name,"_gt_multiexp xoshiro512** seed: ", timeseed
Expand Down

0 comments on commit 45bac91

Please sign in to comment.