⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ec2_smpl.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;		buf[0] = form;#ifdef OPENSSL_EC_BIN_PT_COMP		if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))			{			if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;			if (BN_is_odd(yxi)) buf[0]++;			}#endif		i = 1;				skip = field_len - BN_num_bytes(x);		if (skip > field_len)			{			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);			goto err;			}		while (skip > 0)			{			buf[i++] = 0;			skip--;			}		skip = BN_bn2bin(x, buf + i);		i += skip;		if (i != 1 + field_len)			{			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);			goto err;			}		if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)			{			skip = field_len - BN_num_bytes(y);			if (skip > field_len)				{				ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);				goto err;				}			while (skip > 0)				{				buf[i++] = 0;				skip--;				}			skip = BN_bn2bin(y, buf + i);			i += skip;			}		if (i != ret)			{			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);			goto err;			}		}		if (used_ctx)		BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret; err:	if (used_ctx)		BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return 0;	}/* Converts an octet string representation to an EC_POINT.  * Note that the simple implementation only uses affine coordinates. */int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,	const unsigned char *buf, size_t len, BN_CTX *ctx)	{	point_conversion_form_t form;	int y_bit;	BN_CTX *new_ctx = NULL;	BIGNUM *x, *y, *yxi;	size_t field_len, enc_len;	int ret = 0;	if (len == 0)		{		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);		return 0;		}	form = buf[0];	y_bit = form & 1;	form = form & ~1U;	if ((form != 0)	&& (form != POINT_CONVERSION_COMPRESSED)		&& (form != POINT_CONVERSION_UNCOMPRESSED)		&& (form != POINT_CONVERSION_HYBRID))		{		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);		return 0;		}	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)		{		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);		return 0;		}	if (form == 0)		{		if (len != 1)			{			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);			return 0;			}		return EC_POINT_set_to_infinity(group, point);		}		field_len = (EC_GROUP_get_degree(group) + 7) / 8;	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;	if (len != enc_len)		{		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);		return 0;		}	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return 0;		}	BN_CTX_start(ctx);	x = BN_CTX_get(ctx);	y = BN_CTX_get(ctx);	yxi = BN_CTX_get(ctx);	if (yxi == NULL) goto err;	if (!BN_bin2bn(buf + 1, field_len, x)) goto err;	if (BN_ucmp(x, &group->field) >= 0)		{		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);		goto err;		}	if (form == POINT_CONVERSION_COMPRESSED)		{		if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;		}	else		{		if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;		if (BN_ucmp(y, &group->field) >= 0)			{			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);			goto err;			}		if (form == POINT_CONVERSION_HYBRID)			{			if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;			if (y_bit != BN_is_odd(yxi))				{				ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);				goto err;				}			}		if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;		}		if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */		{		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);		goto err;		}	ret = 1;	 err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}/* Computes a + b and stores the result in r.  r could be a or b, a could be b. * Uses algorithm A.10.2 of IEEE P1363. */int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)	{	BN_CTX *new_ctx = NULL;	BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;	int ret = 0;		if (EC_POINT_is_at_infinity(group, a))		{		if (!EC_POINT_copy(r, b)) return 0;		return 1;		}	if (EC_POINT_is_at_infinity(group, b))		{		if (!EC_POINT_copy(r, a)) return 0;		return 1;		}	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return 0;		}	BN_CTX_start(ctx);	x0 = BN_CTX_get(ctx);	y0 = BN_CTX_get(ctx);	x1 = BN_CTX_get(ctx);	y1 = BN_CTX_get(ctx);	x2 = BN_CTX_get(ctx);	y2 = BN_CTX_get(ctx);	s = BN_CTX_get(ctx);	t = BN_CTX_get(ctx);	if (t == NULL) goto err;	if (a->Z_is_one) 		{		if (!BN_copy(x0, &a->X)) goto err;		if (!BN_copy(y0, &a->Y)) goto err;		}	else		{		if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;		}	if (b->Z_is_one) 		{		if (!BN_copy(x1, &b->X)) goto err;		if (!BN_copy(y1, &b->Y)) goto err;		}	else		{		if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;		}	if (BN_GF2m_cmp(x0, x1))		{		if (!BN_GF2m_add(t, x0, x1)) goto err;		if (!BN_GF2m_add(s, y0, y1)) goto err;		if (!group->meth->field_div(group, s, s, t, ctx)) goto err;		if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;		if (!BN_GF2m_add(x2, x2, s)) goto err;		if (!BN_GF2m_add(x2, x2, t)) goto err;		}	else		{		if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))			{			if (!EC_POINT_set_to_infinity(group, r)) goto err;			ret = 1;			goto err;			}		if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;		if (!BN_GF2m_add(s, s, x1)) goto err;				if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;		if (!BN_GF2m_add(x2, x2, s)) goto err;		if (!BN_GF2m_add(x2, x2, &group->a)) goto err;		}	if (!BN_GF2m_add(y2, x1, x2)) goto err;	if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;	if (!BN_GF2m_add(y2, y2, x2)) goto err;	if (!BN_GF2m_add(y2, y2, y1)) goto err;	if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;	ret = 1; err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}/* Computes 2 * a and stores the result in r.  r could be a. * Uses algorithm A.10.2 of IEEE P1363. */int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)	{	return ec_GF2m_simple_add(group, r, a, a, ctx);	}int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)	{	if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))		/* point is its own inverse */		return 1;		if (!EC_POINT_make_affine(group, point, ctx)) return 0;	return BN_GF2m_add(&point->Y, &point->X, &point->Y);	}/* Indicates whether the given point is the point at infinity. */int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)	{	return BN_is_zero(&point->Z);	}/* Determines whether the given EC_POINT is an actual point on the curve defined * in the EC_GROUP.  A point is valid if it satisfies the Weierstrass equation: *      y^2 + x*y = x^3 + a*x^2 + b. */int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)	{	int ret = -1;	BN_CTX *new_ctx = NULL;	BIGNUM *lh, *y2;	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);	if (EC_POINT_is_at_infinity(group, point))		return 1;	field_mul = group->meth->field_mul;	field_sqr = group->meth->field_sqr;		/* only support affine coordinates */	if (!point->Z_is_one) goto err;	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return -1;		}	BN_CTX_start(ctx);	y2 = BN_CTX_get(ctx);	lh = BN_CTX_get(ctx);	if (lh == NULL) goto err;	/* We have a curve defined by a Weierstrass equation	 *      y^2 + x*y = x^3 + a*x^2 + b.	 *  <=> x^3 + a*x^2 + x*y + b + y^2 = 0	 *  <=> ((x + a) * x + y ) * x + b + y^2 = 0	 */	if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;	if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;	if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;	if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;	if (!BN_GF2m_add(lh, lh, &group->b)) goto err;	if (!field_sqr(group, y2, &point->Y, ctx)) goto err;	if (!BN_GF2m_add(lh, lh, y2)) goto err;	ret = BN_is_zero(lh); err:	if (ctx) BN_CTX_end(ctx);	if (new_ctx) BN_CTX_free(new_ctx);	return ret;	}/* Indicates whether two points are equal. * Return values: *  -1   error *   0   equal (in affine coordinates) *   1   not equal */int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)	{	BIGNUM *aX, *aY, *bX, *bY;	BN_CTX *new_ctx = NULL;	int ret = -1;	if (EC_POINT_is_at_infinity(group, a))		{		return EC_POINT_is_at_infinity(group, b) ? 0 : 1;		}		if (a->Z_is_one && b->Z_is_one)		{		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;		}	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return -1;		}	BN_CTX_start(ctx);	aX = BN_CTX_get(ctx);	aY = BN_CTX_get(ctx);	bX = BN_CTX_get(ctx);	bY = BN_CTX_get(ctx);	if (bY == NULL) goto err;	if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;	if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;	ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;  err:		if (ctx) BN_CTX_end(ctx);	if (new_ctx) BN_CTX_free(new_ctx);	return ret;	}/* Forces the given EC_POINT to internally use affine coordinates. */int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)	{	BN_CTX *new_ctx = NULL;	BIGNUM *x, *y;	int ret = 0;	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))		return 1;		if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return 0;		}	BN_CTX_start(ctx);	x = BN_CTX_get(ctx);	y = BN_CTX_get(ctx);	if (y == NULL) goto err;		if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;	if (!BN_copy(&point->X, x)) goto err;	if (!BN_copy(&point->Y, y)) goto err;	if (!BN_one(&point->Z)) goto err;		ret = 1;		  err:	if (ctx) BN_CTX_end(ctx);	if (new_ctx) BN_CTX_free(new_ctx);	return ret;	}/* Forces each of the EC_POINTs in the given array to use affine coordinates. */int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)	{	size_t i;	for (i = 0; i < num; i++)		{		if (!group->meth->make_affine(group, points[i], ctx)) return 0;		}	return 1;	}/* Wrapper to simple binary polynomial field multiplication implementation. */int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)	{	return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);	}/* Wrapper to simple binary polynomial field squaring implementation. */int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)	{	return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);	}/* Wrapper to simple binary polynomial field division implementation. */int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)	{	return BN_GF2m_mod_div(r, a, b, &group->field, ctx);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -