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

📄 ecp_smpl.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!field_mul(group, n1, n2, n5, ctx)) goto end;	if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;	if (BN_is_odd(n0))		if (!BN_add(n0, n0, p)) goto end;	/* now  0 <= n0 < 2*p,  and n0 is even */	if (!BN_rshift1(&r->Y, n0)) goto end;	/* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */	ret = 1; end:	if (ctx) /* otherwise we already called BN_CTX_end */		BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 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;	int ret = 0;		if (EC_POINT_is_at_infinity(group, a))		{		BN_zero(&r->Z);		r->Z_is_one = 0;		return 1;		}	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);	if (n3 == NULL) goto err;	/* Note that in this function we must not read components of 'a'	 * once we have written the corresponding components of 'r'.	 * ('r' might the same as 'a'.)	 */	/* n1 */	if (a->Z_is_one)		{		if (!field_sqr(group, n0, &a->X, ctx)) goto err;		if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;		if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;		if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;		/* n1 = 3 * X_a^2 + a_curve */		}	else if (group->a_is_minus3)		{		if (!field_sqr(group, n1, &a->Z, ctx)) goto err;		if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;		if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;		if (!field_mul(group, n1, n0, n2, ctx)) goto err;		if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;		if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;		/* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)		 *    = 3 * X_a^2 - 3 * Z_a^4 */		}	else		{		if (!field_sqr(group, n0, &a->X, ctx)) goto err;		if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;		if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;		if (!field_sqr(group, n1, &a->Z, ctx)) goto err;		if (!field_sqr(group, n1, n1, ctx)) goto err;		if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;		if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;		/* n1 = 3 * X_a^2 + a_curve * Z_a^4 */		}	/* Z_r */	if (a->Z_is_one)		{		if (!BN_copy(n0, &a->Y)) goto err;		}	else		{		if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;		}	if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;	r->Z_is_one = 0;	/* Z_r = 2 * Y_a * Z_a */	/* n2 */	if (!field_sqr(group, n3, &a->Y, ctx)) goto err;	if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;	if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;	/* n2 = 4 * X_a * Y_a^2 */	/* X_r */	if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;	if (!field_sqr(group, &r->X, n1, ctx)) goto err;	if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;	/* X_r = n1^2 - 2 * n2 */		/* n3 */	if (!field_sqr(group, n0, n3, ctx)) goto err;	if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;	/* n3 = 8 * Y_a^4 */		/* Y_r */	if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;	if (!field_mul(group, n0, n1, n0, ctx)) goto err;	if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;	/* Y_r = n1 * (n2 - X_r) - n3 */	ret = 1; err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}int ec_GFp_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;		return BN_usub(&point->Y, &group->field, &point->Y);	}int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)	{	return BN_is_zero(&point->Z);	}int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 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 *rh, *tmp, *Z4, *Z6;	int ret = -1;	if (EC_POINT_is_at_infinity(group, point))		return 1;		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 -1;		}	BN_CTX_start(ctx);	rh = BN_CTX_get(ctx);	tmp = BN_CTX_get(ctx);	Z4 = BN_CTX_get(ctx);	Z6 = BN_CTX_get(ctx);	if (Z6 == NULL) goto err;	/* We have a curve defined by a Weierstrass equation	 *      y^2 = x^3 + a*x + b.	 * The point to consider is given in Jacobian projective coordinates	 * where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).	 * Substituting this and multiplying by  Z^6  transforms the above equation into	 *      Y^2 = X^3 + a*X*Z^4 + b*Z^6.	 * To test this, we add up the right-hand side in 'rh'.	 */	/* rh := X^2 */	if (!field_sqr(group, rh, &point->X, ctx)) goto err;	if (!point->Z_is_one)		{		if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;		if (!field_sqr(group, Z4, tmp, ctx)) goto err;		if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;		/* rh := (rh + a*Z^4)*X */		if (group->a_is_minus3)			{			if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;			if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;			if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;			if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;			}		else			{			if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;			if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;			if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;			}		/* rh := rh + b*Z^6 */		if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;		if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;		}	else		{		/* point->Z_is_one */		/* rh := (rh + a)*X */		if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;		if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;		/* rh := rh + b */		if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;		}	/* 'lh' := Y^2 */	if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;	ret = (0 == BN_ucmp(tmp, rh)); err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)	{	/* return values:	 *  -1   error	 *   0   equal (in affine coordinates)	 *   1   not equal	 */	int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);	int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);	BN_CTX *new_ctx = NULL;	BIGNUM *tmp1, *tmp2, *Za23, *Zb23;	const BIGNUM *tmp1_, *tmp2_;	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;		}	field_mul = group->meth->field_mul;	field_sqr = group->meth->field_sqr;	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return -1;		}	BN_CTX_start(ctx);	tmp1 = BN_CTX_get(ctx);	tmp2 = BN_CTX_get(ctx);	Za23 = BN_CTX_get(ctx);	Zb23 = BN_CTX_get(ctx);	if (Zb23 == NULL) goto end;	/* We have to decide whether	 *     (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),	 * or equivalently, whether	 *     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).	 */	if (!b->Z_is_one)		{		if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;		if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;		tmp1_ = tmp1;		}	else		tmp1_ = &a->X;	if (!a->Z_is_one)		{		if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;		if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;		tmp2_ = tmp2;		}	else		tmp2_ = &b->X;		/* compare  X_a*Z_b^2  with  X_b*Z_a^2 */	if (BN_cmp(tmp1_, tmp2_) != 0)		{		ret = 1; /* points differ */		goto end;		}	if (!b->Z_is_one)		{		if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;		if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;		/* tmp1_ = tmp1 */		}	else		tmp1_ = &a->Y;	if (!a->Z_is_one)		{		if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;		if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;		/* tmp2_ = tmp2 */		}	else		tmp2_ = &b->Y;	/* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */	if (BN_cmp(tmp1_, tmp2_) != 0)		{		ret = 1; /* points differ */		goto end;		}	/* points are equal */	ret = 0; end:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}int ec_GFp_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_GFp(group, point, x, y, ctx)) goto err;	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;	if (!point->Z_is_one)		{		ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);		goto err;		}		ret = 1; err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	return ret;	}int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)	{	BN_CTX *new_ctx = NULL;	BIGNUM *tmp0, *tmp1;	size_t pow2 = 0;	BIGNUM **heap = NULL;	size_t i;	int ret = 0;	if (num == 0)		return 1;	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			return 0;		}	BN_CTX_start(ctx);	tmp0 = BN_CTX_get(ctx);	tmp1 = BN_CTX_get(ctx);	if (tmp0  == NULL || tmp1 == NULL) goto err;	/* Before converting the individual points, compute inverses of all Z values.	 * Modular inversion is rather slow, but luckily we can do with a single	 * explicit inversion, plus about 3 multiplications per input value.	 */	pow2 = 1;	while (num > pow2)		pow2 <<= 1;	/* Now pow2 is the smallest power of 2 satifsying pow2 >= num.	 * We need twice that. */	pow2 <<= 1;	heap = OPENSSL_malloc(pow2 * sizeof heap[0]);	if (heap == NULL) goto err;		/* The array is used as a binary tree, exactly as in heapsort:	 *	 *                               heap[1]	 *                 heap[2]                     heap[3]	 *          heap[4]       heap[5]       heap[6]       heap[7]	 *   heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]	 *	 * We put the Z's in the last line;	 * then we set each other node to the product of its two child-nodes (where	 * empty or 0 entries are treated as ones);	 * then we invert heap[1];	 * then we invert each other node by replacing it by the product of its	 * parent (after inversion) and its sibling (before inversion).	 */	heap[0] = NULL;	for (i = pow2/2 - 1; i > 0; i--)		heap[i] = NULL;	for (i = 0; i < num; i++)		heap[pow2/2 + i] = &points[i]->Z;	for (i = pow2/2 + num; i < pow2; i++)		heap[i] = NULL;		/* set each node to the product of its children */	for (i = pow2/2 - 1; i > 0; i--)		{		heap[i] = BN_new();		if (heap[i] == NULL) goto err;				if (heap[2*i] != NULL)			{			if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))				{				if (!BN_copy(heap[i], heap[2*i])) goto err;				}			else				{				if (BN_is_zero(heap[2*i]))					{					if (!BN_copy(heap[i], heap[2*i + 1])) goto err;					}				else					{					if (!group->meth->field_mul(group, heap[i],						heap[2*i], heap[2*i + 1], ctx)) goto err;					}				}			}		}	/* invert heap[1] */	if (!BN_is_zero(heap[1]))		{		if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))			{			ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);			goto err;			}		}	if (group->meth->field_encode != 0)		{		/* in the Montgomery case, we just turned  R*H  (representing H)		 * into  1/(R*H),  but we need  R*(1/H)  (representing 1/H);		 * i.e. we have need to multiply by the Montgomery factor twice */		if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;		if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;		}	/* set other heap[i]'s to their inverses */	for (i = 2; i < pow2/2 + num; i += 2)		{		/* i is even */		if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))			{			if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;			if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;			if (!BN_copy(heap[i], tmp0)) goto err;			if (!BN_copy(heap[i + 1], tmp1)) goto err;			}		else			{			if (!BN_copy(heap[i], heap[i/2])) goto err;			}		}	/* we have replaced all non-zero Z's by their inverses, now fix up all the points */	for (i = 0; i < num; i++)		{		EC_POINT *p = points[i];				if (!BN_is_zero(&p->Z))			{			/* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */			if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;			if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;			if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;			if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;					if (group->meth->field_set_to_one != 0)				{				if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;				}			else				{				if (!BN_one(&p->Z)) goto err;				}			p->Z_is_one = 1;			}		}	ret = 1;		 err:	BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	if (heap != NULL)		{		/* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */		for (i = pow2/2 - 1; i > 0; i--)			{			if (heap[i] != NULL)				BN_clear_free(heap[i]);			}		OPENSSL_free(heap);		}	return ret;	}int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)	{	return BN_mod_mul(r, a, b, &group->field, ctx);	}int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)	{	return BN_mod_sqr(r, a, &group->field, ctx);	}

⌨️ 快捷键说明

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