/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

/* AMCL Fp^8 functions */

/* FP8 elements are of the form a+ib, where i is sqrt(sqrt(-1+sqrt(-1))) */

#include "fp8_YYY.h"

using namespace XXX;

/* test x==0 ? */
int YYY::FP8_iszilch(FP8 *x)
{
    if (FP4_iszilch(&(x->a)) && FP4_iszilch(&(x->b))) return 1;
    return 0;
}

/* test x==1 ? */
int YYY::FP8_isunity(FP8 *x)
{
    if (FP4_isunity(&(x->a)) && FP4_iszilch(&(x->b))) return 1;
    return 0;
}

/* test is w real? That is in a+ib test b is zero */
int YYY::FP8_isreal(FP8 *w)
{
    return FP4_iszilch(&(w->b));
}

/* return 1 if x==y, else 0 */
int YYY::FP8_equals(FP8 *x,FP8 *y)
{
    if (FP4_equals(&(x->a),&(y->a)) && FP4_equals(&(x->b),&(y->b)))
        return 1;
    return 0;
}

/* set FP8 from two FP4s */
void YYY::FP8_from_FP4s(FP8 *w,FP4 * x,FP4* y)
{
    FP4_copy(&(w->a), x);
    FP4_copy(&(w->b), y);
}

/* set FP8 from FP4 */
void YYY::FP8_from_FP4(FP8 *w,FP4 *x)
{
    FP4_copy(&(w->a), x);
    FP4_zero(&(w->b));
}

/* set high part of FP8 from FP4 */
void YYY::FP8_from_FP4H(FP8 *w,FP4 *x)
{
    FP4_copy(&(w->b), x);
    FP4_zero(&(w->a));
}

/* FP8 copy w=x */
void YYY::FP8_copy(FP8 *w,FP8 *x)
{
    if (w==x) return;
    FP4_copy(&(w->a), &(x->a));
    FP4_copy(&(w->b), &(x->b));
}

/* FP8 w=0 */
void YYY::FP8_zero(FP8 *w)
{
    FP4_zero(&(w->a));
    FP4_zero(&(w->b));
}

/* FP8 w=1 */
void YYY::FP8_one(FP8 *w)
{
    FP4_one(&(w->a));
    FP4_zero(&(w->b));
}

/* Set w=-x */
void YYY::FP8_neg(FP8 *w,FP8 *x)
{
    /* Just one field neg */
    FP4 m,t;
	FP8_norm(x);
    FP4_add(&m,&(x->a),&(x->b));
	FP4_norm(&m);
    FP4_neg(&m,&m);
    FP4_add(&t,&m,&(x->b));
    FP4_add(&(w->b),&m,&(x->a));
    FP4_copy(&(w->a),&t);
	FP8_norm(w);
}

/* Set w=conj(x) */
void YYY::FP8_conj(FP8 *w,FP8 *x)
{
    FP4_copy(&(w->a), &(x->a));
    FP4_neg(&(w->b), &(x->b));
	FP8_norm(w);
}

/* Set w=-conj(x) */
void YYY::FP8_nconj(FP8 *w,FP8 *x)
{
    FP4_copy(&(w->b),&(x->b));
    FP4_neg(&(w->a), &(x->a));
	FP8_norm(w);
}

/* Set w=x+y */
void YYY::FP8_add(FP8 *w,FP8 *x,FP8 *y)
{
    FP4_add(&(w->a), &(x->a), &(y->a));
    FP4_add(&(w->b), &(x->b), &(y->b));
}

/* Set w=x-y */
/* Input y MUST be normed */
void YYY::FP8_sub(FP8 *w,FP8 *x,FP8 *y)
{
    FP8 my;

    FP8_neg(&my, y);
    FP8_add(w, x, &my);

}

/* reduce all components of w mod Modulus */
void YYY::FP8_reduce(FP8 *w)
{
    FP4_reduce(&(w->a));
    FP4_reduce(&(w->b));
}

/* normalise all elements of w */
void YYY::FP8_norm(FP8 *w)
{
    FP4_norm(&(w->a));
    FP4_norm(&(w->b));
}

/* Set w=s*x, where s is FP4 */
void YYY::FP8_pmul(FP8 *w,FP8 *x,FP4 *s)
{
    FP4_mul(&(w->a),&(x->a),s);
    FP4_mul(&(w->b),&(x->b),s);
}

/* Set w=s*x, where s is FP2 */
void YYY::FP8_qmul(FP8 *w,FP8 *x,FP2 *s)
{
    FP4_pmul(&(w->a),&(x->a),s);
    FP4_pmul(&(w->b),&(x->b),s);
}

/* Set w=s*x, where s is FP2 */
void YYY::FP8_tmul(FP8 *w,FP8 *x,FP *s)
{
    FP4_qmul(&(w->a),&(x->a),s);
    FP4_qmul(&(w->b),&(x->b),s);
}

/* Set w=s*x, where s is int */
void YYY::FP8_imul(FP8 *w,FP8 *x,int s)
{
    FP4_imul(&(w->a),&(x->a),s);
    FP4_imul(&(w->b),&(x->b),s);
}

/* Set w=x^2 */
/* Input MUST be normed  */
void YYY::FP8_sqr(FP8 *w,FP8 *x)
{
    FP4 t1,t2,t3;

    FP4_mul(&t3,&(x->a),&(x->b)); /* norms x */
    FP4_copy(&t2,&(x->b));
    FP4_add(&t1,&(x->a),&(x->b));
    FP4_times_i(&t2);

    FP4_add(&t2,&(x->a),&t2);

	FP4_norm(&t1);  // 2
	FP4_norm(&t2);  // 2

    FP4_mul(&(w->a),&t1,&t2);

    FP4_copy(&t2,&t3);
    FP4_times_i(&t2);

    FP4_add(&t2,&t2,&t3);

	FP4_norm(&t2);  // 2
    FP4_neg(&t2,&t2);
    FP4_add(&(w->a),&(w->a),&t2);  /* a=(a+b)(a+i^2.b)-i^2.ab-ab = a*a+ib*ib */
    FP4_add(&(w->b),&t3,&t3);  /* b=2ab */

    FP8_norm(w);
}

/* Set w=x*y */
/* Inputs MUST be normed  */
void YYY::FP8_mul(FP8 *w,FP8 *x,FP8 *y)
{

    FP4 t1,t2,t3,t4;

    FP4_mul(&t1,&(x->a),&(y->a)); 
    FP4_mul(&t2,&(x->b),&(y->b)); 
    FP4_add(&t3,&(y->b),&(y->a));
    FP4_add(&t4,&(x->b),&(x->a));

	FP4_norm(&t4); // 2
	FP4_norm(&t3); // 2

    FP4_mul(&t4,&t4,&t3); /* (xa+xb)(ya+yb) */
	FP4_neg(&t3,&t1);  // 1
	FP4_add(&t4,&t4,&t3);  //t4E=3
    FP4_norm(&t4);

	FP4_neg(&t3,&t2);  // 1
	FP4_add(&(w->b),&t4,&t3); //wbE=3

    FP4_times_i(&t2);
    FP4_add(&(w->a),&t2,&t1);

    FP8_norm(w);
}

/* output FP8 in format [a,b] */
void YYY::FP8_output(FP8 *w)
{
    printf("[");
    FP4_output(&(w->a));
    printf(",");
    FP4_output(&(w->b));
    printf("]");
}

void YYY::FP8_rawoutput(FP8 *w)
{
    printf("[");
    FP4_rawoutput(&(w->a));
    printf(",");
    FP4_rawoutput(&(w->b));
    printf("]");
}

/* Set w=1/x */
void YYY::FP8_inv(FP8 *w,FP8 *x)
{
    FP4 t1,t2;
    FP4_sqr(&t1,&(x->a));
    FP4_sqr(&t2,&(x->b));
    FP4_times_i(&t2);
	FP4_norm(&t2);

    FP4_sub(&t1,&t1,&t2);
	FP4_norm(&t1);
    FP4_inv(&t1,&t1);

    FP4_mul(&(w->a),&t1,&(x->a));
    FP4_neg(&t1,&t1);
	FP4_norm(&t1);
    FP4_mul(&(w->b),&t1,&(x->b));
}

/* w*=i where i = sqrt(sqrt(-1+sqrt(-1))) */
void YYY::FP8_times_i(FP8 *w)
{
	FP4 s,t;
	FP4_copy(&s,&(w->b));
	FP4_copy(&t,&(w->a));
	FP4_times_i(&s);
	FP4_copy(&(w->a),&s);
	FP4_copy(&(w->b),&t);
	FP8_norm(w);
}

void YYY::FP8_times_i2(FP8 *w)
{
	FP4_times_i(&(w->a));
	FP4_times_i(&(w->b));
}

/* Set w=w^p using Frobenius */
void YYY::FP8_frob(FP8 *w,FP2 *f)
{ // f=(i+1)^(p-3)/4
	FP2 ff;
	FP2_sqr(&ff,f);  // (i+1)^(p-3)/2
	FP2_mul_ip(&ff); // (i+1)^(p-1)/2
	FP2_norm(&ff);
	FP4_frob(&(w->a),&ff);
	FP4_frob(&(w->b),&ff);
	FP4_pmul(&(w->b),&(w->b),f);  // times (1+i)^(p-3)/4
	FP4_times_i(&(w->b));		// (i+1)^(p-1)/4
}

/* Set r=a^b mod m */
void YYY::FP8_pow(FP8 *r,FP8* a,BIG b)
{
    FP8 w;
    BIG z,zilch;
    int bt;

    BIG_zero(zilch);

    BIG_copy(z,b);
    FP8_copy(&w,a);
    FP8_one(r);
    BIG_norm(z);

    while(1)
    {
        bt=BIG_parity(z);
        BIG_shr(z,1);
        if (bt) FP8_mul(r,r,&w);
        if (BIG_comp(z,zilch)==0) break;
        FP8_sqr(&w,&w);
    }
    FP8_reduce(r);
}

#if CURVE_SECURITY_ZZZ == 192

/* XTR xtr_a function */
void YYY::FP8_xtr_A(FP8 *r,FP8 *w,FP8 *x,FP8 *y,FP8 *z)
{
    FP8 t1,t2;

    FP8_copy(r,x);
    FP8_sub(&t1,w,y);
	FP8_norm(&t1);
    FP8_pmul(&t1,&t1,&(r->a));
    FP8_add(&t2,w,y);
	FP8_norm(&t2);
    FP8_pmul(&t2,&t2,&(r->b));
    FP8_times_i(&t2);

    FP8_add(r,&t1,&t2);
    FP8_add(r,r,z);

    FP8_reduce(r);
}

/* XTR xtr_d function */
void YYY::FP8_xtr_D(FP8 *r,FP8 *x)
{
    FP8 w;
    FP8_copy(r,x);
    FP8_conj(&w,r);
    FP8_add(&w,&w,&w);
    FP8_sqr(r,r);
	FP8_norm(&w);
    FP8_sub(r,r,&w);
    FP8_reduce(r);    /* reduce here as multiple calls trigger automatic reductions */
}

/* r=x^n using XTR method on traces of FP12s */
void YYY::FP8_xtr_pow(FP8 *r,FP8 *x,BIG n)
{
    int i,par,nb;
    BIG v;
    FP2 w2;
	FP4 w4;
    FP8 t,a,b,c,sf;

    BIG_zero(v);
    BIG_inc(v,3);
	BIG_norm(v);
    FP2_from_BIG(&w2,v);
    FP4_from_FP2(&w4,&w2);
    FP8_from_FP4(&a,&w4);

	FP8_copy(&sf,x);
	FP8_norm(&sf);
	FP8_copy(&b,&sf);
    FP8_xtr_D(&c,&sf);

    par=BIG_parity(n);
    BIG_copy(v,n);
	BIG_norm(v);
    BIG_shr(v,1);
    if (par==0)
    {
        BIG_dec(v,1);
        BIG_norm(v);
    }

    nb=BIG_nbits(v);
    for (i=nb-1; i>=0; i--)
    {
        if (!BIG_bit(v,i))
        {
            FP8_copy(&t,&b);
            FP8_conj(&sf,&sf);
            FP8_conj(&c,&c);
            FP8_xtr_A(&b,&a,&b,&sf,&c);
            FP8_conj(&sf,&sf);
            FP8_xtr_D(&c,&t);
            FP8_xtr_D(&a,&a);
        }
        else
        {
            FP8_conj(&t,&a);
            FP8_xtr_D(&a,&b);
            FP8_xtr_A(&b,&c,&b,&sf,&t);
            FP8_xtr_D(&c,&c);
        }
    }

    if (par==0) FP8_copy(r,&c);
    else FP8_copy(r,&b);
    FP8_reduce(r);
}

/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
void YYY::FP8_xtr_pow2(FP8 *r,FP8 *ck,FP8 *cl,FP8 *ckml,FP8 *ckm2l,BIG a,BIG b)
{
    int i,f2;
    BIG d,e,w;
    FP8 t,cu,cv,cumv,cum2v;


    BIG_copy(e,a);
    BIG_copy(d,b);
    BIG_norm(e);
	BIG_norm(d);

    FP8_copy(&cu,ck);
    FP8_copy(&cv,cl);
    FP8_copy(&cumv,ckml);
    FP8_copy(&cum2v,ckm2l);

    f2=0;
    while (BIG_parity(d)==0 && BIG_parity(e)==0)
    {
        BIG_shr(d,1);
        BIG_shr(e,1);
        f2++;
    }
    while (BIG_comp(d,e)!=0)
    {
        if (BIG_comp(d,e)>0)
        {
            BIG_imul(w,e,4);
            BIG_norm(w);
            if (BIG_comp(d,w)<=0)
            {
                BIG_copy(w,d);
                BIG_copy(d,e);
                BIG_sub(e,w,e);
                BIG_norm(e);
                FP8_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
                FP8_conj(&cum2v,&cumv);
                FP8_copy(&cumv,&cv);
                FP8_copy(&cv,&cu);
                FP8_copy(&cu,&t);
            }
            else if (BIG_parity(d)==0)
            {
                BIG_shr(d,1);
                FP8_conj(r,&cum2v);
                FP8_xtr_A(&t,&cu,&cumv,&cv,r);
                FP8_xtr_D(&cum2v,&cumv);
                FP8_copy(&cumv,&t);
                FP8_xtr_D(&cu,&cu);
            }
            else if (BIG_parity(e)==1)
            {
                BIG_sub(d,d,e);
                BIG_norm(d);
                BIG_shr(d,1);
                FP8_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
                FP8_xtr_D(&cu,&cu);
                FP8_xtr_D(&cum2v,&cv);
                FP8_conj(&cum2v,&cum2v);
                FP8_copy(&cv,&t);
            }
            else
            {
                BIG_copy(w,d);
                BIG_copy(d,e);
                BIG_shr(d,1);
                BIG_copy(e,w);
                FP8_xtr_D(&t,&cumv);
                FP8_conj(&cumv,&cum2v);
                FP8_conj(&cum2v,&t);
                FP8_xtr_D(&t,&cv);
                FP8_copy(&cv,&cu);
                FP8_copy(&cu,&t);
            }
        }
        if (BIG_comp(d,e)<0)
        {
            BIG_imul(w,d,4);
            BIG_norm(w);
            if (BIG_comp(e,w)<=0)
            {
                BIG_sub(e,e,d);
                BIG_norm(e);
                FP8_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
                FP8_copy(&cum2v,&cumv);
                FP8_copy(&cumv,&cu);
                FP8_copy(&cu,&t);
            }
            else if (BIG_parity(e)==0)
            {
                BIG_copy(w,d);
                BIG_copy(d,e);
                BIG_shr(d,1);
                BIG_copy(e,w);
                FP8_xtr_D(&t,&cumv);
                FP8_conj(&cumv,&cum2v);
                FP8_conj(&cum2v,&t);
                FP8_xtr_D(&t,&cv);
                FP8_copy(&cv,&cu);
                FP8_copy(&cu,&t);
            }
            else if (BIG_parity(d)==1)
            {
                BIG_copy(w,e);
                BIG_copy(e,d);
                BIG_sub(w,w,d);
                BIG_norm(w);
                BIG_copy(d,w);
                BIG_shr(d,1);
                FP8_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
                FP8_conj(&cumv,&cumv);
                FP8_xtr_D(&cum2v,&cu);
                FP8_conj(&cum2v,&cum2v);
                FP8_xtr_D(&cu,&cv);
                FP8_copy(&cv,&t);
            }
            else
            {
                BIG_shr(d,1);
                FP8_conj(r,&cum2v);
                FP8_xtr_A(&t,&cu,&cumv,&cv,r);
                FP8_xtr_D(&cum2v,&cumv);
                FP8_copy(&cumv,&t);
                FP8_xtr_D(&cu,&cu);
            }
        }
    }
    FP8_xtr_A(r,&cu,&cv,&cumv,&cum2v);
    for (i=0; i<f2; i++)	FP8_xtr_D(r,r);
    FP8_xtr_pow(r,r,d);
}

#endif


/* New stuff for ECp8 support */

/* Move b to a if d=1 */
void YYY::FP8_cmove(FP8 *f,FP8 *g,int d)
{
    FP4_cmove(&(f->a),&(g->a),d);
    FP4_cmove(&(f->b),&(g->b),d);
}

#if CURVE_SECURITY_ZZZ == 256

/* sqrt(a+xb) = sqrt((a+sqrt(a*a-n*b*b))/2)+x.b/(2*sqrt((a+sqrt(a*a-n*b*b))/2)) */
/* returns true if x is QR */
int YYY::FP8_sqrt(FP8 *r,FP8* x)
{
	FP4 a,s,t;

	FP8_copy(r,x);
	if (FP8_iszilch(x))
		return 1;
	
	FP4_copy(&a,&(x->a));
	FP4_copy(&s,&(x->b));

	if (FP4_iszilch(&s))
	{
		if (FP4_sqrt(&t,&a))
		{
			FP8_from_FP4(r,&t);
		}
		else
		{
			FP4_div_i(&a);
			FP4_sqrt(&t,&a);
			FP8_from_FP4H(r,&t);
		}
		return 1;
	}

	FP4_sqr(&s,&s);  // s*=s
	FP4_sqr(&a,&a);  // a*=a
	FP4_times_i(&s);
	FP4_norm(&s);
	FP4_sub(&a,&a,&s); // a-=txx(s)

	if (!FP4_sqrt(&s,&a)) return 0;

	FP4_copy(&t,&(x->a));
	FP4_add(&a,&t,&s);
	FP4_norm(&a);
	FP4_div2(&a,&a);

	if (!FP4_sqrt(&a,&a))
	{
		FP4_sub(&a,&t,&s);
		FP4_norm(&a);
		FP4_div2(&a,&a);
		if (!FP4_sqrt(&a,&a)) return 0;
	}

	FP4_copy(&t,&(x->b));
	FP4_add(&s,&a,&a);
	FP4_inv(&s,&s);

	FP4_mul(&t,&t,&s);
	FP8_from_FP4s(r,&a,&t);

	return 1;

}

void YYY::FP8_div_i(FP8 *f)
{
	FP4 u,v;
	FP4_copy(&u,&(f->a));
	FP4_copy(&v,&(f->b));
	FP4_div_i(&u);
	FP4_copy(&(f->a),&v);
	FP4_copy(&(f->b),&u);
}

void YYY::FP8_div_i2(FP8 *f)
{
	FP4_div_i(&(f->a));
	FP4_div_i(&(f->b));
}

void YYY::FP8_div_2i(FP8 *f)
{
	FP4 u,v;
	FP4_copy(&u,&(f->a));
	FP4_copy(&v,&(f->b));
	FP4_div_2i(&u);
	FP4_add(&v,&v,&v);
	FP4_norm(&v);
	FP4_copy(&(f->a),&v);
	FP4_copy(&(f->b),&u);
}

#endif
