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

📄 19.c

📁 这是一个C的源代码
💻 C
字号:
/*  * Toy example of a field where the Tate pairing can be used * but the Weil pairing cannot. * * Consider the curve E: y^2 = x^3 + x + 6 over F_19: * E(F_19) is a cyclic group of order 18. * Thus E[3] is not contained in F_19 * (it turns out E[3] is contained in F_19^3). * * Hence the Weil pairing cannot be defined over F_19 * However, F_19 contains the cube roots of unity * so we can compute the Tate pairing *//* * P = (12,13) generates a group of order 3: * <(12,13)> = {(12,13), (12,6), O} * e(P,P) = 7, so we have the isomorphism * <(12,13)> = <7> (in F_19^*) * * Similarly P = (4, 6) generates a group of order 9, and we find * <(4,6)> = <4> * * P = (0, 5) generates all of E(F_19) * Miller's algorithm will not allow us to calculate e(P, P) without * first extending F_19. * Instead of extending, we could manipulate rational functions since * 19 is small enough that an explicit expression of f_P can be found. */#include "pbc.h"#include "pbc_fp.h"#include "pbc_fieldquadratic.h"static void miller(element_t res, element_t P,	element_ptr QR, element_ptr R, int n){    //collate divisions    int m;    element_t v, vd;    element_t Z;    element_t a, b, c;    const element_ptr cca = curve_a_coeff(P);    const element_ptr Px = curve_x_coord(P);    const element_ptr Py = curve_y_coord(P);    element_t e0, e1;    mpz_t q;    element_ptr Zx, Zy;    const element_ptr numx = curve_x_coord(QR);    const element_ptr numy = curve_y_coord(QR);    const element_ptr denomx = curve_x_coord(R);    const element_ptr denomy = curve_y_coord(R);    void do_vertical(element_t e, element_t edenom)    {	element_sub(e0, numx, Zx);	element_mul(e, e, e0);	element_sub(e0, denomx, Zx);	element_mul(edenom, edenom, e0);    }    void do_tangent(element_t e, element_t edenom)    {	//a = -slope_tangent(A.x, A.y);	//b = 1;	//c = -(A.y + a * A.x);	//but we multiply by 2*A.y to avoid division	//a = -Ax * (Ax + Ax + Ax + twicea_2) - a_4;	//Common curves: a2 = 0 (and cc->a is a_4), so	//a = -(3 Ax^2 + cc->a)	//b = 2 * Ay	//c = -(2 Ay^2 + a Ax);	if (element_is0(Zy)) {	    do_vertical(e, edenom);	    return;	}	element_square(a, Zx);	element_mul_si(a, a, 3);	element_add(a, a, cca);	element_neg(a, a);	element_add(b, Zy, Zy);	element_mul(e0, b, Zy);	element_mul(c, a, Zx);	element_add(c, c, e0);	element_neg(c, c);	element_mul(e0, a, numx);	element_mul(e1, b, numy);	element_add(e0, e0, e1);	element_add(e0, e0, c);	element_mul(e, e, e0);	element_mul(e0, a, denomx);	element_mul(e1, b, denomy);	element_add(e0, e0, e1);	element_add(e0, e0, c);	element_mul(edenom, edenom, e0);    }    void do_line(element_ptr e, element_ptr edenom)    {	if (!element_cmp(Zx, Px)) {	    if (!element_cmp(Zy, Py)) {		do_tangent(e, edenom);	    } else {		do_vertical(e, edenom);	    }	    return;	}	element_sub(b, Px, Zx);	element_sub(a, Zy, Py);	element_mul(c, Zx, Py);	element_mul(e0, Zy, Px);	element_sub(c, c, e0);	element_mul(e0, a, numx);	element_mul(e1, b, numy);	element_add(e0, e0, e1);	element_add(e0, e0, c);	element_mul(e, e, e0);	element_mul(e0, a, denomx);	element_mul(e1, b, denomy);	element_add(e0, e0, e1);	element_add(e0, e0, c);	element_mul(edenom, edenom, e0);    }    element_init(a, res->field);    element_init(b, res->field);    element_init(c, res->field);    element_init(e0, res->field);    element_init(e1, res->field);    element_init(v, res->field);    element_init(vd, res->field);    element_init(Z, P->field);    element_set(Z, P);    Zx = curve_x_coord(Z);    Zy = curve_y_coord(Z);    element_set1(v);    element_set1(vd);    mpz_init(q);    mpz_set_ui(q, n);    m = mpz_sizeinbase(q, 2) - 2;    while(m >= 0) {	element_square(v, v);	element_square(vd, vd);	do_tangent(v, vd);	element_double(Z, Z);	do_vertical(vd, v);	if (mpz_tstbit(q, m)) {	    do_line(v, vd);	    element_add(Z, Z, P);	    if (m) {		do_vertical(vd, v);	    }	}	m--;    }    mpz_clear(q);    element_invert(vd, vd);    element_mul(res, v, vd);    element_clear(v);    element_clear(vd);    element_clear(Z);    element_clear(a);    element_clear(b);    element_clear(c);    element_clear(e0);    element_clear(e1);}static void tate_3(element_ptr out, element_ptr P, element_ptr Q, element_ptr R){    mpz_t six;    mpz_init(six);    mpz_set_ui(six, 6);    element_t QR;    element_t e0;    element_init(QR, P->field);    element_init(e0, out->field);    element_add(QR, Q, R);    //for subgroup size 3, -2P = P, hence    //the tangent line at P has divisor 3(P) - 3(O)    miller(out, P, QR, R, 3);    element_pow_mpz(out, out, six);    element_clear(QR);    element_clear(e0);    mpz_clear(six);}static void tate_9(element_ptr out, element_ptr P, element_ptr Q, element_ptr R){    element_t QR;    element_init(QR, P->field);    element_add(QR, Q, R);    miller(out, P, QR, R, 9);    element_square(out, out);    element_clear(QR);}static void tate_18(element_ptr out, element_ptr P, element_ptr Q, element_ptr R, element_ptr S){    mpz_t pow;    element_t PR;    element_t QS;    element_init(PR, P->field);    element_init(QS, P->field);    element_t outd;    element_init(outd, out->field);    mpz_init(pow);    mpz_set_ui(pow, (19*19-1)/18);    element_add(PR, P, R);    element_add(QS, Q, S);    if (element_is0(QS)) {	element_t S2;	element_init(S2, P->field);	element_double(S2, S);	miller(out, PR, S, S2, 18);	miller(outd, R, S, S2, 18);	element_clear(S2);    } else {	miller(out, PR, QS, S, 18);	miller(outd, R, QS, S, 18);    }    element_clear(PR);    element_clear(QS);    element_invert(outd, outd);    element_mul(out, out, outd);    element_pow_mpz(out, out, pow);    element_clear(outd);    mpz_clear(pow);}int main(void){    field_t c;    field_t Z19;    element_t P, Q, R;    mpz_t q, z;    element_t a, b;    int i;    field_t Z19_2;    field_t c2;    element_t P2, Q2, R2;    element_t a2;    mpz_init(q);    mpz_init(z);    mpz_set_ui(q, 19);    field_init_fp(Z19, q);    element_init(a, Z19);    element_init(b, Z19);    element_set_si(a, 1);    element_set_si(b, 6);    mpz_set_ui(q, 18);    field_init_curve_ab(c, a, b, q, NULL);    element_init(P, c);    element_init(Q, c);    element_init(R, c);    printf("Y^2 = X^3 + X + 6 over F_19\n");    //(0,+/-5) is a generator    element_set0(a);    curve_from_x(R, a);    for (i=1; i<19; i++) {	mpz_set_si(z, i);	element_mul_mpz(Q, R, z);	element_printf("%dR = %B\n", i, Q);    }    mpz_set_ui(z, 6);    element_mul_mpz(P, R, z);    //P has order 3    element_printf("P = %B\n", P);    for (i=1; i<=3; i++) {	mpz_set_si(z, i);	element_mul_mpz(Q, R, z);	tate_3(a, P, Q, R);	element_printf("e_3(P,%dR) = %B\n", i, a);    }    element_double(P, R);    //P has order 9    element_printf("P = %B\n", P);    for (i=1; i<=9; i++) {	mpz_set_si(z, i);	//we're supposed to use multiples of R	//but 2R works just as well and it allows us	//to use R as the offset every time	element_mul_mpz(Q, P, z);	tate_9(a, P, Q, R);	element_printf("e_9(P,%dP) = %B\n", i, a);    }    //to do the pairing on all of E(F_19) we need to move to F_19^2    //or compute the rational function explicitly    printf("moving to F_19^2\n");    field_init_fi(Z19_2, Z19);    //don't need to tell it the real order    field_init_curve_ab_map(c2, c, element_field_to_fi, Z19_2, q, NULL);    element_init(P2, c2);    element_init(Q2, c2);    element_init(R2, c2);    element_init(a2, Z19_2);    element_set0(a2);    curve_from_x(P2, a2);    element_random(R2);    element_printf("P = %B\n", P2);    for (i=1; i<=18; i++) {	mpz_set_si(z, i);	element_mul_mpz(Q2, P2, z);	tate_18(a2, P2, Q2, R2, P2);	element_printf("e_18(P,%dP) = %B\n", i, a2);    }    element_clear(P2);    element_clear(Q2);    element_clear(R2);    element_clear(a2);    field_clear(c2);    field_clear(Z19_2);    field_clear(c);    element_clear(a);    element_clear(b);    element_clear(P);    element_clear(Q);    element_clear(R);    field_clear(Z19);    mpz_clear(q);    mpz_clear(z);    return 0;}

⌨️ 快捷键说明

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