As discovered by sipa in #1033.
See commit message for reasoning but note that the infinity handling will be replaced in the second commit again.
As discovered by sipa in #1033.
See commit message for reasoning but note that the infinity handling will be replaced in the second commit again.
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>
Benchmarks on Ryzen 5950X, locked at 2.2 GHz, GCC 12.2.0, running with SECP256K1_BENCH_ITERS=1000000 ./bench_internal add
:
Master:
0Benchmark , Min(us) , Avg(us) , Max(us)
1group_add_affine , 0.444 , 0.444 , 0.444
Master + #1078
0Benchmark , Min(us) , Avg(us) , Max(us)
1group_add_affine , 0.432 , 0.433 , 0.433