edwards: improve the performance of Add, MixedAdd and IsOnCurve #441
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This PR improves the performance if Edwards-related curves in methods:
Add
,MixedAdd
andIsOnCuve
. The crux of the problem is two indirect allocations produced byGetEdwardsCurve(...)
call.I’m pretty sure that, at least for
MixedAdd
, this is a regression since we didn’t have this allocation some version ago. While fixing it, I noticed this was also happening today forAdd
andIsOnCuve
, so I’m unsure if those are regressions.The benchmarks also surface a performance problem I’m not fixing in this PR to avoid convoluting topics. I’ll give a brief explanation in the benchmark section below.
Type of change
How has this been tested?
This PR doesn’t change the logic or add new border cases, so existing tests cover correct behavior.
How has this been benchmarked?
The three mentioned methods (
Add
,MixedAdd
andIsOnCurve
) didn’t have benchmarks for Edwards curves, so that’s potentially the reason this was not detected before. I’ve created new benchmarks for each of them to measure the effect of this change.Running these benchmarks before and after this PR:
Note: you can run the “before” by checking out commit
53784cadc54d39c1d1
where I’ve included the benchmarks formaster
without the performance improvements.Note-2: I'm only showing differences for Bandersnatch; but the same would apply to other edwards.
In summary: 2x speedup in computation, and removing both existing allocations.
Now, notice the
Add/Extended
benchmark. This result is unchanged, which makes sense since it didn’t callGetEdwardsCurve(...)
in the implementation, but the performance is odd since it should be faster than projective. I know the reason, so I’d recommend seeing this draft PR and maybe continuing the discussion there. :)