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

📄 ec_mult.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	if (numblocks)		{		/* we go here iff scalar != NULL */				if (pre_comp == NULL)			{			if (num_scalar != 1)				{				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);				goto err;				}			/* we have already generated a wNAF for 'scalar' */			}		else			{			signed char *tmp_wNAF = NULL;			size_t tmp_len = 0;						if (num_scalar != 0)				{				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);				goto err;				}			/* use the window size for which we have precomputation */			wsize[num] = pre_comp->w;			tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);			if (!tmp_wNAF)				goto err;			if (tmp_len <= max_len)				{				/* One of the other wNAFs is at least as long				 * as the wNAF belonging to the generator,				 * so wNAF splitting will not buy us anything. */				numblocks = 1;				totalnum = num + 1; /* don't use wNAF splitting */				wNAF[num] = tmp_wNAF;				wNAF[num + 1] = NULL;				wNAF_len[num] = tmp_len;				if (tmp_len > max_len)					max_len = tmp_len;				/* pre_comp->points starts with the points that we need here: */				val_sub[num] = pre_comp->points;				}			else				{				/* don't include tmp_wNAF directly into wNAF array				 * - use wNAF splitting and include the blocks */				signed char *pp;				EC_POINT **tmp_points;								if (tmp_len < numblocks * blocksize)					{					/* possibly we can do with fewer blocks than estimated */					numblocks = (tmp_len + blocksize - 1) / blocksize;					if (numblocks > pre_comp->numblocks)						{						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);						goto err;						}					totalnum = num + numblocks;					}								/* split wNAF in 'numblocks' parts */				pp = tmp_wNAF;				tmp_points = pre_comp->points;				for (i = num; i < totalnum; i++)					{					if (i < totalnum - 1)						{						wNAF_len[i] = blocksize;						if (tmp_len < blocksize)							{							ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);							goto err;							}						tmp_len -= blocksize;						}					else						/* last block gets whatever is left						 * (this could be more or less than 'blocksize'!) */						wNAF_len[i] = tmp_len;										wNAF[i + 1] = NULL;					wNAF[i] = OPENSSL_malloc(wNAF_len[i]);					if (wNAF[i] == NULL)						{						ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);						OPENSSL_free(tmp_wNAF);						goto err;						}					memcpy(wNAF[i], pp, wNAF_len[i]);					if (wNAF_len[i] > max_len)						max_len = wNAF_len[i];					if (*tmp_points == NULL)						{						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);						OPENSSL_free(tmp_wNAF);						goto err;						}					val_sub[i] = tmp_points;					tmp_points += pre_points_per_block;					pp += blocksize;					}				OPENSSL_free(tmp_wNAF);				}			}		}	/* All points we precompute now go into a single array 'val'.	 * 'val_sub[i]' is a pointer to the subarray for the i-th point,	 * or to a subarray of 'pre_comp->points' if we already have precomputation. */	val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);	if (val == NULL)		{		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);		goto err;		}	val[num_val] = NULL; /* pivot element */	/* allocate points for precomputation */	v = val;	for (i = 0; i < num + num_scalar; i++)		{		val_sub[i] = v;		for (j = 0; j < (1u << (wsize[i] - 1)); j++)			{			*v = EC_POINT_new(group);			if (*v == NULL) goto err;			v++;			}		}	if (!(v == val + num_val))		{		ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);		goto err;		}	if (!(tmp = EC_POINT_new(group)))		goto err;	/* prepare precomputed values:	 *    val_sub[i][0] :=     points[i]	 *    val_sub[i][1] := 3 * points[i]	 *    val_sub[i][2] := 5 * points[i]	 *    ...	 */	for (i = 0; i < num + num_scalar; i++)		{		if (i < num)			{			if (!EC_POINT_copy(val_sub[i][0], points[i])) goto err;			}		else			{			if (!EC_POINT_copy(val_sub[i][0], generator)) goto err;			}		if (wsize[i] > 1)			{			if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err;			for (j = 1; j < (1u << (wsize[i] - 1)); j++)				{				if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err;				}			}		}#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */	if (!EC_POINTs_make_affine(group, num_val, val, ctx))		goto err;#endif	r_is_at_infinity = 1;	for (k = max_len - 1; k >= 0; k--)		{		if (!r_is_at_infinity)			{			if (!EC_POINT_dbl(group, r, r, ctx)) goto err;			}				for (i = 0; i < totalnum; i++)			{			if (wNAF_len[i] > (size_t)k)				{				int digit = wNAF[i][k];				int is_neg;				if (digit) 					{					is_neg = digit < 0;					if (is_neg)						digit = -digit;					if (is_neg != r_is_inverted)						{						if (!r_is_at_infinity)							{							if (!EC_POINT_invert(group, r, ctx)) goto err;							}						r_is_inverted = !r_is_inverted;						}					/* digit > 0 */					if (r_is_at_infinity)						{						if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) goto err;						r_is_at_infinity = 0;						}					else						{						if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) goto err;						}					}				}			}		}	if (r_is_at_infinity)		{		if (!EC_POINT_set_to_infinity(group, r)) goto err;		}	else		{		if (r_is_inverted)			if (!EC_POINT_invert(group, r, ctx)) goto err;		}		ret = 1; err:	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	if (tmp != NULL)		EC_POINT_free(tmp);	if (wsize != NULL)		OPENSSL_free(wsize);	if (wNAF_len != NULL)		OPENSSL_free(wNAF_len);	if (wNAF != NULL)		{		signed char **w;				for (w = wNAF; *w != NULL; w++)			OPENSSL_free(*w);				OPENSSL_free(wNAF);		}	if (val != NULL)		{		for (v = val; *v != NULL; v++)			EC_POINT_clear_free(*v);		OPENSSL_free(val);		}	if (val_sub != NULL)		{		OPENSSL_free(val_sub);		}	return ret;	}/* ec_wNAF_precompute_mult() * creates an EC_PRE_COMP object with preprecomputed multiples of the generator * for use with wNAF splitting as implemented in ec_wNAF_mul(). *  * 'pre_comp->points' is an array of multiples of the generator * of the following form: * points[0] =     generator; * points[1] = 3 * generator; * ... * points[2^(w-1)-1] =     (2^(w-1)-1) * generator; * points[2^(w-1)]   =     2^blocksize * generator; * points[2^(w-1)+1] = 3 * 2^blocksize * generator; * ... * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) * generator * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) * generator * ... * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) * generator * points[2^(w-1)*numblocks]       = NULL */int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)	{	const EC_POINT *generator;	EC_POINT *tmp_point = NULL, *base = NULL, **var;	BN_CTX *new_ctx = NULL;	BIGNUM *order;	size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;	EC_POINT **points = NULL;	EC_PRE_COMP *pre_comp;	int ret = 0;	/* if there is an old EC_PRE_COMP object, throw it away */	EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);	if ((pre_comp = ec_pre_comp_new(group)) == NULL)		return 0;	generator = EC_GROUP_get0_generator(group);	if (generator == NULL)		{		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);		goto err;		}	if (ctx == NULL)		{		ctx = new_ctx = BN_CTX_new();		if (ctx == NULL)			goto err;		}		BN_CTX_start(ctx);	order = BN_CTX_get(ctx);	if (order == NULL) goto err;		if (!EC_GROUP_get_order(group, order, ctx)) goto err;			if (BN_is_zero(order))		{		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);		goto err;		}	bits = BN_num_bits(order);	/* The following parameters mean we precompute (approximately)	 * one point per bit.	 *	 * TBD: The combination  8, 4  is perfect for 160 bits; for other	 * bit lengths, other parameter combinations might provide better	 * efficiency.	 */	blocksize = 8;	w = 4;	if (EC_window_bits_for_scalar_size(bits) > w)		{		/* let's not make the window too small ... */		w = EC_window_bits_for_scalar_size(bits);		}	numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */		pre_points_per_block = 1u << (w - 1);	num = pre_points_per_block * numblocks; /* number of points to compute and store */	points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1));	if (!points)		{		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);		goto err;		}	var = points;	var[num] = NULL; /* pivot */	for (i = 0; i < num; i++)		{		if ((var[i] = EC_POINT_new(group)) == NULL)			{			ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);			goto err;			}		}	if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group)))		{		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);		goto err;		}			if (!EC_POINT_copy(base, generator))		goto err;		/* do the precomputation */	for (i = 0; i < numblocks; i++)		{		size_t j;		if (!EC_POINT_dbl(group, tmp_point, base, ctx))			goto err;		if (!EC_POINT_copy(*var++, base))			goto err;		for (j = 1; j < pre_points_per_block; j++, var++)			{			/* calculate odd multiples of the current base point */			if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))				goto err;			}		if (i < numblocks - 1)			{			/* get the next base (multiply current one by 2^blocksize) */			size_t k;			if (blocksize <= 2)				{				ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);				goto err;				}							if (!EC_POINT_dbl(group, base, tmp_point, ctx))				goto err;			for (k = 2; k < blocksize; k++)				{				if (!EC_POINT_dbl(group,base,base,ctx))					goto err;				}			} 		}	if (!EC_POINTs_make_affine(group, num, points, ctx))		goto err;		pre_comp->group = group;	pre_comp->blocksize = blocksize;	pre_comp->numblocks = numblocks;	pre_comp->w = w;	pre_comp->points = points;	points = NULL;	pre_comp->num = num;	if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,		ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))		goto err;	pre_comp = NULL;	ret = 1; err:	if (ctx != NULL)		BN_CTX_end(ctx);	if (new_ctx != NULL)		BN_CTX_free(new_ctx);	if (pre_comp)		ec_pre_comp_free(pre_comp);	if (points)		{		EC_POINT **p;		for (p = points; *p != NULL; p++)			EC_POINT_free(*p);		OPENSSL_free(points);		}	if (tmp_point)		EC_POINT_free(tmp_point);	if (base)		EC_POINT_free(base);	return ret;	}int ec_wNAF_have_precompute_mult(const EC_GROUP *group)	{	if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)		return 1;	else		return 0;	}

⌨️ 快捷键说明

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