2527{
2528 if (
a[2].isZero()) {
2529 copy(out, b);
2530 return;
2531 }
2532 if (b[2].isZero()) {
2534 return;
2535 }
2536 FF Z1Z1, Z2Z2, U1, U2, t0, S1, t1, S2, H, t2, I, J, t3,
r,
V, t4, t5;
2537 FF t6, t7, t8, t9, t10, t11, t12, t13, t14;
2538 FF::square(Z1Z1,
a[2]);
2539 FF::square(Z2Z2, b[2]);
2540 FF::mul(U1,
a[0], Z2Z2);
2541 FF::mul(U2, b[0], Z1Z1);
2542 FF::mul(t0, b[2], Z2Z2);
2543 FF::mul(S1,
a[1], t0);
2544 FF::mul(t1,
a[2], Z1Z1);
2545 FF::mul(S2, b[1], t1);
2546 FF::sub(H, U2, U1);
2547 FF::sub(t3, S2, S1);
2548
2549 if (H.isZero()) {
2550 if (t3.isZero()) {
2552 } else {
2553 out[2].clear();
2554 }
2555 return;
2556 }
2557
2558 FF::add(t2, H, H);
2559 FF::square(I, t2);
2560 FF::mul(J, H, I);
2565 FF::sub(t6, t4, J);
2566 FF::sub(out[0], t6, t5);
2567 FF::sub(t7,
V, out[0]);
2568 FF::mul(t8, S1, J);
2569 FF::add(t9, t8, t8);
2570 FF::mul(t10,
r, t7);
2571 FF::sub(out[1], t10, t9);
2572 FF::add(t11,
a[2], b[2]);
2573 FF::square(t12, t11);
2574 FF::sub(t13, t12, Z1Z1);
2575 FF::sub(t14, t13, Z2Z2);
2576 FF::mul(out[2], t14, H);
2577}
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a