2002-08-02 14:28:37 +00:00
|
|
|
/*
|
2018-05-01 12:34:30 +00:00
|
|
|
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
2017-06-15 14:16:46 +00:00
|
|
|
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
2001-03-05 20:13:37 +00:00
|
|
|
*
|
2018-12-06 12:38:06 +00:00
|
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
2016-05-17 18:51:04 +00:00
|
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
|
|
* in the file LICENSE in the source distribution or at
|
|
|
|
* https://www.openssl.org/source/license.html
|
2001-03-05 20:13:37 +00:00
|
|
|
*/
|
2016-05-17 18:51:04 +00:00
|
|
|
|
2003-02-10 11:14:35 +00:00
|
|
|
#include <string.h>
|
2001-03-10 23:18:35 +00:00
|
|
|
#include <openssl/err.h>
|
|
|
|
|
2016-02-29 16:57:11 +00:00
|
|
|
#include "internal/cryptlib.h"
|
2014-10-28 22:58:56 +00:00
|
|
|
#include "internal/bn_int.h"
|
2001-03-05 20:13:37 +00:00
|
|
|
#include "ec_lcl.h"
|
2017-08-21 21:17:35 +00:00
|
|
|
#include "internal/refcount.h"
|
2001-03-10 23:18:35 +00:00
|
|
|
|
2003-02-06 19:25:12 +00:00
|
|
|
/*
|
2016-02-05 20:23:54 +00:00
|
|
|
* This file implements the wNAF-based interleaving multi-exponentiation method
|
2017-05-02 14:53:10 +00:00
|
|
|
* Formerly at:
|
|
|
|
* http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp
|
|
|
|
* You might now find it here:
|
|
|
|
* http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13
|
|
|
|
* http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf
|
|
|
|
* For multiplication with precomputation, we use wNAF splitting, formerly at:
|
|
|
|
* http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp
|
2003-02-06 19:25:12 +00:00
|
|
|
*/
|
2001-03-10 23:18:35 +00:00
|
|
|
|
2003-02-06 19:25:12 +00:00
|
|
|
/* structure for precomputed multiples of the generator */
|
2016-01-05 18:06:03 +00:00
|
|
|
struct ec_pre_comp_st {
|
2015-01-22 03:40:55 +00:00
|
|
|
const EC_GROUP *group; /* parent EC_GROUP object */
|
|
|
|
size_t blocksize; /* block size for wNAF splitting */
|
|
|
|
size_t numblocks; /* max. number of blocks for which we have
|
|
|
|
* precomputation */
|
|
|
|
size_t w; /* window size */
|
|
|
|
EC_POINT **points; /* array with pre-calculated multiples of
|
|
|
|
* generator: 'num' pointers to EC_POINT
|
|
|
|
* objects followed by a NULL */
|
|
|
|
size_t num; /* numblocks * 2^(w-1) */
|
2016-08-27 14:01:08 +00:00
|
|
|
CRYPTO_REF_COUNT references;
|
2016-02-29 16:57:11 +00:00
|
|
|
CRYPTO_RWLOCK *lock;
|
2016-01-05 18:06:03 +00:00
|
|
|
};
|
2003-02-06 19:25:12 +00:00
|
|
|
|
|
|
|
static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
|
2015-01-22 03:40:55 +00:00
|
|
|
{
|
|
|
|
EC_PRE_COMP *ret = NULL;
|
|
|
|
|
|
|
|
if (!group)
|
|
|
|
return NULL;
|
|
|
|
|
2015-09-03 13:15:26 +00:00
|
|
|
ret = OPENSSL_zalloc(sizeof(*ret));
|
2015-10-30 11:12:26 +00:00
|
|
|
if (ret == NULL) {
|
2015-01-22 03:40:55 +00:00
|
|
|
ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
|
|
|
return ret;
|
|
|
|
}
|
2016-02-29 16:57:11 +00:00
|
|
|
|
2015-01-22 03:40:55 +00:00
|
|
|
ret->group = group;
|
|
|
|
ret->blocksize = 8; /* default */
|
|
|
|
ret->w = 4; /* default */
|
|
|
|
ret->references = 1;
|
2016-02-29 16:57:11 +00:00
|
|
|
|
|
|
|
ret->lock = CRYPTO_THREAD_lock_new();
|
|
|
|
if (ret->lock == NULL) {
|
|
|
|
ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
|
|
|
OPENSSL_free(ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-01-22 03:40:55 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2003-02-06 19:25:12 +00:00
|
|
|
|
2016-01-05 18:06:03 +00:00
|
|
|
EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)
|
2015-01-22 03:40:55 +00:00
|
|
|
{
|
2016-02-29 16:57:11 +00:00
|
|
|
int i;
|
2016-01-05 18:06:03 +00:00
|
|
|
if (pre != NULL)
|
2016-08-27 14:01:08 +00:00
|
|
|
CRYPTO_UP_REF(&pre->references, &i, pre->lock);
|
2016-01-05 18:06:03 +00:00
|
|
|
return pre;
|
2015-01-22 03:40:55 +00:00
|
|
|
}
|
2003-02-06 19:25:12 +00:00
|
|
|
|
2016-01-05 18:06:03 +00:00
|
|
|
void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
|
2015-01-22 03:40:55 +00:00
|
|
|
{
|
2016-02-29 16:57:11 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (pre == NULL)
|
|
|
|
return;
|
|
|
|
|
2016-08-27 14:01:08 +00:00
|
|
|
CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);
|
2016-02-29 16:57:11 +00:00
|
|
|
REF_PRINT_COUNT("EC_ec", pre);
|
|
|
|
if (i > 0)
|
2015-01-22 03:40:55 +00:00
|
|
|
return;
|
2016-02-29 16:57:11 +00:00
|
|
|
REF_ASSERT_ISNT(i < 0);
|
2003-02-12 18:30:16 +00:00
|
|
|
|
2016-01-05 18:06:03 +00:00
|
|
|
if (pre->points != NULL) {
|
|
|
|
EC_POINT **pts;
|
2003-02-06 19:25:12 +00:00
|
|
|
|
2016-01-05 18:06:03 +00:00
|
|
|
for (pts = pre->points; *pts != NULL; pts++)
|
|
|
|
EC_POINT_free(*pts);
|
2015-01-22 03:40:55 +00:00
|
|
|
OPENSSL_free(pre->points);
|
|
|
|
}
|
2016-02-29 16:57:11 +00:00
|
|
|
CRYPTO_THREAD_lock_free(pre->lock);
|
2015-01-22 03:40:55 +00:00
|
|
|
OPENSSL_free(pre);
|
|
|
|
}
|
2003-02-06 19:25:12 +00:00
|
|
|
|
2018-04-19 12:43:33 +00:00
|
|
|
#define EC_POINT_BN_set_flags(P, flags) do { \
|
2018-04-19 09:21:51 +00:00
|
|
|
BN_set_flags((P)->X, (flags)); \
|
|
|
|
BN_set_flags((P)->Y, (flags)); \
|
|
|
|
BN_set_flags((P)->Z, (flags)); \
|
|
|
|
} while(0)
|
|
|
|
|
2018-04-20 11:02:52 +00:00
|
|
|
/*-
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
* This functions computes a single point multiplication over the EC group,
|
|
|
|
* using, at a high level, a Montgomery ladder with conditional swaps, with
|
|
|
|
* various timing attack defenses.
|
2018-04-19 16:10:21 +00:00
|
|
|
*
|
2018-04-24 13:00:08 +00:00
|
|
|
* It performs either a fixed point multiplication
|
2018-04-19 09:21:51 +00:00
|
|
|
* (scalar * generator)
|
2018-04-24 13:00:08 +00:00
|
|
|
* when point is NULL, or a variable point multiplication
|
2018-04-19 09:21:51 +00:00
|
|
|
* (scalar * point)
|
|
|
|
* when point is not NULL.
|
|
|
|
*
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
* `scalar` cannot be NULL and should be in the range [0,n) otherwise all
|
|
|
|
* constant time bets are off (where n is the cardinality of the EC group).
|
2018-04-19 09:21:51 +00:00
|
|
|
*
|
2018-07-08 07:39:39 +00:00
|
|
|
* This function expects `group->order` and `group->cardinality` to be well
|
|
|
|
* defined and non-zero: it fails with an error code otherwise.
|
|
|
|
*
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
* NB: This says nothing about the constant-timeness of the ladder step
|
|
|
|
* implementation (i.e., the default implementation is based on EC_POINT_add and
|
|
|
|
* EC_POINT_dbl, which of course are not constant time themselves) or the
|
|
|
|
* underlying multiprecision arithmetic.
|
2018-04-19 09:21:51 +00:00
|
|
|
*
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
* The product is stored in `r`.
|
2018-04-19 09:21:51 +00:00
|
|
|
*
|
2018-07-08 07:39:39 +00:00
|
|
|
* This is an internal function: callers are in charge of ensuring that the
|
|
|
|
* input parameters `group`, `r`, `scalar` and `ctx` are not NULL.
|
|
|
|
*
|
2018-04-19 09:21:51 +00:00
|
|
|
* Returns 1 on success, 0 otherwise.
|
|
|
|
*/
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
|
|
|
const BIGNUM *scalar, const EC_POINT *point,
|
|
|
|
BN_CTX *ctx)
|
2018-04-19 09:21:51 +00:00
|
|
|
{
|
2018-06-20 07:56:37 +00:00
|
|
|
int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
EC_POINT *p = NULL;
|
2018-04-19 09:21:51 +00:00
|
|
|
EC_POINT *s = NULL;
|
|
|
|
BIGNUM *k = NULL;
|
|
|
|
BIGNUM *lambda = NULL;
|
2018-06-20 07:56:37 +00:00
|
|
|
BIGNUM *cardinality = NULL;
|
2018-04-19 12:43:33 +00:00
|
|
|
int ret = 0;
|
2018-04-19 09:21:51 +00:00
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
/* early exit if the input point is the point at infinity */
|
|
|
|
if (point != NULL && EC_POINT_is_at_infinity(group, point))
|
|
|
|
return EC_POINT_set_to_infinity(group, r);
|
|
|
|
|
2018-07-08 07:39:39 +00:00
|
|
|
if (BN_is_zero(group->order)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER);
|
2018-05-07 08:27:45 +00:00
|
|
|
return 0;
|
2018-07-08 07:39:39 +00:00
|
|
|
}
|
2019-03-31 15:46:53 +00:00
|
|
|
if (BN_is_zero(group->cofactor)) {
|
2018-07-08 07:39:39 +00:00
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR);
|
|
|
|
return 0;
|
|
|
|
}
|
2018-05-07 08:27:45 +00:00
|
|
|
|
|
|
|
BN_CTX_start(ctx);
|
2018-04-19 09:21:51 +00:00
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (((p = EC_POINT_new(group)) == NULL)
|
|
|
|
|| ((s = EC_POINT_new(group)) == NULL)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
|
|
|
|
if (point == NULL) {
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (!EC_POINT_copy(p, group->generator)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
} else {
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (!EC_POINT_copy(p, point)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
}
|
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
EC_POINT_BN_set_flags(p, BN_FLG_CONSTTIME);
|
|
|
|
EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
|
2018-04-19 12:43:33 +00:00
|
|
|
EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
|
2018-04-19 09:21:51 +00:00
|
|
|
|
2018-06-20 07:56:37 +00:00
|
|
|
cardinality = BN_CTX_get(ctx);
|
2018-04-19 09:21:51 +00:00
|
|
|
lambda = BN_CTX_get(ctx);
|
|
|
|
k = BN_CTX_get(ctx);
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (k == NULL) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
|
|
|
|
/*
|
2018-06-20 07:56:37 +00:00
|
|
|
* Group cardinalities are often on a word boundary.
|
2018-04-19 09:21:51 +00:00
|
|
|
* So when we pad the scalar, some timing diff might
|
|
|
|
* pop if it needs to be expanded due to carries.
|
|
|
|
* So expand ahead of time.
|
|
|
|
*/
|
2018-06-20 07:56:37 +00:00
|
|
|
cardinality_bits = BN_num_bits(cardinality);
|
|
|
|
group_top = bn_get_top(cardinality);
|
2018-10-26 00:54:58 +00:00
|
|
|
if ((bn_wexpand(k, group_top + 2) == NULL)
|
|
|
|
|| (bn_wexpand(lambda, group_top + 2) == NULL)) {
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (!BN_copy(k, scalar)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
|
|
|
|
BN_set_flags(k, BN_FLG_CONSTTIME);
|
|
|
|
|
2018-06-20 07:56:37 +00:00
|
|
|
if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) {
|
2018-04-20 11:02:52 +00:00
|
|
|
/*-
|
2018-04-19 09:21:51 +00:00
|
|
|
* this is an unusual input, and we don't guarantee
|
|
|
|
* constant-timeness
|
|
|
|
*/
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (!BN_nnmod(k, k, cardinality, ctx)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
}
|
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (!BN_add(lambda, k, cardinality)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
BN_set_flags(lambda, BN_FLG_CONSTTIME);
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (!BN_add(k, lambda, cardinality)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
/*
|
2018-06-20 07:56:37 +00:00
|
|
|
* lambda := scalar + cardinality
|
|
|
|
* k := scalar + 2*cardinality
|
2018-04-19 09:21:51 +00:00
|
|
|
*/
|
2018-06-20 07:56:37 +00:00
|
|
|
kbit = BN_is_bit_set(lambda, cardinality_bits);
|
2018-10-26 00:54:58 +00:00
|
|
|
BN_consttime_swap(kbit, k, lambda, group_top + 2);
|
2018-04-19 09:21:51 +00:00
|
|
|
|
|
|
|
group_top = bn_get_top(group->field);
|
|
|
|
if ((bn_wexpand(s->X, group_top) == NULL)
|
|
|
|
|| (bn_wexpand(s->Y, group_top) == NULL)
|
|
|
|
|| (bn_wexpand(s->Z, group_top) == NULL)
|
|
|
|
|| (bn_wexpand(r->X, group_top) == NULL)
|
|
|
|
|| (bn_wexpand(r->Y, group_top) == NULL)
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
|| (bn_wexpand(r->Z, group_top) == NULL)
|
|
|
|
|| (bn_wexpand(p->X, group_top) == NULL)
|
|
|
|
|| (bn_wexpand(p->Y, group_top) == NULL)
|
|
|
|
|| (bn_wexpand(p->Z, group_top) == NULL)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
|
Implement coordinate blinding for EC_POINT
This commit implements coordinate blinding, i.e., it randomizes the
representative of an elliptic curve point in its equivalence class, for
prime curves implemented through EC_GFp_simple_method,
EC_GFp_mont_method, and EC_GFp_nist_method.
This commit is derived from the patch
https://marc.info/?l=openssl-dev&m=131194808413635 by Billy Brumley.
Coordinate blinding is a generally useful side-channel countermeasure
and is (mostly) free. The function itself takes a few field
multiplicationss, but is usually only necessary at the beginning of a
scalar multiplication (as implemented in the patch). When used this way,
it makes the values that variables take (i.e., field elements in an
algorithm state) unpredictable.
For instance, this mitigates chosen EC point side-channel attacks for
settings such as ECDH and EC private key decryption, for the
aforementioned curves.
For EC_METHODs using different coordinate representations this commit
does nothing, but the corresponding coordinate blinding function can be
easily added in the future to extend these changes to such curves.
Co-authored-by: Nicola Tuveri <nic.tuv@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 https://github.com/openssl/openssl/pull/6501)
2018-06-16 14:07:40 +00:00
|
|
|
/*-
|
|
|
|
* Apply coordinate blinding for EC_POINT.
|
|
|
|
*
|
|
|
|
* The underlying EC_METHOD can optionally implement this function:
|
|
|
|
* ec_point_blind_coordinates() returns 0 in case of errors or 1 on
|
|
|
|
* success or if coordinate blinding is not implemented for this
|
|
|
|
* group.
|
|
|
|
*/
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
if (!ec_point_blind_coordinates(group, p, ctx)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
/* Initialize the Montgomery ladder */
|
|
|
|
if (!ec_point_ladder_pre(group, r, s, p, ctx)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_PRE_FAILURE);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
/* top bit is a 1, in a fixed pos */
|
|
|
|
pbit = 1;
|
2018-04-19 09:21:51 +00:00
|
|
|
|
|
|
|
#define EC_POINT_CSWAP(c, a, b, w, t) do { \
|
|
|
|
BN_consttime_swap(c, (a)->X, (b)->X, w); \
|
|
|
|
BN_consttime_swap(c, (a)->Y, (b)->Y, w); \
|
|
|
|
BN_consttime_swap(c, (a)->Z, (b)->Z, w); \
|
|
|
|
t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
|
|
|
|
(a)->Z_is_one ^= (t); \
|
|
|
|
(b)->Z_is_one ^= (t); \
|
|
|
|
} while(0)
|
|
|
|
|
2018-04-20 11:02:52 +00:00
|
|
|
/*-
|
2018-04-19 16:10:21 +00:00
|
|
|
* The ladder step, with branches, is
|
|
|
|
*
|
|
|
|
* k[i] == 0: S = add(R, S), R = dbl(R)
|
|
|
|
* k[i] == 1: R = add(S, R), S = dbl(S)
|
|
|
|
*
|
|
|
|
* Swapping R, S conditionally on k[i] leaves you with state
|
|
|
|
*
|
|
|
|
* k[i] == 0: T, U = R, S
|
|
|
|
* k[i] == 1: T, U = S, R
|
|
|
|
*
|
|
|
|
* Then perform the ECC ops.
|
|
|
|
*
|
|
|
|
* U = add(T, U)
|
|
|
|
* T = dbl(T)
|
|
|
|
*
|
|
|
|
* Which leaves you with state
|
|
|
|
*
|
|
|
|
* k[i] == 0: U = add(R, S), T = dbl(R)
|
|
|
|
* k[i] == 1: U = add(S, R), T = dbl(S)
|
|
|
|
*
|
|
|
|
* Swapping T, U conditionally on k[i] leaves you with state
|
|
|
|
*
|
|
|
|
* k[i] == 0: R, S = T, U
|
|
|
|
* k[i] == 1: R, S = U, T
|
|
|
|
*
|
|
|
|
* Which leaves you with state
|
|
|
|
*
|
|
|
|
* k[i] == 0: S = add(R, S), R = dbl(R)
|
|
|
|
* k[i] == 1: R = add(S, R), S = dbl(S)
|
|
|
|
*
|
|
|
|
* So we get the same logic, but instead of a branch it's a
|
|
|
|
* conditional swap, followed by ECC ops, then another conditional swap.
|
|
|
|
*
|
|
|
|
* Optimization: The end of iteration i and start of i-1 looks like
|
|
|
|
*
|
|
|
|
* ...
|
|
|
|
* CSWAP(k[i], R, S)
|
|
|
|
* ECC
|
|
|
|
* CSWAP(k[i], R, S)
|
|
|
|
* (next iteration)
|
|
|
|
* CSWAP(k[i-1], R, S)
|
|
|
|
* ECC
|
|
|
|
* CSWAP(k[i-1], R, S)
|
|
|
|
* ...
|
|
|
|
*
|
|
|
|
* So instead of two contiguous swaps, you can merge the condition
|
|
|
|
* bits and do a single swap.
|
|
|
|
*
|
2018-04-20 11:02:52 +00:00
|
|
|
* k[i] k[i-1] Outcome
|
|
|
|
* 0 0 No Swap
|
|
|
|
* 0 1 Swap
|
|
|
|
* 1 0 Swap
|
|
|
|
* 1 1 No Swap
|
2018-04-19 16:10:21 +00:00
|
|
|
*
|
|
|
|
* This is XOR. pbit tracks the previous bit of k.
|
|
|
|
*/
|
|
|
|
|
2018-06-20 07:56:37 +00:00
|
|
|
for (i = cardinality_bits - 1; i >= 0; i--) {
|
2018-04-19 09:21:51 +00:00
|
|
|
kbit = BN_is_bit_set(k, i) ^ pbit;
|
|
|
|
EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
|
|
|
|
/* Perform a single step of the Montgomery ladder */
|
|
|
|
if (!ec_point_ladder_step(group, r, s, p, ctx)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_STEP_FAILURE);
|
2018-04-19 09:21:51 +00:00
|
|
|
goto err;
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
}
|
2018-04-19 09:21:51 +00:00
|
|
|
/*
|
|
|
|
* pbit logic merges this cswap with that of the
|
|
|
|
* next iteration
|
|
|
|
*/
|
|
|
|
pbit ^= kbit;
|
|
|
|
}
|
|
|
|
/* one final cswap to move the right value into r */
|
|
|
|
EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
|
|
|
|
#undef EC_POINT_CSWAP
|
|
|
|
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
/* Finalize ladder (and recover full point coordinates) */
|
|
|
|
if (!ec_point_ladder_post(group, r, s, p, ctx)) {
|
|
|
|
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_POST_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2018-04-19 09:21:51 +00:00
|
|
|
ret = 1;
|
|
|
|
|
2018-04-20 11:02:52 +00:00
|
|
|
err:
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
EC_POINT_free(p);
|
2019-03-17 16:28:24 +00:00
|
|
|
EC_POINT_clear_free(s);
|
2018-04-19 09:21:51 +00:00
|
|
|
BN_CTX_end(ctx);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2018-04-20 11:02:52 +00:00
|
|
|
|
2018-04-19 12:43:33 +00:00
|
|
|
#undef EC_POINT_BN_set_flags
|
2018-04-19 09:21:51 +00:00
|
|
|
|
2015-01-22 03:40:55 +00:00
|
|
|
/*
|
|
|
|
* TODO: table should be optimised for the wNAF-based implementation,
|
|
|
|
* sometimes smaller windows will give better performance (thus the
|
|
|
|
* boundaries should be increased)
|
2001-11-22 11:08:38 +00:00
|
|
|
*/
|
2001-11-15 22:32:11 +00:00
|
|
|
#define EC_window_bits_for_scalar_size(b) \
|
2015-01-22 03:40:55 +00:00
|
|
|
((size_t) \
|
|
|
|
((b) >= 2000 ? 6 : \
|
|
|
|
(b) >= 800 ? 5 : \
|
|
|
|
(b) >= 300 ? 4 : \
|
|
|
|
(b) >= 70 ? 3 : \
|
|
|
|
(b) >= 20 ? 2 : \
|
|
|
|
1))
|
2001-11-15 22:32:11 +00:00
|
|
|
|
2015-01-16 09:21:50 +00:00
|
|
|
/*-
|
|
|
|
* Compute
|
2001-11-15 22:32:11 +00:00
|
|
|
* \sum scalars[i]*points[i],
|
|
|
|
* also including
|
|
|
|
* scalar*generator
|
|
|
|
* in the addition if scalar != NULL
|
|
|
|
*/
|
2002-08-02 13:42:24 +00:00
|
|
|
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
2015-01-22 03:40:55 +00:00
|
|
|
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
|
|
|
BN_CTX *ctx)
|
|
|
|
{
|
|
|
|
const EC_POINT *generator = NULL;
|
|
|
|
EC_POINT *tmp = NULL;
|
|
|
|
size_t totalnum;
|
|
|
|
size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
|
|
|
|
size_t pre_points_per_block = 0;
|
|
|
|
size_t i, j;
|
|
|
|
int k;
|
|
|
|
int r_is_inverted = 0;
|
|
|
|
int r_is_at_infinity = 1;
|
|
|
|
size_t *wsize = NULL; /* individual window sizes */
|
|
|
|
signed char **wNAF = NULL; /* individual wNAFs */
|
|
|
|
size_t *wNAF_len = NULL;
|
|
|
|
size_t max_len = 0;
|
|
|
|
size_t num_val;
|
|
|
|
EC_POINT **val = NULL; /* precomputation */
|
|
|
|
EC_POINT **v;
|
|
|
|
EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
|
|
|
|
* 'pre_comp->points' */
|
|
|
|
const EC_PRE_COMP *pre_comp = NULL;
|
|
|
|
int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be
|
|
|
|
* treated like other scalars, i.e.
|
|
|
|
* precomputation is not available */
|
|
|
|
int ret = 0;
|
|
|
|
|
2018-07-04 12:35:18 +00:00
|
|
|
if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) {
|
2018-04-20 11:02:52 +00:00
|
|
|
/*-
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
* Handle the common cases where the scalar is secret, enforcing a
|
|
|
|
* scalar multiplication implementation based on a Montgomery ladder,
|
|
|
|
* with various timing attack defenses.
|
2018-04-19 12:43:33 +00:00
|
|
|
*/
|
2019-04-12 12:28:00 +00:00
|
|
|
if ((scalar != group->order) && (scalar != NULL) && (num == 0)) {
|
2018-07-04 12:35:18 +00:00
|
|
|
/*-
|
|
|
|
* In this case we want to compute scalar * GeneratorPoint: this
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
* codepath is reached most prominently by (ephemeral) key
|
|
|
|
* generation of EC cryptosystems (i.e. ECDSA keygen and sign setup,
|
|
|
|
* ECDH keygen/first half), where the scalar is always secret. This
|
|
|
|
* is why we ignore if BN_FLG_CONSTTIME is actually set and we
|
|
|
|
* always call the ladder version.
|
2018-07-04 12:35:18 +00:00
|
|
|
*/
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
|
2018-07-04 12:35:18 +00:00
|
|
|
}
|
2019-04-12 12:28:00 +00:00
|
|
|
if ((scalar == NULL) && (num == 1) && (scalars[0] != group->order)) {
|
2018-07-04 12:35:18 +00:00
|
|
|
/*-
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
* In this case we want to compute scalar * VariablePoint: this
|
|
|
|
* codepath is reached most prominently by the second half of ECDH,
|
|
|
|
* where the secret scalar is multiplied by the peer's public point.
|
|
|
|
* To protect the secret scalar, we ignore if BN_FLG_CONSTTIME is
|
|
|
|
* actually set and we always call the ladder version.
|
2018-07-04 12:35:18 +00:00
|
|
|
*/
|
EC point multiplication: add `ladder` scaffold
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 https://github.com/openssl/openssl/pull/6690)
2018-07-07 21:50:49 +00:00
|
|
|
return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
|
2018-07-04 12:35:18 +00:00
|
|
|
}
|
2018-04-19 12:43:33 +00:00
|
|
|
}
|
|
|
|
|
2015-01-22 03:40:55 +00:00
|
|
|
if (scalar != NULL) {
|
|
|
|
generator = EC_GROUP_get0_generator(group);
|
|
|
|
if (generator == NULL) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* look if we can use precomputed multiples of generator */
|
|
|
|
|
2016-01-05 18:06:03 +00:00
|
|
|
pre_comp = group->pre_comp.ec;
|
2015-01-22 03:40:55 +00:00
|
|
|
if (pre_comp && pre_comp->numblocks
|
|
|
|
&& (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==
|
|
|
|
0)) {
|
|
|
|
blocksize = pre_comp->blocksize;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* determine maximum number of blocks that wNAF splitting may
|
|
|
|
* yield (NB: maximum wNAF length is bit length plus one)
|
|
|
|
*/
|
|
|
|
numblocks = (BN_num_bits(scalar) / blocksize) + 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* we cannot use more blocks than we have precomputation for
|
|
|
|
*/
|
|
|
|
if (numblocks > pre_comp->numblocks)
|
|
|
|
numblocks = pre_comp->numblocks;
|
|
|
|
|
|
|
|
pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
|
|
|
|
|
|
|
|
/* check that pre_comp looks sane */
|
|
|
|
if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* can't use precomputation */
|
|
|
|
pre_comp = NULL;
|
|
|
|
numblocks = 1;
|
|
|
|
num_scalar = 1; /* treat 'scalar' like 'num'-th element of
|
|
|
|
* 'scalars' */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
totalnum = num + numblocks;
|
|
|
|
|
2017-12-07 18:39:34 +00:00
|
|
|
wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0]));
|
|
|
|
wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0]));
|
|
|
|
/* include space for pivot */
|
|
|
|
wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0]));
|
|
|
|
val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0]));
|
2015-01-22 03:40:55 +00:00
|
|
|
|
|
|
|
/* Ensure wNAF is initialised in case we end up going to err */
|
2015-10-30 11:12:26 +00:00
|
|
|
if (wNAF != NULL)
|
2015-01-22 03:40:55 +00:00
|
|
|
wNAF[0] = NULL; /* preliminary pivot */
|
|
|
|
|
2015-10-30 11:12:26 +00:00
|
|
|
if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {
|
2015-01-22 03:40:55 +00:00
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* num_val will be the total number of temporarily precomputed points
|
|
|
|
*/
|
|
|
|
num_val = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < num + num_scalar; i++) {
|
|
|
|
size_t bits;
|
|
|
|
|
|
|
|
bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
|
|
|
|
wsize[i] = EC_window_bits_for_scalar_size(bits);
|
|
|
|
num_val += (size_t)1 << (wsize[i] - 1);
|
|
|
|
wNAF[i + 1] = NULL; /* make sure we always have a pivot */
|
|
|
|
wNAF[i] =
|
|
|
|
bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
|
|
|
|
&wNAF_len[i]);
|
|
|
|
if (wNAF[i] == NULL)
|
|
|
|
goto err;
|
|
|
|
if (wNAF_len[i] > max_len)
|
|
|
|
max_len = wNAF_len[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (numblocks) {
|
|
|
|
/* we go here iff scalar != NULL */
|
|
|
|
|
|
|
|
if (pre_comp == NULL) {
|
|
|
|
if (num_scalar != 1) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
/* we have already generated a wNAF for 'scalar' */
|
|
|
|
} else {
|
|
|
|
signed char *tmp_wNAF = NULL;
|
|
|
|
size_t tmp_len = 0;
|
|
|
|
|
|
|
|
if (num_scalar != 0) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* use the window size for which we have precomputation
|
|
|
|
*/
|
|
|
|
wsize[num] = pre_comp->w;
|
|
|
|
tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);
|
|
|
|
if (!tmp_wNAF)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (tmp_len <= max_len) {
|
|
|
|
/*
|
|
|
|
* One of the other wNAFs is at least as long as the wNAF
|
|
|
|
* belonging to the generator, so wNAF splitting will not buy
|
|
|
|
* us anything.
|
|
|
|
*/
|
|
|
|
|
|
|
|
numblocks = 1;
|
|
|
|
totalnum = num + 1; /* don't use wNAF splitting */
|
|
|
|
wNAF[num] = tmp_wNAF;
|
|
|
|
wNAF[num + 1] = NULL;
|
|
|
|
wNAF_len[num] = tmp_len;
|
|
|
|
/*
|
|
|
|
* pre_comp->points starts with the points that we need here:
|
|
|
|
*/
|
|
|
|
val_sub[num] = pre_comp->points;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* don't include tmp_wNAF directly into wNAF array - use wNAF
|
|
|
|
* splitting and include the blocks
|
|
|
|
*/
|
|
|
|
|
|
|
|
signed char *pp;
|
|
|
|
EC_POINT **tmp_points;
|
|
|
|
|
|
|
|
if (tmp_len < numblocks * blocksize) {
|
|
|
|
/*
|
|
|
|
* possibly we can do with fewer blocks than estimated
|
|
|
|
*/
|
|
|
|
numblocks = (tmp_len + blocksize - 1) / blocksize;
|
|
|
|
if (numblocks > pre_comp->numblocks) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
2016-04-27 13:38:44 +00:00
|
|
|
OPENSSL_free(tmp_wNAF);
|
2015-01-22 03:40:55 +00:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
totalnum = num + numblocks;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* split wNAF in 'numblocks' parts */
|
|
|
|
pp = tmp_wNAF;
|
|
|
|
tmp_points = pre_comp->points;
|
|
|
|
|
|
|
|
for (i = num; i < totalnum; i++) {
|
|
|
|
if (i < totalnum - 1) {
|
|
|
|
wNAF_len[i] = blocksize;
|
|
|
|
if (tmp_len < blocksize) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
2016-04-27 13:38:44 +00:00
|
|
|
OPENSSL_free(tmp_wNAF);
|
2015-01-22 03:40:55 +00:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
tmp_len -= blocksize;
|
|
|
|
} else
|
|
|
|
/*
|
|
|
|
* last block gets whatever is left (this could be
|
|
|
|
* more or less than 'blocksize'!)
|
|
|
|
*/
|
|
|
|
wNAF_len[i] = tmp_len;
|
|
|
|
|
|
|
|
wNAF[i + 1] = NULL;
|
|
|
|
wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
|
|
|
|
if (wNAF[i] == NULL) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
|
|
|
OPENSSL_free(tmp_wNAF);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
memcpy(wNAF[i], pp, wNAF_len[i]);
|
|
|
|
if (wNAF_len[i] > max_len)
|
|
|
|
max_len = wNAF_len[i];
|
|
|
|
|
|
|
|
if (*tmp_points == NULL) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
|
|
|
OPENSSL_free(tmp_wNAF);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
val_sub[i] = tmp_points;
|
|
|
|
tmp_points += pre_points_per_block;
|
|
|
|
pp += blocksize;
|
|
|
|
}
|
|
|
|
OPENSSL_free(tmp_wNAF);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All points we precompute now go into a single array 'val'.
|
|
|
|
* 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a
|
|
|
|
* subarray of 'pre_comp->points' if we already have precomputation.
|
|
|
|
*/
|
2017-12-07 18:39:34 +00:00
|
|
|
val = OPENSSL_malloc((num_val + 1) * sizeof(val[0]));
|
2015-01-22 03:40:55 +00:00
|
|
|
if (val == NULL) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
val[num_val] = NULL; /* pivot element */
|
|
|
|
|
|
|
|
/* allocate points for precomputation */
|
|
|
|
v = val;
|
|
|
|
for (i = 0; i < num + num_scalar; i++) {
|
|
|
|
val_sub[i] = v;
|
|
|
|
for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
|
|
|
|
*v = EC_POINT_new(group);
|
|
|
|
if (*v == NULL)
|
|
|
|
goto err;
|
|
|
|
v++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!(v == val + num_val)) {
|
|
|
|
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2015-05-06 17:43:59 +00:00
|
|
|
if ((tmp = EC_POINT_new(group)) == NULL)
|
2015-01-22 03:40:55 +00:00
|
|
|
goto err;
|
|
|
|
|
2015-01-05 11:30:03 +00:00
|
|
|
/*-
|
|
|
|
* prepare precomputed values:
|
|
|
|
* val_sub[i][0] := points[i]
|
|
|
|
* val_sub[i][1] := 3 * points[i]
|
|
|
|
* val_sub[i][2] := 5 * points[i]
|
|
|
|
* ...
|
|
|
|
*/
|
2015-01-22 03:40:55 +00:00
|
|
|
for (i = 0; i < num + num_scalar; i++) {
|
|
|
|
if (i < num) {
|
|
|
|
if (!EC_POINT_copy(val_sub[i][0], points[i]))
|
|
|
|
goto err;
|
|
|
|
} else {
|
|
|
|
if (!EC_POINT_copy(val_sub[i][0], generator))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wsize[i] > 1) {
|
|
|
|
if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))
|
|
|
|
goto err;
|
|
|
|
for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {
|
|
|
|
if (!EC_POINT_add
|
|
|
|
(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!EC_POINTs_make_affine(group, num_val, val, ctx))
|
|
|
|
goto err;
|
2001-11-15 22:32:11 +00:00
|
|
|
|
2015-01-22 03:40:55 +00:00
|
|
|
r_is_at_infinity = 1;
|
|
|
|
|
|
|
|
for (k = max_len - 1; k >= 0; k--) {
|
|
|
|
if (!r_is_at_infinity) {
|
|
|
|
if (!EC_POINT_dbl(group, r, r, ctx))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < totalnum; i++) {
|
|
|
|
if (wNAF_len[i] > (size_t)k) {
|
|
|
|
int digit = wNAF[i][k];
|
|
|
|
int is_neg;
|
|
|
|
|
|
|
|
if (digit) {
|
|
|
|
is_neg = digit < 0;
|
|
|
|
|
|
|
|
if (is_neg)
|
|
|
|
digit = -digit;
|
|
|
|
|
|
|
|
if (is_neg != r_is_inverted) {
|
|
|
|
if (!r_is_at_infinity) {
|
|
|
|
if (!EC_POINT_invert(group, r, ctx))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
r_is_inverted = !r_is_inverted;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* digit > 0 */
|
|
|
|
|
|
|
|
if (r_is_at_infinity) {
|
|
|
|
if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
|
|
|
|
goto err;
|
|
|
|
r_is_at_infinity = 0;
|
|
|
|
} else {
|
|
|
|
if (!EC_POINT_add
|
|
|
|
(group, r, r, val_sub[i][digit >> 1], ctx))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r_is_at_infinity) {
|
|
|
|
if (!EC_POINT_set_to_infinity(group, r))
|
|
|
|
goto err;
|
|
|
|
} else {
|
|
|
|
if (r_is_inverted)
|
|
|
|
if (!EC_POINT_invert(group, r, ctx))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 1;
|
2001-11-15 22:32:11 +00:00
|
|
|
|
|
|
|
err:
|
2015-03-25 22:35:24 +00:00
|
|
|
EC_POINT_free(tmp);
|
2015-05-01 14:02:07 +00:00
|
|
|
OPENSSL_free(wsize);
|
|
|
|
OPENSSL_free(wNAF_len);
|
2015-01-22 03:40:55 +00:00
|
|
|
if (wNAF != NULL) {
|
|
|
|
signed char **w;
|
|
|
|
|
|
|
|
for (w = wNAF; *w != NULL; w++)
|
|
|
|
OPENSSL_free(*w);
|
|
|
|
|
|
|
|
OPENSSL_free(wNAF);
|
|
|
|
}
|
|
|
|
if (val != NULL) {
|
|
|
|
for (v = val; *v != NULL; v++)
|
|
|
|
EC_POINT_clear_free(*v);
|
|
|
|
|
|
|
|
OPENSSL_free(val);
|
|
|
|
}
|
2015-05-01 14:02:07 +00:00
|
|
|
OPENSSL_free(val_sub);
|
2015-01-22 03:40:55 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2001-03-11 12:27:24 +00:00
|
|
|
|
2014-12-28 02:48:40 +00:00
|
|
|
/*-
|
|
|
|
* ec_wNAF_precompute_mult()
|
2003-02-06 19:25:12 +00:00
|
|
|
* creates an EC_PRE_COMP object with preprecomputed multiples of the generator
|
|
|
|
* for use with wNAF splitting as implemented in ec_wNAF_mul().
|
2015-01-22 03:40:55 +00:00
|
|
|
*
|
2003-02-06 19:25:12 +00:00
|
|
|
* 'pre_comp->points' is an array of multiples of the generator
|
|
|
|
* of the following form:
|
|
|
|
* points[0] = generator;
|
|
|
|
* points[1] = 3 * generator;
|
|
|
|
* ...
|
|
|
|
* points[2^(w-1)-1] = (2^(w-1)-1) * generator;
|
|
|
|
* points[2^(w-1)] = 2^blocksize * generator;
|
|
|
|
* points[2^(w-1)+1] = 3 * 2^blocksize * generator;
|
|
|
|
* ...
|
|
|
|
* points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator
|
|
|
|
* points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator
|
|
|
|
* ...
|
|
|
|
* points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
|
|
|
|
* points[2^(w-1)*numblocks] = NULL
|
2002-08-02 13:42:24 +00:00
|
|
|
*/
|
|
|
|
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
2015-01-22 03:40:55 +00:00
|
|
|
{
|
|
|
|
const EC_POINT *generator;
|
|
|
|
EC_POINT *tmp_point = NULL, *base = NULL, **var;
|
2016-01-31 16:34:07 +00:00
|
|
|
const BIGNUM *order;
|
2015-01-22 03:40:55 +00:00
|
|
|
size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
|
|
|
|
EC_POINT **points = NULL;
|
|
|
|
EC_PRE_COMP *pre_comp;
|
|
|
|
int ret = 0;
|
2019-07-03 16:30:03 +00:00
|
|
|
#ifndef FIPS_MODE
|
|
|
|
BN_CTX *new_ctx = NULL;
|
|
|
|
#endif
|
2015-01-22 03:40:55 +00:00
|
|
|
|
|
|
|
/* if there is an old EC_PRE_COMP object, throw it away */
|
2016-01-14 02:26:00 +00:00
|
|
|
EC_pre_comp_free(group);
|
2015-01-22 03:40:55 +00:00
|
|
|
if ((pre_comp = ec_pre_comp_new(group)) == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
generator = EC_GROUP_get0_generator(group);
|
|
|
|
if (generator == NULL) {
|
|
|
|
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2019-07-03 16:30:03 +00:00
|
|
|
#ifndef FIPS_MODE
|
|
|
|
if (ctx == NULL)
|
2015-01-22 03:40:55 +00:00
|
|
|
ctx = new_ctx = BN_CTX_new();
|
2019-07-03 16:30:03 +00:00
|
|
|
#endif
|
|
|
|
if (ctx == NULL)
|
|
|
|
goto err;
|
2015-01-22 03:40:55 +00:00
|
|
|
|
|
|
|
BN_CTX_start(ctx);
|
|
|
|
|
2016-01-31 16:34:07 +00:00
|
|
|
order = EC_GROUP_get0_order(group);
|
|
|
|
if (order == NULL)
|
2015-01-22 03:40:55 +00:00
|
|
|
goto err;
|
|
|
|
if (BN_is_zero(order)) {
|
|
|
|
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
bits = BN_num_bits(order);
|
|
|
|
/*
|
|
|
|
* The following parameters mean we precompute (approximately) one point
|
|
|
|
* per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other
|
|
|
|
* bit lengths, other parameter combinations might provide better
|
|
|
|
* efficiency.
|
|
|
|
*/
|
|
|
|
blocksize = 8;
|
|
|
|
w = 4;
|
|
|
|
if (EC_window_bits_for_scalar_size(bits) > w) {
|
|
|
|
/* let's not make the window too small ... */
|
|
|
|
w = EC_window_bits_for_scalar_size(bits);
|
|
|
|
}
|
|
|
|
|
|
|
|
numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks
|
|
|
|
* to use for wNAF
|
|
|
|
* splitting */
|
|
|
|
|
|
|
|
pre_points_per_block = (size_t)1 << (w - 1);
|
|
|
|
num = pre_points_per_block * numblocks; /* number of points to compute
|
|
|
|
* and store */
|
|
|
|
|
2015-05-02 03:10:31 +00:00
|
|
|
points = OPENSSL_malloc(sizeof(*points) * (num + 1));
|
2015-10-30 11:12:26 +00:00
|
|
|
if (points == NULL) {
|
2015-01-22 03:40:55 +00:00
|
|
|
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
var = points;
|
|
|
|
var[num] = NULL; /* pivot */
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
if ((var[i] = EC_POINT_new(group)) == NULL) {
|
|
|
|
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-06 17:43:59 +00:00
|
|
|
if ((tmp_point = EC_POINT_new(group)) == NULL
|
|
|
|
|| (base = EC_POINT_new(group)) == NULL) {
|
2015-01-22 03:40:55 +00:00
|
|
|
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!EC_POINT_copy(base, generator))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
/* do the precomputation */
|
|
|
|
for (i = 0; i < numblocks; i++) {
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
if (!EC_POINT_dbl(group, tmp_point, base, ctx))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (!EC_POINT_copy(*var++, base))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
for (j = 1; j < pre_points_per_block; j++, var++) {
|
|
|
|
/*
|
|
|
|
* calculate odd multiples of the current base point
|
|
|
|
*/
|
|
|
|
if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i < numblocks - 1) {
|
|
|
|
/*
|
|
|
|
* get the next base (multiply current one by 2^blocksize)
|
|
|
|
*/
|
|
|
|
size_t k;
|
|
|
|
|
|
|
|
if (blocksize <= 2) {
|
|
|
|
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!EC_POINT_dbl(group, base, tmp_point, ctx))
|
|
|
|
goto err;
|
|
|
|
for (k = 2; k < blocksize; k++) {
|
|
|
|
if (!EC_POINT_dbl(group, base, base, ctx))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!EC_POINTs_make_affine(group, num, points, ctx))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
pre_comp->group = group;
|
|
|
|
pre_comp->blocksize = blocksize;
|
|
|
|
pre_comp->numblocks = numblocks;
|
|
|
|
pre_comp->w = w;
|
|
|
|
pre_comp->points = points;
|
|
|
|
points = NULL;
|
|
|
|
pre_comp->num = num;
|
2016-01-05 18:06:03 +00:00
|
|
|
SETPRECOMP(group, ec, pre_comp);
|
2015-01-22 03:40:55 +00:00
|
|
|
pre_comp = NULL;
|
|
|
|
ret = 1;
|
2016-01-05 18:06:03 +00:00
|
|
|
|
2001-03-11 12:27:24 +00:00
|
|
|
err:
|
2019-03-18 23:58:09 +00:00
|
|
|
BN_CTX_end(ctx);
|
2019-07-03 16:30:03 +00:00
|
|
|
#ifndef FIPS_MODE
|
2015-05-01 01:37:06 +00:00
|
|
|
BN_CTX_free(new_ctx);
|
2019-07-03 16:30:03 +00:00
|
|
|
#endif
|
2016-01-05 18:06:03 +00:00
|
|
|
EC_ec_pre_comp_free(pre_comp);
|
2015-01-22 03:40:55 +00:00
|
|
|
if (points) {
|
|
|
|
EC_POINT **p;
|
|
|
|
|
|
|
|
for (p = points; *p != NULL; p++)
|
|
|
|
EC_POINT_free(*p);
|
|
|
|
OPENSSL_free(points);
|
|
|
|
}
|
2015-03-25 22:35:24 +00:00
|
|
|
EC_POINT_free(tmp_point);
|
|
|
|
EC_POINT_free(base);
|
2015-01-22 03:40:55 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2002-08-02 13:42:24 +00:00
|
|
|
|
2003-02-06 19:25:12 +00:00
|
|
|
int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
|
2015-01-22 03:40:55 +00:00
|
|
|
{
|
2016-01-05 18:06:03 +00:00
|
|
|
return HAVEPRECOMP(group, ec);
|
2015-01-22 03:40:55 +00:00
|
|
|
}
|