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

📄 ecp_smpl.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 3 页
字号:
		else			{			if (x != NULL)				{				if (!BN_copy(x, &point->X)) goto err;				}			if (y != NULL)				{				if (!BN_copy(y, &point->Y)) goto err;				}			}		}	else		{		if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))			{			ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);			goto err;			}				if (group->meth->field_encode == 0)			{			/* field_sqr works on standard representation */			if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;			}		else			{			if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;			}			if (x != NULL)			{			/* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */			if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;			}		if (y != NULL)			{			if (group->meth->field_encode == 0)				{				/* field_mul works on standard representation */				if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;				}			else				{				if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;				}			/* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */			if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;			}		}	ret = 1; err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,	const BIGNUM *x_, int y_bit, BN_CTX *ctx)	{	BN_CTX *new_ctx = NULL;	BIGNUM *tmp1, *tmp2, *x, *y;	int ret = 0;	/* clear error queue*/	ERR_clear_error();	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return 0;		}	y_bit = (y_bit != 0);	BN_CTX_start(ctx);	tmp1 = BN_CTX_get(ctx);	tmp2 = BN_CTX_get(ctx);	x = BN_CTX_get(ctx);	y = BN_CTX_get(ctx);	if (y == NULL) goto err;	/* Recover y.  We have a Weierstrass equation	 *     y^2 = x^3 + a*x + b,	 * so  y  is one of the square roots of  x^3 + a*x + b.	 */	/* tmp1 := x^3 */	if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;	if (group->meth->field_decode == 0)		{		/* field_{sqr,mul} work on standard representation */		if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;		if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;		}	else		{		if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;		if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;		}		/* tmp1 := tmp1 + a*x */	if (group->a_is_minus3)		{		if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;		if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;		if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;		}	else		{		if (group->meth->field_decode)			{			if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;			if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;			}		else			{			/* field_mul works on standard representation */			if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;			}				if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;		}		/* tmp1 := tmp1 + b */	if (group->meth->field_decode)		{		if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;		if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;		}	else		{		if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;		}		if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))		{		unsigned long err = ERR_peek_last_error();				if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)			{			ERR_clear_error();			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);			}		else			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);		goto err;		}	if (y_bit != BN_is_odd(y))		{		if (BN_is_zero(y))			{			int kron;			kron = BN_kronecker(x, &group->field, ctx);			if (kron == -2) goto err;			if (kron == 1)				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);			else				/* BN_mod_sqrt() should have cought this error (not a square) */				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);			goto err;			}		if (!BN_usub(y, &group->field, y)) goto err;		}	if (y_bit != BN_is_odd(y))		{		ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);		goto err;		}	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;	ret = 1; err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,	unsigned char *buf, size_t len, BN_CTX *ctx)	{	size_t ret;	BN_CTX *new_ctx = NULL;	int used_ctx = 0;	BIGNUM *x, *y;	size_t field_len, i, skip;	if ((form != POINT_CONVERSION_COMPRESSED)		&& (form != POINT_CONVERSION_UNCOMPRESSED)		&& (form != POINT_CONVERSION_HYBRID))		{		ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);		goto err;		}	if (EC_POINT_is_at_infinity(group, point))		{		/* encodes to a single 0 octet */		if (buf != NULL)			{			if (len < 1)				{				ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);				return 0;				}			buf[0] = 0;			}		return 1;		}	/* ret := required output buffer length */	field_len = BN_num_bytes(&group->field);	ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;	/* if 'buf' is NULL, just return required length */	if (buf != NULL)		{		if (len < ret)			{			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);			goto err;			}		if (ctx == NULL)			{			ctx = new_ctx = BN_CTX_new();			if (ctx == NULL)				return 0;			}		BN_CTX_start(ctx);		used_ctx = 1;		x = BN_CTX_get(ctx);		y = BN_CTX_get(ctx);		if (y == NULL) goto err;		if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;		if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))			buf[0] = form + 1;		else			buf[0] = form;			i = 1;				skip = field_len - BN_num_bytes(x);		if (skip > field_len)			{			ECerr(EC_F_EC_GFP_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_GFP_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_GFP_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_GFP_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;	}int ec_GFp_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;	size_t field_len, enc_len;	int ret = 0;	if (len == 0)		{		ECerr(EC_F_EC_GFP_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_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);		return 0;		}	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)		{		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);		return 0;		}	if (form == 0)		{		if (len != 1)			{			ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);			return 0;			}		return EC_POINT_set_to_infinity(group, point);		}		field_len = BN_num_bytes(&group->field);	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;	if (len != enc_len)		{		ECerr(EC_F_EC_GFP_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);	if (y == NULL) goto err;	if (!BN_bin2bn(buf + 1, field_len, x)) goto err;	if (BN_ucmp(x, &group->field) >= 0)		{		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);		goto err;		}	if (form == POINT_CONVERSION_COMPRESSED)		{		if (!EC_POINT_set_compressed_coordinates_GFp(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_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);			goto err;			}		if (form == POINT_CONVERSION_HYBRID)			{			if (y_bit != BN_is_odd(y))				{				ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);				goto err;				}			}		if (!EC_POINT_set_affine_coordinates_GFp(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_GFP_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;	}int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)	{	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);	const BIGNUM *p;	BN_CTX *new_ctx = NULL;	BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;	int ret = 0;		if (a == b)		return EC_POINT_dbl(group, r, a, ctx);	if (EC_POINT_is_at_infinity(group, a))		return EC_POINT_copy(r, b);	if (EC_POINT_is_at_infinity(group, b))		return EC_POINT_copy(r, a);		field_mul = group->meth->field_mul;	field_sqr = group->meth->field_sqr;	p = &group->field;	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return 0;		}	BN_CTX_start(ctx);	n0 = BN_CTX_get(ctx);	n1 = BN_CTX_get(ctx);	n2 = BN_CTX_get(ctx);	n3 = BN_CTX_get(ctx);	n4 = BN_CTX_get(ctx);	n5 = BN_CTX_get(ctx);	n6 = BN_CTX_get(ctx);	if (n6 == NULL) goto end;	/* Note that in this function we must not read components of 'a' or 'b'	 * once we have written the corresponding components of 'r'.	 * ('r' might be one of 'a' or 'b'.)	 */	/* n1, n2 */	if (b->Z_is_one)		{		if (!BN_copy(n1, &a->X)) goto end;		if (!BN_copy(n2, &a->Y)) goto end;		/* n1 = X_a */		/* n2 = Y_a */		}	else		{		if (!field_sqr(group, n0, &b->Z, ctx)) goto end;		if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;		/* n1 = X_a * Z_b^2 */		if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;		if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;		/* n2 = Y_a * Z_b^3 */		}	/* n3, n4 */	if (a->Z_is_one)		{		if (!BN_copy(n3, &b->X)) goto end;		if (!BN_copy(n4, &b->Y)) goto end;		/* n3 = X_b */		/* n4 = Y_b */		}	else		{		if (!field_sqr(group, n0, &a->Z, ctx)) goto end;		if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;		/* n3 = X_b * Z_a^2 */		if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;		if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;		/* n4 = Y_b * Z_a^3 */		}	/* n5, n6 */	if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;	if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;	/* n5 = n1 - n3 */	/* n6 = n2 - n4 */	if (BN_is_zero(n5))		{		if (BN_is_zero(n6))			{			/* a is the same point as b */			BN_CTX_end(ctx);			ret = EC_POINT_dbl(group, r, a, ctx);			ctx = NULL;			goto end;			}		else			{			/* a is the inverse of b */			BN_zero(&r->Z);			r->Z_is_one = 0;			ret = 1;			goto end;			}		}	/* 'n7', 'n8' */	if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;	if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;	/* 'n7' = n1 + n3 */	/* 'n8' = n2 + n4 */	/* Z_r */	if (a->Z_is_one && b->Z_is_one)		{		if (!BN_copy(&r->Z, n5)) goto end;		}	else		{		if (a->Z_is_one)			{ if (!BN_copy(n0, &b->Z)) goto end; }		else if (b->Z_is_one)			{ if (!BN_copy(n0, &a->Z)) goto end; }		else			{ if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }		if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;		}	r->Z_is_one = 0;	/* Z_r = Z_a * Z_b * n5 */	/* X_r */	if (!field_sqr(group, n0, n6, ctx)) goto end;	if (!field_sqr(group, n4, n5, ctx)) goto end;	if (!field_mul(group, n3, n1, n4, ctx)) goto end;	if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;	/* X_r = n6^2 - n5^2 * 'n7' */		/* 'n9' */	if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;	if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;	/* n9 = n5^2 * 'n7' - 2 * X_r */	/* Y_r */	if (!field_mul(group, n0, n0, n6, ctx)) goto end;	if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */

⌨️ 快捷键说明

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