/*
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
if debug {println!("sf2= {}",self.tostring())}
  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::dbig::DBIG;
use super::big::BIG;
use super::super::arch::Chunk;
use rand::RAND;

use super::super::arch::DChunk;

/* Finite field support - for RSA, DH etc. */
/* RSA/DH modulus length as multiple of BIGBITS */

pub use super::rom::FFLEN;
use std::str::SplitWhitespace;

pub const FF_BITS: usize = (big::BIGBITS * FFLEN); /* Finite Field Size in bits - must be 256.2^n */
pub const HFLEN: usize = (FFLEN / 2); /* Useful for half-size RSA private key operations */

pub const P_MBITS: usize = (big::MODBYTES as usize) * 8;
pub const P_OMASK: Chunk = ((-1) << (P_MBITS % big::BASEBITS));
pub const P_FEXCESS: Chunk = (1 << (big::BASEBITS * big::NLEN - P_MBITS - 1));
pub const P_TBITS: usize = (P_MBITS % big::BASEBITS);

pub struct FF {
    v: Vec<BIG>,
    length: usize,
}

impl FF {
    pub fn excess(a: &BIG) -> Chunk {
        return ((a.w[big::NLEN - 1] & P_OMASK) >> (P_TBITS)) + 1;
    }

    pub fn pexceed(a: &BIG, b: &BIG) -> bool {
        let ea = FF::excess(a);
        let eb = FF::excess(b);
        if ((ea + 1) as DChunk) * ((eb + 1) as DChunk) > P_FEXCESS as DChunk {
            return true;
        }
        return false;
    }

    pub fn sexceed(a: &BIG) -> bool {
        let ea = FF::excess(a);
        if ((ea + 1) as DChunk) * ((ea + 1) as DChunk) > P_FEXCESS as DChunk {
            return true;
        }
        return false;
    }

    /* Constructors */
    pub fn new_int(n: usize) -> FF {
        let mut f = FF {
            v: Vec::new(),
            length: 0,
        };
        for _ in 0..n {
            f.v.push(BIG::new());
        }
        f.length = n;
        return f;
    }

    pub fn zero(&mut self) {
        for i in 0..self.length {
            self.v[i].zero();
        }
    }

    pub fn getlen(&self) -> usize {
        return self.length;
    }

    /* set to integer */
    pub fn set(&mut self, m: isize) {
        self.zero();
        self.v[0].set(0, m as Chunk);
    }

    /* copy from FF b */
    pub fn copy(&mut self, b: &FF) {
        for i in 0..self.length {
            self.v[i].copy(&b.v[i]);
        }
    }

    /* x=y<<n */
    pub fn dsucopy(&mut self, b: &FF) {
        for i in 0..b.length {
            self.v[b.length + i].copy(&b.v[i]);
            self.v[i].zero();
        }
    }

    /* x=y */
    pub fn dscopy(&mut self, b: &FF) {
        for i in 0..b.length {
            self.v[i].copy(&b.v[i]);
            self.v[b.length + i].zero();
        }
    }

    /* x=y>>n */
    pub fn sducopy(&mut self, b: &FF) {
        for i in 0..self.length {
            self.v[i].copy(&b.v[self.length + i]);
        }
    }

    pub fn one(&mut self) {
        self.v[0].one();
        for i in 1..self.length {
            self.v[i].zero();
        }
    }

    /* test equals 0 */
    pub fn iszilch(&mut self) -> bool {
        for i in 0..self.length {
            if !self.v[i].iszilch() {
                return false;
            }
        }
        return true;
    }

    /* shift right by BIGBITS-bit words */
    pub fn shrw(&mut self, n: usize) {
        let mut t = BIG::new();
        for i in 0..n {
            t.copy(&self.v[i + n]);
            self.v[i].copy(&t);
            self.v[i + n].zero();
        }
    }

    /* shift left by BIGBITS-bit words */
    pub fn shlw(&mut self, n: usize) {
        let mut t = BIG::new();
        for i in 0..n {
            t.copy(&self.v[i]);
            self.v[n + i].copy(&t);
            self.v[i].zero();
        }
    }

    /* extract last bit */
    pub fn parity(&self) -> isize {
        return self.v[0].parity();
    }

    pub fn lastbits(&mut self, m: usize) -> isize {
        return self.v[0].lastbits(m);
    }

    /* compare x and y - must be normalised, and of same length */
    pub fn comp(a: &FF, b: &FF) -> isize {
        let mut i = a.length - 1;

        loop {
            let j = BIG::comp(&a.v[i], &b.v[i]);
            if j != 0 {
                return j;
            }
            if i == 0 {
                break;
            }
            i -= 1;
        }
        return 0;
    }

    /* recursive add */
    pub fn radd(&mut self, vp: usize, x: &FF, xp: usize, y: &FF, yp: usize, n: usize) {
        for i in 0..n {
            self.v[vp + i].copy(&x.v[xp + i]);
            self.v[vp + i].add(&y.v[yp + i]);
        }
    }

    /* recursive inc */
    pub fn rinc(&mut self, vp: usize, y: &FF, yp: usize, n: usize) {
        for i in 0..n {
            self.v[vp + i].add(&y.v[yp + i]);
        }
    }

    pub fn rsinc(&mut self, n: usize) {
        let mut t = BIG::new();
        for i in 0..n {
            t.copy(&self.v[i]);
            self.v[n + i].add(&t);
        }
    }

    /* recursive sub */
    pub fn rsub(&mut self, vp: usize, x: &FF, xp: usize, y: &FF, yp: usize, n: usize) {
        for i in 0..n {
            self.v[vp + i].copy(&x.v[xp + i]);
            self.v[vp + i].sub(&y.v[yp + i]);
        }
    }

    /* recursive dec */
    pub fn rdec(&mut self, vp: usize, y: &FF, yp: usize, n: usize) {
        for i in 0..n {
            self.v[vp + i].sub(&y.v[yp + i]);
        }
    }

    /* simple add */
    pub fn add(&mut self, b: &FF) {
        for i in 0..self.length {
            self.v[i].add(&b.v[i]);
        }
    }

    /* simple sub */
    pub fn sub(&mut self, b: &FF) {
        for i in 0..self.length {
            self.v[i].sub(&b.v[i]);
        }
    }

    /* reverse sub */
    pub fn revsub(&mut self, b: &FF) {
        for i in 0..self.length {
            self.v[i].rsub(&b.v[i]);
        }
    }

    /* normalise - but hold any overflow in top part unless n<0 */
    pub fn rnorm(&mut self, vp: usize, n: isize) {
        let mut trunc = false;
        let mut carry: Chunk;
        let mut nn: usize = n as usize;
        if n < 0 {
            /* -v n signals to do truncation */
            nn = (-n) as usize;
            trunc = true;
        }
        for i in 0..nn - 1 {
            carry = self.v[vp + i].norm();
            self.v[vp + i].xortop(carry << P_TBITS);
            self.v[vp + i + 1].w[0] += carry;
        }
        carry = self.v[vp + nn - 1].norm();
        if trunc {
            self.v[vp + nn - 1].xortop(carry << P_TBITS);
        }
    }

    pub fn norm(&mut self) {
        let n: isize = self.length as isize;
        self.rnorm(0, n);
    }

    /* increment/decrement by a small integer */
    pub fn inc(&mut self, m: isize) {
        self.v[0].inc(m);
        self.norm();
    }

    pub fn dec(&mut self, m: isize) {
        self.v[0].dec(m);
        self.norm();
    }

    /* shift left by one bit */
    pub fn shl(&mut self) {
        let mut delay_carry: isize = 0;
        for i in 0..self.length - 1 {
            let carry = self.v[i].fshl(1);
            self.v[i].inc(delay_carry);
            self.v[i].xortop((carry as Chunk) << P_TBITS);
            delay_carry = carry;
        }
        self.v[self.length - 1].fshl(1);
        self.v[self.length - 1].inc(delay_carry);
    }

    /* shift right by one bit */

    pub fn shr(&mut self) {
        let mut i = self.length - 1;
        while i > 0 {
            let carry = self.v[i].fshr(1);
            self.v[i - 1].xortop((carry as Chunk) << P_TBITS);
            i -= 1;
        }
        self.v[0].fshr(1);
    }

    /* Convert to Hex String */
    pub fn tostring(&mut self) -> String {
        self.norm();
        let mut s = String::new();
        let mut i: usize = self.length - 1;
        loop {
            s = s + self.v[i].tostring().as_ref();
            if i == 0 {
                break;
            }
            i -= 1;
        }
        return s;
    }

    /* Convert FFs to/from byte arrays */
    pub fn tobytes(&mut self, b: &mut [u8]) {
        for i in 0..self.length {
            self.v[i].tobytearray(b, (self.length - i - 1) * (big::MODBYTES as usize))
        }
    }

    pub fn frombytes(x: &mut FF, b: &[u8]) {
        for i in 0..x.length {
            x.v[i] = BIG::frombytearray(b, (x.length - i - 1) * (big::MODBYTES as usize))
        }
    }

    /* in-place swapping using xor - side channel resistant - lengths must be the same */
    pub fn cswap(a: &mut FF, b: &mut FF, d: isize) {
        for i in 0..a.length {
            a.v[i].cswap(&mut b.v[i], d);
        }
    }

    /* z=x*y, t is workspace */
    fn karmul(
        &mut self,
        vp: usize,
        x: &FF,
        xp: usize,
        y: &FF,
        yp: usize,
        t: *mut FF,
        tp: usize,
        n: usize,
    ) {
        if n == 1 {
            let xx = BIG::new_copy(&x.v[xp]);
            let yy = BIG::new_copy(&y.v[yp]);
            let mut d = BIG::mul(&xx, &yy);
            self.v[vp + 1] = d.split(8 * big::MODBYTES);
            self.v[vp].dcopy(&d);
            return;
        }
        let nd2 = n / 2;
        self.radd(vp, x, xp, x, xp + nd2, nd2);
        self.rnorm(vp, nd2 as isize); /* Important - required for 32-bit build */
        self.radd(vp + nd2, y, yp, y, yp + nd2, nd2);
        self.rnorm(vp + nd2, nd2 as isize); /* Important - required for 32-bit build */
        unsafe {
            (*t).karmul(tp, self, vp, self, vp + nd2, t, tp + n, nd2);
        }
        self.karmul(vp, x, xp, y, yp, t, tp + n, nd2);
        self.karmul(vp + n, x, xp + nd2, y, yp + nd2, t, tp + n, nd2);
        unsafe {
            (*t).rdec(tp, self, vp, n);
            (*t).rdec(tp, self, vp + n, n);
            self.rinc(vp + nd2, &(*t), tp, n);
        }
        self.rnorm(vp, (2 * n) as isize);
    }

    fn karsqr(&mut self, vp: usize, x: &FF, xp: usize, t: *mut FF, tp: usize, n: usize) {
        if n == 1 {
            let xx = BIG::new_copy(&x.v[xp]);
            let mut d = BIG::sqr(&xx);
            self.v[vp + 1].copy(&d.split(8 * big::MODBYTES));
            self.v[vp].dcopy(&d);
            return;
        }

        let nd2 = n / 2;
        self.karsqr(vp, x, xp, t, tp + n, nd2);
        self.karsqr(vp + n, x, xp + nd2, t, tp + n, nd2);
        unsafe {
            (*t).karmul(tp, x, xp, x, xp + nd2, t, tp + n, nd2);
            self.rinc(vp + nd2, &(*t), tp, n);
            self.rinc(vp + nd2, &(*t), tp, n);
        }
        self.rnorm(vp + nd2, n as isize);
    }

    /* Calculates Least Significant bottom half of x*y */
    fn karmul_lower(
        &mut self,
        vp: usize,
        x: &FF,
        xp: usize,
        y: &FF,
        yp: usize,
        t: *mut FF,
        tp: usize,
        n: usize,
    ) {
        if n == 1 {
            /* only calculate bottom half of product */
            self.v[vp].copy(&BIG::smul(&x.v[xp], &y.v[yp]));
            return;
        }
        let nd2 = n / 2;

        self.karmul(vp, x, xp, y, yp, t, tp + n, nd2);
        unsafe {
            (*t).karmul_lower(tp, x, xp + nd2, y, yp, t, tp + n, nd2);
            self.rinc(vp + nd2, &(*t), tp, nd2);
            (*t).karmul_lower(tp, x, xp, y, yp + nd2, t, tp + n, nd2);
            self.rinc(vp + nd2, &(*t), tp, nd2);
        }
        let sn: isize = nd2 as isize;
        self.rnorm(vp + nd2, -sn); /* truncate it */
    }

    /* Calculates Most Significant upper half of x*y, given lower part */
    fn karmul_upper(&mut self, x: &FF, y: &FF, t: *mut FF, n: usize) {
        let nd2 = n / 2;
        self.radd(n, x, 0, x, nd2, nd2);
        self.radd(n + nd2, y, 0, y, nd2, nd2);
        self.rnorm(n, nd2 as isize);
        self.rnorm(n + nd2, nd2 as isize);

        unsafe {
            (*t).karmul(0, self, n + nd2, self, n, t, n, nd2); /* t = (a0+a1)(b0+b1) */
        }
        self.karmul(n, x, nd2, y, nd2, t, n, nd2); /* z[n]= a1*b1 */
        /* z[0-nd2]=l(a0b0) z[nd2-n]= h(a0b0)+l(t)-l(a0b0)-l(a1b1) */
        unsafe {
            (*t).rdec(0, self, n, n); /* t=t-a1b1  */

            self.rsinc(nd2); /* z[nd2-n]+=l(a0b0) = h(a0b0)+l(t)-l(a1b1)  */
            self.rdec(nd2, &(*t), 0, nd2); /* z[nd2-n]=h(a0b0)+l(t)-l(a1b1)-l(t-a1b1)=h(a0b0) */
        }

        let sn: isize = n as isize;
        self.rnorm(0, -sn); /* a0b0 now in z - truncate it */
        unsafe {
            (*t).rdec(0, self, 0, n); /* (a0+a1)(b0+b1) - a0b0 */
            self.rinc(nd2, &(*t), 0, n);
        }
        self.rnorm(nd2, sn);
    }

    /* z=x*y. Assumes x and y are of same length. */
    pub fn mul(x: &FF, y: &FF) -> FF {
        let n = x.length;
        let mut z = FF::new_int(2 * n);
        let mut t = FF::new_int(2 * n);
        z.karmul(0, &x, 0, &y, 0, &mut t, 0, n);
        return z;
    }

    /* return low part of product this*y */
    pub fn lmul(&mut self, y: &FF) {
        let n = self.length;
        let mut t = FF::new_int(2 * n);
        let mut x = FF::new_int(n);
        x.copy(&self);
        self.karmul_lower(0, &x, 0, &y, 0, &mut t, 0, n);
    }

    /* Set b=b mod c */
    pub fn rmod(&mut self, m: &FF) {
        let mut k = 1;
        let n = m.length;
        let mut c = FF::new_int(n);
        c.copy(m);

        self.norm();
        if FF::comp(&self, &c) < 0 {
            return;
        }

        c.shl();
        while FF::comp(&self, &c) >= 0 {
            c.shl();
            k += 1;
        }

        while k > 0 {
            c.shr();
            if FF::comp(&self, &c) >= 0 {
                self.sub(&c);
                self.norm();
            }
            k -= 1;
        }
    }

    /* z=x^2 */
    pub fn sqr(x: &FF) -> FF {
        let n = x.length;
        let mut z = FF::new_int(2 * n);
        let mut t = FF::new_int(2 * n);
        z.karsqr(0, &x, 0, &mut t, 0, n);
        return z;
    }

    /* return This mod modulus, ms is modulus, md is Montgomery Constant */
    pub fn reduce(&mut self, ms: &FF, md: &FF) -> FF {
        /* fast karatsuba Montgomery reduction */
        let n = ms.length;
        let mut t = FF::new_int(2 * n);
        let mut r = FF::new_int(n);
        let mut m = FF::new_int(n);

        r.sducopy(&self);
        m.karmul_lower(0, &self, 0, &md, 0, &mut t, 0, n);
        self.karmul_upper(&ms, &m, &mut t, n);

        m.sducopy(self);
        r.add(&ms);
        r.sub(&m);
        r.norm();

        return r;
    }

    /* Set r=this mod b */
    /* this is of length - 2*n */
    /* r,b is of length - n */
    pub fn dmod(&mut self, b: &FF) -> FF {
        let n = b.length;
        let mut m = FF::new_int(2 * n);
        let mut x = FF::new_int(2 * n);
        let mut r = FF::new_int(n);

        x.copy(&self);
        x.norm();
        m.dsucopy(&b);
        let mut k = big::BIGBITS * n;

        while FF::comp(&x, &m) >= 0 {
            x.sub(&m);
            x.norm();
        }

        while k > 0 {
            m.shr();

            if FF::comp(&x, &m) >= 0 {
                x.sub(&m);
                x.norm();
            }
            k -= 1;
        }

        r.copy(&x);
        r.rmod(b);
        return r;
    }

    /* Set return=1/this mod p. Binary method - a<p on entry */

    pub fn invmodp(&mut self, p: &FF) {
        let n = p.length;

        let mut u = FF::new_int(n);
        let mut v = FF::new_int(n);
        let mut x1 = FF::new_int(n);
        let mut x2 = FF::new_int(n);
        let mut t = FF::new_int(n);
        let mut one = FF::new_int(n);

        one.one();
        u.copy(&self);
        v.copy(&p);
        x1.copy(&one);
        x2.zero();

        // reduce n in here as well!
        while FF::comp(&u, &one) != 0 && FF::comp(&v, &one) != 0 {
            while u.parity() == 0 {
                u.shr();
                if x1.parity() != 0 {
                    x1.add(&p);
                    x1.norm();
                }
                x1.shr();
            }
            while v.parity() == 0 {
                v.shr();
                if x2.parity() != 0 {
                    x2.add(&p);
                    x2.norm();
                }
                x2.shr();
            }
            if FF::comp(&u, &v) >= 0 {
                u.sub(&v);
                u.norm();
                if FF::comp(&x1, &x2) >= 0 {
                    x1.sub(&x2);
                } else {
                    t.copy(&p);
                    t.sub(&x2);
                    x1.add(&t);
                }
                x1.norm();
            } else {
                v.sub(&u);
                v.norm();
                if FF::comp(&x2, &x1) >= 0 {
                    x2.sub(&x1);
                } else {
                    t.copy(&p);
                    t.sub(&x1);
                    x2.add(&t);
                }
                x2.norm();
            }
        }
        if FF::comp(&u, &one) == 0 {
            self.copy(&x1);
        } else {
            self.copy(&x2);
        }
    }

    /* nresidue mod m */
    pub fn nres(&mut self, m: &FF) {
        let n = m.length;
        if n == 1 {
            let mut d = DBIG::new_scopy(&(self.v[0]));
            d.shl(big::NLEN * (big::BASEBITS as usize));
            self.v[0].copy(&d.dmod(&(m.v[0])));
        } else {
            let mut d = FF::new_int(2 * n);
            d.dsucopy(&self);
            self.copy(&d.dmod(m));
        }
    }

    pub fn redc(&mut self, m: &FF, md: &FF) {
        let n = m.length;
        if n == 1 {
            let mut d = DBIG::new_scopy(&(self.v[0]));
            self.v[0].copy(&BIG::monty(
                &(m.v[0]),
                ((1 as Chunk) << big::BASEBITS) - md.v[0].w[0],
                &mut d,
            ));
        } else {
            let mut d = FF::new_int(2 * n);
            self.rmod(m);
            d.dscopy(&self);
            self.copy(&d.reduce(&m, &md));
            self.rmod(m);
        }
    }

    pub fn mod2m(&mut self, m: usize) {
        for i in m..self.length {
            self.v[i].zero()
        }
    }

    /* U=1/a mod 2^m - Arazi & Qi */
    pub fn invmod2m(&self) -> FF {
        let n = self.length;

        let mut b = FF::new_int(n);
        let mut c = FF::new_int(n);
        let mut u = FF::new_int(n);

        u.zero();
        u.v[0].copy(&self.v[0]);
        u.v[0].invmod2m();

        let mut i = 1;
        while i < n {
            b.copy(&self);
            b.mod2m(i);
            let mut t = FF::mul(&u, &b);
            t.shrw(i);
            b.copy(&t);
            c.copy(&self);
            c.shrw(i);
            c.mod2m(i);
            c.lmul(&u);
            c.mod2m(i);

            b.add(&c);
            b.norm();
            b.lmul(&u);
            b.mod2m(i);

            c.one();
            c.shlw(i);
            b.revsub(&c);
            b.norm();
            b.shlw(i);
            u.add(&b);
            i <<= 1;
        }
        u.norm();
        return u;
    }

    pub fn random(&mut self, rng: &mut RAND) {
        let n = self.length;
        for i in 0..n {
            self.v[i].copy(&BIG::random(rng))
        }
        /* make sure top bit is 1 */
        while self.v[n - 1].nbits() < (big::MODBYTES as usize) * 8 {
            self.v[n - 1].copy(&BIG::random(rng));
        }
    }

    /* generate random x less than p */
    pub fn randomnum(&mut self, p: &FF, rng: &mut RAND) {
        let n = self.length;
        let mut d = FF::new_int(2 * n);

        for i in 0..2 * n {
            d.v[i].copy(&BIG::random(rng));
        }
        self.copy(&d.dmod(p));
    }

    /* this*=y mod p */
    pub fn modmul(&mut self, y: &FF, p: &FF, nd: &FF) {
        if FF::pexceed(&self.v[self.length - 1], &y.v[y.length - 1]) {
            self.rmod(p)
        }
        let n = p.length;
        if n == 1 {
            let mut d = BIG::mul(&self.v[0], &y.v[0]);
            self.v[0].copy(&BIG::monty(
                &(p.v[0]),
                ((1 as Chunk) << big::BASEBITS) - nd.v[0].w[0],
                &mut d,
            ));
        } else {
            let mut d = FF::mul(&self, y);
            self.copy(&d.reduce(p, nd));
        }
    }

    /* this*=y mod p */
    pub fn modsqr(&mut self, p: &FF, nd: &FF) {
        if FF::sexceed(&self.v[self.length - 1]) {
            self.rmod(p);
        }
        let n = p.length;
        if n == 1 {
            let mut d = BIG::sqr(&self.v[0]);
            self.v[0].copy(&BIG::monty(
                &(p.v[0]),
                ((1 as Chunk) << big::BASEBITS) - nd.v[0].w[0],
                &mut d,
            ));
        } else {
            let mut d = FF::sqr(&self);
            d.norm();
            self.copy(&d.reduce(p, nd));
        }
    }

    /* this=this^e mod p using side-channel resistant Montgomery Ladder, for large e */
    pub fn skpow(&mut self, e: &FF, p: &FF) {
        let n = p.length;
        let mut r0 = FF::new_int(n);
        let mut r1 = FF::new_int(n);
        let nd = p.invmod2m();

        self.rmod(p);
        r0.one();
        r1.copy(&self);
        r0.nres(p);
        r1.nres(p);

        let mut i = 8 * (big::MODBYTES as usize) * n - 1;
        loop {
            let b = (e.v[i / (big::BIGBITS as usize)]).bit(i % (big::BIGBITS as usize)) as isize;
            self.copy(&r0);
            self.modmul(&r1, p, &nd);

            FF::cswap(&mut r0, &mut r1, b);
            r0.modsqr(p, &nd);

            r1.copy(&self);
            FF::cswap(&mut r0, &mut r1, b);
            if i == 0 {
                break;
            }
            i -= 1;
        }
        self.copy(&r0);
        self.redc(p, &nd);
    }

    /* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */
    pub fn skpows(&mut self, e: &BIG, p: &FF) {
        let n = p.length;
        let mut r0 = FF::new_int(n);
        let mut r1 = FF::new_int(n);
        let nd = p.invmod2m();

        self.rmod(p);
        r0.one();
        r1.copy(&self);
        r0.nres(p);
        r1.nres(p);

        let mut i = 8 * (big::MODBYTES as usize) - 1;
        loop {
            let b = e.bit(i);
            self.copy(&r0);
            self.modmul(&r1, p, &nd);

            FF::cswap(&mut r0, &mut r1, b);
            r0.modsqr(p, &nd);

            r1.copy(&self);
            FF::cswap(&mut r0, &mut r1, b);
            if i == 0 {
                break;
            }
            i -= 1;
        }
        self.copy(&r0);
        self.redc(p, &nd);
    }

    /* raise to an integer power - right-to-left method */
    pub fn power(&mut self, e: isize, p: &FF) {
        let n = p.length;
        let mut w = FF::new_int(n);
        let nd = p.invmod2m();
        let mut f = true;
        let mut ee = e;

        w.copy(&self);
        w.nres(p);

        if ee == 2 {
            self.copy(&w);
            self.modsqr(p, &nd);
        } else {
            loop {
                if ee % 2 == 1 {
                    if f {
                        self.copy(&w);
                    } else {
                        self.modmul(&w, p, &nd)
                    }
                    f = false;
                }
                ee >>= 1;
                if ee == 0 {
                    break;
                }
                w.modsqr(p, &nd);
            }
        }

        self.redc(p, &nd);
    }

    /* this=this^e mod p, faster but not side channel resistant */
    pub fn pow(&mut self, e: &FF, p: &FF) {
        let n = p.length;
        let mut w = FF::new_int(n);
        let nd = p.invmod2m();

        w.copy(&self);
        self.one();
        self.nres(p);
        w.nres(p);
        let mut i = 8 * (big::MODBYTES as usize) * n - 1;
        loop {
            self.modsqr(p, &nd);
            let b = (e.v[i / (big::BIGBITS as usize)]).bit(i % (big::BIGBITS as usize)) as isize;
            if b == 1 {
                self.modmul(&w, p, &nd)
            }
            if i == 0 {
                break;
            }
            i -= 1;
        }
        self.redc(p, &nd);
    }

    /* double exponentiation r=x^e.y^f mod p */
    pub fn pow2(&mut self, e: &BIG, y: &FF, f: &BIG, p: &FF) {
        let n = p.length;
        let mut xn = FF::new_int(n);
        let mut yn = FF::new_int(n);
        let mut xy = FF::new_int(n);
        let nd = p.invmod2m();

        xn.copy(&self);
        yn.copy(y);
        xn.nres(p);
        yn.nres(p);
        xy.copy(&xn);
        xy.modmul(&yn, p, &nd);
        self.one();
        self.nres(p);

        let mut i = 8 * (big::MODBYTES as usize) - 1;
        loop {
            let eb = e.bit(i);
            let fb = f.bit(i);
            self.modsqr(p, &nd);
            if eb == 1 {
                if fb == 1 {
                    self.modmul(&xy, p, &nd);
                } else {
                    self.modmul(&xn, p, &nd)
                }
            } else {
                if fb == 1 {
                    self.modmul(&yn, p, &nd)
                }
            }
            if i == 0 {
                break;
            }
            i -= 1;
        }
        self.redc(p, &nd);
    }

    pub fn igcd(x: isize, y: isize) -> isize {
        /* integer GCD, returns GCD of x and y */

        if y == 0 {
            return x;
        }
        let mut xx = x;
        let mut yy = y;
        loop {
            let r = xx % yy;
            if r == 0 {
                break;
            }
            xx = yy;
            yy = r;
        }
        return yy;
    }

    /* quick and dirty check for common factor with n */
    pub fn cfactor(&self, s: isize) -> bool {
        let n = self.length;

        let mut x = FF::new_int(n);
        let mut y = FF::new_int(n);

        y.set(s);
        x.copy(&self);
        x.norm();

        x.sub(&y);
        x.norm();

        while !x.iszilch() && x.parity() == 0 {
            x.shr()
        }

        while FF::comp(&x, &y) > 0 {
            x.sub(&y);
            x.norm();
            while !x.iszilch() && x.parity() == 0 {
                x.shr()
            }
        }

        let g = x.v[0].get(0) as isize;
        let r = FF::igcd(s, g);
        if r > 1 {
            return true;
        }
        return false;
    }

    /* Miller-Rabin test for primality. Slow. */
    pub fn prime(pp: &FF, rng: &mut RAND) -> bool {
        let mut s = 0;
        let n = pp.length;
        let mut d = FF::new_int(n);
        let mut x = FF::new_int(n);
        let mut unity = FF::new_int(n);
        let mut nm1 = FF::new_int(n);
        let mut p = FF::new_int(n);
        p.copy(pp);

        let sf = 4849845; /* 3*5*.. *19 */
        p.norm();

        if p.cfactor(sf) {
            return false;
        }
        unity.one();
        nm1.copy(&p);
        nm1.sub(&unity);
        nm1.norm();
        d.copy(&nm1);

        while d.parity() == 0 {
            d.shr();
            s += 1;
        }
        if s == 0 {
            return false;
        }
        for _ in 0..10 {
            x.randomnum(&p, rng);

            x.pow(&d, &p);

            if FF::comp(&x, &unity) == 0 || FF::comp(&x, &nm1) == 0 {
                continue;
            }
            let mut looper = false;
            for _ in 1..s {
                x.power(2, &p);
                if FF::comp(&x, &unity) == 0 {
                    return false;
                }
                if FF::comp(&x, &nm1) == 0 {
                    looper = true;
                    break;
                }
            }
            if looper {
                continue;
            }
            return false;
        }

        return true;
    }
}
