-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Effective affine precomputation (by Peter Dettman) #210
Conversation
2f2d6d2
to
01c3529
Compare
6d972e2
to
7305b6e
Compare
Rebased. |
This seems to give a 4.5-6.5% speedup for verification (without and with GLV). |
@gmaxwell @apoelstra: feel like reviewing this? |
Sure. I will need to do the prereading. |
Rebased. |
I believe this needs a citation to https://eprint.iacr.org/2008/051 (you should check to see that the technique agrees). |
Rebased. |
Rebased. |
@apoelstra Feel free to ask any questions. |
@apoelstra Happy to answer questions also. |
Hi guys, sorry for the delay. I've been caught up in schoolwork as I transition departments and haven't had enough spare cycles at once. This weekend is hopeful. Am I correct that there is an explicit description of the new code in https://eprint.iacr.org/2008/051 (which I haven't read)? Or should I use the algebra and motivations from the Co-Z paper (which I have read in some detail)? |
That paper is about using Co-Z for speeding up precomputations. It has
nothing to do with the effective affine trick (which can, however, be used
ad an alternative to co-z for the precomputation).
IIRC the effective affine trick is novel.
|
@apoelstra Further to @sipa's comments, "Co-Z" and "Effective affine" are independent techniques. Possibly that was somewhat obscured during the initial development, but with hindsight and a subsequent refactoring of the code (thanks to @sipa) it is now clear. I would like to clarify my position on claims of novelty. Since here we wish only to deal with "Effective affine", please also see #211 where I will shortly add a similar statement regarding "Co-Z". I claim independent discovery of "the effective affine trick", the essence of which is to perform the main ladder of a scalar multiplication on an isomorphism of the original curve, which avoids the cost of an inversion in the field, whilst still admitting the use of mixed addition with precomputed points. There are some minor corollary techniques reflected in the implementation, to wit: i) applying the trick to the pre-computation itself, and ii) applying the trick in the context of a Strauss-Shamir ladder (with one point fixed). I think it would be premature to claim novelty at this time, for (at least) the following reasons. Although I read quite widely in the relevant literature and know of no previous description or implementation of the technique, I have made only moderate efforts in a directed search. The technique is only a small step away from other commonly-understood techniques. I have not yet directly solicited the opinion of academic researchers, who are likely to have a more complete (e.g. paywalled) and up-to-date view of the literature. Although I have described the techniques on e.g. the IETF CFRG mailing list and in a few private communications, it has never been in the context of establishing novelty. Finally, I have not conducted or requested a prior art search with any patent office. |
Thanks for the summary!
|
The isomorphism involved can be compactly written as:
This is used in two different ways:
|
Awesome, thanks for the summary @peterdettman and for the algebra @sipa. I'll check over the code today (as in now) and tomorrow. |
@apoelstra In particular, feel free to comment about explanations given in comments (not enough, confusing, ...). |
@@ -82,10 +93,10 @@ static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a); | |||
static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a); | |||
|
|||
/** Set r equal to the double of a. */ | |||
static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a); | |||
static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_t *rzr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the doccomment needs to be updated to reflect what happens to rzr
. ("Is it r.z/a.z
or its recipricol?" is not obvious just from the name. I also don't think the behaviour for infinity is obvious since then rzr ought be be "0/0".)
@@ -93,11 +104,14 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c | |||
/** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient | |||
than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time | |||
guarantee, and b is allowed to be infinity. */ | |||
static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b); | |||
static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b, secp256k1_fe_t *rzr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here.
Tested ACK. Confirmed that the algebra made sense, comments were sensible, that it was implemented clearly and correctly. Ran unit tests on both commits under valgrind (no leaks or errors) and kcov ("full coverage" as much as that tool can tell), also ran the unit tests for This is a really elegant and clever improvement. Thanks a ton for your contribution @peterdettman . Sorry all for the delays in my review. |
* Make secp256k1_gej_add_var and secp256k1_gej_double return the Z ratio to go from a.z to r.z. * Use these Z ratios to speed up batch point conversion to affine coordinates, and to speed up batch conversion of points to a common Z coordinate. * Add a point addition function that takes a point with a known Z inverse. * Due to secp256k1's endomorphism, all additions in the EC multiplication code can work on affine coordinate (with an implicit common Z coordinate), correcting the Z coordinate of the result afterwards. Refactoring by Pieter Wuille: * Move more global-z logic into the group code. * Separate code for computing the odd multiples from the code to bring it to either storage or globalz format. * Rename functions. * Make all addition operations return Z ratios, and test them. * Make the zr table format compatible with future batch chaining (the first entry in zr becomes the ratio between the input and the first output). Original idea and code by Peter Dettman.
Updated the comments, as requested by @apoelstra. |
@apoelstra Thanks for the review! |
@apoelstra Thanks for your review, and for your kind words. |
Significantly refactored version of Peter Dettman's effective affine precomputation tricks.
See #174 and #41 for old discussion.