//c_iとk_iをペアリングする関数 //¬記号で別々の処理する //(v_i - x_t)も必要→とりあえず置いておこう……→一応できた? Element *pairing_c_k(EC_PAIRING p, rho_i *rho, EC_POINT *c, EC_POINT *k, mpz_t *alpha_i) { int i; Element *result; result = (Element*)malloc(sizeof(Element)); Element egg, tempegg1, tempegg2; element_init(egg, p->g3); element_init(tempegg1, p->g3); element_init(tempegg2, p->g3); element_init(*result, p->g3); mpz_t temp1; mpz_init(temp1); mpz_t temp2; mpz_init(temp2); mpz_t order; mpz_init(order); mpz_set(order, *pairing_get_order(p)); element_set_one(*result); if (alpha_i == NULL && rho == NULL) { //e(c_0, k_0) for (i = 0; i < 5; i++) { pairing_map(tempegg1, c[i], k[i], p); element_mul(tempegg2, tempegg1, *result); element_set(*result, tempegg2); } } else if (mpz_cmp_ui(*alpha_i, 0) == 0) {//return 1 } else if (rho->is_negated == FALSE) { for (i = 0; i < 7; i++) { pairing_map(tempegg1, c[i], k[i], p); element_mul(tempegg2, tempegg1, *result); element_set(*result, tempegg2); } element_pow(tempegg1, *result, *alpha_i); element_set(*result, tempegg1); } else { //is_negated == TRUE for (i = 0; i < 7; i++) { pairing_map(tempegg1, c[i], k[i], p); element_mul(tempegg2, tempegg1, *result); element_set(*result, tempegg2); } mpz_set_ui(temp1, rho->v_t[0]); //v_i - x_t mpz_invert(temp2, temp1, order); mpz_mul(temp1, temp2, *alpha_i); // alpha_i / (v_i - x_t) mpz_mod(*alpha_i, temp1, order); element_pow(tempegg1, *result, *alpha_i); element_set(*result, tempegg1); } mpz_clear(order); mpz_clear(temp2); mpz_clear(temp1); element_clear(egg); element_clear(tempegg1); element_clear(tempegg2); return result; }
//============================================ // Frobenius Map \phi_p //============================================ void test_frob(Field f) { int i; unsigned long long int t1, t2; mpz_t p; Element a, b, c; mpz_init_set(p, *field_get_char(f)); element_init(a, f); element_init(b, f); element_init(c, f); for (i = 0; i < 100; i++) { element_random(a); element_pow(b, a, p); bn254_fp2_frob_p(c, a); assert(element_cmp(b, c) == 0); } t1 = rdtsc(); for (i = 0; i < N; i++) { bn254_fp2_frob_p(c, a); } t2 = rdtsc(); printf("element frob: %.2lf [clock]\n", (double)(t2 - t1) / N); mpz_clear(p); element_clear(a); element_clear(b); element_clear(c); }
//-------------------------------------------------- // square root in extended Fp //-------------------------------------------------- int bn254_fp2_sqrt(Element z, const Element x) { mpz_t _v; int m, r, i; field_precomp_sqrt_p ps; Element *t = field(z)->tmp; if (!element_is_sqr(x)) { return FALSE; } ps = ((field_precomp_p)(field(x)->precomp))->ps; element_set(t[0], ps->n_v); // t0 = n^v r = ps->e; // r = e mpz_init_set(_v, ps->v); mpz_sub_ui(_v, _v, 1); mpz_tdiv_q_2exp(_v, _v, 1); element_pow(t[1], x, _v); // t1 = x^{(v-1)/2} element_sqr(t[2], t[1]); element_mul(t[2], t[2], x); // t2 = x*t1^2 element_mul(t[1], x, t[1]); // t1 = x*t1 mpz_clear(_v); while (!element_is_one(t[2])) { m = 0; element_set(t[3], t[2]); do { element_sqr(t[3], t[3]); m++; } while (!element_is_one(t[3]) && m < r); r = r - m - 1; element_set(t[3], t[0]); for (i = 1; i <= r; i++) { element_sqr(t[3], t[3]); } // t3 = t2^{r-m-1} element_sqr(t[0], t[3]); // t0 = t3^2 r = m; element_mul(t[1], t[1], t[3]);// t1 = t1*t3 element_mul(t[2], t[2], t[0]);// t2 = t2*t0 } element_set(z, t[1]); return TRUE; }
//--------------------------------------------------------- // precomputation for sqrt //--------------------------------------------------------- void bn254_fp2_precomp_sqrt(field_precomp_sqrt_p ps, const Field f) { //----------------------------- // decompose of value // (p^2-1) = 2^e * v //----------------------------- mpz_init_set(ps->v, f->order); mpz_sub_ui(ps->v, ps->v, 1); ps->e = (int)mpz_scan1(ps->v, 0); mpz_fdiv_q_2exp(ps->v, ps->v, ps->e); //---------------------------------- // n_v = n^v : // n is some integer (n/p) = -1 //---------------------------------- element_init(ps->n_v, f); do { element_random(ps->n_v); } while (element_is_sqr(ps->n_v)); element_pow(ps->n_v, ps->n_v, ps->v); }
//============================================ // 四則演算のテストプログラム //============================================ void test_arithmetic_operation(Field f) { int i; unsigned long long int t1, t2; Element a, b, c, d; Element d1, d2, d3; mpz_t exp; //-------------------- // init //-------------------- element_init(a, f); element_init(b, f); element_init(c, f); element_init(d, f); element_init(d1, f->base); element_init(d2, f->base); element_init(d3, f->base); //-------------------- // add //-------------------- element_set_str(a, "17A767D1D0F35B9B2CE7CF00A9D036B7E087E24F1CBFFEF8C599F75DFDAD470B 107B87895D05703A57532E47A7BD8CA9C6406B5378C7E81F064749BB848490B2 44C128CE2774FC5C7022584909212BAB973CE5CA964D1B6A0ED9CCED1FA77DD 61C632B1BA796F688FF4A04475242B4116296B8A873B6C535C090278D88A7DB 685D0DA4D199864C925BAC4FD9EDBC9522367F43054E28E4E529A0FBF9BA604 7533624DC55FB89EDD5417E8F7E88E0B4A1F4CABD11353BEB3BD55FB62E7555"); element_set_str(b, "19A7AA060E14E19A21FEF364C2BA8C3015EE7951DC51B928A55CE8C77E8998D9 43D2B55CCF3C20793C1402EE521F63E0DA933666152D14E6B35670281BB24E7 1A27F4DA83812A83B3189BAA7B9CB92F8401337F9334D9E155F66F31F33DE5DC 189A48DEB41106F112E6CCC46C55110E9BCF02C2B727B373CC6E46F3F80147F5 1A6243EC30C85C55E948EFF298055B8B5991E3CBD578CAB7DF4C1E52427329B7 2331BDFFF829F8D50BC7FD2BEF8607985B8C3F4805BA05F0F5CAB75DAD1E0194"); element_set_str(d, "DDE16D341C72D770070A7CCE5A5C0A679741C60E111B81FEC7680257C36DFE3 14B8B2DF29F93241EB146E768CDF82E7D3E99EB9DA1AB96D717CB0BE063FB599 1E74076765F87A497A1AC12F0C2ECBEA3D7501DC3C99AB97F6E40C00C5385DB9 1EB6AC09CFB89DE79BE616C8B3A753C2AD31997B5F9B6A39022ED71B8589EFD0 20E814C67DE1F4BAB26EAAB795A43754ABB54BC005CDAD462D9EB862020ECFBB 713F920373EE4A0AB272411F81F8E37932BF4D2AACB3B2B62862CBD634C76E8"); element_add(c, a, b); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_add(c, a, b); } t2 = rdtsc(); printf("element add: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // sub //-------------------- element_set(d, c); element_sub(c, c, d); assert(element_is_zero(c)); //-------------------- // mul //-------------------- element_mul(c, a, b); element_set_str(d1, "12B60569C8620CA5D70141D319878E5B060A4AA80413BEC52B5173D61E8A3387 1EF2082B9DCA3ABF201AA99B0230714369969A04C6064A7E9288B9551F95CA36"); element_set_str(d2, "17B103CB3F5567B2C3A06E07CD31923CD87D72406E23B25B5066E61D029991F1 1791B2FB67A6FE4BC47F7719F2B5720ED863499E582E787A3EE2F513B4BDB4CF"); element_set_str(d3, "2264428EB266F97E47163B2BE433146D0D5FBD32F6552D6079B4D85719F10635 14418C5689124B593F626719E1A07B7D0A2DA48E5BFEC13BDE16F0B8CC521F9B"); element_set(((Element *)d->data)[0], d1); element_set(((Element *)d->data)[1], d2); element_set(((Element *)d->data)[2], d3); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_mul(c, a, b); } t2 = rdtsc(); printf("element mul: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // sqr //-------------------- element_sqr(c, a); element_mul(d, a, a); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_sqr(c, a); } t2 = rdtsc(); printf("element sqr: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // random //-------------------- element_random(b); //-------------------- // inv //-------------------- element_mul(c, a, b); element_inv(b, b); element_mul(c, c, b); element_inv(d, a); element_mul(d, a, d); assert(element_cmp(c, a) == 0); assert(element_is_one(d)); t1 = rdtsc(); for (i = 0; i < N; i++) { element_inv(c, a); } t2 = rdtsc(); printf("element inv: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // pow //-------------------- mpz_init(exp); mpz_set_str(exp, "AA4A2EE5234E0E95E8BB01F6B4A67F0EE8F2ADC1AA153C48D163AA85F3F534C", 16); element_pow(c, a, exp); element_set_str(d, "1CE3C3F32AC26429F4B8CDA845C051A4E88297DCCF33466FE03DDBCB06D7F83C 12AB1B1C4204A483CB230C3A25F3D3498CBC006D7DFF3F9D3565544BF09EEECD 16449675C385AA37E54DC18FABD35B84D1714E22991BEBD5CE7EFFBBEB110517 4B8B39A2E4C86D3BBD58B771A220F62E988136ECBB92D1213B3D268152A4E14 5C3CF6A5663F06A4F805674B29A6D2D7B9F0A8DA7E366EC239420E78B5BFAB6 C762C8ECC272929A992D55227F9C2927A04731122265C0E217B9B47AF524AA1"); assert(element_cmp(c, d) == 0); mpz_set(exp, f->order); for (i = 0; i < 50; i++) { element_random(a); element_pow(b, a, exp); assert(element_cmp(b, a) == 0); } t1 = rdtsc(); for (i = 0; i < M; i++) { element_pow(b, a, exp); } t2 = rdtsc(); printf("element pow with order: %.2lf [clock]\n", (double)(t2 - t1) / M); mpz_clear(exp); //-------------------- // clear //-------------------- element_clear(a); element_clear(b); element_clear(c); element_clear(d); element_clear(d1); element_clear(d2); element_clear(d3); }
//============================================ // 四則演算のテストプログラム //============================================ void test_arithmetic_operation(Field f) { int i; unsigned long long int t1, t2; Element a, b, c, d; char loop[] = "100"; mpz_t e, exp; //-------------------- // init //-------------------- element_init(a, f); element_init(b, f); element_init(c, f); element_init(d, f); //-------------------- // add //-------------------- element_set_str(a, "1C12C39A2AD14054EDC9EE504301127AFFEEAADC59A78B50FCFFED87AC6EB8BF 20E1A922384561EA82602CD664D85D442DAC5D391E142ABB3CFEC2A095C22DF9"); element_set_str(b, "F1B91250A124F268B8239185B23B31EB25179A11A9A0398E61B701F7D4F7265 20D206C5F7D007EDBA34A4B041622289D64F04CA28CEAC490619585AA14F7B2F"); element_set_str(d, "7BD59BA97A27FBD2AD60CD0173FC358353DE53D5C418EE8649AFDA729BE2B23 1E42B4E392D45A19EE1EB6EE1F557D8C86F922C32EE2D702C497BAFB3711A927"); element_add(c, a, b); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_add(c, a, b); } t2 = rdtsc(); printf("element add: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // sub //-------------------- element_set(d, c); element_sub(c, c, d); assert(element_is_zero(c)); //-------------------- // mul //-------------------- element_mul(c, a, b); element_set_str(d, "1D0562FF0AB317FFDE555320A7072D2B29C07077E08996CE5F093BB8E4200B2C 9B04361A24DC7F37C8BD09A7C51A9D8577168AD021BF2B4AC3D67552F481B1A"); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_mul(c, a, b); } t2 = rdtsc(); printf("element mul: %.2lf [clock]\n", (double)(t2 - t1) / N); mpz_init_set_str(e, "1B45F16C848B9C476C1D2FF1FD60A0D0C19BBA6F3ECE3CF6C5FCE4FAB7CAD4FF", 16); element_pow(c, a, e); element_set_str(d, "B40190CE812CB4F668A839952128D19B1748F3BB19E902480D089AF9053A6D2 19DA59F09C3C20472C3BD19A4FC95BCAF266B9D1539AAD23E3C67C4F3A7CA51D"); assert(element_cmp(c, d) == 0); mpz_clear(e); //-------------------- // sqr //-------------------- element_sqr(c, a); element_mul(d, a, a); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_sqr(c, a); } t2 = rdtsc(); printf("element sqr: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // random //-------------------- element_random(a); element_random(b); //-------------------- // inv //-------------------- element_mul(c, a, b); element_inv(b, b); element_mul(c, c, b); element_inv(d, a); element_mul(d, a, d); assert(element_cmp(c, a) == 0); assert(element_is_one(d)); t1 = rdtsc(); for (i = 0; i < N; i++) { element_inv(b, a); } t2 = rdtsc(); printf("element inv: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // pow //-------------------- mpz_init_set_str(exp, loop, 10); element_set_one(b); for (i = 0; i < atoi(loop); i++) { element_mul(b, b, a); } element_pow(c, a, exp); assert(element_cmp(b, c) == 0); mpz_set(exp, f->order); for (i = 0; i < 100; i++) { element_random(a); element_pow(b, a, exp); assert(element_cmp(b, a) == 0); } t1 = rdtsc(); for (i = 0; i < N; i++) { element_pow(b, a, exp); } t2 = rdtsc(); printf("element pow with order: %.2lf [clock]\n", (double)(t2 - t1) / N); mpz_clear(exp); //-------------------- // clear //-------------------- element_clear(a); element_clear(b); element_clear(c); element_clear(d); }