-/* $OpenBSD: ec2_mult.c,v 1.10 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec2_mult.c,v 1.11 2018/07/15 05:38:48 jsg Exp $ */
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
return ret;
}
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
return ret;
}
ret = 2;
- err:
+err:
BN_CTX_end(ctx);
return ret;
}
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
return ret;
}
ret = 1;
- err:
+err:
EC_POINT_free(p);
EC_POINT_free(acc);
BN_CTX_free(new_ctx);
-/* $OpenBSD: ec2_oct.c,v 1.9 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec2_oct.c,v 1.10 2018/07/15 05:38:48 jsg Exp $ */
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
BN_CTX_free(new_ctx);
return ret;
- err:
+err:
if (used_ctx)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
}
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
-/* $OpenBSD: ec2_smpl.c,v 1.17 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec2_smpl.c,v 1.18 2018/07/15 05:38:48 jsg Exp $ */
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
.point_cmp = ec_GF2m_simple_cmp,
.make_affine = ec_GF2m_simple_make_affine,
.points_make_affine = ec_GF2m_simple_points_make_affine,
- .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
- .mul_single_ct = ec_GFp_simple_mul_single_ct,
- .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
+
+ /*
+ * the following three method functions are defined in
+ * ec2_mult.c
+ */
+ .mul = ec_GF2m_simple_mul,
.precompute_mult = ec_GF2m_precompute_mult,
.have_precompute_mult = ec_GF2m_have_precompute_mult,
+
.field_mul = ec_GF2m_simple_field_mul,
.field_sqr = ec_GF2m_simple_field_sqr,
.field_div = ec_GF2m_simple_field_div,
group->b.d[i] = 0;
ret = 1;
- err:
+err:
return ret;
}
}
ret = 1;
- err:
+err:
return ret;
}
ret = 1;
- err:
+err:
if (ctx != NULL)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
point->Z_is_one = 1;
ret = 1;
- err:
+err:
return ret;
}
}
ret = 1;
- err:
+err:
return ret;
}
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
if (!BN_GF2m_add(lh, lh, y2))
goto err;
ret = BN_is_zero(lh);
- err:
+err:
if (ctx)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
goto err;
ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
- err:
+err:
if (ctx)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
ret = 1;
- err:
+err:
if (ctx)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
-/* $OpenBSD: ec_ameth.c,v 1.21 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec_ameth.c,v 1.22 2018/07/15 05:38:48 jsg Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
ptype, pval, penc, penclen))
return 1;
- err:
+err:
if (ptype == V_ASN1_OBJECT)
ASN1_OBJECT_free(pval);
else
return eckey;
- ecerr:
+ecerr:
if (eckey)
EC_KEY_free(eckey);
return NULL;
EVP_PKEY_assign_EC_KEY(pkey, eckey);
return 1;
- ecerr:
+ecerr:
if (eckey)
EC_KEY_free(eckey);
return 0;
EVP_PKEY_assign_EC_KEY(pkey, eckey);
return 1;
- ecliberr:
+ecliberr:
ECerror(ERR_R_EC_LIB);
- ecerr:
+ecerr:
if (eckey)
EC_KEY_free(eckey);
return 0;
if (!ECPKParameters_print(bp, group, off))
goto err;
ret = 1;
- err:
+err:
if (!ret)
ECerror(reason);
BN_free(pub_key);
-/* $OpenBSD: ec_asn1.c,v 1.28 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec_asn1.c,v 1.29 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
ok = 1;
- err:
+err:
BN_free(tmp);
return (ok);
}
ok = 1;
- err:
+err:
free(buffer_1);
free(buffer_2);
BN_free(tmp_1);
}
ok = 1;
- err:
- if (!ok) {
+err: if (!ok) {
if (ret && !param)
ECPARAMETERS_free(ret);
ret = NULL;
}
ok = 1;
- err:
- if (!ok) {
+err: if (!ok) {
EC_GROUP_clear_free(ret);
ret = NULL;
}
*a = group;
}
- err:
+err:
ECPKPARAMETERS_free(params);
return (group);
}
*a = ret;
return (ret);
- err:
+err:
if (a == NULL || *a != ret)
EC_KEY_free(ret);
if (priv_key)
goto err;
}
ok = 1;
- err:
+err:
free(buffer);
if (priv_key)
EC_PRIVATEKEY_free(priv_key);
-/* $OpenBSD: ec_check.c,v 1.7 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec_check.c,v 1.8 2018/07/15 05:38:48 jsg Exp $ */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
}
ret = 1;
- err:
+err:
if (ctx != NULL)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
-/* $OpenBSD: ec_curve.c,v 1.17 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec_curve.c,v 1.18 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
}
}
ok = 1;
- err:
+err:
if (!ok) {
EC_GROUP_free(group);
group = NULL;
-/* $OpenBSD: ec_key.c,v 1.15 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec_key.c,v 1.16 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
ok = 1;
- err:
+err:
BN_free(order);
if (pub_key != NULL && eckey->pub_key == NULL)
EC_POINT_free(pub_key);
}
}
ok = 1;
- err:
+err:
BN_CTX_free(ctx);
EC_POINT_free(point);
return (ok);
ok = 1;
- err:
+err:
BN_CTX_free(ctx);
EC_POINT_free(point);
return ok;
-/* $OpenBSD: ec_lcl.h,v 1.8 2018/07/10 21:55:49 tb Exp $ */
+/* $OpenBSD: ec_lcl.h,v 1.9 2018/07/15 05:38:48 jsg Exp $ */
/*
* Originally written by Bodo Moeller for the OpenSSL project.
*/
int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
- /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult */
- int (*mul_generator_ct)(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, BN_CTX *);
- int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
- const EC_POINT *point, BN_CTX *);
- int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
- const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *);
+ /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
+ * (default implementations are used if the 'mul' pointer is 0): */
+ int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
int (*have_precompute_mult)(const EC_GROUP *group);
int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
-int ec_GFp_simple_mul_generator_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, BN_CTX *);
-int ec_GFp_simple_mul_single_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar,
- const EC_POINT *point, BN_CTX *);
-int ec_GFp_simple_mul_double_nonct(const EC_GROUP *, EC_POINT *r, const BIGNUM *g_scalar,
- const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *);
/* method functions in ecp_mont.c */
-/* $OpenBSD: ec_lib.c,v 1.26 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec_lib.c,v 1.27 2018/07/15 05:38:48 jsg Exp $ */
/*
* Originally written by Bodo Moeller for the OpenSSL project.
*/
return r;
- err:
+err:
BN_CTX_end(ctx);
if (ctx_new)
BN_CTX_free(ctx);
}
-/* Functions for point multiplication */
+/* Functions for point multiplication.
+ *
+ * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
+ * otherwise we dispatch through methods.
+ */
+
int
EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
{
- /*
- * The function pointers must be set, and only support num == 0 and
- * num == 1.
- */
- if (group->meth->mul_generator_ct == NULL ||
- group->meth->mul_single_ct == NULL ||
- group->meth->mul_double_nonct == NULL ||
- num > 1) {
- ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
-
- /* Either bP or aG + bP, this is sane. */
- if (num == 1 && points != NULL && scalars != NULL)
- return EC_POINT_mul(group, r, scalar, points[0], scalars[0],
- ctx);
-
- /* aG, this is sane */
- if (scalar != NULL && points == NULL && scalars == NULL)
- return EC_POINT_mul(group, r, scalar, NULL, NULL, ctx);
-
- /* anything else is an error */
- ECerror(ERR_R_EC_LIB);
- return 0;
+ if (group->meth->mul == 0)
+ /* use default */
+ return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+
+ return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
}
int
EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
{
- if (group->meth->mul_generator_ct == NULL ||
- group->meth->mul_single_ct == NULL ||
- group->meth->mul_double_nonct == NULL) {
- ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
- /*
- * In this case we want to compute g_scalar * GeneratorPoint:
- * this 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 constant time version.
- */
- return group->meth->mul_generator_ct(group, r, g_scalar, ctx);
- }
- if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
- /* In this case we want to compute p_scalar * GenericPoint:
- * 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
- * constant time version.
- */
- return group->meth->mul_single_ct(group, r, p_scalar, point,
- ctx);
- }
- if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
- /*
- * In this case we want to compute
- * g_scalar * GeneratorPoint + p_scalar * GenericPoint:
- * this codepath is reached most prominently by ECDSA signature
- * verification. So we call the non-ct version.
- */
- return group->meth->mul_double_nonct(group, r, g_scalar,
- p_scalar, point, ctx);
- }
-
- /* Anything else is an error. */
- ECerror(ERR_R_EC_LIB);
- return 0;
+ /* just a convenient interface to EC_POINTs_mul() */
+
+ const EC_POINT *points[1];
+ const BIGNUM *scalars[1];
+
+ points[0] = point;
+ scalars[0] = p_scalar;
+
+ return EC_POINTs_mul(group, r, g_scalar,
+ (point != NULL && p_scalar != NULL),
+ points, scalars, ctx);
}
int
EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
{
+ if (group->meth->mul == 0)
+ /* use default */
+ return ec_wNAF_precompute_mult(group, ctx);
+
if (group->meth->precompute_mult != 0)
return group->meth->precompute_mult(group, ctx);
else
int
EC_GROUP_have_precompute_mult(const EC_GROUP * group)
{
+ if (group->meth->mul == 0)
+ /* use default */
+ return ec_wNAF_have_precompute_mult(group);
+
if (group->meth->have_precompute_mult != 0)
return group->meth->have_precompute_mult(group);
else
-/* $OpenBSD: ec_mult.c,v 1.22 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ec_mult.c,v 1.23 2018/07/15 05:38:48 jsg Exp $ */
/*
* Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
*/
len = j;
ok = 1;
- err:
+err:
if (!ok) {
free(r);
r = NULL;
ret = 1;
- err:
+err:
BN_CTX_free(new_ctx);
EC_POINT_free(tmp);
free(wsize);
pre_comp = NULL;
ret = 1;
- err:
+err:
if (ctx != NULL)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
-/* $OpenBSD: eck_prn.c,v 1.13 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: eck_prn.c,v 1.14 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
goto err;
}
ret = 1;
- err:
+err:
if (!ret)
ECerror(reason);
BN_free(p);
-/* $OpenBSD: ecp_mont.c,v 1.13 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_mont.c,v 1.14 2018/07/15 05:38:48 jsg Exp $ */
/*
* Originally written by Bodo Moeller for the OpenSSL project.
*/
.point_cmp = ec_GFp_simple_cmp,
.make_affine = ec_GFp_simple_make_affine,
.points_make_affine = ec_GFp_simple_points_make_affine,
- .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
- .mul_single_ct = ec_GFp_simple_mul_single_ct,
- .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
.field_mul = ec_GFp_mont_field_mul,
.field_sqr = ec_GFp_mont_field_sqr,
.field_encode = ec_GFp_mont_field_encode,
}
return 1;
- err:
+err:
if (dest->field_data1 != NULL) {
BN_MONT_CTX_free(dest->field_data1);
dest->field_data1 = NULL;
BN_free(group->field_data2);
group->field_data2 = NULL;
}
- err:
+err:
BN_CTX_free(new_ctx);
BN_MONT_CTX_free(mont);
BN_free(one);
-/* $OpenBSD: ecp_nist.c,v 1.11 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_nist.c,v 1.12 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
goto err;
ret = 1;
- err:
+err:
BN_CTX_free(ctx_new);
return ret;
}
goto err;
ret = 1;
- err:
+err:
BN_CTX_free(ctx_new);
return ret;
}
-/* $OpenBSD: ecp_nistp224.c,v 1.20 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_nistp224.c,v 1.21 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Emilia Kasper (Google) for the OpenSSL project.
*/
}
group->field_mod_func = BN_nist_mod_224;
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
}
ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
- err:
+err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
goto err;
ret = 1;
pre = NULL;
- err:
+err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
-/* $OpenBSD: ecp_nistp256.c,v 1.19 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_nistp256.c,v 1.20 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Adam Langley (Google) for the OpenSSL project
*/
}
group->field_mod_func = BN_nist_mod_256;
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
}
ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
- err:
+err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
goto err;
ret = 1;
pre = NULL;
- err:
+err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
-/* $OpenBSD: ecp_nistp521.c,v 1.20 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_nistp521.c,v 1.21 2018/07/15 05:38:48 jsg Exp $ */
/*
* Written by Adam Langley (Google) for the OpenSSL project
*/
}
group->field_mod_func = BN_nist_mod_521;
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
}
ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
- err:
+err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
goto err;
ret = 1;
pre = NULL;
- err:
+err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
-/* $OpenBSD: ecp_nistz256.c,v 1.4 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_nistz256.c,v 1.5 2018/07/15 05:38:48 jsg Exp $ */
/* Copyright (c) 2014, Intel Corporation.
*
* Permission to use, copy, modify, and/or distribute this software for any
}
ret = 1;
- err:
+err:
free(table);
free(p_str);
free(scalars);
ec_pre_comp = NULL;
ret = 1;
- err:
+err:
if (ctx != NULL)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
ret = 1;
- err:
+err:
if (ctx)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
-/* $OpenBSD: ecp_oct.c,v 1.9 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_oct.c,v 1.10 2018/07/15 05:38:48 jsg Exp $ */
/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
* for the OpenSSL project.
* Includes code written by Bodo Moeller for the OpenSSL project.
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
BN_CTX_free(new_ctx);
return ret;
- err:
+err:
if (used_ctx)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
}
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
-/* $OpenBSD: ecp_smpl.c,v 1.19 2018/07/10 22:06:14 tb Exp $ */
+/* $OpenBSD: ecp_smpl.c,v 1.20 2018/07/15 05:38:48 jsg Exp $ */
/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
* for the OpenSSL project.
* Includes code written by Bodo Moeller for the OpenSSL project.
.point_cmp = ec_GFp_simple_cmp,
.make_affine = ec_GFp_simple_make_affine,
.points_make_affine = ec_GFp_simple_points_make_affine,
- .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
- .mul_single_ct = ec_GFp_simple_mul_single_ct,
- .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
.field_mul = ec_GFp_simple_field_mul,
.field_sqr = ec_GFp_simple_field_sqr
};
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
}
ret = 1;
- err:
+err:
BN_CTX_free(new_ctx);
return ret;
}
}
ret = 1;
- err:
+err:
if (ctx != NULL)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
}
ret = 1;
- err:
+err:
BN_CTX_free(new_ctx);
return ret;
}
ret = 1;
- err:
+err:
BN_CTX_free(new_ctx);
return ret;
}
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
ret = 1;
- end:
+end:
if (ctx) /* otherwise we already called BN_CTX_end */
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
ret = (0 == BN_ucmp(tmp, rh));
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
/* points are equal */
ret = 0;
- end:
+end:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
}
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
ret = 1;
- err:
+err:
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
if (heap != NULL) {
{
return BN_mod_sqr(r, a, &group->field, ctx);
}
-
-#define EC_POINT_BN_set_flags(P, flags) do { \
- BN_set_flags(&(P)->X, (flags)); \
- BN_set_flags(&(P)->Y, (flags)); \
- BN_set_flags(&(P)->Z, (flags)); \
-} while(0)
-
-#define EC_POINT_CSWAP(c, a, b, w, t) do { \
- if (!BN_swap_ct(c, &(a)->X, &(b)->X, w) || \
- !BN_swap_ct(c, &(a)->Y, &(b)->Y, w) || \
- !BN_swap_ct(c, &(a)->Z, &(b)->Z, w)) \
- goto err; \
- t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
- (a)->Z_is_one ^= (t); \
- (b)->Z_is_one ^= (t); \
-} while(0)
-
-/*
- * This function computes (in constant time) a point multiplication over the
- * EC group.
- *
- * At a high level, it is Montgomery ladder with conditional swaps.
- *
- * It performs either a fixed point multiplication
- * (scalar * generator)
- * when point is NULL, or a variable point multiplication
- * (scalar * point)
- * when point is not NULL.
- *
- * scalar should be in the range [0,n) otherwise all constant time bets are off.
- *
- * NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
- * which of course are not constant time themselves.
- *
- * The product is stored in r.
- *
- * Returns 1 on success, 0 otherwise.
- */
-static int
-ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
- const EC_POINT *point, BN_CTX *ctx)
-{
- int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
- EC_POINT *s = NULL;
- BIGNUM *k = NULL;
- BIGNUM *lambda = NULL;
- BIGNUM *cardinality = NULL;
- BN_CTX *new_ctx = NULL;
- int ret = 0;
-
- if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
-
- BN_CTX_start(ctx);
-
- if ((s = EC_POINT_new(group)) == NULL)
- goto err;
-
- if (point == NULL) {
- if (!EC_POINT_copy(s, group->generator))
- goto err;
- } else {
- if (!EC_POINT_copy(s, point))
- goto err;
- }
-
- EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
-
- if ((cardinality = BN_CTX_get(ctx)) == NULL)
- goto err;
- if ((lambda = BN_CTX_get(ctx)) == NULL)
- goto err;
- if ((k = BN_CTX_get(ctx)) == NULL)
- goto err;
- if (!BN_mul(cardinality, &group->order, &group->cofactor, ctx))
- goto err;
-
- /*
- * Group cardinalities are often on a word boundary.
- * 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.
- */
- cardinality_bits = BN_num_bits(cardinality);
- group_top = cardinality->top;
- if ((bn_wexpand(k, group_top + 1) == NULL) ||
- (bn_wexpand(lambda, group_top + 1) == NULL))
- goto err;
-
- if (!BN_copy(k, scalar))
- goto err;
-
- BN_set_flags(k, BN_FLG_CONSTTIME);
-
- if (BN_num_bits(k) > cardinality_bits || BN_is_negative(k)) {
- /*
- * This is an unusual input, and we don't guarantee
- * constant-timeness
- */
- if (!BN_nnmod(k, k, cardinality, ctx))
- goto err;
- }
-
- if (!BN_add(lambda, k, cardinality))
- goto err;
- BN_set_flags(lambda, BN_FLG_CONSTTIME);
- if (!BN_add(k, lambda, cardinality))
- goto err;
- /*
- * lambda := scalar + cardinality
- * k := scalar + 2*cardinality
- */
- kbit = BN_is_bit_set(lambda, cardinality_bits);
- if (!BN_swap_ct(kbit, k, lambda, group_top + 1))
- goto err;
-
- group_top = group->field.top;
- 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) ||
- (bn_wexpand(&r->Z, group_top) == NULL))
- goto err;
-
- /* top bit is a 1, in a fixed pos */
- if (!EC_POINT_copy(r, s))
- goto err;
-
- EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
-
- if (!EC_POINT_dbl(group, s, s, ctx))
- goto err;
-
- pbit = 0;
-
- /*
- * 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.
- *
- * k[i] k[i-1] Outcome
- * 0 0 No Swap
- * 0 1 Swap
- * 1 0 Swap
- * 1 1 No Swap
- *
- * This is XOR. pbit tracks the previous bit of k.
- */
-
- for (i = cardinality_bits - 1; i >= 0; i--) {
- kbit = BN_is_bit_set(k, i) ^ pbit;
- EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
- if (!EC_POINT_add(group, s, r, s, ctx))
- goto err;
- if (!EC_POINT_dbl(group, r, r, ctx))
- goto err;
- /*
- * 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);
-
- ret = 1;
-
- err:
- EC_POINT_free(s);
- if (ctx != NULL)
- BN_CTX_end(ctx);
- BN_CTX_free(new_ctx);
-
- return ret;
-}
-
-#undef EC_POINT_BN_set_flags
-#undef EC_POINT_CSWAP
-
-int
-ec_GFp_simple_mul_generator_ct(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, BN_CTX *ctx)
-{
- return ec_GFp_simple_mul_ct(group, r, scalar, NULL, ctx);
-}
-
-int
-ec_GFp_simple_mul_single_ct(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx)
-{
- return ec_GFp_simple_mul_ct(group, r, scalar, point, ctx);
-}
-
-int
-ec_GFp_simple_mul_double_nonct(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *g_scalar, const BIGNUM *p_scalar, const EC_POINT *point,
- BN_CTX *ctx)
-{
- return ec_wNAF_mul(group, r, g_scalar, 1, &point, &p_scalar, ctx);
-}
-.\" $OpenBSD: EC_POINT_add.3,v 1.9 2018/07/11 08:42:38 tb Exp $
+.\" $OpenBSD: EC_POINT_add.3,v 1.10 2018/07/15 05:38:48 jsg Exp $
.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100
.\"
.\" This file was written by Matt Caswell <matt@openssl.org>.
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 11 2018 $
+.Dd $Mdocdate: July 15 2018 $
.Dt EC_POINT_ADD 3
.Os
.Sh NAME
.Fa n
may be
.Dv NULL ,
-in which case the result is just
+in which case the result is just q * m.
.Pp
-.Dl q * m.
-.Pp
-.Fn EC_POINTs_mul
-only supports the values 0 and 1 for
-.Fa num .
-If it is 1, then
.Fn EC_POINTs_mul
calculates the value
.Pp
-.Dl generator * n + q[0] * m[0].
-.Pp
-If
-.Fa num
-is 0 then
-.Fa q
-and
-.Fa m
-must be
-.Dv NULL ,
-and the result is just
-.Pp
-.Dl generator * n .
+.Dl generator * n + q[0] * m[0] + ... + q[num-1] * m[num-1]
.Pp
As for
.Fn EC_POINT_mul ,