/* SU= 600 */ void FP12_inv(FP12 *w,FP12 *x) { FP4 f0,f1,f2,f3; FP12_norm(x); FP4_sqr(&f0,&(x->a)); FP4_mul(&f1,&(x->b),&(x->c)); FP4_times_i(&f1); FP4_sub(&f0,&f0,&f1); /* y.a */ FP4_sqr(&f1,&(x->c)); FP4_times_i(&f1); FP4_mul(&f2,&(x->a),&(x->b)); FP4_sub(&f1,&f1,&f2); /* y.b */ FP4_sqr(&f2,&(x->b)); FP4_mul(&f3,&(x->a),&(x->c)); FP4_sub(&f2,&f2,&f3); /* y.c */ FP4_mul(&f3,&(x->b),&f2); FP4_times_i(&f3); FP4_mul(&(w->a),&f0,&(x->a)); FP4_add(&f3,&(w->a),&f3); FP4_mul(&(w->c),&f1,&(x->c)); FP4_times_i(&(w->c)); FP4_add(&f3,&(w->c),&f3); FP4_inv(&f3,&f3); FP4_mul(&(w->a),&f0,&f3); FP4_mul(&(w->b),&f1,&f3); FP4_mul(&(w->c),&f2,&f3); }
/* SU= 600 */ void FP12_usqr(FP12 *w,FP12 *x) { FP4 A,B,C,D; FP4_copy(&A,&(x->a)); FP4_sqr(&(w->a),&(x->a)); FP4_add(&D,&(w->a),&(w->a)); FP4_add(&(w->a),&D,&(w->a)); #if CHUNK<64 FP4_norm(&(w->a)); #endif FP4_nconj(&A,&A); FP4_add(&A,&A,&A); FP4_add(&(w->a),&(w->a),&A); FP4_sqr(&B,&(x->c)); FP4_times_i(&B); FP4_add(&D,&B,&B); FP4_add(&B,&B,&D); #if CHUNK<64 FP4_norm(&B); #endif FP4_sqr(&C,&(x->b)); FP4_add(&D,&C,&C); FP4_add(&C,&C,&D); #if CHUNK<64 FP4_norm(&C); #endif FP4_conj(&(w->b),&(x->b)); FP4_add(&(w->b),&(w->b),&(w->b)); FP4_nconj(&(w->c),&(x->c)); FP4_add(&(w->c),&(w->c),&(w->c)); FP4_add(&(w->b),&B,&(w->b)); FP4_add(&(w->c),&C,&(w->c)); FP12_reduce(w); /* reduce here as in pow function repeated squarings would trigger multiple reductions */ }
/* XTR xtr_d function */ void FP4_xtr_D(FP4 *r,FP4 *x) { FP4 w; FP4_copy(r,x); FP4_conj(&w,r); FP4_add(&w,&w,&w); FP4_sqr(r,r); FP4_sub(r,r,&w); FP4_reduce(r); /* reduce here as multiple calls trigger automatic reductions */ }
/* SU= 600 */ void FP12_sqr(FP12 *w,FP12 *x) { /* Use Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */ FP4 A,B,C,D; FP4_sqr(&A,&(x->a)); FP4_mul(&B,&(x->b),&(x->c)); FP4_add(&B,&B,&B); FP4_sqr(&C,&(x->c)); FP4_mul(&D,&(x->a),&(x->b)); FP4_add(&D,&D,&D); FP4_add(&(w->c),&(x->a),&(x->c)); FP4_add(&(w->c),&(x->b),&(w->c)); FP4_sqr(&(w->c),&(w->c)); FP4_copy(&(w->a),&A); FP4_add(&A,&A,&B); #if CHUNK<64 FP4_norm(&A); #endif FP4_add(&A,&A,&C); FP4_add(&A,&A,&D); #if CHUNK<64 FP4_norm(&A); #endif FP4_neg(&A,&A); FP4_times_i(&B); FP4_times_i(&C); FP4_add(&(w->a),&(w->a),&B); FP4_add(&(w->b),&C,&D); FP4_add(&(w->c),&(w->c),&A); FP12_norm(w); }
/* SU= 240 */ void FP4_pow(FP4 *r,FP4* a,BIG b) { FP4 w; BIG z,zilch; int bt; BIG_zero(zilch); BIG_norm(b); BIG_copy(z,b); FP4_copy(&w,a); FP4_one(r); while(1) { bt=BIG_parity(z); BIG_shr(z,1); if (bt) FP4_mul(r,r,&w); if (BIG_comp(z,zilch)==0) break; FP4_sqr(&w,&w); } FP4_reduce(r); }