Fix substraction being addition following tower refactor

This commit is contained in:
Mamy André-Ratsimbazafy 2020-04-14 18:30:59 +02:00 committed by Mamy Ratsimbazafy
parent 5784e78606
commit d61680e1ad
6 changed files with 135 additions and 14 deletions

View File

@ -121,7 +121,10 @@ func steinsGCD*(v: var Limbs, a: Limbs, F, M: Limbs, bits: int, mp1div2: Limbs)
debug:
doAssert bool a.isZero()
doAssert bool b.isOne() # GCD always exist if a and M are relatively prime
# GCD exist (always true if a and M are relatively prime)
doAssert bool b.isOne() or
# or not (on prime fields iff input was zero) and no GCD fallback output is zero
(a.isZero() and v.isZero())
# ############################################################
#

View File

@ -18,18 +18,26 @@ func square*(r: var CubicExt, a: CubicExt) =
## Returns r = a²
# Algorithm is Chung-Hasan Squaring SQR2
# http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf
# https://www.lirmm.fr/arith18/papers/Chung-Squaring.pdf
#
# TODO: change to SQR1 or SQR3 (requires div2)
# which are faster for the sizes we are interested in.
# Cost in base field operation
# M -> Mul, S -> Square, B -> Bitshift (doubling/div2), A -> Add
#
# SQR1: 3M + 2S + 5B + 9A
# SQR2: 2M + 3S + 5B + 11A
# SQR3: 1M + 4S + 6B + 15A
# Schoolbook: 3S + 3M + 6B + 2A
#
# TODO: Implement all variants, bench and select one depending on number of limbs and extension degree.
mixin prod, square, sum
var v2{.noInit.}, v3{.noInit.}, v4{.noInit.}, v5{.noInit.}: typeof(r.c0)
var v3{.noInit.}, v4{.noInit.}, v5{.noInit.}: typeof(r.c0)
v4.prod(a.c0, a.c1)
v4.double()
v5.square(a.c2)
r.c1 = β * v5
r.c1 += v4
v2.diff(v4, v5)
r.c2.diff(v4, v5)
v3.square(a.c0)
v4.diff(a.c0, a.c1)
v4 += a.c2
@ -38,7 +46,7 @@ func square*(r: var CubicExt, a: CubicExt) =
v4.square()
r.c0 = β * v5
r.c0 += v3
r.c2.sum(v2, v4)
r.c2 += v4
r.c2 += v5
r.c2 -= v3

View File

@ -74,7 +74,7 @@ func isZero*(a: ExtensionField): CTBool[Word] =
func isOne*(a: ExtensionField): CTBool[Word] =
## Constant-time check if one
result = CtTrue
for fieldName, fA in fields(a):
for fieldName, fA in fieldPairs(a):
when fieldName == "c0":
result = result and fA.isOne()
else:
@ -121,11 +121,11 @@ func sum*(r: var CubicExt, a, b: CubicExt) =
func diff*(r: var QuadraticExt, a, b: QuadraticExt) =
## Diff ``a`` and ``b`` into ``r``
r.c0.sum(a.c0, b.c0)
r.c1.sum(a.c1, b.c1)
r.c0.diff(a.c0, b.c0)
r.c1.diff(a.c1, b.c1)
func diff*(r: var CubicExt, a, b: CubicExt) =
## Diff ``a`` and ``b`` into ``r``
r.c0.sum(a.c0, b.c0)
r.c1.sum(a.c1, b.c1)
r.c2.sum(a.c2, b.c2)
r.c0.diff(a.c0, b.c0)
r.c1.diff(a.c1, b.c1)
r.c2.diff(a.c2, b.c2)

View File

@ -31,7 +31,6 @@ echo "test_fp12 xoshiro512** seed: ", seed
# will significantly slow down testing (100x is possible)
suite "𝔽p12 = 𝔽p6[w] (irreducible polynomial w² - γ)":
test "Comparison sanity checks":
proc test(C: static Curve) =
var z, o {.noInit.}: Fp12[C]
@ -44,6 +43,43 @@ suite "𝔽p12 = 𝔽p6[w] (irreducible polynomial w² - γ)":
test(BN254_Snarks)
test(BLS12_381)
test "Addition, substraction negation are consistent":
proc test(C: static Curve) =
# Try to exercise all code paths for in-place/out-of-place add/sum/sub/diff/double/neg
# (1 - (-a) - b + (-a) - 2a) + (2a + 2b + (-b)) == 1
var accum {.noInit.}, One {.noInit.}, a{.noInit.}, na{.noInit.}, b{.noInit.}, nb{.noInit.}, a2 {.noInit.}, b2 {.noInit.}: Fp12[C]
One.setOne()
a = rng.random(Fp12[C])
a2 = a
a2.double()
na.neg(a)
b = rng.random(Fp12[C])
b2.double(b)
nb.neg(b)
accum.diff(One, na)
accum -= b
accum += na
accum -= a2
var t{.noInit.}: Fp12[C]
t.sum(a2, b2)
t += nb
accum += t
check: bool accum.isOne()
# test(BN254_Nogami)
test(BN254_Snarks)
test(BLS12_377)
test(BLS12_381)
# test(BN446)
# test(FKM12_447)
# test(BLS12_461)
# test(BN462)
test "Squaring 1 returns 1":
template test(C: static Curve) =
block:
@ -489,7 +525,7 @@ suite "𝔽p12 = 𝔽p6[w] (irreducible polynomial w² - γ)":
var z: Fp12[curve]
z.setZero()
var zInv{.noInit.}: Fp6[curve]
var zInv{.noInit.}: Fp12[curve]
zInv.inv(z)
check: bool zInv.isZero()

View File

@ -67,6 +67,43 @@ suite "𝔽p2 = 𝔽p[µ] (irreducible polynomial x²+µ)":
test(BN254_Snarks)
test(BLS12_381)
test "Addition, substraction negation are consistent":
proc test(C: static Curve) =
# Try to exercise all code paths for in-place/out-of-place add/sum/sub/diff/double/neg
# (1 - (-a) - b + (-a) - 2a) + (2a + 2b + (-b)) == 1
var accum {.noInit.}, One {.noInit.}, a{.noInit.}, na{.noInit.}, b{.noInit.}, nb{.noInit.}, a2 {.noInit.}, b2 {.noInit.}: Fp2[C]
One.setOne()
a = rng.random(Fp2[C])
a2 = a
a2.double()
na.neg(a)
b = rng.random(Fp2[C])
b2.double(b)
nb.neg(b)
accum.diff(One, na)
accum -= b
accum += na
accum -= a2
var t{.noInit.}: Fp2[C]
t.sum(a2, b2)
t += nb
accum += t
check: bool accum.isOne()
# test(BN254_Nogami)
test(BN254_Snarks)
test(BLS12_377)
test(BLS12_381)
# test(BN446)
# test(FKM12_447)
# test(BLS12_461)
# test(BN462)
test "Squaring 1 returns 1":
template test(C: static Curve) =
block:

View File

@ -43,6 +43,43 @@ suite "𝔽p6 = 𝔽p2[v] (irreducible polynomial v³ - ξ)":
test(BN254_Snarks)
test(BLS12_381)
test "Addition, substraction negation are consistent":
proc test(C: static Curve) =
# Try to exercise all code paths for in-place/out-of-place add/sum/sub/diff/double/neg
# (1 - (-a) - b + (-a) - 2a) + (2a + 2b + (-b)) == 1
var accum {.noInit.}, One {.noInit.}, a{.noInit.}, na{.noInit.}, b{.noInit.}, nb{.noInit.}, a2 {.noInit.}, b2 {.noInit.}: Fp6[C]
One.setOne()
a = rng.random(Fp6[C])
a2 = a
a2.double()
na.neg(a)
b = rng.random(Fp6[C])
b2.double(b)
nb.neg(b)
accum.diff(One, na)
accum -= b
accum += na
accum -= a2
var t{.noInit.}: Fp6[C]
t.sum(a2, b2)
t += nb
accum += t
check: bool accum.isOne()
# test(BN254_Nogami)
test(BN254_Snarks)
test(BLS12_377)
test(BLS12_381)
# test(BN446)
# test(FKM12_447)
# test(BLS12_461)
# test(BN462)
test "Squaring 1 returns 1":
template test(C: static Curve) =
block: