Repository navigation
EC2m LD ladder - #6690
EC2m LD ladder#6690romen wants to merge 8 commits into
Conversation
There was a problem hiding this comment.
I'm not sure why make update wants to remove SM2 stuff, should this have been removed in a previous PR?
There was a problem hiding this comment.
@richsalz am I doing something wrong here? Should I use something more specific to update the error codes, rather than a full make update to avoid removing this SM2 stuff?
There was a problem hiding this comment.
I'm not sure what's happening. Maybe you're not on the current master? Curious.
There was a problem hiding this comment.
I am on latest master, but apparently it's "dirty" and apparently make update does not remove superfluous unused error codes unless new error codes are detected:
~/repos/openssl >>> git log -1
commit 03a5e5ae6304c75f611d3613bedf2019524ff0d6 (HEAD -> master, upstream/master)
Author: Patrick Steuer <patrick.steuer@de.ibm.com>
Date: Thu Jul 12 13:19:07 2018 -0400
Fix undefined behavior in s390x aes-gcm/ccm
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Andy Polyakov <appro@openssl.org>
~/repos/openssl >>> ack EC_F_PKEY_SM2_CTRL
crypto/ec/ec_err.c
264: {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_CTRL, 0), "pkey_sm2_ctrl"},
265: {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_CTRL_STR, 0), "pkey_sm2_ctrl_str"},
include/openssl/ecerr.h
186:# define EC_F_PKEY_SM2_CTRL 284
187:# define EC_F_PKEY_SM2_CTRL_STR 285
EC_F_PKEY_SM2_CTRL is one of the error codes that gets removed on my make update step, and as you can see there is no function currently using it: the SM2 functions now are using their own "submodule", e.g., SM2_F_PKEY_SM2_CTRL.
f57a97b to
562ded8
Compare
|
I just rebased on master after improving the "EC2M LD ladder: use it also for ECDSA verify" commit, hardening it against weird arguments that could be passed in but are not currently covered by testing. I actually moved most of those checks to the /cc @bbbrumley (that gave me the original input for the latest changes) for feedback on 063e3d9 |
|
Ping @richsalz for an opinion about moving the checks to the wrapper (and if that should actually be ported to 1.1.0 as well) and possibly also on how OMC would prefer the commits to be organized. I know @mattcaswell is on holiday, does anyone else from the committers care to give feedback on this? Maybe @dot-asm ? |
|
I'm not worried about how the commits are organized, although others might be. Moving the checks to the wrapper, and out of the internal functions is reasonable if those aren't part of the public API. |
There was a problem hiding this comment.
I'd like to suggest to add a space here, to align it with group, to denote the fact that they are in same expression.
There was a problem hiding this comment.
Explicit new_ctx != NULL is preferred nowadays.
There was a problem hiding this comment.
In such case you can remove new_ctx altogether. This comment applies even below.
There was a problem hiding this comment.
EC_POINT_free checks for NULL, no need to do it here.
|
The fact that some of errors are removed is no mystery. They are actually unreferenced, and should be removed. Note that they start with EC_F_PKEY, while all actual codes are SM2_F_PKEY. So right thing to do would be to run |
|
@dot-asm I saw your comment only now, after replying to @richsalz above with the same answer.
I will do a rebase now, with a commit to remove the old unused ones, followed by our new commits, making them "atomic" so that each of them will include only its own Thanks! (I'll now temporarily mark this PR as WIP and ping you again when it's ready for review!) |
There was a problem hiding this comment.
Formatting nit, two lines are one space too short.
There was a problem hiding this comment.
thanks for catching this! I will fix both of them during the rebase!
There was a problem hiding this comment.
Formatting nit. Two lines are one space too short.
0f9ed0d to
84e3bdd
Compare
|
@dot-asm @davidben @richsalz @mattcaswell Out of WIP now:
Thanks everyone for the feedback so far! |
There was a problem hiding this comment.
Formatting nit, two lines are one space too long.
There was a problem hiding this comment.
Even though it's kind of obvious from the context I'd like to see "LD" expanded. Even elsewhere.
There was a problem hiding this comment.
I fixed this in the code, it might be useful to rewrite the message for commit 84e3bdd722cc0, e.g.:
EC2M Lopez-Dahab ladder: use it also for ECDSA verify
By default `ec_mul_consttime` (which uses the ladder implementation) is
used only for k*Generator or k*GenericPoint.
ECDSA verification uses a*Generator+b*GenericPoint: this commit
forces the use of `ec_mul_consttime` (and the Lopez-Dahab ladder) also
for the ECDSA verification path, while using the default wNAF
implementation for any other case.
With this commit ec_mul_consttime loses the static attribute, and is
added to ec_lcl.h so EC_METHODs can directly use it.
While working on a new custom EC_POINTs_mul implementation, I realized
that many checks (e.g. all the points being compatible with the given
group, creating ctx if NULL, scalar==NULL && num==0) were duplicated
again and again in every single implementation (and actually some
implementations lacked some tests). I thought that it makes way more
sense for those checks that are independent from the actual
implementation and should always be done, to be moved in the
EC_POINTs_mul wrapper: so this commit also includes these changes.
There was a problem hiding this comment.
Sytle nit: spaces in front of and after "=" are required; i.e. int ret = 0;
There was a problem hiding this comment.
Style nit: space needed after ","
There was a problem hiding this comment.
There seems to be inconsistency in this function about whether we call ECerr or not.
There was a problem hiding this comment.
The "fixup!" commits below fix the reported formatting nits in the corresponding commits.
I will have now a look at ec_mul_consttime to raise ECerr in the appropriate cases.
There was a problem hiding this comment.
@mattcaswell can you check 6f9fd585222 ?
(I couldn't find more specific reasons than ERR_R_EC_LIB/ERR_R_BN_LIB). Suggestions?
There was a problem hiding this comment.
Indentation seems strange here.
There was a problem hiding this comment.
This is side note, which means that no action is actually expected, just think about it. While p != q works, I find it a bit less readable. Because you have to unravel it to scalar being NULL. At the same time replacing it with scalar == NULL doesn't make it perfect either. Maybe [again, this is just for consideration] one can arrange code so that condition would be q != NULL? So that pattern would be
if (q != NULL) EC_POINT_add(group, q, q, p, ctx);
else q = p;
There was a problem hiding this comment.
On additional thought, it's probably names being so generic that tips me off. For example if q was called say acc[umulator], it wouldn't be a problem. Point is that generic names make you wonder if there is any meaning behind letter. For example you would think of p as "product", and what would be q? And what is connection? With name like acc[umulator] you see directly that it's just a placeholder...
There was a problem hiding this comment.
bbd0e2b is my attempt at maximizing readability: I clearly and explicitly separated the 3 cases: this comes at the "cost" of duplicating one line of code (ec_mul_consttime(group, r, scalars[0], points[0], ctx)) but I think it is a good tradeoff which does not uglify the code and solves way more problems in readability and upkeep than it creates.
There was a problem hiding this comment.
I for one sense inconsistency in this function naming. Now when it's shared, a better name might be more appropriate. Maybe ec_mul_by_scalar_consttime? Just me? Obviously side note...
There was a problem hiding this comment.
What about ec_scalarmul_ladder?
I feel a bit of resistance in naming anything "consttime" given that we cannot promise anything about the underlying layer.
There was a problem hiding this comment.
Once we agree on the renaming, given that it would require fixing themake update step and rewrite some commit messages, I would do a proper rebase, also squashing the stack of small fixup commits that piled up till now.
But I will have to wait until tomorrow to act upon this.
I totally favor a renaming, for the reason above, let's just agree on a proper name.
@bbbrumley /@mattcaswell would you care to chime in with your opinion on proper names?
There was a problem hiding this comment.
What about ec_scalarmul_ladder?
Great! Except maybe ec_scalar_mul_ladder? Just pick either :-)
There was a problem hiding this comment.
maybe ec_scalar_mul_ladder
+1
There was a problem hiding this comment.
ec_scalar_mul_ladder works for me.
Run `make update ERROR_REBUILD=-rebuild` to remove some stale error codes for SM2 (which is now using its own submodule for error codes, i.e., `SM2_*`). I filtered out copyright bumps for other unmodified headers, and also the following diff (as both files are internal and should never be included in C++ source): ```diff diff --git a/crypto/include/internal/sm2err.h b/crypto/include/internal/sm2err.h index f32d26c..9a7e2b6 100644 --- a/crypto/include/internal/sm2err.h +++ b/crypto/include/internal/sm2err.h @@ -15,6 +15,9 @@ # ifndef OPENSSL_NO_SM2 +# ifdef __cplusplus +extern "C" +# endif int ERR_load_SM2_strings(void); /* diff --git a/include/internal/dsoerr.h b/include/internal/dsoerr.h index ac6bdcd..a54a185 100644 --- a/include/internal/dsoerr.h +++ b/include/internal/dsoerr.h @@ -15,6 +15,9 @@ # ifndef OPENSSL_NO_DSO +# ifdef __cplusplus +extern "C" +# endif int ERR_load_DSO_strings(void); /* ```
6f9fd58 to
3e0abd5
Compare
for specialized Montgomery ladder implementations PR openssl#6009 and openssl#6070 replaced the default EC point multiplication path for prime and binary curves with a unified Montgomery ladder implementation with various timing attack defenses (for the common paths when a secret scalar is feed to the point multiplication). The newly introduced default implementation directly used EC_POINT_add/dbl in the main loop. The scaffolding introduced by this commit allows EC_METHODs to define a specialized `ladder_step` function to improve performances by taking advantage of efficient formulas for differential addition-and-doubling and different coordinate systems. - `ladder_pre` is executed before the main loop of the ladder: by default it copies the input point P into S, and doubles it into R. Specialized implementations could, e.g., use this hook to transition to different coordinate systems before copying and doubling; - `ladder_step` is the core of the Montgomery ladder loop: by default it computes `S := R+S; R := 2R;`, but specific implementations could, e.g., implement a more efficient formula for differential addition-and-doubling; - `ladder_post` is executed after the Montgomery ladder loop: by default it's a noop, but specialized implementations could, e.g., use this hook to transition back from the coordinate system used for optimizing the differential addition-and-doubling or recover the y coordinate of the result point. This commit also renames `ec_mul_consttime` to `ec_scalar_mul_ladder`, as it better corresponds to what this function does: nothing can be truly said about the constant-timeness of the overall execution of this function, given that the underlying operations are not necessarily constant-time themselves. What this implementation ensures is that the same fixed sequence of operations is executed for each scalar multiplication (for a given EC_GROUP), with no dependency on the value of the input scalar. Co-authored-by: Sohaib ul Hassan <soh.19.hassan@gmail.com> Co-authored-by: Billy Brumley <bbrumley@gmail.com>
As for copyright bumps, I'd say it's appropriate. As for pair of extern "C", one could just as well leave them. Because they are auto-generated, and the script will keep re-adding them, because it makes no difference between public and private headers. One can argue that script should be fixed, but couple of extern "C" in private headers is really no biggie, and one can just as well tolerate them. Let's put it this way. If it's not much trouble to re-add those extern "C", do so. And if you feel that it's rather a distraction in the context of this request, do nothing. Script might get fixed at later point [or not]. |
|
So 243fb25 adds the Re @bbbrumley :
I think it is appropriate to have the checks (and documentation) added where @dot-asm : 99ae74e adds back the |
|
Out of WIP now. |
| * order or cofactor set to 0. | ||
| */ | ||
| if (num > 1 || BN_is_zero(group->order) || BN_is_zero(group->cofactor)) | ||
| return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); |
There was a problem hiding this comment.
On side note one can find it confusing that ec_wNAF_mul calls ec_scalar_mul_ladder with inverse conditions. In other words except for scalar != NULL && num==1 case one can simply call ec_wNAF_mul. This makes you wonder if it would be appropriate to implement the additional scalar != NULL && num==1 in ec_wNAF_mul. In which case this method can be simply omitted, right?
There was a problem hiding this comment.
If I understand correctly, you are suggesting to handle the (scalar != NULL && num==1) in ec_wNAF_mul() calling ec_scalar_mul_ladder: the problem with that is that for other implementations ec_scalar_mul_ladder can be slower than the regular "non-const-time" path.
Double multiplication is basically only used by ECDSA verification right now, where all the inputs are public, so a fast and insecure implementation could be used, rather than ec_scalar_mul_ladder.
What we really would need is refactor the EC_METHOD API to ditch/deprecate the unified EC_POINTs_mul (which makes a sense from a mathematical point of view, but is not really the way the 3 different scalar multiplication cases are used by cryptosystems) in favor of 3 different function pointers for fixed_point_mul, variable_point_mul, double_point_mul.
Right now we have wrappers that are forcing the 3 different operations into the unified EC_POINTs_mul path, and then in ec_scalar_mul_ladder we split them again.
In some cases, a specific double_point_mul could almost half the current execution cost of the verification step, as we could use formulas (e.g., derived from Shamir's trick) that avoid doing 2 distinct scalar multiplications and then 1 addition, and share as much computation as possible.
But this must wait for the next major release development cycle!
Does this answer your comment, or did I completely misunderstand what you meant?
Edit: grammar, formatting
There was a problem hiding this comment.
the problem with that is that for other implementations ec_scalar_mul_ladder can be slower
Fair enough. Then how about
if (scalar == NULL || num != 1 || order == 0 || cofactor == 0)
return ec_wNAF_mul()
/* scalar != NULL && num == 1 is faster with ec_scalar_mul_ladder here [and now] */
...
Just keep in mind that this is side note, so "how about" is really just a question, it's not a suggestion. Point is not larger than order != 0 && cofactor !=0 case in ec_wNAF_mul being partial duplicate of the code below this line. [Off topic, this kind of asks for question if ec_wNAF_mul is actually suitable name.]
There was a problem hiding this comment.
I think this change would hinder readability and mask intent: what we want to convey is that binary non-degenerate curves (i.e., have a order and cardinality that makes sense, given that mathematically speaking 0 is not really an option for either value) use ec_scalar_mul_ladder for the 3 cases, any other crazyness that can be fed through the EC_POINTs_mul API is basically uncharted territory and not cryptographically relevant, so we will let the default wNAF implementation handle it.
It's true that, currently, we could let ec_wNAF_mul handle every case but the double scalar multiplication, and it would work, depending on the fact that that function will itself call the ec_scalar_mul_ladder for the fixed and variable point.
But I think that relying on the fact that currently something called ec_wNAF_mul is hijacked to perform a completely different code path in specific cases is even worse than duplicating the checks!
Re: renaming ec_wNAF_mul
I would argue that it would make sense to have in ec_mult.c something like ec_points_mul_default working as a wrapper distinguishing the two single point multiplication cases (for which ec_scalar_mul_ladder is then called) from the truly multi-point multiplication case (for which ec_wNAF_mul is called).
But I would leave this to a separate PR.
Even better, in a separate PR I would rather start a transition to 3 separate function pointers in EC_METHOD for the fixed/variable/double point multiplication, and let the EC_POINTs_mul wrapper do something like:
/* All kinds of checks on not NULL args, every point_is_compat, etc. */
if (group->meth->points_mul)
/* you're on your own, probably will have to replicate most of the checks below */
return group->meth->points_mul(...);
degenerate = BN_is_zero(group->order) || BN_is_zero(group->cofactor);
if (scalar != NULL && num == 0)
if (group->meth->fixed_scalar_mul)
/* you still have to handle degenerate cases */
return group->meth->fixed_scalar_mul(...);
else if (!degenerate)
return ec_scalar_mul_ladder(...);
if (scalar == NULL && num == 1)
if (group->meth->variable_scalar_mul)
/* you still have to handle degenerate cases */
return group->meth->variable_scalar_mul(...);
else if (!degenerate)
return ec_scalar_mul_ladder(...);
if (scalar != NULL && num == 1 && group->meth->double_scalar_mul)
/* you still have to handle degenerate cases */
return group->meth->double_scalar_mul(...);
/* HIC SUNT DRACONES */
return ec_wNAF_mul(...);Until something similar exists, I don't think we can avoid specific EC_POINTs_mul implementations to repeat the checks for the 3 cases.
And the existence of the degenerate case will also probably mean that most non-default implementations of the 3 scalar_mul variants will need to repeat the check for degenerate cases.
Edit: Reword a bit and fixed a lot of typos....
|
This looks good to me, but I'll not approve until/unless @mattcaswell says that his concerns have been addressed. |
|
I will merge shortly |
|
Thanks @mattcaswell! It might have gotten lost in the conversation, but during rebase the msg for the first commit is in need of editing! |
Yes..I spotted that, thanks. |
|
Pushed! Thanks! |
Run `make update ERROR_REBUILD=-rebuild` to remove some stale error codes for SM2 (which is now using its own submodule for error codes, i.e., `SM2_*`). Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from #6690)
for specialized Montgomery ladder implementations PR #6009 and #6070 replaced the default EC point multiplication path for prime and binary curves with a unified Montgomery ladder implementation with various timing attack defenses (for the common paths when a secret scalar is feed to the point multiplication). The newly introduced default implementation directly used EC_POINT_add/dbl in the main loop. The scaffolding introduced by this commit allows EC_METHODs to define a specialized `ladder_step` function to improve performances by taking advantage of efficient formulas for differential addition-and-doubling and different coordinate systems. - `ladder_pre` is executed before the main loop of the ladder: by default it copies the input point P into S, and doubles it into R. Specialized implementations could, e.g., use this hook to transition to different coordinate systems before copying and doubling; - `ladder_step` is the core of the Montgomery ladder loop: by default it computes `S := R+S; R := 2R;`, but specific implementations could, e.g., implement a more efficient formula for differential addition-and-doubling; - `ladder_post` is executed after the Montgomery ladder loop: by default it's a noop, but specialized implementations could, e.g., use this hook to transition back from the coordinate system used for optimizing the differential addition-and-doubling or recover the y coordinate of the result point. This commit also renames `ec_mul_consttime` to `ec_scalar_mul_ladder`, as it better corresponds to what this function does: nothing can be truly said about the constant-timeness of the overall execution of this function, given that the underlying operations are not necessarily constant-time themselves. What this implementation ensures is that the same fixed sequence of operations is executed for each scalar multiplication (for a given EC_GROUP), with no dependency on the value of the input scalar. Co-authored-by: Sohaib ul Hassan <soh.19.hassan@gmail.com> Co-authored-by: Billy Brumley <bbrumley@gmail.com> Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from #6690)
and catch corner cases better and earlier Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from #6690)
This commit uses the new ladder scaffold to implement a specialized ladder step based on differential addition-and-doubling in mixed Lopez-Dahab projective coordinates, modified to independently blind the operands. The arithmetic in `ladder_pre`, `ladder_step` and `ladder_post` is auto generated with tooling: - see, e.g., "Guide to ECC" Alg 3.40 for reference about the `ladder_pre` implementation; - see https://www.hyperelliptic.org/EFD/g12o/auto-code/shortw/xz/ladder/mladd-2003-s.op3 for the differential addition-and-doubling formulas implemented in `ladder_step`; - see, e.g., "Fast Multiplication on Elliptic Curves over GF(2**m) without Precomputation" (Lopez and Dahab, CHES 1999) Appendix Alg Mxy for the `ladder_post` implementation to recover the `(x,y)` result in affine coordinates. Co-authored-by: Billy Brumley <bbrumley@gmail.com> Co-authored-by: Sohaib ul Hassan <soh.19.hassan@gmail.com> Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from #6690)
By default `ec_scalar_mul_ladder` (which uses the Lopez-Dahab ladder implementation) is used only for (k * Generator) or (k * VariablePoint). ECDSA verification uses (a * Generator + b * VariablePoint): this commit forces the use of `ec_scalar_mul_ladder` also for the ECDSA verification path, while using the default wNAF implementation for any other case. With this commit `ec_scalar_mul_ladder` loses the static attribute, and is added to ec_lcl.h so EC_METHODs can directly use it. While working on a new custom EC_POINTs_mul implementation, I realized that many checks (e.g. all the points being compatible with the given EC_GROUP, creating a temporary BN_CTX if `ctx == NULL`, check for the corner case `scalar == NULL && num == 0`) were duplicated again and again in every single implementation (and actually some implementations lacked some of the tests). I thought that it makes way more sense for those checks that are independent from the actual implementation and should always be done, to be moved in the EC_POINTs_mul wrapper: so this commit also includes these changes. Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from #6690)
This commit leverages the Montgomery ladder scaffold introduced in openssl#6690 (alongside a specialized Lopez-Dahab ladder for binary curves) to provide a specialized differential addition-and-double implementation to speedup prime curves, while keeping all the features of `ec_scalar_mul_ladder` against SCA attacks. The arithmetic in ladder_pre, ladder_step and ladder_post is auto generated with tooling, from the following formulae: - `ladder_pre`: Formula 3 for doubling from Izu-Takagi "A fast parallel elliptic curve multiplication resistant against side channel attacks", as described at https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2 - `ladder_step`: differential addition-and-doubling Eq. (8) and (10) from Izu-Takagi "A fast parallel elliptic curve multiplication resistant against side channel attacks", as described at https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-ladd-2002-it-3 - `ladder_post`: y-coordinate recovery using Eq. (8) from Brier-Joye "Weierstrass Elliptic Curves and Side-Channel Attacks", modified to work in projective coordinates. Co-authored-by: Nicola Tuveri <nic.tuv@gmail.com>
This commit leverages the Montgomery ladder scaffold introduced in #6690 (alongside a specialized Lopez-Dahab ladder for binary curves) to provide a specialized differential addition-and-double implementation to speedup prime curves, while keeping all the features of `ec_scalar_mul_ladder` against SCA attacks. The arithmetic in ladder_pre, ladder_step and ladder_post is auto generated with tooling, from the following formulae: - `ladder_pre`: Formula 3 for doubling from Izu-Takagi "A fast parallel elliptic curve multiplication resistant against side channel attacks", as described at https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2 - `ladder_step`: differential addition-and-doubling Eq. (8) and (10) from Izu-Takagi "A fast parallel elliptic curve multiplication resistant against side channel attacks", as described at https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-ladd-2002-it-3 - `ladder_post`: y-coordinate recovery using Eq. (8) from Brier-Joye "Weierstrass Elliptic Curves and Side-Channel Attacks", modified to work in projective coordinates. Co-authored-by: Nicola Tuveri <nic.tuv@gmail.com> Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from #6772)
TL;DR
PR #6009 and #6070 unified the code path for EC point multiplication for prime and binary curves, introducing several SCA defenses.
For binary curves the impact on performance of the security improvements was very high (as reported in some GitHub issues, e.g., #6396 ).
This PR aims at improving the existing
ec_mul_consttime(now renamed to a more fittingec_scalar_mul_ladder) function introducing hooks that anEC_METHODcould use to provide specialized, and faster, implementations.We then provide such a specialized implementation that applies to binary curves, bringing the performance of cryptosystems built on top of such curves reasonably close to the performance level of
1.1.1-pre3(before most of the new SCA countermeasures were applied).In most instances (see the detailed table below) the new implementation is more than 10x times faster than current master.
The new implementation is still (reasonably) slower than
1.1.1-pre3, but:1.1.1-pre3is leaky in, e.g., bit length for keygen and derive;1.1.1-pre3has no bug attack or DPA mitigations.This PR only affects binary curves, but the scaffold introduced by the first commit opens the way for improving in a similar way also prime curves, which also suffered a slowdown as a consequence of the recent SCA hardening process, although minor in comparison to the effect on binary curves.
Co-authored by @sohhas and @bbbrumley .
Benchmark table
The following table presents the CPU cycles average computed over 1000 runs per operation.
The benchmarks were executed on Intel Core i7-6700 CPU, running at 3.40GHz, with Turbo Boost disabled, no frequency scaling and on a single core reserved only for the execution of the benchmark, while the rest of the system was mostly idle.
pre3masterLD_ladderLD/pre3LD/masterCommits breakout
Remove stale SM2 error codes
Run
make update ERROR_REBUILD=-rebuildto remove some stale error codes for SM2 (which is now using its own submodule for error codes, i.e.,SM2_*).I filtered out copyright bumps for other unmodified headers.
EC point multiplication: add
ladderscaffold for specialized Montgomery ladder implementationsPR #6009 and #6070 replaced the default EC point multiplication path for prime and binary curves with a unified Montgomery ladder implementation with various timing attack defenses (for the common paths when a secret scalar is feed to the point multiplication).
The newly introduced default implementation directly used
EC_POINT_add/dblin the main loop.The scaffolding introduced by this commit allows
EC_METHODs to define a specializedladder_stepfunction to improve performances by taking advantage of efficient formulas for differential addition-and-doubling and different coordinate systems.ladder_preis executed before the main loop of the ladder: by default it copies the input pointPintoS, and doubles it intoR.Specialized implementations could, e.g., use this hook to transition to different coordinate systems before copying and doubling;
ladder_stepis the core of the Montgomery ladder loop: by default it computesS := R+S; R := 2R;, but specific implementations could, e.g., implement a more efficient formula for differential addition-and-doubling;ladder_postis executed after the Montgomery ladder loop: by default it's a noop, but specialized implementations could, e.g., use this hook to transition back from the coordinate system used for optimizing the differential addition-and-doubling or recover the y coordinate of the result point.This commit also renames
ec_mul_consttimetoec_scalar_mul_ladder, as it better corresponds to what this function does: nothing can be truly said about the constant-timeness of the overall execution of this function, given that the underlying operations are not necessarily constant-time themselves.What this implementation ensures is that the same fixed sequence of operations is executed for each scalar multiplication (for a given
EC_GROUP), with no dependency on the value of the input scalar.[test] test some important ladder corner cases and catch corner cases better and earlier
Self explicative, you might consider squashing this commit with the previous one; I decided to keep it separate as it is technically independent from any other change in this PR and because it was authored by @bbbrumley alone.
EC2M Lopez-Dahab ladder implementation
This commit uses the new ladder scaffold to implement a specialized ladder step based on differential addition-and-doubling in mixed Lopez-Dahab projective coordinates, modified to independently blind the operands.
The arithmetic in
ladder_pre,ladder_stepandladder_postis auto generated with tooling:ladder_preimplementation;ladder_step;ladder_postimplementation to recover the(x,y)result in affine coordinates.EC2M Lopez-Dahab ladder: use it also for ECDSA verify
By default
ec_scalar_mul_ladder(which uses the Lopez-Dahab ladder implementation) is used only for (k * Generator) or (k * VariablePoint).ECDSA verification uses (
a * Generator + b * VariablePoint): this commit forces the use ofec_scalar_mul_ladderalso for the ECDSA verification path, while using the default wNAF implementation for any other case.With this commit
ec_scalar_mul_ladderloses the static attribute, and is added to ec_lcl.h so EC_METHODs can directly use it.While working on a new custom
EC_POINTs_mulimplementation, I realized that many checks (e.g. all the points being compatible with the givenEC_GROUP, creating a temporaryBN_CTXifctx == NULL, check for the corner casescalar == NULL && num == 0) were duplicated again and again in every single implementation (and actually some implementations lacked some of the tests).I thought that it makes way more sense for those checks that are independent from the actual implementation and should always be done, to be moved in the
EC_POINTs_mulwrapper: so this commit also includes these changes.Again this is technically independent from the parent commit, but you might consider squashing it with the parent: without this ECDSA verification using binary curves does not benefit from the performance boost brought by the new implementation.
Checklist
make update) once we receive feedbackec_mul_consttimetoec_scalar_mul_laddergroup->orderandgroup->cofactorchecks inec_scalar_mul_ladder