/*
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::big;
use super::big::BIG;
use super::dbig::DBIG;
use super::rom;
use super::super::arch::Chunk;
use super::super::arch;
use types::ModType;
use std::str::FromStr;

#[derive(Copy, Clone)]
pub struct FP {
    pub x: BIG,
    pub xes: i32,
}

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

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

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

pub use super::rom::{MODBITS, MOD8, MODTYPE, SH};
use std::str::SplitWhitespace;
use std::fmt;

pub const FEXCESS:i32 = (((1 as i32)<<SH)-1);
pub const OMASK:Chunk = (-1)<<(MODBITS%big::BASEBITS);
pub const TBITS:usize=MODBITS%big::BASEBITS; // Number of active bits in top word
pub const TMASK:Chunk=(1<<TBITS)-1;

impl FP {
    /* Constructors */
    pub fn new() -> FP {
        FP {
            x: BIG::new(),
            xes: 1,
        }
    }

    pub fn new_int(a: isize) -> FP {
        let mut f = FP::new();
        f.x.inc(a);
        f.nres();
        return f;
    }

    pub fn new_copy(y: &FP) -> FP {
        let mut f = FP::new();
        f.x.copy(&(y.x));
        f.xes = y.xes;
        return f;
    }

    pub fn new_big(y: &BIG) -> FP {
        let mut f = FP::new();
        f.x.copy(y);
        f.nres();
        return f;
    }

    pub fn nres(&mut self) {
        if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
            let r=BIG::new_ints(&rom::R2MODP);
            let mut d=BIG::mul(&(self.x),&r);
            self.x.copy(&FP::modulo(&mut d));
            self.xes = 2;
        } else {
            self.xes = 1;
        }
    }

    pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP {
        let xes = i32::from_str(iter.next().unwrap()).unwrap();
        let x = iter.next().unwrap();
        FP {
            x: BIG::from_hex(x.to_string()),
            xes
        }
    }

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

    pub fn to_hex(&self) -> String {
        let mut x = self.x;
        let big = x.to_hex();
        format!("{} {}", self.xes, big)
    }

/* convert back to regular form */
    pub fn redc(&mut self) -> BIG {
        if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
            let mut d=DBIG::new_scopy(&(self.x));
            return FP::modulo(&mut d);
        } else {
            let r = BIG::new_copy(&(self.x));
            return r;
        }
    }

    /* reduce a DBIG to a BIG using the appropriate form of the modulus */
    /* dd */
    pub fn modulo(d: &mut DBIG) -> BIG {
        if MODTYPE==ModType::PSEUDO_MERSENNE {
            let mut b=BIG::new();
            let mut t=d.split(MODBITS);
            b.dcopy(&d);
            let v = t.pmul(rom::MCONST as isize);

            t.add(&b);
            t.norm();

            let tw = t.w[big::NLEN - 1];
            t.w[big::NLEN - 1] &= TMASK;
            t.w[0] += rom::MCONST * ((tw >> TBITS) + (v << (big::BASEBITS - TBITS)));
            t.norm();
            return t;
        }
    
        if MODTYPE==ModType::MONTGOMERY_FRIENDLY {
            let mut b = BIG::new();
            for i in 0..big::NLEN {
                let x = d.w[i];

                let tuple = BIG::muladd(x, rom::MCONST - 1, x, d.w[big::NLEN + i - 1]);
                d.w[big::NLEN + i] += tuple.0;
                d.w[big::NLEN + i - 1] = tuple.1;
            }

            b.zero();

            for i in 0..big::NLEN {
                b.w[i] = d.w[big::NLEN + i];
            }
            b.norm();
            return b;
        }

        if MODTYPE == ModType::GENERALISED_MERSENNE {
            // GoldiLocks Only
            let mut b = BIG::new();
            let t = d.split(MODBITS);
            let rm2 = (MODBITS / 2) as usize;
            b.dcopy(&d);
            b.add(&t);
            let mut dd = DBIG::new_scopy(&t);
            dd.shl(rm2);

            let mut tt = dd.split(MODBITS);
            let lo = BIG::new_dcopy(&dd);
            b.add(&tt);
            b.add(&lo);
            b.norm();
            tt.shl(rm2);
            b.add(&tt);

            let carry = b.w[big::NLEN - 1] >> TBITS;
            b.w[big::NLEN - 1] &= TMASK;
            b.w[0] += carry;

            b.w[(224 / big::BASEBITS) as usize] += carry << (224 % big::BASEBITS);
            b.norm();
            return b;
        }
        if MODTYPE == ModType::NOT_SPECIAL {
            let m = BIG::new_ints(&rom::MODULUS);
            return BIG::monty(&m, rom::MCONST, d);
        }
        return BIG::new();
    }

    /* convert to string */
    pub fn tostring(&mut self) -> String {
        let s = self.redc().tostring();
        return s;
    }

    /* reduce this mod Modulus */
    pub fn reduce(&mut self) {
        let mut m = BIG::new_ints(&rom::MODULUS);
        let mut r = BIG::new_copy(&m);
        let mut sb: usize;
        self.x.norm();
        if self.xes > 16 {
            let q = FP::quo(&self.x, &m);
            let carry = r.pmul(q);
            r.w[big::NLEN - 1] += carry << big::BASEBITS; // correction - put any carry out back in again
            self.x.sub(&r);
            self.x.norm();
            sb = 2;
        } else {
            sb = FP::logb2((self.xes - 1) as u32);
        }
        m.fshl(sb);

        while sb > 0 {
            let sr = BIG::ssn(&mut r, &self.x, &mut m);
            self.x.cmove(&r, 1 - sr);
            sb = sb - 1;
        }

        self.xes = 1;
    }

    /* test this=0? */
    pub fn iszilch(&self) -> bool {
        let mut a = FP::new_copy(self);
        a.reduce();
        return a.x.iszilch();
    }

    /* copy from FP b */
    pub fn copy(&mut self, b: &FP) {
        self.x.copy(&(b.x));
        self.xes = b.xes;
    }

    /* copy from BIG b */
    pub fn bcopy(&mut self, b: &BIG) {
        self.x.copy(&b);
        self.nres();
    }

    /* set this=0 */
    pub fn zero(&mut self) {
        self.x.zero();
        self.xes = 1;
    }

    /* set this=1 */
    pub fn one(&mut self) {
        self.x.one();
        self.nres()
    }

    /* normalise this */
    pub fn norm(&mut self) {
        self.x.norm();
    }
    /* swap FPs depending on d */
    pub fn cswap(&mut self, b: &mut FP, d: isize) {
        self.x.cswap(&mut (b.x), d);
        let mut c = d as i32;
        c = !(c - 1);
        let t = c & (self.xes ^ b.xes);
        self.xes ^= t;
        b.xes ^= t;
    }

    /* copy FPs depending on d */
    pub fn cmove(&mut self, b: &FP, d: isize) {
        self.x.cmove(&(b.x), d);
        let c = d as i32;
        self.xes ^= (self.xes ^ b.xes) & (-c);
    }

    /* this*=b mod Modulus */
    pub fn mul(&mut self, b: &FP) {
        if (self.xes as i64) * (b.xes as i64) > FEXCESS as i64 {
            self.reduce()
        }

        let mut d = BIG::mul(&(self.x), &(b.x));
        self.x.copy(&FP::modulo(&mut d));
        self.xes = 2;
    }

    fn logb2(w: u32) -> usize {
        let mut v = w;
        v |= v >> 1;
        v |= v >> 2;
        v |= v >> 4;
        v |= v >> 8;
        v |= v >> 16;

        v = v - ((v >> 1) & 0x55555555);
        v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
        let r = ((((v + (v >> 4)) & 0xF0F0F0F).wrapping_mul(0x1010101)) >> 24) as usize;
        return r;
    }

    // find appoximation to quotient of a/m
    // Out by at most 2.
    // Note that MAXXES is bounded to be 2-bits less than half a word
    fn quo(n: &BIG, m: &BIG) -> isize {
        let hb = arch::CHUNK / 2;

        if TBITS < hb {
            let sh = hb - TBITS;
            let num = (n.w[big::NLEN - 1] << sh) | (n.w[big::NLEN - 2] >> (big::BASEBITS - sh));
            let den = (m.w[big::NLEN - 1] << sh) | (m.w[big::NLEN - 2] >> (big::BASEBITS - sh));
            return (num / (den + 1)) as isize;
        } else {
            let num = n.w[big::NLEN - 1];
            let den = m.w[big::NLEN - 1];
            return (num / (den + 1)) as isize;
        }
    }

    /* this = -this mod Modulus */
    pub fn neg(&mut self) {
        let mut p = BIG::new_ints(&rom::MODULUS);
        let sb = FP::logb2((self.xes - 1) as u32);

        p.fshl(sb);
        self.x.rsub(&p);
        self.xes = 1 << (sb as i32) + 1;
        if self.xes > FEXCESS {
            self.reduce()
        }
    }

    /* this*=c mod Modulus, where c is a small int */
    pub fn imul(&mut self, c: isize) {
        let mut cc = c;
        let mut s = false;
        if cc < 0 {
            cc = -cc;
            s = true;
        }

        if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
            let mut d = self.x.pxmul(cc);
            self.x.copy(&FP::modulo(&mut d));
            self.xes = 2
        } else {
            if self.xes * (cc as i32) <= FEXCESS {
                self.x.pmul(cc);
                self.xes *= cc as i32;
            } else {
                let n = FP::new_int(cc);
                self.mul(&n);
            }
        }

        if s {
            self.neg();
            self.norm();
        }
    }

    /* self*=self mod Modulus */
    pub fn sqr(&mut self) {
        if (self.xes as i64) * (self.xes as i64) > FEXCESS as i64 {
            self.reduce()
        }

        let mut d = BIG::sqr(&(self.x));
        self.x.copy(&FP::modulo(&mut d));
        self.xes = 2
    }

    /* self+=b */
    pub fn add(&mut self, b: &FP) {
        self.x.add(&(b.x));
        self.xes += b.xes;
        if self.xes > FEXCESS {
            self.reduce()
        }
    }

    /* self+=self */
    pub fn dbl(&mut self) {
        self.x.dbl();
        self.xes += self.xes;
        if self.xes > FEXCESS {
            self.reduce()
        }
    }

    /* self-=b */
    pub fn sub(&mut self, b: &FP) {
        let mut n = FP::new_copy(b);
        n.neg();
        self.add(&n);
    }

    /* self=b-self */
    pub fn rsub(&mut self, b: &FP) {
        self.neg();
        self.add(&b);
    }

    /* self/=2 mod Modulus */
    pub fn div2(&mut self) {
        if self.x.parity() == 0 {
            self.x.fshr(1);
        } else {
            let p = BIG::new_ints(&rom::MODULUS);
            self.x.add(&p);
            self.x.norm();
            self.x.fshr(1);
        }
    }

    // See eprint paper https://eprint.iacr.org/2018/1038
    // return this^(p-3)/4 or this^(p-5)/8
    pub fn fpow(&mut self) -> FP {
        let ac: [isize; 11] = [1, 2, 3, 6, 12, 15, 30, 60, 120, 240, 255];
        let mut xp: [FP; 11] = [
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
        ];
        // phase 1
        let mut t = FP::new();
        xp[0].copy(&self); // 1
        xp[1].copy(&self);
        xp[1].sqr(); // 2
        t.copy(&xp[1]);
        xp[2].copy(&t);
        xp[2].mul(&self); // 3
        t.copy(&xp[2]);
        xp[3].copy(&t);
        xp[3].sqr(); // 6
        t.copy(&xp[3]);
        xp[4].copy(&t);
        xp[4].sqr(); // 12
        t.copy(&xp[4]);
        t.mul(&xp[2]);
        xp[5].copy(&t); // 15
        t.copy(&xp[5]);
        xp[6].copy(&t);
        xp[6].sqr(); // 30
        t.copy(&xp[6]);
        xp[7].copy(&t);
        xp[7].sqr(); // 60
        t.copy(&xp[7]);
        xp[8].copy(&t);
        xp[8].sqr(); // 120
        t.copy(&xp[8]);
        xp[9].copy(&t);
        xp[9].sqr(); // 240
        t.copy(&xp[9]);
        t.mul(&xp[5]);
        xp[10].copy(&t); // 255

        let mut n = MODBITS as isize;
        let c: isize;

        if MODTYPE == ModType::GENERALISED_MERSENNE {
            // Goldilocks ONLY
            n /= 2;
        }

        if MOD8 == 5 {
            n -= 3;
            c = ((rom::MCONST as isize) + 5) / 8;
        } else {
            n -= 2;
            c = ((rom::MCONST as isize) + 3) / 4;
        }
        let mut bw = 0;
        let mut w = 1;
        while w < c {
            w *= 2;
            bw += 1;
        }
        let mut k = w - c;

        let mut i = 10;
        let mut key = FP::new();
        if k != 0 {
            while ac[i] > k {
                i -= 1;
            }
            key.copy(&xp[i]);
            k -= ac[i];
        }
        while k != 0 {
            i -= 1;
            if ac[i] > k {
                continue;
            }
            key.mul(&xp[i]);
            k -= ac[i];
        }
        // phase 2
        t.copy(&xp[2]);
        xp[1].copy(&t);
        t.copy(&xp[5]);
        xp[2].copy(&t);
        t.copy(&xp[10]);
        xp[3].copy(&t);

        let mut j = 3;
        let mut m = 8;
        let nw = n - bw;
        let mut r = FP::new();

        while 2 * m < nw {
            t.copy(&xp[j]);
            j += 1;
            for _ in 0..m {
                t.sqr();
            }
            r.copy(&xp[j - 1]);
            r.mul(&t);
            xp[j].copy(&r);
            m *= 2;
        }
        let mut lo = nw - m;
        r.copy(&xp[j]);

        while lo != 0 {
            m /= 2;
            j -= 1;
            if lo < m {
                continue;
            }
            lo -= m;
            t.copy(&r);
            for _ in 0..m {
                t.sqr();
            }
            r.copy(&t);
            r.mul(&xp[j]);
        }
        // phase 3
        if bw != 0 {
            for _ in 0..bw {
                r.sqr();
            }
            r.mul(&key);
        }
        if MODTYPE == ModType::GENERALISED_MERSENNE {
            // Goldilocks ONLY
            key.copy(&r);
            r.sqr();
            r.mul(&self);
            for _ in 0..n + 1 {
                r.sqr();
            }
            r.mul(&key);
        }
        return r;
    }
    /* self=1/self mod Modulus */
    pub fn inverse(&mut self) {
        if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
            let mut y = self.fpow();
            if MOD8 == 5 {
                let mut t = FP::new_copy(self);
                t.sqr();
                self.mul(&t);
                y.sqr();
            }
            y.sqr();
            y.sqr();
            self.mul(&y);
        } else {
            let mut m2 = BIG::new_ints(&rom::MODULUS);
            m2.dec(2);
            m2.norm();
            let inv = self.pow(&mut m2);
            self.copy(&inv);
        }
    }

    /* return TRUE if self==a */
    pub fn equals(&self, a: &FP) -> bool {
        let mut f = FP::new_copy(self);
        let mut s = FP::new_copy(a);
        f.reduce();
        s.reduce();
        if BIG::comp(&(f.x), &(s.x)) == 0 {
            return true;
        }
        return false;
    }

    /* return self^e mod Modulus */
    pub fn pow(&mut self, e: &mut BIG) -> FP {
        let mut tb: [FP; 16] = [
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
            FP::new(),
        ];
        const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 3) / 4;
        let mut w: [i8; CT] = [0; CT];

        self.norm();
        let mut t = BIG::new_copy(e);
        t.norm();
        let nb = 1 + (t.nbits() + 3) / 4;

        for i in 0..nb {
            let lsbs = t.lastbits(4);
            t.dec(lsbs);
            t.norm();
            w[i] = lsbs as i8;
            t.fshr(4);
        }
        tb[0].one();
        tb[1].copy(&self);

        let mut c = FP::new();
        for i in 2..16 {
            c.copy(&tb[i - 1]);
            tb[i].copy(&c);
            tb[i].mul(&self);
        }
        let mut r = FP::new_copy(&tb[w[nb - 1] as usize]);
        for i in (0..nb - 1).rev() {
            r.sqr();
            r.sqr();
            r.sqr();
            r.sqr();
            r.mul(&tb[w[i] as usize])
        }
        r.reduce();
        return r;
    }

    /* return sqrt(this) mod Modulus */
    pub fn sqrt(&mut self) -> FP {
        self.reduce();

        if MOD8 == 5 {
            let v: FP;
            let mut i = FP::new_copy(self);
            i.x.shl(1);
            if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
                v = i.fpow();
            } else {
                let mut p = BIG::new_ints(&rom::MODULUS);
                p.dec(5);
                p.norm();
                p.shr(3);
                v = i.pow(&mut p);
            }
            i.mul(&v);
            i.mul(&v);
            i.x.dec(1);
            let mut r = FP::new_copy(self);
            r.mul(&v);
            r.mul(&i);
            r.reduce();
            return r;
        } else {
            let mut r: FP;
            if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
                r = self.fpow();
                r.mul(self);
            } else {
                let mut p = BIG::new_ints(&rom::MODULUS);
                p.inc(1);
                p.norm();
                p.shr(2);
                r = self.pow(&mut p);
            }
            return r;
        }
    }
    /* return jacobi symbol (this/Modulus) */
    pub fn jacobi(&mut self) -> isize {
        let mut p = BIG::new_ints(&rom::MODULUS);
        let mut w = self.redc();
        return w.jacobi(&mut p);
    }
}
