/*
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.
*/


use super::fp::FP;
use super::ecp::ECP;
use super::fp2::FP2;
use super::ecp8::ECP8;
use super::fp8::FP8;
use super::fp16::FP16;
use super::fp48;
use super::fp48::FP48;
use super::big::BIG;
use super::ecp;
use super::rom;
use types::{SignOfX, SexticTwist};

#[allow(non_snake_case)]
fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
    let mut a = FP16::new();
    let mut b = FP16::new();
    let mut c = FP16::new();

    let mut xx = FP8::new_copy(&A.getpx()); //X
    let mut yy = FP8::new_copy(&A.getpy()); //Y
    let mut zz = FP8::new_copy(&A.getpz()); //Z
    let mut yz = FP8::new_copy(&yy); //Y
    yz.mul(&zz); //YZ
    xx.sqr(); //X^2
    yy.sqr(); //Y^2
    zz.sqr(); //Z^2

    yz.imul(4);
    yz.neg();
    yz.norm(); //-2YZ
    yz.tmul(qy); //-2YZ.Ys

    xx.imul(6); //3X^2
    xx.tmul(qx); //3X^2.Xs

    let sb = 3 * rom::CURVE_B_I;
    zz.imul(sb);
    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
        zz.div_2i();
    }
    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
        zz.times_i();
        zz.dbl();
        yz.times_i();
    }

    zz.norm(); // 3b.Z^2

    yy.dbl();
    zz.sub(&yy);
    zz.norm(); // 3b.Z^2-Y^2

    a.copy(&FP16::new_fp8s(&yz, &zz)); // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs
    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
        b.copy(&FP16::new_fp8(&xx)); // L(0,1) | L(0,0) | L(1,0)
    }
    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
        c.copy(&FP16::new_fp8(&xx));
        c.times_i();
    }
    A.dbl();
    let mut res= FP48::new_fp16s(&a, &b, &c);
    res.settype(fp48::SPARSER);
    return res;
}

#[allow(non_snake_case)]
fn lineadd(A: &mut ECP8, B: &ECP8, qx: &FP, qy: &FP) -> FP48 {
    let mut a = FP16::new();
    let mut b = FP16::new();
    let mut c = FP16::new();

    let mut x1 = FP8::new_copy(&A.getpx()); // X1
    let mut y1 = FP8::new_copy(&A.getpy()); // Y1
    let mut t1 = FP8::new_copy(&A.getpz()); // Z1
    let mut t2 = FP8::new_copy(&A.getpz()); // Z1

    t1.mul(&B.getpy()); // T1=Z1.Y2
    t2.mul(&B.getpx()); // T2=Z1.X2

    x1.sub(&t2);
    x1.norm(); // X1=X1-Z1.X2
    y1.sub(&t1);
    y1.norm(); // Y1=Y1-Z1.Y2

    t1.copy(&x1); // T1=X1-Z1.X2
    x1.tmul(qy); // X1=(X1-Z1.X2).Ys
    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
        x1.times_i();
    }

    t1.mul(&B.getpy()); // T1=(X1-Z1.X2).Y2

    t2.copy(&y1); // T2=Y1-Z1.Y2
    t2.mul(&B.getpx()); // T2=(Y1-Z1.Y2).X2
    t2.sub(&t1);
    t2.norm(); // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
    y1.tmul(qx);
    y1.neg();
    y1.norm(); // Y1=-(Y1-Z1.Y2).Xs

    a.copy(&FP16::new_fp8s(&x1, &t2)); // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
        b.copy(&FP16::new_fp8(&y1));
    }
    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
        c.copy(&FP16::new_fp8(&y1));
        c.times_i();
    }

    A.add(B);
    let mut res= FP48::new_fp16s(&a, &b, &c);
    res.settype(fp48::SPARSER);
    return res;
}

/* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
#[allow(non_snake_case)]
fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
    n.copy(&BIG::new_ints(&rom::CURVE_BNX));
    n3.copy(&n);
    n3.pmul(3);
    n3.norm();
    return n3.nbits();
}

/* prepare for multi-pairing */
pub fn initmp() -> [FP48; rom::ATE_BITS] {
    let r: [FP48; rom::ATE_BITS] = [FP48::new_int(1); rom::ATE_BITS];
    return r
}

/* basic Miller loop */
pub fn miller(r:&[FP48]) -> FP48 {
    let mut res=FP48::new_int(1);
    for i in (1..rom::ATE_BITS).rev() {
        res.sqr();
        res.ssmul(&r[i]);
    }

    if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
        res.conj();
    }
    res.ssmul(&r[0]);
    return res;
}

/* Accumulate another set of line functions for n-pairing */
#[allow(non_snake_case)]
pub fn another(r:&mut [FP48],P1: &ECP8,Q1: &ECP) {
    let mut n = BIG::new();
    let mut n3 = BIG::new();

// P is needed in affine form for line function, Q for (Qx,Qy) extraction
    let mut P = ECP8::new();
    P.copy(P1);
    P.affine();
    let mut Q = ECP::new();
    Q.copy(Q1);
    Q.affine();

    let qx = FP::new_copy(&Q.getpx());
    let qy = FP::new_copy(&Q.getpy());
    let mut A = ECP8::new();

    A.copy(&P);
    let mut NP = ECP8::new();
    NP.copy(&P);
    NP.neg();

    let nb=lbits(&mut n3,&mut n);

    for i in (1..nb-1).rev() {
        let mut lv=linedbl(&mut A,&qx,&qy);

	let bt=n3.bit(i)-n.bit(i);
        if bt==1 {
            let lv2=lineadd(&mut A,&P,&qx,&qy);
            lv.smul(&lv2);
        }
        if bt==-1 {
            let lv2=lineadd(&mut A,&NP,&qx,&qy);
            lv.smul(&lv2);
        }
        r[i].ssmul(&lv);
    }
}

#[allow(non_snake_case)]
/* Optimal R-ate pairing */
pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
    let mut n = BIG::new();
    let mut n3 = BIG::new();

    let mut P = ECP8::new();
    P.copy(P1);
    P.affine();
    let mut Q = ECP::new();
    Q.copy(Q1);
    Q.affine();

    let qx = FP::new_copy(&Q.getpx());
    let qy = FP::new_copy(&Q.getpy());

    let mut A = ECP8::new();
    let mut r = FP48::new_int(1);

    A.copy(&P);
    let mut NP = ECP8::new();
    NP.copy(&P);
    NP.neg();

    let nb=lbits(&mut n3,&mut n);

    for i in (1..nb - 1).rev() {
        r.sqr();
        let mut lv = linedbl(&mut A, &qx, &qy);
        let bt = n3.bit(i) - n.bit(i);
        if bt == 1 {
            let lv2 = lineadd(&mut A, &P, &qx, &qy);
            lv.smul(&lv2);
        }
        if bt == -1 {
            let lv2 = lineadd(&mut A, &NP, &qx, &qy);
            lv.smul(&lv2);
        }
        r.ssmul(&lv);
    }

    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        r.conj();
    }

    return r;
}

#[allow(non_snake_case)]
/* Optimal R-ate double pairing e(P,Q).e(R,S) */
pub fn ate2(P1: &ECP8, Q1: &ECP, R1: &ECP8, S1: &ECP) -> FP48 {
    let mut n = BIG::new();
    let mut n3 = BIG::new();

    let mut P = ECP8::new();
    P.copy(P1);
    P.affine();
    let mut Q = ECP::new();
    Q.copy(Q1);
    Q.affine();
    let mut R = ECP8::new();
    R.copy(R1);
    R.affine();
    let mut S = ECP::new();
    S.copy(S1);
    S.affine();

    let qx = FP::new_copy(&Q.getpx());
    let qy = FP::new_copy(&Q.getpy());

    let sx = FP::new_copy(&S.getpx());
    let sy = FP::new_copy(&S.getpy());

    let mut A = ECP8::new();
    let mut B = ECP8::new();
    let mut r = FP48::new_int(1);

    A.copy(&P);
    B.copy(&R);

    let mut NP = ECP8::new();
    NP.copy(&P);
    NP.neg();
    let mut NR = ECP8::new();
    NR.copy(&R);
    NR.neg();

     let nb=lbits(&mut n3,&mut n);

    for i in (1..nb - 1).rev() {
        r.sqr();
        let mut lv = linedbl(&mut A, &qx, &qy);
        let lv2 = linedbl(&mut B, &sx, &sy);
	lv.smul(&lv2);
        r.ssmul(&lv);
        let bt = n3.bit(i) - n.bit(i);
        if bt == 1 {
            lv = lineadd(&mut A, &P, &qx, &qy);
            let lv2 = lineadd(&mut B, &R, &sx, &sy);
	    lv.smul(&lv2);
            r.ssmul(&lv);
        }
        if bt == -1 {
            lv = lineadd(&mut A, &NP, &qx, &qy);
            let lv2 = lineadd(&mut B, &NR, &sx, &sy);
	    lv.smul(&lv2);
            r.ssmul(&lv);
        }
    }

    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        r.conj();
    }

    return r;
}

/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
pub fn fexp(m: &FP48) -> FP48 {
    let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
    let mut x = BIG::new_ints(&rom::CURVE_BNX);
    let mut r = FP48::new_copy(m);

    /* Easy part of final exp */
    let mut lv = FP48::new_copy(&r);
    lv.inverse();
    r.conj();

    r.mul(&lv);
    lv.copy(&r);
    r.frob(&f, 8);
    r.mul(&lv);
    if r.isunity() {
	r.zero();
	return r;
    }
    /* Hard part of final exp */
    // Ghamman & Fouotsa Method

    let mut t7 = FP48::new_copy(&r);
    t7.usqr();
    let mut t1 = t7.pow(&mut x);

    x.fshr(1);
    let mut t2 = t1.pow(&mut x);
    x.fshl(1);

    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    let mut t3 = FP48::new_copy(&t1);
    t3.conj();
    t2.mul(&t3);
    t2.mul(&r);

    r.mul(&t7);

    t1.copy(&t2.pow(&mut x));

    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }
    t3.copy(&t1);
    t3.frob(&f, 14);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 13);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 12);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 11);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 10);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 9);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 8);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t2);
    t3.conj();
    t1.mul(&t3);
    t3.copy(&t1);
    t3.frob(&f, 7);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 6);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 5);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 4);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 3);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 2);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    t3.copy(&t1);
    t3.frob(&f, 1);
    r.mul(&t3);
    lv.copy(&t1.pow(&mut x));
    t1.copy(&lv);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        t1.conj();
    }

    r.mul(&t1);
    t2.frob(&f, 15);
    r.mul(&t2);

    r.reduce();
    return r;
}

#[allow(non_snake_case)]
/* GLV method */
fn glv(e: &BIG) -> [BIG; 2] {
    let mut u: [BIG; 2] = [BIG::new(), BIG::new()];
    let q = BIG::new_ints(&rom::CURVE_ORDER);
    let mut x = BIG::new_ints(&rom::CURVE_BNX);
    let mut x2 = BIG::smul(&x, &x);
    x.copy(&BIG::smul(&x2, &x2));
    x2.copy(&BIG::smul(&x, &x));
    u[0].copy(&e);
    u[0].rmod(&x2);
    u[1].copy(&e);
    u[1].div(&x2);
    u[1].rsub(&q);

    return u;
}

#[allow(non_snake_case)]
/* Galbraith & Scott Method */
pub fn gs(e: &BIG) -> [BIG; 16] {
    let mut u: [BIG; 16] = [
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
        BIG::new(),
    ];
    let q = BIG::new_ints(&rom::CURVE_ORDER);
    let x = BIG::new_ints(&rom::CURVE_BNX);
    let mut w = BIG::new_copy(&e);
    for i in 0..15 {
        u[i].copy(&w);
        u[i].rmod(&x);
        w.div(&x);
    }
    u[15].copy(&w);
    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
        let mut t = BIG::new();
        t.copy(&BIG::modneg(&mut u[1], &q));
        u[1].copy(&t);
        t.copy(&BIG::modneg(&mut u[3], &q));
        u[3].copy(&t);
        t.copy(&BIG::modneg(&mut u[5], &q));
        u[5].copy(&t);
        t.copy(&BIG::modneg(&mut u[7], &q));
        u[7].copy(&t);
        t.copy(&BIG::modneg(&mut u[9], &q));
        u[9].copy(&t);
        t.copy(&BIG::modneg(&mut u[11], &q));
        u[11].copy(&t);
        t.copy(&BIG::modneg(&mut u[13], &q));
        u[13].copy(&t);
        t.copy(&BIG::modneg(&mut u[15], &q));
        u[15].copy(&t);
    }
    return u;
}

#[allow(non_snake_case)]
/* Multiply P by e in group G1 */
pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
    let mut R = ECP::new();
    if rom::USE_GLV {
        R.copy(P);
        let mut Q = ECP::new();
        Q.copy(P);
        Q.affine();
        let q = BIG::new_ints(&rom::CURVE_ORDER);
        let mut cru = FP::new_big(&BIG::new_ints(&rom::CURVE_CRU));
        let mut u = glv(e);
        Q.mulx(&mut cru);

        let mut np = u[0].nbits();
        let mut t: BIG = BIG::modneg(&mut u[0], &q);
        let mut nn = t.nbits();
        if nn < np {
            u[0].copy(&t);
            R.neg();
        }

        np = u[1].nbits();
        t = BIG::modneg(&mut u[1], &q);
        nn = t.nbits();
        if nn < np {
            u[1].copy(&t);
            Q.neg();
        }
        u[0].norm();
        u[1].norm();
        R = R.mul2(&u[0], &mut Q, &u[1]);
    } else {
        R = P.mul(e);
    }
    return R;
}

#[allow(non_snake_case)]
/* Multiply P by e in group G2 */
pub fn g2mul(P: &ECP8, e: &BIG) -> ECP8 {
    let mut R = ECP8::new();
    if rom::USE_GS_G2 {
        let mut Q: [ECP8; 16] = [
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
            ECP8::new(),
        ];
        let q = BIG::new_ints(&rom::CURVE_ORDER);
        let mut u = gs(e);
        let mut T = ECP8::new();

        let f = ECP8::frob_constants();

        let mut t = BIG::new();
        Q[0].copy(&P);
        for i in 1..16 {
            T.copy(&Q[i - 1]);
            Q[i].copy(&T);
            Q[i].frob(&f, 1);
        }
        for i in 0..16 {
            let np = u[i].nbits();
            t.copy(&BIG::modneg(&mut u[i], &q));
            let nn = t.nbits();
            if nn < np {
                u[i].copy(&t);
                Q[i].neg();
            }
            u[i].norm();
        }

        R.copy(&ECP8::mul16(&mut Q, &u));
    } else {
        R.copy(&P.mul(e));
    }
    return R;
}

/* f=f^e */
/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
pub fn gtpow(d: &FP48, e: &BIG) -> FP48 {
    let mut r = FP48::new();
    if rom::USE_GS_GT {
        let mut g: [FP48; 16] = [
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
            FP48::new(),
        ];
        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
        let q = BIG::new_ints(&rom::CURVE_ORDER);
        let mut t = BIG::new();
        let mut u = gs(e);
        let mut w = FP48::new();

        g[0].copy(&d);
        for i in 1..16 {
            w.copy(&g[i - 1]);
            g[i].copy(&w);
            g[i].frob(&f, 1);
        }
        for i in 0..16 {
            let np = u[i].nbits();
            t.copy(&BIG::modneg(&mut u[i], &q));
            let nn = t.nbits();
            if nn < np {
                u[i].copy(&t);
                g[i].conj();
            }
            u[i].norm();
        }
        r.copy(&FP48::pow16(&mut g, &u));
    } else {
        r.copy(&d.pow(e));
    }
    return r;
}
