/*
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::big::BIG;
use super::big;
use super::rom;

pub use super::rom::{CURVETYPE, CURVE_PAIRING_TYPE, SEXTIC_TWIST, SIGN_OF_X, HASH_TYPE, AESKEY};
pub use types::CurveType;
use std::str::SplitWhitespace;
use std::fmt;

#[derive(Copy, Clone)]
pub struct ECP {
    x: FP,
    y: FP,
    z: FP,
}

impl PartialEq for ECP {
    fn eq(&self, other: &ECP) -> bool {
        self.equals(other)
    }
}

impl fmt::Display for ECP {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
	}
}

impl fmt::Debug for ECP {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
	}
}

#[allow(non_snake_case)]
impl ECP {
    pub fn pnew() -> ECP {
        ECP {
            x: FP::new(),
            y: FP::new_int(1),
            z: FP::new(),
        }
    }

    pub fn new() -> ECP {
        let mut E = ECP::pnew();
        if CURVETYPE == CurveType::EDWARDS {
            E.z.one();
        }
        return E;
    }

    /* set (x,y) from two BIGs */
    pub fn new_bigs(ix: &BIG, iy: &BIG) -> ECP {
        let mut E = ECP::new();
        E.x.bcopy(ix);
        E.y.bcopy(iy);
        E.z.one();
        E.x.norm();
        let mut rhs = ECP::rhs(&E.x);
        if CURVETYPE == CurveType::MONTGOMERY {
            if rhs.jacobi() != 1 {
                E.inf();
            }
        } else {
            let mut y2 = FP::new_copy(&E.y);
            y2.sqr();
            if !y2.equals(&mut rhs) {
                E.inf();
            }
        }
        return E;
    }

    /* set (x,y) from BIG and a bit */
    pub fn new_bigint(ix: &BIG, s: isize) -> ECP {
        let mut E = ECP::new();
        E.x.bcopy(ix);
        E.x.norm();
        E.z.one();

        let mut rhs = ECP::rhs(&E.x);

        if rhs.jacobi() == 1 {
            let mut ny = rhs.sqrt();
            if ny.redc().parity() != s {
                ny.neg()
            }
            E.y.copy(&ny);
        } else {
            E.inf()
        }
        return E;
    }

    #[allow(non_snake_case)]
    /* set from x - calculate y from curve equation */
    pub fn new_big(ix: &BIG) -> ECP {
        let mut E = ECP::new();
        E.x.bcopy(ix);
        E.x.norm();
        E.z.one();
        let mut rhs = ECP::rhs(&E.x);
        if rhs.jacobi() == 1 {
            if CURVETYPE != CurveType::MONTGOMERY {
                E.y.copy(&rhs.sqrt())
            }
        } else {
            E.inf();
        }
        return E;
    }

    /* set this=O */
    pub fn inf(&mut self) {
        self.x.zero();
        if CURVETYPE != CurveType::MONTGOMERY {
            self.y.one();
        }
        if CURVETYPE != CurveType::EDWARDS {
            self.z.zero();
        } else {
            self.z.one()
        }
    }

    /* Calculate RHS of curve equation */
    fn rhs(x: &FP) -> FP {
        let mut r = FP::new_copy(x);
        r.sqr();

        if CURVETYPE == CurveType::WEIERSTRASS {
            // x^3+Ax+B
            let b = FP::new_big(&BIG::new_ints(&rom::CURVE_B));
            r.mul(x);
            if rom::CURVE_A == -3 {
                let mut cx = FP::new_copy(x);
                cx.imul(3);
                cx.neg();
                cx.norm();
                r.add(&cx);
            }
            r.add(&b);
        }
        if CURVETYPE == CurveType::EDWARDS {
            // (Ax^2-1)/(Bx^2-1)
            let mut b = FP::new_big(&BIG::new_ints(&rom::CURVE_B));
            let one = FP::new_int(1);
            b.mul(&r);
            b.sub(&one);
            b.norm();
            if rom::CURVE_A == -1 {
                r.neg()
            }
            r.sub(&one);
            r.norm();
            b.inverse();
            r.mul(&b);
        }
        if CURVETYPE == CurveType::MONTGOMERY {
            // x^3+Ax^2+x
            let mut x3 = FP::new();
            x3.copy(&r);
            x3.mul(x);
            r.imul(rom::CURVE_A);
            r.add(&x3);
            r.add(&x);
        }
        r.reduce();
        return r;
    }

    /* test for O point-at-infinity */
    pub fn is_infinity(&self) -> bool {
        let xx = FP::new_copy(&self.x);
        let zz = FP::new_copy(&self.z);

        if CURVETYPE == CurveType::EDWARDS {
            let yy = FP::new_copy(&self.y);
            return xx.iszilch() && yy.equals(&zz);
        }
        if CURVETYPE == CurveType::WEIERSTRASS {
            return xx.iszilch() && zz.iszilch();
        }
        if CURVETYPE == CurveType::MONTGOMERY {
            return zz.iszilch();
        }
        return true;
    }

    /* Conditional swap of P and Q dependant on d */
    pub fn cswap(&mut self, Q: &mut ECP, d: isize) {
        self.x.cswap(&mut Q.x, d);
        if CURVETYPE != CurveType::MONTGOMERY {
            self.y.cswap(&mut Q.y, d)
        }
        self.z.cswap(&mut Q.z, d);
    }

    /* Conditional move of Q to P dependant on d */
    pub fn cmove(&mut self, Q: &ECP, d: isize) {
        self.x.cmove(&Q.x, d);
        if CURVETYPE != CurveType::MONTGOMERY {
            self.y.cmove(&Q.y, d)
        }
        self.z.cmove(&Q.z, d);
    }

    /* return 1 if b==c, no branching */
    fn teq(b: i32, c: i32) -> isize {
        let mut x = b ^ c;
        x -= 1; // if x=0, x now -1
        return ((x >> 31) & 1) as isize;
    }

    /* this=P */
    pub fn copy(&mut self, P: &ECP) {
        self.x.copy(&P.x);
        if CURVETYPE != CurveType::MONTGOMERY {
            self.y.copy(&P.y)
        }
        self.z.copy(&P.z);
    }

    /* this=-this */
    pub fn neg(&mut self) {
        if CURVETYPE == CurveType::WEIERSTRASS {
            self.y.neg();
            self.y.norm();
        }
        if CURVETYPE == CurveType::EDWARDS {
            self.x.neg();
            self.x.norm();
        }
        return;
    }
    /* multiply x coordinate */
    pub fn mulx(&mut self, c: &mut FP) {
        self.x.mul(c);
    }

    /* Constant time select from pre-computed table */
    fn selector(&mut self, W: &[ECP], b: i32) {
        // unsure about &[& syntax. An array of pointers I hope..
        let mut MP = ECP::new();
        let m = b >> 31;
        let mut babs = (b ^ m) - m;

        babs = (babs - 1) / 2;

        self.cmove(&W[0], ECP::teq(babs, 0)); // conditional move
        self.cmove(&W[1], ECP::teq(babs, 1));
        self.cmove(&W[2], ECP::teq(babs, 2));
        self.cmove(&W[3], ECP::teq(babs, 3));
        self.cmove(&W[4], ECP::teq(babs, 4));
        self.cmove(&W[5], ECP::teq(babs, 5));
        self.cmove(&W[6], ECP::teq(babs, 6));
        self.cmove(&W[7], ECP::teq(babs, 7));

        MP.copy(self);
        MP.neg();
        self.cmove(&MP, (m & 1) as isize);
    }

    /* Test P == Q */
    pub fn equals(&self, Q: &ECP) -> bool {
        let mut a = FP::new();
        let mut b = FP::new();
        a.copy(&self.x);
        a.mul(&Q.z);
        b.copy(&Q.x);
        b.mul(&self.z);
        if !a.equals(&mut b) {
            return false;
        }
        if CURVETYPE != CurveType::MONTGOMERY {
            a.copy(&self.y);
            a.mul(&Q.z);
            b.copy(&Q.y);
            b.mul(&self.z);
            if !a.equals(&mut b) {
                return false;
            }
        }
        return true;
    }

    /* set to affine - from (x,y,z) to (x,y) */
    pub fn affine(&mut self) {
        if self.is_infinity() {
            return;
        }
        let mut one = FP::new_int(1);
        if self.z.equals(&mut one) {
            return;
        }
        self.z.inverse();

        self.x.mul(&self.z);
        self.x.reduce();
        if CURVETYPE != CurveType::MONTGOMERY {
            self.y.mul(&self.z);
            self.y.reduce();
        }
        self.z.copy(&one);
    }

    /* extract x as a BIG */
    pub fn getx(&self) -> BIG {
        let mut W = ECP::new();
        W.copy(self);
        W.affine();
        return W.x.redc();
    }

    /* extract y as a BIG */
    pub fn gety(&self) -> BIG {
        let mut W = ECP::new();
        W.copy(self);
        W.affine();
        return W.y.redc();
    }

    /* get sign of Y */
    pub fn gets(&self) -> isize {
        let y = self.gety();
        return y.parity();
    }

    /* extract x as an FP */
    pub fn getpx(&self) -> FP {
        let w = FP::new_copy(&self.x);
        return w;
    }
    /* extract y as an FP */
    pub fn getpy(&self) -> FP {
        let w = FP::new_copy(&self.y);
        return w;
    }

    /* extract z as an FP */
    pub fn getpz(&self) -> FP {
        let w = FP::new_copy(&self.z);
        return w;
    }

    /* convert to byte array */
    pub fn tobytes(&self, b: &mut [u8], compress: bool) {
        let mb = big::MODBYTES as usize;
        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
        let mut W = ECP::new();
        W.copy(self);

        W.affine();
        W.x.redc().tobytes(&mut t);
        for i in 0..mb {
            b[i + 1] = t[i]
        }

        if CURVETYPE == CurveType::MONTGOMERY {
            b[0] = 0x06;
            return;
        }

        if compress {
            b[0] = 0x02;
            if W.y.redc().parity() == 1 {
                b[0] = 0x03
            }
            return;
        }

        b[0] = 0x04;

        W.y.redc().tobytes(&mut t);
        for i in 0..mb {
            b[i + mb + 1] = t[i]
        }
    }

    /* convert from byte array to point */
    pub fn frombytes(b: &[u8]) -> ECP {
        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
        let mb = big::MODBYTES as usize;
        let p = BIG::new_ints(&rom::MODULUS);

        for i in 0..mb {
            t[i] = b[i + 1]
        }
        let px = BIG::frombytes(&t);
        if BIG::comp(&px, &p) >= 0 {
            return ECP::new();
        }

        if CURVETYPE == CurveType::MONTGOMERY {
            return ECP::new_big(&px);
        }

        if b[0] == 0x04 {
            for i in 0..mb {
                t[i] = b[i + mb + 1]
            }
            let py = BIG::frombytes(&t);
            if BIG::comp(&py, &p) >= 0 {
                return ECP::new();
            }
            return ECP::new_bigs(&px, &py);
        }

        if b[0] == 0x02 || b[0] == 0x03 {
            return ECP::new_bigint(&px, (b[0] & 1) as isize);
        }

        return ECP::new();
    }

    /* convert to hex string */
    pub fn tostring(&self) -> String {
        let mut W = ECP::new();
        W.copy(self);
        if W.is_infinity() {
            return String::from("infinity");
        }
        if CURVETYPE == CurveType::MONTGOMERY {
            return format!("({})", W.x.redc().tostring());
        } else {
            return format!("({},{})", W.x.redc().tostring(), W.y.redc().tostring());
        };
    }

    pub fn to_hex(&self) -> String {
        format!("{} {} {}", self.x.to_hex(), self.y.to_hex(), self.z.to_hex())
    }

    pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP {
        ECP {
            x: FP::from_hex_iter(iter),
            y: FP::from_hex_iter(iter),
            z: FP::from_hex_iter(iter),
        }
    }

    pub fn from_hex(val: String) -> ECP {
        let mut iter = val.split_whitespace();
        return ECP::from_hex_iter(&mut iter);
    }

    /* this*=2 */
    pub fn dbl(&mut self) {
        if CURVETYPE == CurveType::WEIERSTRASS {
            if rom::CURVE_A == 0 {
                let mut t0 = FP::new_copy(&self.y);
                t0.sqr();
                let mut t1 = FP::new_copy(&self.y);
                t1.mul(&self.z);
                let mut t2 = FP::new_copy(&self.z);
                t2.sqr();

                self.z.copy(&t0);
                self.z.add(&t0);
                self.z.norm();
                self.z.dbl();
                self.z.dbl();
                self.z.norm();
                t2.imul(3 * rom::CURVE_B_I);

                let mut x3 = FP::new_copy(&t2);
                x3.mul(&self.z);

                let mut y3 = FP::new_copy(&t0);
                y3.add(&t2);
                y3.norm();
                self.z.mul(&t1);
                t1.copy(&t2);
                t1.add(&t2);
                t2.add(&t1);
                t0.sub(&t2);
                t0.norm();
                y3.mul(&t0);
                y3.add(&x3);
                t1.copy(&self.x);
                t1.mul(&self.y);
                self.x.copy(&t0);
                self.x.norm();
                self.x.mul(&t1);
                self.x.dbl();
                self.x.norm();
                self.y.copy(&y3);
                self.y.norm();
            } else {
                let mut t0 = FP::new_copy(&self.x);
                let mut t1 = FP::new_copy(&self.y);
                let mut t2 = FP::new_copy(&self.z);
                let mut t3 = FP::new_copy(&self.x);
                let mut z3 = FP::new_copy(&self.z);
                let mut y3 = FP::new();
                let mut x3 = FP::new();
                let mut b = FP::new();

                if rom::CURVE_B_I == 0 {
                    b.copy(&FP::new_big(&BIG::new_ints(&rom::CURVE_B)));
                }

                t0.sqr(); //1    x^2
                t1.sqr(); //2    y^2
                t2.sqr(); //3

                t3.mul(&self.y); //4
                t3.dbl();
                t3.norm(); //5
                z3.mul(&self.x); //6
                z3.dbl();
                z3.norm(); //7
                y3.copy(&t2);

                if rom::CURVE_B_I == 0 {
                    y3.mul(&b); //8
                } else {
                    y3.imul(rom::CURVE_B_I);
                }

                y3.sub(&z3); //9  ***
                x3.copy(&y3);
                x3.add(&y3);
                x3.norm(); //10

                y3.add(&x3); //11
                x3.copy(&t1);
                x3.sub(&y3);
                x3.norm(); //12
                y3.add(&t1);
                y3.norm(); //13
                y3.mul(&x3); //14
                x3.mul(&t3); //15
                t3.copy(&t2);
                t3.add(&t2); //16
                t2.add(&t3); //17

                if rom::CURVE_B_I == 0 {
                    z3.mul(&b); //18
                } else {
                    z3.imul(rom::CURVE_B_I);
                }

                z3.sub(&t2); //19
                z3.sub(&t0);
                z3.norm(); //20  ***
                t3.copy(&z3);
                t3.add(&z3); //21

                z3.add(&t3);
                z3.norm(); //22
                t3.copy(&t0);
                t3.add(&t0); //23
                t0.add(&t3); //24
                t0.sub(&t2);
                t0.norm(); //25

                t0.mul(&z3); //26
                y3.add(&t0); //27
                t0.copy(&self.y);
                t0.mul(&self.z); //28
                t0.dbl();
                t0.norm(); //29
                z3.mul(&t0); //30
                x3.sub(&z3); //31
                t0.dbl();
                t0.norm(); //32
                t1.dbl();
                t1.norm(); //33
                z3.copy(&t0);
                z3.mul(&t1); //34

                self.x.copy(&x3);
                self.x.norm();
                self.y.copy(&y3);
                self.y.norm();
                self.z.copy(&z3);
                self.z.norm();
            }
        }
        if CURVETYPE == CurveType::EDWARDS {
            let mut c = FP::new_copy(&self.x);
            let mut d = FP::new_copy(&self.y);
            let mut h = FP::new_copy(&self.z);
            let mut j = FP::new();

            self.x.mul(&self.y);
            self.x.dbl();
            self.x.norm();
            c.sqr();
            d.sqr();
            if rom::CURVE_A == -1 {
                c.neg()
            }
            self.y.copy(&c);
            self.y.add(&d);
            self.y.norm();
            h.sqr();
            h.dbl();
            self.z.copy(&self.y);
            j.copy(&self.y);
            j.sub(&h);
            j.norm();
            self.x.mul(&j);
            c.sub(&d);
            c.norm();
            self.y.mul(&c);
            self.z.mul(&j);
        }
        if CURVETYPE == CurveType::MONTGOMERY {
            let mut a = FP::new_copy(&self.x);
            let mut b = FP::new_copy(&self.x);
            let mut aa = FP::new();
            let mut bb = FP::new();
            let mut c = FP::new();

            a.add(&self.z);
            a.norm();
            aa.copy(&a);
            aa.sqr();
            b.sub(&self.z);
            b.norm();
            bb.copy(&b);
            bb.sqr();
            c.copy(&aa);
            c.sub(&bb);
            c.norm();

            self.x.copy(&aa);
            self.x.mul(&bb);

            a.copy(&c);
            a.imul((rom::CURVE_A + 2) / 4);

            bb.add(&a);
            bb.norm();
            self.z.copy(&bb);
            self.z.mul(&c);
        }
        return;
    }

    /* self+=Q */
    pub fn add(&mut self, Q: &ECP) {
        if CURVETYPE == CurveType::WEIERSTRASS {
            if rom::CURVE_A == 0 {
                let b = 3 * rom::CURVE_B_I;
                let mut t0 = FP::new_copy(&self.x);
                t0.mul(&Q.x);
                let mut t1 = FP::new_copy(&self.y);
                t1.mul(&Q.y);
                let mut t2 = FP::new_copy(&self.z);
                t2.mul(&Q.z);
                let mut t3 = FP::new_copy(&self.x);
                t3.add(&self.y);
                t3.norm();
                let mut t4 = FP::new_copy(&Q.x);
                t4.add(&Q.y);
                t4.norm();
                t3.mul(&t4);
                t4.copy(&t0);
                t4.add(&t1);

                t3.sub(&t4);
                t3.norm();
                t4.copy(&self.y);
                t4.add(&self.z);
                t4.norm();
                let mut x3 = FP::new_copy(&Q.y);
                x3.add(&Q.z);
                x3.norm();

                t4.mul(&x3);
                x3.copy(&t1);
                x3.add(&t2);

                t4.sub(&x3);
                t4.norm();
                x3.copy(&self.x);
                x3.add(&self.z);
                x3.norm();
                let mut y3 = FP::new_copy(&Q.x);
                y3.add(&Q.z);
                y3.norm();
                x3.mul(&y3);
                y3.copy(&t0);
                y3.add(&t2);
                y3.rsub(&x3);
                y3.norm();
                x3.copy(&t0);
                x3.add(&t0);
                t0.add(&x3);
                t0.norm();
                t2.imul(b);

                let mut z3 = FP::new_copy(&t1);
                z3.add(&t2);
                z3.norm();
                t1.sub(&t2);
                t1.norm();
                y3.imul(b);

                x3.copy(&y3);
                x3.mul(&t4);
                t2.copy(&t3);
                t2.mul(&t1);
                x3.rsub(&t2);
                y3.mul(&t0);
                t1.mul(&z3);
                y3.add(&t1);
                t0.mul(&t3);
                z3.mul(&t4);
                z3.add(&t0);

                self.x.copy(&x3);
                self.x.norm();
                self.y.copy(&y3);
                self.y.norm();
                self.z.copy(&z3);
                self.z.norm();
            } else {
                let mut t0 = FP::new_copy(&self.x);
                let mut t1 = FP::new_copy(&self.y);
                let mut t2 = FP::new_copy(&self.z);
                let mut t3 = FP::new_copy(&self.x);
                let mut t4 = FP::new_copy(&Q.x);
                let mut z3 = FP::new();
                let mut y3 = FP::new_copy(&Q.x);
                let mut x3 = FP::new_copy(&Q.y);
                let mut b = FP::new();

                if rom::CURVE_B_I == 0 {
                    b.copy(&FP::new_big(&BIG::new_ints(&rom::CURVE_B)));
                }

                t0.mul(&Q.x); //1
                t1.mul(&Q.y); //2
                t2.mul(&Q.z); //3

                t3.add(&self.y);
                t3.norm(); //4
                t4.add(&Q.y);
                t4.norm(); //5
                t3.mul(&t4); //6
                t4.copy(&t0);
                t4.add(&t1); //7
                t3.sub(&t4);
                t3.norm(); //8
                t4.copy(&self.y);
                t4.add(&self.z);
                t4.norm(); //9
                x3.add(&Q.z);
                x3.norm(); //10
                t4.mul(&x3); //11
                x3.copy(&t1);
                x3.add(&t2); //12

                t4.sub(&x3);
                t4.norm(); //13
                x3.copy(&self.x);
                x3.add(&self.z);
                x3.norm(); //14
                y3.add(&Q.z);
                y3.norm(); //15

                x3.mul(&y3); //16
                y3.copy(&t0);
                y3.add(&t2); //17

                y3.rsub(&x3);
                y3.norm(); //18
                z3.copy(&t2);

                if rom::CURVE_B_I == 0 {
                    z3.mul(&b); //18
                } else {
                    z3.imul(rom::CURVE_B_I);
                }

                x3.copy(&y3);
                x3.sub(&z3);
                x3.norm(); //20
                z3.copy(&x3);
                z3.add(&x3); //21

                x3.add(&z3); //22
                z3.copy(&t1);
                z3.sub(&x3);
                z3.norm(); //23
                x3.add(&t1);
                x3.norm(); //24

                if rom::CURVE_B_I == 0 {
                    y3.mul(&b); //18
                } else {
                    y3.imul(rom::CURVE_B_I);
                }

                t1.copy(&t2);
                t1.add(&t2); //t1.norm();//26
                t2.add(&t1); //27

                y3.sub(&t2); //28

                y3.sub(&t0);
                y3.norm(); //29
                t1.copy(&y3);
                t1.add(&y3); //30
                y3.add(&t1);
                y3.norm(); //31

                t1.copy(&t0);
                t1.add(&t0); //32
                t0.add(&t1); //33
                t0.sub(&t2);
                t0.norm(); //34
                t1.copy(&t4);
                t1.mul(&y3); //35
                t2.copy(&t0);
                t2.mul(&y3); //36
                y3.copy(&x3);
                y3.mul(&z3); //37
                y3.add(&t2); //y3.norm();//38
                x3.mul(&t3); //39
                x3.sub(&t1); //40
                z3.mul(&t4); //41
                t1.copy(&t3);
                t1.mul(&t0); //42
                z3.add(&t1);
                self.x.copy(&x3);
                self.x.norm();
                self.y.copy(&y3);
                self.y.norm();
                self.z.copy(&z3);
                self.z.norm();
            }
        }
        if CURVETYPE == CurveType::EDWARDS {
            let bb = FP::new_big(&BIG::new_ints(&rom::CURVE_B));
            let mut a = FP::new_copy(&self.z);
            let mut b = FP::new();
            let mut c = FP::new_copy(&self.x);
            let mut d = FP::new_copy(&self.y);
            let mut e = FP::new();
            let mut f = FP::new();
            let mut g = FP::new();

            a.mul(&Q.z);
            b.copy(&a);
            b.sqr();
            c.mul(&Q.x);
            d.mul(&Q.y);

            e.copy(&c);
            e.mul(&d);
            e.mul(&bb);
            f.copy(&b);
            f.sub(&e);
            g.copy(&b);
            g.add(&e);

            if rom::CURVE_A == 1 {
                e.copy(&d);
                e.sub(&c);
            }
            c.add(&d);

            b.copy(&self.x);
            b.add(&self.y);
            d.copy(&Q.x);
            d.add(&Q.y);
            b.norm();
            d.norm();
            b.mul(&d);
            b.sub(&c);
            b.norm();
            f.norm();
            b.mul(&f);
            self.x.copy(&a);
            self.x.mul(&b);
            g.norm();
            if rom::CURVE_A == 1 {
                e.norm();
                c.copy(&e);
                c.mul(&g);
            }
            if rom::CURVE_A == -1 {
                c.norm();
                c.mul(&g);
            }
            self.y.copy(&a);
            self.y.mul(&c);
            self.z.copy(&f);
            self.z.mul(&g);
        }
        return;
    }

    /* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
    pub fn dadd(&mut self, Q: &ECP, W: &ECP) {
        let mut a = FP::new_copy(&self.x);
        let mut b = FP::new_copy(&self.x);
        let mut c = FP::new_copy(&Q.x);
        let mut d = FP::new_copy(&Q.x);
        let mut da = FP::new();
        let mut cb = FP::new();

        a.add(&self.z);
        b.sub(&self.z);

        c.add(&Q.z);
        d.sub(&Q.z);

        a.norm();
        d.norm();

        da.copy(&d);
        da.mul(&a);

        c.norm();
        b.norm();

        cb.copy(&c);
        cb.mul(&b);

        a.copy(&da);
        a.add(&cb);
        a.norm();
        a.sqr();
        b.copy(&da);
        b.sub(&cb);
        b.norm();
        b.sqr();

        self.x.copy(&a);
        self.z.copy(&W.x);
        self.z.mul(&b);
    }

    /* self-=Q */
    pub fn sub(&mut self, Q: &ECP) {
        let mut NQ = ECP::new();
        NQ.copy(Q);
        NQ.neg();
        self.add(&NQ);
    }

    /* constant time multiply by small integer of length bts - use ladder */
    pub fn pinmul(&self, e: i32, bts: i32) -> ECP {
        if CURVETYPE == CurveType::MONTGOMERY {
            return self.mul(&mut BIG::new_int(e as isize));
        } else {
            let mut P = ECP::new();
            let mut R0 = ECP::new();
            let mut R1 = ECP::new();
            R1.copy(&self);

            for i in (0..bts).rev() {
                let b = ((e >> i) & 1) as isize;
                P.copy(&R1);
                P.add(&mut R0);
                R0.cswap(&mut R1, b);
                R1.copy(&P);
                R0.dbl();
                R0.cswap(&mut R1, b);
            }
            P.copy(&R0);
            P.affine();
            return P;
        }
    }

    /* return e.self */

    pub fn mul(&self, e: &BIG) -> ECP {
        if e.iszilch() || self.is_infinity() {
            return ECP::new();
        }
        let mut P = ECP::new();
        if CURVETYPE == CurveType::MONTGOMERY {
            /* use Ladder */
            let mut D = ECP::new();
            let mut R0 = ECP::new();
            R0.copy(&self);
            let mut R1 = ECP::new();
            R1.copy(&self);
            R1.dbl();
            D.copy(&self);
            D.affine();
            let nb = e.nbits();

            for i in (0..nb - 1).rev() {
                let b = e.bit(i);
                P.copy(&R1);
                P.dadd(&mut R0, &D);
                R0.cswap(&mut R1, b);
                R1.copy(&P);
                R0.dbl();
                R0.cswap(&mut R1, b);
            }
            P.copy(&R0)
        } else {
            // fixed size windows
            let mut mt = BIG::new();
            let mut t = BIG::new();
            let mut Q = ECP::new();
            let mut C = ECP::new();

            let mut W: [ECP; 8] = [
                ECP::new(),
                ECP::new(),
                ECP::new(),
                ECP::new(),
                ECP::new(),
                ECP::new(),
                ECP::new(),
                ECP::new(),
            ];

            const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 3) / 4;
            let mut w: [i8; CT] = [0; CT];

            Q.copy(&self);
            Q.dbl();

            W[0].copy(&self);

            for i in 1..8 {
                C.copy(&W[i - 1]);
                W[i].copy(&C);
                W[i].add(&mut Q);
            }

            // make exponent odd - add 2P if even, P if odd
            t.copy(&e);
            let s = t.parity();
            t.inc(1);
            t.norm();
            let ns = t.parity();
            mt.copy(&t);
            mt.inc(1);
            mt.norm();
            t.cmove(&mt, s);
            Q.cmove(&self, ns);
            C.copy(&Q);

            let nb = 1 + (t.nbits() + 3) / 4;

            // convert exponent to signed 4-bit window
            for i in 0..nb {
                w[i] = (t.lastbits(5) - 16) as i8;
                t.dec(w[i] as isize);
                t.norm();
                t.fshr(4);
            }
            w[nb] = t.lastbits(5) as i8;

            P.copy(&W[((w[nb] as usize) - 1) / 2]);
            for i in (0..nb).rev() {
                Q.selector(&W, w[i] as i32);
                P.dbl();
                P.dbl();
                P.dbl();
                P.dbl();
                P.add(&mut Q);
            }
            P.sub(&mut C); /* apply correction */
        }
        P.affine();
        return P;
    }

    /* Return e.this+f.Q */

    pub fn mul2(&self, e: &BIG, Q: &ECP, f: &BIG) -> ECP {
        let mut te = BIG::new();
        let mut tf = BIG::new();
        let mut mt = BIG::new();
        let mut S = ECP::new();
        let mut T = ECP::new();
        let mut C = ECP::new();

        let mut W: [ECP; 8] = [
            ECP::new(),
            ECP::new(),
            ECP::new(),
            ECP::new(),
            ECP::new(),
            ECP::new(),
            ECP::new(),
            ECP::new(),
        ];

        const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 1) / 2;
        let mut w: [i8; CT] = [0; CT];

        te.copy(e);
        tf.copy(f);

        // precompute table

        W[1].copy(&self);
        W[1].sub(Q);
        W[2].copy(&self);
        W[2].add(Q);
        S.copy(&Q);
        S.dbl();
        C.copy(&W[1]);
        W[0].copy(&C);
        W[0].sub(&mut S); // copy to C is stupid Rust thing..
        C.copy(&W[2]);
        W[3].copy(&C);
        W[3].add(&mut S);
        T.copy(&self);
        T.dbl();
        C.copy(&W[1]);
        W[5].copy(&C);
        W[5].add(&mut T);
        C.copy(&W[2]);
        W[6].copy(&C);
        W[6].add(&mut T);
        C.copy(&W[5]);
        W[4].copy(&C);
        W[4].sub(&mut S);
        C.copy(&W[6]);
        W[7].copy(&C);
        W[7].add(&mut S);

        // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction

        let mut s = te.parity();
        te.inc(1);
        te.norm();
        let mut ns = te.parity();
        mt.copy(&te);
        mt.inc(1);
        mt.norm();
        te.cmove(&mt, s);
        T.cmove(&self, ns);
        C.copy(&T);

        s = tf.parity();
        tf.inc(1);
        tf.norm();
        ns = tf.parity();
        mt.copy(&tf);
        mt.inc(1);
        mt.norm();
        tf.cmove(&mt, s);
        S.cmove(&Q, ns);
        C.add(&mut S);

        mt.copy(&te);
        mt.add(&tf);
        mt.norm();
        let nb = 1 + (mt.nbits() + 1) / 2;

        // convert exponent to signed 2-bit window
        for i in 0..nb {
            let a = te.lastbits(3) - 4;
            te.dec(a);
            te.norm();
            te.fshr(2);
            let b = tf.lastbits(3) - 4;
            tf.dec(b);
            tf.norm();
            tf.fshr(2);
            w[i] = (4 * a + b) as i8;
        }
        w[nb] = (4 * te.lastbits(3) + tf.lastbits(3)) as i8;
        S.copy(&W[((w[nb] as usize) - 1) / 2]);

        for i in (0..nb).rev() {
            T.selector(&W, w[i] as i32);
            S.dbl();
            S.dbl();
            S.add(&mut T);
        }
        S.sub(&mut C); /* apply correction */
        S.affine();
        return S;
    }

    pub fn cfp(&mut self) {
        let cf = rom::CURVE_COF_I;
        if cf == 1 {
            return;
        }
        if cf == 4 {
            self.dbl();
            self.dbl();
            return;
        }
        if cf == 8 {
            self.dbl();
            self.dbl();
            self.dbl();
            return;
        }
        let c = BIG::new_ints(&rom::CURVE_COF);
        let P = self.mul(&c);
        self.copy(&P);
    }

    #[allow(non_snake_case)]
    pub fn mapit(h: &[u8]) -> ECP {
        let mut q = BIG::new_ints(&rom::MODULUS);
        let mut x = BIG::frombytes(h);
        x.rmod(&mut q);
        let mut P: ECP;

        loop {
            loop {
                if CURVETYPE != CurveType::MONTGOMERY {
                    P = ECP::new_bigint(&x, 0);
                } else {
                    P = ECP::new_big(&x);
                }
                x.inc(1);
                x.norm();
                if !P.is_infinity() {
                    break;
                }
            }
            P.cfp();
            if !P.is_infinity() {
                break;
            }
        }

        return P;
    }

    pub fn generator() -> ECP {
        let G: ECP;

        let gx = BIG::new_ints(&rom::CURVE_GX);

        if CURVETYPE != CurveType::MONTGOMERY {
            let gy = BIG::new_ints(&rom::CURVE_GY);
            G = ECP::new_bigs(&gx, &gy);
        } else {
            G = ECP::new_big(&gx);
        }
        return G;
    }
}
