summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2018-07-16 17:32:39 +0000
committertb <>2018-07-16 17:32:39 +0000
commitcb198f135c139c2e0ab679576187b5a4c9876304 (patch)
treeb66bb68417b97c5fbb3ce4243eab9a7889ecfb82
parente8aad185bc3296229a54ff70b7d536b3acbf89c4 (diff)
downloadopenbsd-cb198f135c139c2e0ab679576187b5a4c9876304.tar.gz
openbsd-cb198f135c139c2e0ab679576187b5a4c9876304.tar.bz2
openbsd-cb198f135c139c2e0ab679576187b5a4c9876304.zip
Recommit Billy Brumley's ECC constant time patch with a fix for sparc64
from Nicola Tuveri (who spotted the omission of ecp_nist.c from the PR). discussed with jsing tested by jsg
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c12
-rw-r--r--src/lib/libcrypto/ec/ec_lcl.h17
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c99
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c5
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c5
-rw-r--r--src/lib/libcrypto/ec/ecp_smpl.c250
6 files changed, 341 insertions, 47 deletions
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
index 19a4250e41..1ca04194b3 100644
--- a/src/lib/libcrypto/ec/ec2_smpl.c
+++ b/src/lib/libcrypto/ec/ec2_smpl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec2_smpl.c,v 1.19 2018/07/15 16:27:39 tb Exp $ */ 1/* $OpenBSD: ec2_smpl.c,v 1.20 2018/07/16 17:32:39 tb Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 * 4 *
@@ -107,15 +107,11 @@ EC_GF2m_simple_method(void)
107 .point_cmp = ec_GF2m_simple_cmp, 107 .point_cmp = ec_GF2m_simple_cmp,
108 .make_affine = ec_GF2m_simple_make_affine, 108 .make_affine = ec_GF2m_simple_make_affine,
109 .points_make_affine = ec_GF2m_simple_points_make_affine, 109 .points_make_affine = ec_GF2m_simple_points_make_affine,
110 110 .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
111 /* 111 .mul_single_ct = ec_GFp_simple_mul_single_ct,
112 * the following three method functions are defined in 112 .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
113 * ec2_mult.c
114 */
115 .mul = ec_GF2m_simple_mul,
116 .precompute_mult = ec_GF2m_precompute_mult, 113 .precompute_mult = ec_GF2m_precompute_mult,
117 .have_precompute_mult = ec_GF2m_have_precompute_mult, 114 .have_precompute_mult = ec_GF2m_have_precompute_mult,
118
119 .field_mul = ec_GF2m_simple_field_mul, 115 .field_mul = ec_GF2m_simple_field_mul,
120 .field_sqr = ec_GF2m_simple_field_sqr, 116 .field_sqr = ec_GF2m_simple_field_sqr,
121 .field_div = ec_GF2m_simple_field_div, 117 .field_div = ec_GF2m_simple_field_div,
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h
index bcfd817b70..e430b3f64d 100644
--- a/src/lib/libcrypto/ec/ec_lcl.h
+++ b/src/lib/libcrypto/ec/ec_lcl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_lcl.h,v 1.9 2018/07/15 05:38:48 jsg Exp $ */ 1/* $OpenBSD: ec_lcl.h,v 1.10 2018/07/16 17:32:39 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -160,10 +160,12 @@ struct ec_method_st {
160 int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *); 160 int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
161 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); 161 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
162 162
163 /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult 163 /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult */
164 * (default implementations are used if the 'mul' pointer is 0): */ 164 int (*mul_generator_ct)(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, BN_CTX *);
165 int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 165 int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
166 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); 166 const EC_POINT *point, BN_CTX *);
167 int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
168 const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *);
167 int (*precompute_mult)(EC_GROUP *group, BN_CTX *); 169 int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
168 int (*have_precompute_mult)(const EC_GROUP *group); 170 int (*have_precompute_mult)(const EC_GROUP *group);
169 171
@@ -337,6 +339,11 @@ int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
337int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); 339int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
338int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 340int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
339int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); 341int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
342int ec_GFp_simple_mul_generator_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, BN_CTX *);
343int ec_GFp_simple_mul_single_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar,
344 const EC_POINT *point, BN_CTX *);
345int ec_GFp_simple_mul_double_nonct(const EC_GROUP *, EC_POINT *r, const BIGNUM *g_scalar,
346 const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *);
340 347
341 348
342/* method functions in ecp_mont.c */ 349/* method functions in ecp_mont.c */
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 53d79f232c..7e0ea017f9 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_lib.c,v 1.28 2018/07/15 16:27:39 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.29 2018/07/16 17:32:39 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -1026,47 +1026,88 @@ EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1026} 1026}
1027 1027
1028 1028
1029/* Functions for point multiplication. 1029/* Functions for point multiplication */
1030 *
1031 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1032 * otherwise we dispatch through methods.
1033 */
1034
1035int 1030int
1036EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 1031EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1037 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) 1032 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1038{ 1033{
1039 if (group->meth->mul == 0) 1034 /*
1040 /* use default */ 1035 * The function pointers must be set, and only support num == 0 and
1041 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 1036 * num == 1.
1042 1037 */
1043 return group->meth->mul(group, r, scalar, num, points, scalars, ctx); 1038 if (group->meth->mul_generator_ct == NULL ||
1039 group->meth->mul_single_ct == NULL ||
1040 group->meth->mul_double_nonct == NULL ||
1041 num > 1) {
1042 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1043 return 0;
1044 }
1045
1046 /* Either bP or aG + bP, this is sane. */
1047 if (num == 1 && points != NULL && scalars != NULL)
1048 return EC_POINT_mul(group, r, scalar, points[0], scalars[0],
1049 ctx);
1050
1051 /* aG, this is sane */
1052 if (scalar != NULL && points == NULL && scalars == NULL)
1053 return EC_POINT_mul(group, r, scalar, NULL, NULL, ctx);
1054
1055 /* anything else is an error */
1056 ECerror(ERR_R_EC_LIB);
1057 return 0;
1044} 1058}
1045 1059
1046int 1060int
1047EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 1061EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1048 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) 1062 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1049{ 1063{
1050 /* just a convenient interface to EC_POINTs_mul() */ 1064 if (group->meth->mul_generator_ct == NULL ||
1051 1065 group->meth->mul_single_ct == NULL ||
1052 const EC_POINT *points[1]; 1066 group->meth->mul_double_nonct == NULL) {
1053 const BIGNUM *scalars[1]; 1067 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1054 1068 return 0;
1055 points[0] = point; 1069 }
1056 scalars[0] = p_scalar; 1070 if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
1057 1071 /*
1058 return EC_POINTs_mul(group, r, g_scalar, 1072 * In this case we want to compute g_scalar * GeneratorPoint:
1059 (point != NULL && p_scalar != NULL), 1073 * this codepath is reached most prominently by (ephemeral) key
1060 points, scalars, ctx); 1074 * generation of EC cryptosystems (i.e. ECDSA keygen and sign
1075 * setup, ECDH keygen/first half), where the scalar is always
1076 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
1077 * set and we always call the constant time version.
1078 */
1079 return group->meth->mul_generator_ct(group, r, g_scalar, ctx);
1080 }
1081 if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
1082 /* In this case we want to compute p_scalar * GenericPoint:
1083 * this codepath is reached most prominently by the second half
1084 * of ECDH, where the secret scalar is multiplied by the peer's
1085 * public point. To protect the secret scalar, we ignore if
1086 * BN_FLG_CONSTTIME is actually set and we always call the
1087 * constant time version.
1088 */
1089 return group->meth->mul_single_ct(group, r, p_scalar, point,
1090 ctx);
1091 }
1092 if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1093 /*
1094 * In this case we want to compute
1095 * g_scalar * GeneratorPoint + p_scalar * GenericPoint:
1096 * this codepath is reached most prominently by ECDSA signature
1097 * verification. So we call the non-ct version.
1098 */
1099 return group->meth->mul_double_nonct(group, r, g_scalar,
1100 p_scalar, point, ctx);
1101 }
1102
1103 /* Anything else is an error. */
1104 ECerror(ERR_R_EC_LIB);
1105 return 0;
1061} 1106}
1062 1107
1063int 1108int
1064EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx) 1109EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
1065{ 1110{
1066 if (group->meth->mul == 0)
1067 /* use default */
1068 return ec_wNAF_precompute_mult(group, ctx);
1069
1070 if (group->meth->precompute_mult != 0) 1111 if (group->meth->precompute_mult != 0)
1071 return group->meth->precompute_mult(group, ctx); 1112 return group->meth->precompute_mult(group, ctx);
1072 else 1113 else
@@ -1076,10 +1117,6 @@ EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
1076int 1117int
1077EC_GROUP_have_precompute_mult(const EC_GROUP * group) 1118EC_GROUP_have_precompute_mult(const EC_GROUP * group)
1078{ 1119{
1079 if (group->meth->mul == 0)
1080 /* use default */
1081 return ec_wNAF_have_precompute_mult(group);
1082
1083 if (group->meth->have_precompute_mult != 0) 1120 if (group->meth->have_precompute_mult != 0)
1084 return group->meth->have_precompute_mult(group); 1121 return group->meth->have_precompute_mult(group);
1085 else 1122 else
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
index 40c512a357..ba4b9cad97 100644
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ b/src/lib/libcrypto/ec/ecp_mont.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_mont.c,v 1.15 2018/07/15 16:27:39 tb Exp $ */ 1/* $OpenBSD: ecp_mont.c,v 1.16 2018/07/16 17:32:39 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -102,6 +102,9 @@ EC_GFp_mont_method(void)
102 .point_cmp = ec_GFp_simple_cmp, 102 .point_cmp = ec_GFp_simple_cmp,
103 .make_affine = ec_GFp_simple_make_affine, 103 .make_affine = ec_GFp_simple_make_affine,
104 .points_make_affine = ec_GFp_simple_points_make_affine, 104 .points_make_affine = ec_GFp_simple_points_make_affine,
105 .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
106 .mul_single_ct = ec_GFp_simple_mul_single_ct,
107 .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
105 .field_mul = ec_GFp_mont_field_mul, 108 .field_mul = ec_GFp_mont_field_mul,
106 .field_sqr = ec_GFp_mont_field_sqr, 109 .field_sqr = ec_GFp_mont_field_sqr,
107 .field_encode = ec_GFp_mont_field_encode, 110 .field_encode = ec_GFp_mont_field_encode,
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
index 3e6005eebb..6ae1170808 100644
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ b/src/lib/libcrypto/ec/ecp_nist.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_nist.c,v 1.13 2018/07/15 16:27:39 tb Exp $ */ 1/* $OpenBSD: ecp_nist.c,v 1.14 2018/07/16 17:32:39 tb Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project. 3 * Written by Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -103,6 +103,9 @@ EC_GFp_nist_method(void)
103 .point_cmp = ec_GFp_simple_cmp, 103 .point_cmp = ec_GFp_simple_cmp,
104 .make_affine = ec_GFp_simple_make_affine, 104 .make_affine = ec_GFp_simple_make_affine,
105 .points_make_affine = ec_GFp_simple_points_make_affine, 105 .points_make_affine = ec_GFp_simple_points_make_affine,
106 .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
107 .mul_single_ct = ec_GFp_simple_mul_single_ct,
108 .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
106 .field_mul = ec_GFp_nist_field_mul, 109 .field_mul = ec_GFp_nist_field_mul,
107 .field_sqr = ec_GFp_nist_field_sqr 110 .field_sqr = ec_GFp_nist_field_sqr
108 }; 111 };
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c
index eabad4bd86..a25fd1df84 100644
--- a/src/lib/libcrypto/ec/ecp_smpl.c
+++ b/src/lib/libcrypto/ec/ecp_smpl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_smpl.c,v 1.21 2018/07/15 16:27:39 tb Exp $ */ 1/* $OpenBSD: ecp_smpl.c,v 1.22 2018/07/16 17:32:39 tb Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. 3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project. 4 * Includes code written by Bodo Moeller for the OpenSSL project.
@@ -103,6 +103,9 @@ EC_GFp_simple_method(void)
103 .point_cmp = ec_GFp_simple_cmp, 103 .point_cmp = ec_GFp_simple_cmp,
104 .make_affine = ec_GFp_simple_make_affine, 104 .make_affine = ec_GFp_simple_make_affine,
105 .points_make_affine = ec_GFp_simple_points_make_affine, 105 .points_make_affine = ec_GFp_simple_points_make_affine,
106 .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
107 .mul_single_ct = ec_GFp_simple_mul_single_ct,
108 .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
106 .field_mul = ec_GFp_simple_field_mul, 109 .field_mul = ec_GFp_simple_field_mul,
107 .field_sqr = ec_GFp_simple_field_sqr 110 .field_sqr = ec_GFp_simple_field_sqr
108 }; 111 };
@@ -1409,3 +1412,248 @@ ec_GFp_simple_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, BN
1409{ 1412{
1410 return BN_mod_sqr(r, a, &group->field, ctx); 1413 return BN_mod_sqr(r, a, &group->field, ctx);
1411} 1414}
1415
1416#define EC_POINT_BN_set_flags(P, flags) do { \
1417 BN_set_flags(&(P)->X, (flags)); \
1418 BN_set_flags(&(P)->Y, (flags)); \
1419 BN_set_flags(&(P)->Z, (flags)); \
1420} while(0)
1421
1422#define EC_POINT_CSWAP(c, a, b, w, t) do { \
1423 if (!BN_swap_ct(c, &(a)->X, &(b)->X, w) || \
1424 !BN_swap_ct(c, &(a)->Y, &(b)->Y, w) || \
1425 !BN_swap_ct(c, &(a)->Z, &(b)->Z, w)) \
1426 goto err; \
1427 t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
1428 (a)->Z_is_one ^= (t); \
1429 (b)->Z_is_one ^= (t); \
1430} while(0)
1431
1432/*
1433 * This function computes (in constant time) a point multiplication over the
1434 * EC group.
1435 *
1436 * At a high level, it is Montgomery ladder with conditional swaps.
1437 *
1438 * It performs either a fixed point multiplication
1439 * (scalar * generator)
1440 * when point is NULL, or a variable point multiplication
1441 * (scalar * point)
1442 * when point is not NULL.
1443 *
1444 * scalar should be in the range [0,n) otherwise all constant time bets are off.
1445 *
1446 * NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
1447 * which of course are not constant time themselves.
1448 *
1449 * The product is stored in r.
1450 *
1451 * Returns 1 on success, 0 otherwise.
1452 */
1453static int
1454ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1455 const EC_POINT *point, BN_CTX *ctx)
1456{
1457 int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
1458 EC_POINT *s = NULL;
1459 BIGNUM *k = NULL;
1460 BIGNUM *lambda = NULL;
1461 BIGNUM *cardinality = NULL;
1462 BN_CTX *new_ctx = NULL;
1463 int ret = 0;
1464
1465 if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL)
1466 return 0;
1467
1468 BN_CTX_start(ctx);
1469
1470 if ((s = EC_POINT_new(group)) == NULL)
1471 goto err;
1472
1473 if (point == NULL) {
1474 if (!EC_POINT_copy(s, group->generator))
1475 goto err;
1476 } else {
1477 if (!EC_POINT_copy(s, point))
1478 goto err;
1479 }
1480
1481 EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
1482
1483 if ((cardinality = BN_CTX_get(ctx)) == NULL)
1484 goto err;
1485 if ((lambda = BN_CTX_get(ctx)) == NULL)
1486 goto err;
1487 if ((k = BN_CTX_get(ctx)) == NULL)
1488 goto err;
1489 if (!BN_mul(cardinality, &group->order, &group->cofactor, ctx))
1490 goto err;
1491
1492 /*
1493 * Group cardinalities are often on a word boundary.
1494 * So when we pad the scalar, some timing diff might
1495 * pop if it needs to be expanded due to carries.
1496 * So expand ahead of time.
1497 */
1498 cardinality_bits = BN_num_bits(cardinality);
1499 group_top = cardinality->top;
1500 if ((bn_wexpand(k, group_top + 1) == NULL) ||
1501 (bn_wexpand(lambda, group_top + 1) == NULL))
1502 goto err;
1503
1504 if (!BN_copy(k, scalar))
1505 goto err;
1506
1507 BN_set_flags(k, BN_FLG_CONSTTIME);
1508
1509 if (BN_num_bits(k) > cardinality_bits || BN_is_negative(k)) {
1510 /*
1511 * This is an unusual input, and we don't guarantee
1512 * constant-timeness
1513 */
1514 if (!BN_nnmod(k, k, cardinality, ctx))
1515 goto err;
1516 }
1517
1518 if (!BN_add(lambda, k, cardinality))
1519 goto err;
1520 BN_set_flags(lambda, BN_FLG_CONSTTIME);
1521 if (!BN_add(k, lambda, cardinality))
1522 goto err;
1523 /*
1524 * lambda := scalar + cardinality
1525 * k := scalar + 2*cardinality
1526 */
1527 kbit = BN_is_bit_set(lambda, cardinality_bits);
1528 if (!BN_swap_ct(kbit, k, lambda, group_top + 1))
1529 goto err;
1530
1531 group_top = group->field.top;
1532 if ((bn_wexpand(&s->X, group_top) == NULL) ||
1533 (bn_wexpand(&s->Y, group_top) == NULL) ||
1534 (bn_wexpand(&s->Z, group_top) == NULL) ||
1535 (bn_wexpand(&r->X, group_top) == NULL) ||
1536 (bn_wexpand(&r->Y, group_top) == NULL) ||
1537 (bn_wexpand(&r->Z, group_top) == NULL))
1538 goto err;
1539
1540 /* top bit is a 1, in a fixed pos */
1541 if (!EC_POINT_copy(r, s))
1542 goto err;
1543
1544 EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
1545
1546 if (!EC_POINT_dbl(group, s, s, ctx))
1547 goto err;
1548
1549 pbit = 0;
1550
1551 /*
1552 * The ladder step, with branches, is
1553 *
1554 * k[i] == 0: S = add(R, S), R = dbl(R)
1555 * k[i] == 1: R = add(S, R), S = dbl(S)
1556 *
1557 * Swapping R, S conditionally on k[i] leaves you with state
1558 *
1559 * k[i] == 0: T, U = R, S
1560 * k[i] == 1: T, U = S, R
1561 *
1562 * Then perform the ECC ops.
1563 *
1564 * U = add(T, U)
1565 * T = dbl(T)
1566 *
1567 * Which leaves you with state
1568 *
1569 * k[i] == 0: U = add(R, S), T = dbl(R)
1570 * k[i] == 1: U = add(S, R), T = dbl(S)
1571 *
1572 * Swapping T, U conditionally on k[i] leaves you with state
1573 *
1574 * k[i] == 0: R, S = T, U
1575 * k[i] == 1: R, S = U, T
1576 *
1577 * Which leaves you with state
1578 *
1579 * k[i] == 0: S = add(R, S), R = dbl(R)
1580 * k[i] == 1: R = add(S, R), S = dbl(S)
1581 *
1582 * So we get the same logic, but instead of a branch it's a
1583 * conditional swap, followed by ECC ops, then another conditional swap.
1584 *
1585 * Optimization: The end of iteration i and start of i-1 looks like
1586 *
1587 * ...
1588 * CSWAP(k[i], R, S)
1589 * ECC
1590 * CSWAP(k[i], R, S)
1591 * (next iteration)
1592 * CSWAP(k[i-1], R, S)
1593 * ECC
1594 * CSWAP(k[i-1], R, S)
1595 * ...
1596 *
1597 * So instead of two contiguous swaps, you can merge the condition
1598 * bits and do a single swap.
1599 *
1600 * k[i] k[i-1] Outcome
1601 * 0 0 No Swap
1602 * 0 1 Swap
1603 * 1 0 Swap
1604 * 1 1 No Swap
1605 *
1606 * This is XOR. pbit tracks the previous bit of k.
1607 */
1608
1609 for (i = cardinality_bits - 1; i >= 0; i--) {
1610 kbit = BN_is_bit_set(k, i) ^ pbit;
1611 EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
1612 if (!EC_POINT_add(group, s, r, s, ctx))
1613 goto err;
1614 if (!EC_POINT_dbl(group, r, r, ctx))
1615 goto err;
1616 /*
1617 * pbit logic merges this cswap with that of the
1618 * next iteration
1619 */
1620 pbit ^= kbit;
1621 }
1622 /* one final cswap to move the right value into r */
1623 EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
1624
1625 ret = 1;
1626
1627 err:
1628 EC_POINT_free(s);
1629 if (ctx != NULL)
1630 BN_CTX_end(ctx);
1631 BN_CTX_free(new_ctx);
1632
1633 return ret;
1634}
1635
1636#undef EC_POINT_BN_set_flags
1637#undef EC_POINT_CSWAP
1638
1639int
1640ec_GFp_simple_mul_generator_ct(const EC_GROUP *group, EC_POINT *r,
1641 const BIGNUM *scalar, BN_CTX *ctx)
1642{
1643 return ec_GFp_simple_mul_ct(group, r, scalar, NULL, ctx);
1644}
1645
1646int
1647ec_GFp_simple_mul_single_ct(const EC_GROUP *group, EC_POINT *r,
1648 const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx)
1649{
1650 return ec_GFp_simple_mul_ct(group, r, scalar, point, ctx);
1651}
1652
1653int
1654ec_GFp_simple_mul_double_nonct(const EC_GROUP *group, EC_POINT *r,
1655 const BIGNUM *g_scalar, const BIGNUM *p_scalar, const EC_POINT *point,
1656 BN_CTX *ctx)
1657{
1658 return ec_wNAF_mul(group, r, g_scalar, 1, &point, &p_scalar, ctx);
1659}