group: Save a normalize_to_zero in gej_add_ge

The code currently switches to the alternative formula for lambda only if (R,M)
= (0,0) but the alternative formula works whenever M = 0: Specifically, M = 0
implies y1 = -y2. If x1 = x2, then a = -b this is the r = infinity case that we
handle separately. If x1 != x2, then the denominator in the alternative formula
is non-zero, so this formula is well-defined.

One needs to carefully check that the infinity assignment is still correct
because now the definition of m_alt at this point in the code has changed. But
this is true:

Case y1 = -y2:
  Then degenerate = true and infinity = ((x1 - x2)Z == 0) & ~a->infinity .
  a->infinity is handled separately.
  And if ~a->infinity, then Z = Z1 != 0,
  so infinity = (x1 - x2 == 0) = (a == -b) by case condition.

Case y1 != -y2:
  Then degenerate = false and infinity = ((y1 + y2)Z == 0) & ~a->infinity .
  a->infinity is handled separately.
  And if ~a->infinity, then Z = Z1 != 0,
  so infinity = (y1 + y2 == 0) = false by case condition.

Co-Authored-By: Pieter Wuille <pieter@wuille.net>
This commit is contained in:
Tim Ruffing
2022-02-04 15:11:38 +01:00
parent 1253a27756
commit ac71020ebe
2 changed files with 12 additions and 18 deletions

View File

@@ -157,7 +157,7 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
zeroes = {}
nonzeroes = {}
a_infinity = False
if (branch & 4) != 0:
if (branch & 2) != 0:
nonzeroes.update({a.Infinity : 'a_infinite'})
a_infinity = True
else:
@@ -176,15 +176,11 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
m_alt = -u2
tt = u1 * m_alt
rr = rr + tt
degenerate = (branch & 3) == 3
if (branch & 1) != 0:
degenerate = (branch & 1) != 0
if degenerate:
zeroes.update({m : 'm_zero'})
else:
nonzeroes.update({m : 'm_nonzero'})
if (branch & 2) != 0:
zeroes.update({rr : 'rr_zero'})
else:
nonzeroes.update({rr : 'rr_nonzero'})
rr_alt = s1
rr_alt = rr_alt * 2
m_alt = m_alt + u1
@@ -200,12 +196,11 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
t = rr_alt^2
rz = a.Z * m_alt
infinity = False
if (branch & 8) != 0:
if not a_infinity:
infinity = True
zeroes.update({rz : 'r.z=0'})
if (branch & 4) != 0:
infinity = True
zeroes.update({rz : 'r.z = 0'})
else:
nonzeroes.update({rz : 'r.z!=0'})
nonzeroes.update({rz : 'r.z != 0'})
t = t + q
rx = t
t = t * 2
@@ -289,14 +284,14 @@ if __name__ == "__main__":
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var)
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var)
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var)
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge)
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge)
success = success & (not check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old))
if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive":
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge, 43)
success = success & (not check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43))
sys.exit(int(not success))