void bn254_fp2_sqr(Element z, const Element x) { Element* t = field(z)->base->tmp; if (strcmp(x->field->field_name, "bn254_fp2a") == 0) { bn254_fp_addn(t[0], rep1(x), rep1(x)); // bn254_fp_muln(t[0], t[0], rep0(x)); // t0 = 2*x1*x0 bn254_fp_addp(t[1], rep0(x)); bn254_fp_subn(t[1], t[1], rep1(x)); // t1 = x0-x1 bn254_fp_addn(t[2], rep1(x), rep1(x)); // bn254_fp_addn(t[2], t[2], t[2]); // bn254_fp_addn(t[2], t[2], rep1(x)); // bn254_fp_addn(t[2], t[2], rep0(x)); // t2 = 5*x1 + x0 bn254_fp_muln(t[1], t[1], t[2]); // t1 = t1 * t2 bn254_fp_mod(rep1(z), t[0]); // c1 = t0 bn254_fp_addn(t[0], t[0], t[0]); // bn254_fp_subn(t[1], t[1], t[0]); // t1 = 2*t0*t1 bn254_fp_mod(rep0(z), t[1]); // c0 = t1 } if (strcmp(x->field->field_name, "bn254_fp2b") == 0) { bn254_fp_addn(t[0], rep1(x), rep1(x)); // t0 = 2*x1 bn254_fp_muln(t[0], t[0], rep0(x)); // t0 = 2*x1*x0 bn254_fp_addn(t[1], rep0(x), rep1(x)); // t1 = x0+x1 bn254_fp_subn(t[2], rep0(x), rep1(x)); // t2 = x0-x1 bn254_fp_muln(t[1], t[1], t[2]); // t1 = t1*t2 bn254_fp_mod(rep1(z), t[0]); // c1 = t0 bn254_fp_mod(rep0(z), t[1]); // c0 = t1 } }
void bn254_fp6_muln(Element z, const Element x, const Element y) { Element *t = field(z)->base->tmp; bn254_fp2_muln(t[0], rep0(x), rep0(y)); // t0 = a0*b0 bn254_fp2_muln(t[1], rep1(x), rep1(y)); // t1 = a1*b1 bn254_fp2_muln(t[2], rep2(x), rep2(y)); // t2 = a2*b2 bn254_fp2_OP1_2(t[0], t[0]); bn254_fp2_OP1_2(t[1], t[1]); bn254_fp2_OP1_2(t[2], t[2]); bn254_fp2_addn(t[8], rep1(x), rep2(x)); // t8 = a1+a2 bn254_fp2_addn(t[9], rep1(y), rep2(y)); // t9 = b1+b2 bn254_fp2_muln(t[3], t[8], t[9]); // t3 = t8*t9 bn254_fp2_OP2(t[3], t[3]); bn254_fp2_addn(t[4], t[1], t[2]); // t4 = t1+t2 bn254_fp_sub(rep0(t[3]), rep0(t[3]), rep0(t[4])); bn254_fp_OP2(rep0(t[3]), rep0(t[3])); bn254_fp_subn(rep1(t[3]), rep1(t[3]), rep1(t[4])); bn254_fp2_xi_mul(t[4], t[3]); // t4 = xi*t3 bn254_fp2_OP2(t[4], t[4]); bn254_fp2_add(rep0(z), t[4], t[0]); // t5 = t4+t0 bn254_fp2_OP2(rep0(z), rep0(z)); bn254_fp2_addn(t[8], rep0(x), rep1(x)); // t8 = a0+a1 bn254_fp2_addn(t[9], rep0(y), rep1(y)); // t9 = b0+b1 bn254_fp2_muln(t[3], t[8], t[9]); // t3 = t8*t9 bn254_fp2_OP2(t[3], t[3]); bn254_fp2_addn(t[4], t[0], t[1]); // t4 = t0+t1 bn254_fp_sub(rep0(t[3]), rep0(t[3]), rep0(t[4])); bn254_fp_OP2(rep0(t[3]), rep0(t[3])); bn254_fp_subn(rep1(t[3]), rep1(t[3]), rep1(t[4])); bn254_fp_sub(rep0(t[4]), rep0(t[2]), rep1(t[2])); bn254_fp_OP1_1(rep0(t[4]), rep0(t[4])); bn254_fp_addn(rep1(t[4]), rep0(t[2]), rep1(t[2])); bn254_fp2_add(rep1(z), t[3], t[4]); // t6 = t3+t4 bn254_fp2_OP2(rep1(z), rep1(z)); bn254_fp2_addn(t[8], rep0(x), rep2(x)); // t8 = a0+a2 bn254_fp2_addn(t[9], rep0(y), rep2(y)); // t9 = b0+b2 bn254_fp2_muln(t[3], t[8], t[9]); // t3 = t8*t9 bn254_fp2_OP2(t[3], t[3]); bn254_fp2_addn(t[4], t[0], t[2]); // t4 = t0+t1 bn254_fp_sub(rep0(t[3]), rep0(t[3]), rep0(t[4])); bn254_fp_OP2(rep0(t[3]), rep0(t[3])); bn254_fp_subn(rep1(t[3]), rep1(t[3]), rep1(t[4])); bn254_fp_add(rep0(rep2(z)), rep0(t[3]), rep0(t[1])); bn254_fp_OP2(rep0(rep2(z)), rep0(rep2(z))); bn254_fp_addn(rep1(rep2(z)), rep1(t[3]), rep1(t[1])); }
void bn254_fp2_sqr(Element z, const Element x) { Element* t = field(z)->base->tmp; bn254_fp_addn(t[0], rep1(x), rep1(x)); // bn254_fp_muln(t[0], t[0], rep0(x)); // t0 = 2*x1*x0 bn254_fp_addp(t[1], rep0(x)); bn254_fp_subn(t[1], t[1], rep1(x)); // t1 = x0-x1 bn254_fp_addn(t[2], rep1(x), rep1(x)); // bn254_fp_addn(t[2], t[2], t[2]); // bn254_fp_addn(t[2], t[2], rep1(x)); // bn254_fp_addn(t[2], t[2], rep0(x)); // t2 = 5*x1 + x0 bn254_fp_muln(t[1], t[1], t[2]); // t1 = t1 * t2 bn254_fp_mod(rep1(z), t[0]); // c1 = t0 bn254_fp_addn(t[0], t[0], t[0]); // bn254_fp_subn(t[1], t[1], t[0]); // t1 = 2*t0*t1 bn254_fp_mod(rep0(z), t[1]); // c0 = t1 }
//------------------------------------------------------ // multipulication is implemented by Karatsuba method. //------------------------------------------------------ void bn254_fp2_mul(Element z, const Element x, const Element y) { Element* t = field(z)->base->tmp; bn254_fp_addn(t[1], rep0(x), rep1(x)); // t1 = x0 + x1 bn254_fp_addn(t[2], rep0(y), rep1(y)); // t2 = y0 + y1 bn254_fp_muln(t[0], t[1], t[2]); // t0 = t1 * t2 bn254_fp_muln(t[1], rep0(x), rep0(y)); // t1 = x0 * y0 bn254_fp_muln(t[2], rep1(x), rep1(y)); // t2 = x1 * y1 bn254_fp_subn(t[0], t[0], t[1]); // bn254_fp_subn(rep1(z), t[0], t[2]); // z1 = x0*y1 + y0*x1 bn254_fp_mod(rep1(z), rep1(z)); // bn254_fp_addn(rep0(z), t[2], t[2]); // bn254_fp_addn(rep0(z), rep0(z), rep0(z)); bn254_fp_addn(rep0(z), rep0(z), t[2]); // bn254_fp_subn(rep0(z), t[1], rep0(z)); // bn254_fp_mod(rep0(z), rep0(z)); // z0 = t1 - 5*t2 }
//------------------------------------------------------ // multipulication is implemented by Karatsuba method. //------------------------------------------------------ void bn254_fp2_mul(Element z, const Element x, const Element y) { Element* t = field(z)->base->tmp; //int i; //Element* t = (Element *)malloc(sizeof(Element)*10); //for(i=0;i<10;i++){ element_init(t[i], field(z)->base); } if (strcmp(x->field->field_name, "bn254_fp2a") == 0) { bn254_fp_addn(t[1], rep0(x), rep1(x)); // t1 = x0 + x1 bn254_fp_addn(t[2], rep0(y), rep1(y)); // t2 = y0 + y1 bn254_fp_muln(t[0], t[1], t[2]); // t0 = t1 * t2 bn254_fp_muln(t[1], rep0(x), rep0(y)); // t1 = x0 * y0 bn254_fp_muln(t[2], rep1(x), rep1(y)); // t2 = x1 * y1 bn254_fp_subn(t[0], t[0], t[1]); // bn254_fp_subn(rep1(z), t[0], t[2]); // z1 = x0*y1 + y0*x1 bn254_fp_mod(rep1(z), rep1(z)); // bn254_fp_addn(rep0(z), t[2], t[2]); // bn254_fp_addn(rep0(z), rep0(z), rep0(z)); bn254_fp_addn(rep0(z), rep0(z), t[2]); // bn254_fp_subn(rep0(z), t[1], rep0(z)); // bn254_fp_mod(rep0(z), rep0(z)); // z0 = t1 - 5*t2 } if (strcmp(x->field->field_name, "bn254_fp2b") == 0) { bn254_fp_addn(t[1], rep0(x), rep1(x)); // t1 = x0 + x1 bn254_fp_addn(t[2], rep0(y), rep1(y)); // t2 = y0 + y1 bn254_fp_muln(t[0], t[1], t[2]); // t0 = t1 * t2 bn254_fp_muln(t[1], rep0(x), rep0(y)); // t1 = x0 * y0 bn254_fp_muln(t[2], rep1(x), rep1(y)); // t2 = x1 * y1 bn254_fp_subn(t[0], t[0], t[1]); // (x0+x1)*(y0+y1)-x0*y0 bn254_fp_subn(rep1(z), t[0], t[2]); // z1 = x0*y1 + y0*x1 bn254_fp_mod(rep1(z), rep1(z)); // bn254_fp_sub(rep0(z), t[1], t[2]); // x0*y0 - x1*y1 bn254_fp_mod(rep0(z), rep0(z)); // z0 = t1 - t2 } //for(i=0;i<10;i++){ element_clear(t[i]);} }
void bn254_fp2_muln(Element z, const Element x, const Element y) { Element* t = field(z)->base->tmp; //int i; //Element* t = (Element *)malloc(sizeof(Element)*10); //for(i=0;i<10;i++){ element_init(t[i], field(z)->base); } bn254_fp_muln(t[0], rep0(x), rep0(y)); // t0 = x0 * y0 bn254_fp_muln(t[1], rep1(x), rep1(y)); // t1 = x0 * y1 bn254_fp_addn(t[2], rep0(x), rep1(x)); // t2 = x0 + x1 bn254_fp_addn(t[3], rep0(y), rep1(y)); // t2 = y0 + y1 bn254_fp_muln(t[4], t[2], t[3]); // t4 = t2 * t3 bn254_fp_addn(t[5], t[0], t[1]); // t5 = t0 + t1 bn254_fp_subn(rep1(z), t[4], t[5]); // t5 = t4 - t5 bn254_fp_sub(t[6], t[0], t[1]); // t6 = t0 - t1 bn254_fp_OP2(rep0(z), t[6]); //for(i=0;i<10;i++){ element_clear(t[i]); } }
void bn254_fp2_subn(Element z, const Element x, const Element y) { bn254_fp_subn(rep0(z), rep0(x), rep0(y)); bn254_fp_subn(rep1(z), rep1(x), rep1(y)); }