void fp3_inv_sim(fp3_t * c, fp3_t * a, int n) { int i; fp3_t u, t[n]; for (i = 0; i < n; i++) { fp3_null(t[i]); } fp3_null(u); TRY { for (i = 0; i < n; i++) { fp3_new(t[i]); } fp3_new(u); fp3_copy(c[0], a[0]); fp3_copy(t[0], a[0]); for (i = 1; i < n; i++) { fp3_copy(t[i], a[i]); fp3_mul(c[i], c[i - 1], t[i]); } fp3_inv(u, c[n - 1]); for (i = n - 1; i > 0; i--) { fp3_mul(c[i], c[i - 1], u); fp3_mul(u, u, t[i]); } fp3_copy(c[0], u); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 0; i < n; i++) { fp3_free(t[i]); } fp3_free(u); } }
void fp3_mul_frb(fp3_t c, fp3_t a, int i, int j, int k) { ctx_t *ctx = core_get(); if (i == 0) { switch (j % 3) { case 0: fp3_copy(c, a); break; case 1: fp_copy(c[0], a[0]); fp_mul(c[1], a[1], ctx->fp3_base[0]); fp_mul(c[2], a[2], ctx->fp3_base[1]); break; case 2: fp_copy(c[0], a[0]); fp_mul(c[1], a[1], ctx->fp3_base[1]); fp_mul(c[2], a[2], ctx->fp3_base[0]); break; } } else { switch (j % 6) { case 0: fp3_copy(c, a); break; case 1: fp_mul(c[0], a[0], ctx->fp3_p[k - 1]); fp_mul(c[1], a[1], ctx->fp3_p[k - 1]); fp_mul(c[2], a[2], ctx->fp3_p[k - 1]); if (k != 3) { for (int l = 0; l < 3 - (k % 3); l++) { fp3_mul_art(c, c); } } break; case 2: fp_mul(c[0], a[0], ctx->fp3_p2[k - 1]); fp_mul(c[1], a[1], ctx->fp3_p2[k - 1]); fp_mul(c[2], a[2], ctx->fp3_p2[k - 1]); for (int l = 0; l < (k % 3); l++) { fp3_mul_art(c, c); } break; case 3: fp_mul(c[0], a[0], ctx->fp3_p3[k - 1]); fp_mul(c[1], a[1], ctx->fp3_p3[k - 1]); fp_mul(c[2], a[2], ctx->fp3_p3[k - 1]); break; case 4: fp_mul(c[0], a[0], ctx->fp3_p4[k - 1]); fp_mul(c[1], a[1], ctx->fp3_p4[k - 1]); fp_mul(c[2], a[2], ctx->fp3_p4[k - 1]); if (k != 3) { for (int l = 0; l < 3 - (k % 3); l++) { fp3_mul_art(c, c); } } break; case 5: fp_mul(c[0], a[0], ctx->fp3_p5[k - 1]); fp_mul(c[1], a[1], ctx->fp3_p5[k - 1]); fp_mul(c[2], a[2], ctx->fp3_p5[k - 1]); for (int l = 0; l < (k % 3); l++) { fp3_mul_art(c, c); } break; } } }