From 5784e78606a247a68bdb6224b661c49ec3fd0009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mamy=20Andr=C3=A9-Ratsimbazafy?= Date: Tue, 14 Apr 2020 13:40:03 +0200 Subject: [PATCH] =?UTF-8?q?Towered=20extension=20comparison=20bug:=20squar?= =?UTF-8?q?ing=20in=20=F0=9D=94=BDp6=20is=20not=20properly=20implemented?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tower_field_extensions/tower_common.nim | 19 ++++++++- tests/test_fp12.nim | 40 +++++++++++++++++-- tests/test_fp2.nim | 39 ++++++++++++++++-- tests/test_fp6.nim | 39 ++++++++++++++++-- 4 files changed, 123 insertions(+), 14 deletions(-) diff --git a/constantine/tower_field_extensions/tower_common.nim b/constantine/tower_field_extensions/tower_common.nim index 7d37880..1e3a3da 100644 --- a/constantine/tower_field_extensions/tower_common.nim +++ b/constantine/tower_field_extensions/tower_common.nim @@ -61,9 +61,24 @@ func setOne*(a: var ExtensionField) = func `==`*(a, b: ExtensionField): CTBool[Word] = ## Constant-time equality check - result = CtFalse + result = CtTrue for fA, fB in fields(a, b): - result = result or (fA == fB) + result = result and (fA == fB) + +func isZero*(a: ExtensionField): CTBool[Word] = + ## Constant-time check if zero + result = CtTrue + for fA in fields(a): + result = result and fA.isZero() + +func isOne*(a: ExtensionField): CTBool[Word] = + ## Constant-time check if one + result = CtTrue + for fieldName, fA in fields(a): + when fieldName == "c0": + result = result and fA.isOne() + else: + result = result and fA.isZero() # Abelian group # ------------------------------------------------------------------- diff --git a/tests/test_fp12.nim b/tests/test_fp12.nim index 94b4536..b94a014 100644 --- a/tests/test_fp12.nim +++ b/tests/test_fp12.nim @@ -30,7 +30,20 @@ echo "test_fp12 xoshiro512** seed: ", seed # having too many elements on the stack (a couple kB) # will significantly slow down testing (100x is possible) -suite "𝔽p12 = 𝔽p6[βˆšβˆ›(1+𝑖)]": +suite "𝔽p12 = 𝔽p6[w] (irreducible polynomial wΒ² - Ξ³)": + + test "Comparison sanity checks": + proc test(C: static Curve) = + var z, o {.noInit.}: Fp12[C] + + z.setZero() + o.setOne() + + check: not bool(z == o) + + test(BN254_Snarks) + test(BLS12_381) + test "Squaring 1 returns 1": template test(C: static Curve) = block: @@ -338,7 +351,7 @@ suite "𝔽p12 = 𝔽p6[βˆšβˆ›(1+𝑖)]": # test(BLS12_461) # test(BN462) - test "𝔽p12 = 𝔽p6[βˆšβˆ›(1+𝑖)] addition is associative and commutative": + test "Addition is associative and commutative": proc abelianGroup(curve: static Curve) = for _ in 0 ..< Iters: let a = rng.random(Fp12[curve]) @@ -389,7 +402,7 @@ suite "𝔽p12 = 𝔽p6[βˆšβˆ›(1+𝑖)]": # abelianGroup(BLS12_461) # abelianGroup(BN462) - test "𝔽p12 = 𝔽p6[βˆšβˆ›(1+𝑖)] multiplication is associative and commutative": + test "Multiplication is associative and commutative": proc commutativeRing(curve: static Curve) = for _ in 0 ..< Iters: let a = rng.random(Fp12[curve]) @@ -440,7 +453,7 @@ suite "𝔽p12 = 𝔽p6[βˆšβˆ›(1+𝑖)]": # commutativeRing(BLS12_461) # commutativeRing(BN462) - test "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] extension field multiplicative inverse": + test "Extension field multiplicative inverse": proc mulInvOne(curve: static Curve) = var one: Fp12[curve] one.setOne() @@ -470,3 +483,22 @@ suite "𝔽p12 = 𝔽p6[βˆšβˆ›(1+𝑖)]": # mulInvOne(FKM12_447) # mulInvOne(BLS12_461) # mulInvOne(BN462) + + test "0 does not have a multiplicative inverse and should return 0 for projective/jacobian => affine coordinates conversion": + proc test(curve: static Curve) = + var z: Fp12[curve] + z.setZero() + + var zInv{.noInit.}: Fp6[curve] + + zInv.inv(z) + check: bool zInv.isZero() + + # test(BN254_Nogami) + test(BN254_Snarks) + test(BLS12_377) + test(BLS12_381) + # test(BN446) + # test(FKM12_447) + # test(BLS12_461) + # test(BN462) diff --git a/tests/test_fp2.nim b/tests/test_fp2.nim index 6cbb811..1994a5d 100644 --- a/tests/test_fp2.nim +++ b/tests/test_fp2.nim @@ -30,7 +30,19 @@ echo "test_fp2 xoshiro512** seed: ", seed # having too many elements on the stack (a couple kB) # will significantly slow down testing (100x is possible) -suite "𝔽p2 = 𝔽p[𝑖] (irreducible polynomial xΒ²+1)": +suite "𝔽p2 = 𝔽p[Β΅] (irreducible polynomial xΒ²+Β΅)": + test "Comparison sanity checks": + proc test(C: static Curve) = + var z, o {.noInit.}: Fp2[C] + + z.setZero() + o.setOne() + + check: not bool(z == o) + + test(BN254_Snarks) + test(BLS12_381) + test "Fp2 '1' coordinates in canonical domain": template test(C: static Curve) = block: @@ -235,7 +247,7 @@ suite "𝔽p2 = 𝔽p[𝑖] (irreducible polynomial xΒ²+1)": # test(BLS12_461) # test(BN462) - test "𝔽p2 = 𝔽p[𝑖] addition is associative and commutative": + test "Addition is associative and commutative": proc abelianGroup(curve: static Curve) = for _ in 0 ..< Iters: let a = rng.random(Fp2[curve]) @@ -286,7 +298,7 @@ suite "𝔽p2 = 𝔽p[𝑖] (irreducible polynomial xΒ²+1)": # abelianGroup(BLS12_461) # abelianGroup(BN462) - test "𝔽p2 = 𝔽p[𝑖] multiplication is associative and commutative": + test "Multiplication is associative and commutative": proc commutativeRing(curve: static Curve) = for _ in 0 ..< Iters: let a = rng.random(Fp2[curve]) @@ -337,7 +349,7 @@ suite "𝔽p2 = 𝔽p[𝑖] (irreducible polynomial xΒ²+1)": # commutativeRing(BLS12_461) # commutativeRing(BN462) - test "𝔽p2 = 𝔽p[𝑖] extension field multiplicative inverse": + test "Extension field multiplicative inverse": proc mulInvOne(curve: static Curve) = var one: Fp2[curve] one.setOne() @@ -360,3 +372,22 @@ suite "𝔽p2 = 𝔽p[𝑖] (irreducible polynomial xΒ²+1)": # mulInvOne(FKM12_447) # mulInvOne(BLS12_461) # mulInvOne(BN462) + + test "0 does not have a multiplicative inverse and should return 0 for projective/jacobian => affine coordinates conversion": + proc test(curve: static Curve) = + var z: Fp2[curve] + z.setZero() + + var zInv{.noInit.}: Fp2[curve] + + zInv.inv(z) + check: bool zInv.isZero() + + # test(BN254_Nogami) + test(BN254_Snarks) + test(BLS12_377) + test(BLS12_381) + # test(BN446) + # test(FKM12_447) + # test(BLS12_461) + # test(BN462) diff --git a/tests/test_fp6.nim b/tests/test_fp6.nim index fa6f17f..a06b45c 100644 --- a/tests/test_fp6.nim +++ b/tests/test_fp6.nim @@ -30,7 +30,19 @@ echo "test_fp6 xoshiro512** seed: ", seed # having too many elements on the stack (a couple kB) # will significantly slow down testing (100x is possible) -suite "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] (irreducible polynomial xΒ³ - (1+𝑖))": +suite "𝔽p6 = 𝔽p2[v] (irreducible polynomial vΒ³ - ΞΎ)": + test "Comparison sanity checks": + proc test(C: static Curve) = + var z, o {.noInit.}: Fp6[C] + + z.setZero() + o.setOne() + + check: not bool(z == o) + + test(BN254_Snarks) + test(BLS12_381) + test "Squaring 1 returns 1": template test(C: static Curve) = block: @@ -338,7 +350,7 @@ suite "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] (irreducible polynomial xΒ³ - (1+𝑖))": # test(BLS12_461) # test(BN462) - test "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] addition is associative and commutative": + test "Addition is associative and commutative": proc abelianGroup(curve: static Curve) = for _ in 0 ..< Iters: let a = rng.random(Fp6[curve]) @@ -389,7 +401,7 @@ suite "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] (irreducible polynomial xΒ³ - (1+𝑖))": # abelianGroup(BLS12_461) # abelianGroup(BN462) - test "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] multiplication is associative and commutative": + test "Multiplication is associative and commutative": proc commutativeRing(curve: static Curve) = for _ in 0 ..< Iters: let a = rng.random(Fp6[curve]) @@ -440,7 +452,7 @@ suite "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] (irreducible polynomial xΒ³ - (1+𝑖))": # commutativeRing(BLS12_461) # commutativeRing(BN462) - test "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] extension field multiplicative inverse": + test "Extension field multiplicative inverse": proc mulInvOne(curve: static Curve) = var one: Fp6[curve] one.setOne() @@ -470,3 +482,22 @@ suite "𝔽p6 = 𝔽p2[βˆ›(1+𝑖)] (irreducible polynomial xΒ³ - (1+𝑖))": # mulInvOne(FKM12_447) # mulInvOne(BLS12_461) # mulInvOne(BN462) + + test "0 does not have a multiplicative inverse and should return 0 for projective/jacobian => affine coordinates conversion": + proc test(curve: static Curve) = + var z: Fp6[curve] + z.setZero() + + var zInv{.noInit.}: Fp6[curve] + + zInv.inv(z) + check: bool zInv.isZero() + + # test(BN254_Nogami) + test(BN254_Snarks) + test(BLS12_377) + test(BLS12_381) + # test(BN446) + # test(FKM12_447) + # test(BLS12_461) + # test(BN462)