static void fp4_mul_unr(dv2_t e, dv2_t f, fp2_t a, fp2_t b, fp2_t c, fp2_t d) { fp2_t t0, t1; dv2_t u0, u1; fp2_null(t0); fp2_null(t1); dv2_null(u0); dv2_null(u1); TRY { fp2_new(t0); fp2_new(t1); dv2_new(u0); dv2_new(u1); #ifdef FP_SPACE fp2_mulc_low(u0, a, c); fp2_mulc_low(u1, b, d); fp2_addn_low(t0, c, d); fp2_addn_low(t1, a, b); #else fp2_muln_low(u0, a, c); fp2_muln_low(u1, b, d); fp2_addm_low(t0, c, d); fp2_addm_low(t1, a, b); #endif fp2_muln_low(f, t1, t0); fp2_subc_low(f, f, u0); fp2_subc_low(f, f, u1); fp2_norh_low(e, u1); fp2_addc_low(e, e, u0); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(t0); dv2_free(t1); dv2_free(u0); dv2_free(u1); } }
void fp2_mulm_low(fp2_t c, fp2_t a, fp2_t b) { align dv2_t t; dv2_null(t); TRY { dv2_new(t); fp2_muln_low(t, a, b); fp2_rdcn_low(c, t); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { dv2_free(t); } }
inline static void fp6_mul_dxs_unr_lazyr(dv6_t c, fp6_t a, fp6_t b) { dv2_t u0, u1, u2, u3; fp2_t t0, t1; dv2_null(u0); dv2_null(u1); dv2_null(u2); dv2_null(u3); fp2_null(t0); fp2_null(t1); TRY { dv2_new(u0); dv2_new(u1); dv2_new(u2); dv2_new(u3); fp2_new(t0); fp2_new(t1); #ifdef RLC_FP_ROOM fp2_mulc_low(u0, a[0], b[0]); fp2_mulc_low(u1, a[1], b[1]); fp2_addn_low(t0, a[0], a[1]); fp2_addn_low(t1, b[0], b[1]); /* c_1 = (a_0 + a_1)(b_0 + b_1) - a_0b_0 - a_1b_1 */ fp2_muln_low(u2, t0, t1); fp2_subc_low(u2, u2, u0); fp2_subc_low(c[1], u2, u1); /* c_0 = a_0b_0 + E a_2b_1 */ fp2_mulc_low(u2, a[2], b[1]); fp2_norh_low(c[0], u2); fp2_addc_low(c[0], u0, c[0]); /* c_2 = a_0b_2 + a_1b_1 */ fp2_mulc_low(u2, a[2], b[0]); fp2_addc_low(c[2], u1, u2); #else fp2_muln_low(u0, a[0], b[0]); fp2_muln_low(u1, a[1], b[1]); fp2_addm_low(t0, a[0], a[1]); fp2_addm_low(t1, b[0], b[1]); /* c_1 = (a_0 + a_1)(b_0 + b_1) - a_0b_0 - a_1b_1 */ fp2_muln_low(u2, t0, t1); fp2_subc_low(u2, u2, u0); fp2_subc_low(c[1], u2, u1); /* c_0 = a_0b_0 + E a_2b_1 */ fp2_muln_low(u2, a[2], b[1]); fp2_nord_low(c[0], u2); fp2_addc_low(c[0], u0, c[0]); /* c_2 = a_0b_2 + a_1b_1 */ fp2_muln_low(u2, a[2], b[0]); fp2_addc_low(c[2], u1, u2); #endif #ifdef RLC_FP_ROOM #else #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { dv2_free(u0); dv2_free(u1); dv2_free(u2); dv2_free(u3); fp2_free(t0); fp2_free(t1); } }
void fp12_mul_dxs_lazyr(fp12_t c, fp12_t a, fp12_t b) { fp6_t t0; dv6_t u0, u1, u2; fp6_null(t0); dv6_null(u0); dv6_null(u1); dv6_null(u2); TRY { fp6_new(t0); dv6_new(u0); dv6_new(u1); dv6_new(u2); if (ep2_curve_is_twist() == EP_DTYPE) { #if EP_ADD == BASIC /* t0 = a_0 * b_0. */ fp_muln_low(u0[0][0], a[0][0][0], b[0][0][0]); fp_muln_low(u0[0][1], a[0][0][1], b[0][0][0]); fp_muln_low(u0[1][0], a[0][1][0], b[0][0][0]); fp_muln_low(u0[1][1], a[0][1][1], b[0][0][0]); fp_muln_low(u0[2][0], a[0][2][0], b[0][0][0]); fp_muln_low(u0[2][1], a[0][2][1], b[0][0][0]); /* t2 = b_0 + b_1. */ fp_add(t0[0][0], b[0][0][0], b[1][0][0]); fp_copy(t0[0][1], b[1][0][1]); fp2_copy(t0[1], b[1][1]); #elif EP_ADD == PROJC /* t0 = a_0 * b_0. */ #ifdef RLC_FP_ROOM fp2_mulc_low(u0[0], a[0][0], b[0][0]); fp2_mulc_low(u0[1], a[0][1], b[0][0]); fp2_mulc_low(u0[2], a[0][2], b[0][0]); #else fp2_muln_low(u0[0], a[0][0], b[0][0]); fp2_muln_low(u0[1], a[0][1], b[0][0]); fp2_muln_low(u0[2], a[0][2], b[0][0]); #endif /* t2 = b_0 + b_1. */ fp2_add(t0[0], b[0][0], b[1][0]); fp2_copy(t0[1], b[1][1]); #endif /* t1 = a_1 * b_1. */ fp6_mul_dxs_unr_lazyr(u1, a[1], b[1]); } else { /* t0 = a_0 * b_0. */ fp6_mul_dxs_unr_lazyr(u0, a[0], b[0]); #if EP_ADD == BASIC /* t0 = a_0 * b_0. */ fp_muln_low(u1[1][0], a[1][2][0], b[1][1][0]); fp_muln_low(u1[1][1], a[1][2][1], b[1][1][0]); fp2_nord_low(u1[0], u1[1]); fp_muln_low(u1[1][0], a[1][0][0], b[1][1][0]); fp_muln_low(u1[1][1], a[1][0][1], b[1][1][0]); fp_muln_low(u1[2][0], a[1][1][0], b[1][1][0]); fp_muln_low(u1[2][1], a[1][1][1], b[1][1][0]); /* t2 = b_0 + b_1. */ fp2_copy(t0[0], b[0][0]); fp_add(t0[1][0], b[0][1][0], b[1][1][0]); fp_copy(t0[1][1], b[0][1][1]); #elif EP_ADD == PROJC /* t1 = a_1 * b_1. */ fp2_muln_low(u1[1], a[1][2], b[1][1]); fp2_nord_low(u1[0], u1[1]); fp2_muln_low(u1[1], a[1][0], b[1][1]); fp2_muln_low(u1[2], a[1][1], b[1][1]); /* t2 = b_0 + b_1. */ fp2_copy(t0[0], b[0][0]); fp2_add(t0[1], b[0][1], b[1][1]); #endif } /* c_1 = a_0 + a_1. */ fp6_add(c[1], a[0], a[1]); /* c_1 = (a_0 + a_1) * (b_0 + b_1) */ fp6_mul_dxs_unr_lazyr(u2, c[1], t0); for (int i = 0; i < 3; i++) { fp2_subc_low(u2[i], u2[i], u0[i]); fp2_subc_low(u2[i], u2[i], u1[i]); } fp2_rdcn_low(c[1][0], u2[0]); fp2_rdcn_low(c[1][1], u2[1]); fp2_rdcn_low(c[1][2], u2[2]); fp2_nord_low(u2[0], u1[2]); fp2_addc_low(u0[0], u0[0], u2[0]); fp2_addc_low(u0[1], u0[1], u1[0]); fp2_addc_low(u0[2], u0[2], u1[1]); /* c_0 = a_0b_0 + v * a_1b_1. */ fp2_rdcn_low(c[0][0], u0[0]); fp2_rdcn_low(c[0][1], u0[1]); fp2_rdcn_low(c[0][2], u0[2]); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp6_free(t0); dv6_free(u0); dv6_free(u1); dv6_free(u2); } }