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

📄 curve.c

📁 斯坦福大学密码学家Boneh的基于身份的公钥密码系统
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (b != 0) {	fp2_mul(v, v, fb, p);	fp2_mul(vdenom, vdenom, fbdenom, p);	//g	tate_get_line(v, Qhat, Z, bP, p);	//h	point_add(Z, Z, bP, curve);	tate_get_vertical(vdenom, Qhat, Z, p);    }    if (curve->solinasa < 0) {    //the sign of solinasa records whether it's +1 or -1	tate_get_vertical(vdenom, Qhat, P, p);    }    //g    tate_get_vertical(v, Qhat, Z, p);    //h    fp2_div(res, v, vdenom, p);    point_clear(Z);    point_clear(bP);    fp2_clear(v);    fp2_clear(vdenom);    fp2_clear(fb);    fp2_clear(fbdenom);    mpz_clear(z);    mpz_clear(temp);}int point_valid_p(point_t P, curve_t curve){    int result = 1;    mpz_ptr p = curve->p;    fp2_t error;    fp2_t temp;    if (P->infinity) return result;    fp2_init(error);    fp2_init(temp);    fp2_mul(error, P->x, P->x, p);    fp2_mul(error, error, P->x, p);    fp2_mul(temp, P->y, P->y, p);    fp2_sub(error, temp, error, p);    fp2_sub_ui(error, error, 1, p);    if (mpz_cmp_ui(error->a, 0) || mpz_cmp_ui(error->b, 0)) {	//printf("error = ");	//fp2_out_str(NULL, 0, error);	//printf("\n");	result = 0;    }    fp2_clear(error);    fp2_clear(temp);    return result;}int point_special_p(point_t P, curve_t curve)//check that P is in E/F_p and finite{    int result = 1;    mpz_ptr p = curve->p;    mpz_t error;    mpz_t temp;    if (P->infinity) return 0;    if (mpz_cmp_ui(P->x->b, 0)) return 0;    if (mpz_cmp_ui(P->y->b, 0)) return 0;    mpz_init(error);    mpz_init(temp);    mpz_mul(error, P->x->a, P->x->a);    mpz_mod(error, error, p);    mpz_mul(error, error, P->x->a);    mpz_mod(error, error, p);    mpz_mul(temp, P->y->a, P->y->a);    mpz_sub(error, temp, error);    mpz_sub_ui(error, error, 1);    mpz_mod(error, error, p);    if (mpz_cmp_ui(error, 0)) {	//printf("error = ");	//fp2_out_str(NULL, 0, error);	//printf("\n");	result = 0;    }    mpz_clear(error);    mpz_clear(temp);    return result;}void tate_pairing(fp2_ptr res, point_ptr P, point_ptr Q, curve_t curve)// res = e(P,Q) where e is the Tate pairing// assume P in E/F_p{    bm_put(bm_get_time(), "miller0");    tate_solinas_miller(res, P, Q, curve);    bm_put(bm_get_time(), "miller1");    tate_power(res, curve);}#if 0void weil_pairing(fp2_ptr res, point_ptr P, point_ptr Q)// res = e(P,Q) where e is the Weil pairing{    point_t Phat, Qhat;    fp2_t num, denom;    point_init(Phat);    point_init(Qhat);    fp2_init(num);    fp2_init(denom);    if (!miller_randomized_flag) {	new_random_Rs();    }    for(;;) {	point_add(Phat, P, curve->R1, curve);	point_add(Qhat, Q, curve->R2, curve);	if (!solinas_miller(num, P, Phat, Qhat, curve->R1, curve->R2)) goto millerfail;	if (!solinas_miller(denom, Q, Qhat, Phat, curve->R2, curve->R1)) goto millerfail;	break;millerfail:	new_random_Rs();    }    point_clear(Phat);    point_clear(Qhat);    fp2_div(res, num, denom, p);    fp2_clear(num);    fp2_clear(denom);}#endifvoid zzp_point_double(mpz_t x, mpz_t y, mpz_t Px, mpz_t Py, mpz_t p)//(x,y,1) = 2(Px, Py,1)//assume points are on E/F_p//and we don't expect to get O, either as input or output{    //line: Y - (lambda X + mu)    //we assume a2 = a4 = 0    mpz_t lambda, temp;    mpz_init(lambda);    mpz_init(temp);    mpz_add(lambda, Px, Px);    mpz_add(lambda, lambda, Px);    mpz_mul(lambda, lambda, Px);    mpz_mod(lambda, lambda, p);    mpz_add(temp, Py, Py);    mpz_invert(temp, temp, p);    mpz_mul(lambda, lambda, temp);    mpz_mod(lambda, lambda, p);    mpz_set(temp, Px);    mpz_mul(x, lambda, lambda);    mpz_sub(x, x, temp);    mpz_sub(x, x, temp);    mpz_mod(x, x, p);    mpz_sub(y, temp, x);    mpz_mul(y, y, lambda);    mpz_sub(y, y, Py);    mpz_mod(y, y, p);    mpz_clear(temp);    mpz_clear(lambda);}void zzp_point_add(mpz_t x, mpz_t y, mpz_t Px, mpz_t Py,	mpz_t Qx, mpz_t Qy, mpz_t p)//(x, y) = (Px, Py) + (Qx, Qy)//assume points are on E/F_p, assume output != O{    mpz_t lambda, temp;    mpz_init(lambda);    mpz_init(temp);    //line: Y - (lambda X + mu)    mpz_sub(lambda, Qy, Py);    mpz_sub(temp, Qx, Px);    mpz_invert(temp, temp, p);    mpz_mul(lambda, lambda, temp);    mpz_mod(lambda, lambda, p);    mpz_set(temp, Px);    mpz_mul(x, lambda, lambda);    mpz_sub(x, x, temp);    mpz_sub(x, x, Qx);    mpz_mod(x, x, p);    mpz_sub(y, temp, x);    mpz_mul(y, y, lambda);    mpz_sub(y, y, Py);    mpz_mod(y, y, p);    mpz_clear(temp);    mpz_clear(lambda);}void point_mul_preprocess(point_ptr P, curve_t curve)//get ready for multiplications on P//set up signed sliding-windowS{    int i;    int m;    assert(point_special_p(P, curve));    m = mpz_sizeinbase(curve->q, 2);    //compute x[1], y[1]    mpz_set(curve->pre_x[0], P->x->a);    mpz_set(curve->pre_y[0], P->y->a);    for (i=1; i<=m; i++) {	zzp_point_double(curve->pre_x[i], curve->pre_y[i], curve->pre_x[i-1], curve->pre_y[i-1], curve->p);    }}void point_mul_postprocess(point_ptr R, mpz_t n, curve_t curve)//R = nP (P has been preprocessed)//P must lie on E/F_p, n must be positive//assumes nP != O (?)//uses signed sliding-window method{    //compute NAF form (see Blake, Seroussi & Smart IV.2.4)    int j;    int m = mpz_sizeinbase(n, 2);    int *s = (int *) malloc(sizeof(int) * (m+1));    int c0 = 0, c1;    mpz_t Rx, Ry, Rz;    mpz_t x0, y0;    mpz_ptr p = curve->p;    assert(mpz_cmp_ui(n, 0) > 0);    assert(mpz_cmp(n, curve->q) < 0);    for (j=0; j<=m; j++) {	c1 = (mpz_tstbit(n, j) + mpz_tstbit(n, j+1) + c0) >> 1;	s[j] = mpz_tstbit(n, j) + c0 - 2 * c1;	c0 = c1;    }    mpz_init(Rx); mpz_init(Ry); mpz_init(Rz);    mpz_init(x0); mpz_init(y0);    //first bit might not be used after NAF conversion    if (!s[m]) m--;    mpz_set_ui(Rz, 1);    //now work in projective coordinates    mpz_set(Rx, curve->pre_x[m]);    mpz_set(Ry, curve->pre_y[m]);    m--;    while(m>=0) {	if (s[m]) {	    if (s[m] < 0) {		mpz_sub(x0, p, curve->pre_y[m]);		proj_mix_in(Rx, Ry, Rz, curve->pre_x[m], x0, p);	    } else {		proj_mix_in(Rx, Ry, Rz, curve->pre_x[m], curve->pre_y[m], p);	    }	}	m--;    }    //convert back to affine    mpz_invert(Rz, Rz, p);    mpz_mul(x0, Rz, Rz);    mpz_mod(x0, x0, p);    mpz_mul(Rx, Rx, x0);    mpz_mod(Rx, Rx, p);    mpz_mul(y0, x0, Rz);    mpz_mod(y0, y0, p);    mpz_mul(Ry, Ry, y0);    mpz_mod(Ry, Ry, p);    mpz_set_ui(R->x->b, 0);    mpz_set_ui(R->y->b, 0);    mpz_set(R->x->a, Rx);    mpz_set(R->y->a, Ry);    R->infinity = 0;    mpz_clear(Rx); mpz_clear(Ry); mpz_clear(Rz);    mpz_clear(x0); mpz_clear(y0);    free(s);}void point_mul(point_ptr R, mpz_t n, point_ptr P, curve_t curve)//R = nP//P must lie on E/F_p, 0 < n//uses signed sliding-window method//TODO: handle cases when you get O's during the computation{    //compute NAF form (see Blake, Seroussi & Smart IV.2.4)    int i, j, k, l;    int m = mpz_sizeinbase(n, 2);    int *s = (int *) malloc(sizeof(int) * (m+1));    int c0 = 0, c1;    mpz_t x[2*windowsizepower+2];    mpz_t y[2*windowsizepower+2];    mpz_t Rx, Ry, Rz;    mpz_ptr p = curve->p;    assert(mpz_cmp_ui(n, 0) > 0);    assert(point_special_p(P, curve));    for (j=0; j<=m; j++) {	c1 = (mpz_tstbit(n, j) + mpz_tstbit(n, j+1) + c0) >> 1;	s[j] = mpz_tstbit(n, j) + c0 - 2 * c1;	c0 = c1;    }    mpz_init(Rx); mpz_init(Ry); mpz_init(Rz);    if (0) {	if (mpz_size(P->x->b) || mpz_size(P->y->b) || n <= 0) {	    fprintf(stderr, "BUG: point_mul can't handle points not on E/F_p\n");	    //exit(1);	}    }    mpz_init(y[0]); //we need a temp. variable later    //compute x[1], y[1]    mpz_init(x[1]);    mpz_init(y[1]);    mpz_set(x[1], P->x->a);    mpz_set(y[1], P->y->a);    //compute x[2], y[2]    mpz_init(x[2]);    mpz_init(y[2]);    zzp_point_double(x[2], y[2], x[1], y[1], p);    for (i=1; i<=windowsizepower; i++) {	j = 2 * i + 1;	k = j - 2;	mpz_init(x[j]);	mpz_init(y[j]);	zzp_point_add(x[j], y[j], x[k], y[k], x[2], y[2], p);    }    //first bit might not be used after NAF conversion    if (!s[m]) m--;    mpz_set_ui(Rz, 1);    //now work in projective coordinates    l = m - windowsize + 1;    if (l < 0) l = 0;    for (; l<m; l++) {	if (s[l]) break;    }    j = s[l];    i = 1;    for (k=l+1; k<=m; k++) {	i = i << 1;	j += s[k] * i;    }    if (j < 0) {	j = -j;	mpz_set(Rx, x[j]);	//assumes y[j] != 0	mpz_sub(Ry, p, y[j]);    } else {	mpz_set(Rx, x[j]);	mpz_set(Ry, y[j]);    }    m = l-1;    while(m>=0) {	if (!s[m]) {	    proj_double(Rx, Ry, Rz, p);	    m--;	} else {	    l = m - windowsize + 1;	    if (l < 0) l = 0;	    for (; l<m; l++) {		if (s[l]) break;	    }	    j = s[l];	    proj_double(Rx, Ry, Rz, p);	    i = 1;	    for (k=l+1; k<=m; k++) {		i = i << 1;		j += s[k] * i;		proj_double(Rx, Ry, Rz, p);	    }	    if (j < 0) {		j = -j;		mpz_sub(y[0], p, y[j]);		proj_mix_in(Rx, Ry, Rz, x[j], y[0], p);	    } else {		proj_mix_in(Rx, Ry, Rz, x[j], y[j], p);	    }	    m = l-1;	}    }    //convert back to affine    mpz_invert(Rz, Rz, p);    //x[1], y[1] no longer needed    mpz_mul(x[1], Rz, Rz);    mpz_mod(x[1], x[1], p);    mpz_mul(Rx, Rx, x[1]);    mpz_mod(Rx, Rx, p);    mpz_mul(y[1], x[1], Rz);    mpz_mod(y[1], y[1], p);    mpz_mul(Ry, Ry, y[1]);    mpz_mod(Ry, Ry, p);    mpz_set_ui(R->x->b, 0);    mpz_set_ui(R->y->b, 0);    mpz_set(R->x->a, Rx);    mpz_set(R->y->a, Ry);    R->infinity = 0;    mpz_clear(Rx); mpz_clear(Ry); mpz_clear(Rz);    mpz_clear(x[2]); mpz_clear(y[2]);    for (i=0; i<=windowsizepower; i++) {	j = 2 * i + 1;	mpz_clear(x[j]); mpz_clear(y[j]);    }    mpz_clear(y[0]);    free(s);}void general_point_mul(point_t Q, mpz_t a, point_t P, curve_t curve)//Q = aP//can handle P on E/F_p^2, any integer a{    point_t R;    int i, j, k, l, m;    mpz_t n;    point_t g[2*windowsizepower+2];    mpz_init(n);    point_init(R);    point_set_O(R);    mpz_mod(n, a, curve->q);    if (P->infinity) {	point_set_O(Q);	return;    }    if (!mpz_cmp_ui(a, 0)) {	point_set_O(Q);	return;    }    assert(point_valid_p(P, curve));    //use sliding-window method    point_init(g[1]);    point_set(g[1], P);    point_init(g[2]);    point_add(g[2], P, P, curve);    for (i=1; i<=windowsizepower; i++) {	j = 2 * i + 1;	point_init(g[j]);	point_add(g[j], g[j-2], g[2], curve);    }    m = mpz_sizeinbase(n, 2) - 1;    while(m>=0) {	if (!mpz_tstbit(n, m)) {	    point_add(R, R, R, curve);	    m--;	} else {	    l = m - windowsize + 1;	    if (l < 0) l = 0;	    l = mpz_scan1(n, l);	    j = 1;	    point_add(R, R, R, curve);	    for (k = m - 1; k>=l; k--) {		j = j << 1;		if (mpz_tstbit(n, k)) j++;		point_add(R, R, R, curve);	    }	    point_add(R, R, g[j], curve);	    m = l-1;	}    }    /* check (repeated squaring) */    if (0) {	point_t Rcheck;	point_init(Rcheck);	point_set_O(Rcheck);	m = mpz_sizeinbase(n, 2) - 1;	for(;;) {	    if (mpz_tstbit(n, m)) {		point_add(Rcheck, Rcheck, P, curve);	    }	    if (m == 0) break;	    point_add(Rcheck, Rcheck, Rcheck, curve);	    m--;	}	if (!point_equal(R, Rcheck)) {	    fprintf(stderr, "point_mul(): BUG!\n");	    //exit(1);	}    }    point_clear(g[2]);    for (i=0; i<=windowsizepower; i++) {	j = 2 * i + 1;	point_clear(g[j]);    }    mpz_clear(n);    point_set(Q, R);    point_clear(R);}

⌨️ 快捷键说明

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