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

/* Finite Field arithmetic */
/* AMCL mod p functions */

var FP = function(ctx) {
    "use strict";

    /**
      * Creates an instance of FP.
      *
      * @constructor
      * @this {FP}
      * @param x FP / BIG instance
      */
    var FP = function(x) {
        if (x instanceof FP) {
            this.f = new ctx.BIG(x.f);
            this.XES = x.XES;
        } else {
            this.f = new ctx.BIG(x);
			this.XES = 1;
			if (!this.f.iszilch())
				this.nres();
        }
    };

    FP.NOT_SPECIAL = 0;
    FP.PSEUDO_MERSENNE = 1;
    FP.GENERALISED_MERSENNE = 2;
    FP.MONTGOMERY_FRIENDLY = 3;

	FP.ZERO = 0;
	FP.ONE = 1;
	FP.SPARSER = 2;
	FP.SPARSE = 3;
	FP.DENSE= 4;

    FP.MODBITS = ctx.config["@NBT"];
    FP.MOD8 = ctx.config["@M8"];
    FP.MODTYPE = ctx.config["@MT"];

    FP.FEXCESS = ((1 << ctx.config["@SH"])-1); // 2^(BASEBITS*NLEN-MODBITS)-1
    FP.OMASK = (-1) << FP.TBITS;
    FP.TBITS = FP.MODBITS % ctx.BIG.BASEBITS;
    FP.TMASK = (1 << FP.TBITS) - 1;

    FP.prototype = {
	
	/**
         * Set FP to zero
         *
         * @this {FP}
         */
        zero: function() {
            this.XES = 1;
            this.f.zero();
        },

	/**
         * copy from a ctx.BIG in ROM 
         *
         * @this {FP}
         * @param x FP instance to be copied
         */
        rcopy: function(y) {
            this.f.rcopy(y);
            this.nres();
        },

	/**
         * copy from another ctx.BIG 
         *
         * @this {FP}
         * @param x FP instance to be copied
         */
        bcopy: function(y) {
            this.f.copy(y);
            this.nres();
        },

	/**
         * Copy FP to another FP
         *
         * @this {FP}
         * @param x FP instance to be copied
         */
        copy: function(y) {
            this.XES = y.XES;
            this.f.copy(y.f);
        },

	/**
         * Conditional constant time swap of two FP numbers
         *
         * @this {BIG}
         * @parameter b FP number 
         * @parameter d Integer
         */		
        cswap: function(b, d) {
            this.f.cswap(b.f, d);
            var t, c = d;
            c = ~(c - 1);
            t = c & (this.XES ^ b.XES);
            this.XES ^= t;
            b.XES ^= t;
        },

	/**
         * Conditional copy of FP number
         *
         * @this {FP}
         * @param g FP instance
         * @param d copy depends on this value
         */
        cmove: function(b, d) {
            var c = d;

            c = ~(c - 1);

            this.f.cmove(b.f, d);
            this.XES ^= (this.XES ^ b.XES) & c;
        },

	/**
         * Converts from BIG integer to residue form mod Modulus
         *
         * @this {FP}
         */
        nres: function() {
            var r, d;

            if (FP.MODTYPE != FP.PSEUDO_MERSENNE && FP.MODTYPE != FP.GENERALISED_MERSENNE) {
                r = new ctx.BIG();
                r.rcopy(ctx.ROM_FIELD.R2modp);

                d = ctx.BIG.mul(this.f, r);
                this.f.copy(FP.mod(d));
                this.XES = 2;
            } else {
                this.XES = 1;
            }

            return this;
        },

	/**
         * Converts from residue form back to BIG integer form
         *
         * @this {FP}
         */
        redc: function() {
            var r = new ctx.BIG(0),
                d, w;

            r.copy(this.f);

            if (FP.MODTYPE != FP.PSEUDO_MERSENNE && FP.MODTYPE != FP.GENERALISED_MERSENNE) {
                d = new ctx.DBIG(0);
                d.hcopy(this.f);
                w = FP.mod(d);
                r.copy(w);
            }

            return r;
        },

	/**
         * convert to hex string
         *
         * @this {FP}
         */
        toString: function() {
            var s = this.redc().toString();
            return s;
        },

	/**
         * Tests for FP equal to zero
         *
         * @this {FP}
         */
        iszilch: function() {
			var c=new FP(0); c.copy(this);
            c.reduce();
            return c.f.iszilch();
        },

	/**
         * Reduces all components of possibly unreduced FP mod Modulus
         *
         * @this {FP}
         */
        reduce: function() {
            var q,carry,sr,sb,m = new ctx.BIG(0);
            m.rcopy(ctx.ROM_FIELD.Modulus);
			var r = new ctx.BIG(0);
            r.rcopy(ctx.ROM_FIELD.Modulus);
			this.f.norm();

			if (this.XES>16)
			{
				q=FP.quo(this.f,m);
				carry=r.pmul(q);
				r.w[ctx.BIG.NLEN-1]+=(carry<<ctx.BIG.BASEBITS); // correction - put any carry out back in again
				this.f.sub(r);
				this.f.norm();
				sb=2;
			}
			else {
					sb=FP.logb2(this.XES-1);
			}
			m.fshl(sb);

			while (sb>0)
			{
// constant time...
				sr=ctx.BIG.ssn(r,this.f,m);  // optimized combined shift, subtract and norm
				this.f.cmove(r,1-sr);
				sb--;
			}			

            this.XES = 1;
        },

	/**
         * Set FP to unity
         *
         * @this {FP}
         */
        one: function() {
            this.f.one();
            this.nres();
        },

	/**
         * Normalises the components of an FP
         *
         * @this {FP}
         */
        norm: function() {
            return this.f.norm();
        },

	/**
         * Fast Modular multiplication of two FPs, mod Modulus
         *
         * @this {FP}
         * @param b FP number, the multiplier
         */
        mul: function(b) {
            var d;

            if (this.XES * b.XES > FP.FEXCESS) {
                this.reduce();
            }

            d = ctx.BIG.mul(this.f, b.f);
            this.f.copy(FP.mod(d));
            this.XES = 2;

            return this;
        },

	/**
         * Multiplication of an FP by a small integer
         *
         * @this {FP}
         * @param s integer
         */
        imul: function(c) {
            var s = false,
                d, n;

            if (c < 0) {
                c = -c;
                s = true;
            }

            if (FP.MODTYPE == FP.PSEUDO_MERSENNE || FP.MODTYPE == FP.GENERALISED_MERSENNE) {
                d = this.f.pxmul(c);
                this.f.copy(FP.mod(d));
                this.XES = 2;
            } else {
                if (this.XES * c <= FP.FEXCESS) {
                    this.f.pmul(c);
                    this.XES *= c;
                } else {
                    n = new FP(c);
                    this.mul(n);
                }
            }

            if (s) {
                this.neg();
                this.norm();
            }
            return this;
        },

	/**
         * Fast Squaring of an FP
         *
         * @this {FP}
         */
        sqr: function() {
            var d, t;

            if (this.XES * this.XES > FP.FEXCESS) {
                this.reduce();
            }

            d = ctx.BIG.sqr(this.f);
            t = FP.mod(d);
            this.f.copy(t);
            this.XES = 2;

            return this;
        },

        /* this+=b */
        add: function(b) {
            this.f.add(b.f);
            this.XES += b.XES;

            if (this.XES > FP.FEXCESS) {
                this.reduce();
            }

            return this;
        },
	
	/**
         * negate this
         *
         * @this {FP}
         * @param x FP instance to be set to one
         */
        neg: function() {
            var m = new ctx.BIG(0),
                sb;

            m.rcopy(ctx.ROM_FIELD.Modulus);

            sb = FP.logb2(this.XES - 1);

            m.fshl(sb);
            this.XES = (1 << sb)+1;
            this.f.rsub(m);

            if (this.XES > FP.FEXCESS) {
                this.reduce();
            }

            return this;
        },

	/**
         * subtraction of two FPs
         *
         * @this {FP}
         * @param x FP instance
         */
        sub: function(b) {
            var n = new FP(0);

            n.copy(b);
            n.neg();
            this.add(n);

            return this;
        },

        rsub: function(b) {
            var n = new FP(0);

            n.copy(this);
            n.neg();
            this.copy(b);
            this.add(n);
        },

	/**
         * Divide an FP by 2
         *
         * @this {FP}
         */
        div2: function() {
            var p;

            if (this.f.parity() === 0) {
                this.f.fshr(1);
            } else {
                p = new ctx.BIG(0);
                p.rcopy(ctx.ROM_FIELD.Modulus);

                this.f.add(p);
                this.f.norm();
                this.f.fshr(1);
            }

            return this;
        },

// return this^(p-3)/4 or this^(p-5)/8
	// See https://eprint.iacr.org/2018/1038

	/**
         * return this^(p-3)/4 or this^(p-5)/8
         *
         * @this {FP}
         */	
	fpow: function() {
			var i,j,k,bw,w,c,nw,lo,m,n;
			var xp=[];
			var ac=[1,2,3,6,12,15,30,60,120,240,255];
// phase 1
			
			xp[0]=new FP(this);	// 1 
			xp[1]=new FP(this); xp[1].sqr(); // 2
			xp[2]=new FP(xp[1]); xp[2].mul(this);  //3
			xp[3]=new FP(xp[2]); xp[3].sqr();  // 6 
			xp[4]=new FP(xp[3]); xp[4].sqr();  // 12
			xp[5]=new FP(xp[4]); xp[5].mul(xp[2]);  // 15
			xp[6]=new FP(xp[5]); xp[6].sqr();  // 30
			xp[7]=new FP(xp[6]); xp[7].sqr();  // 60
			xp[8]=new FP(xp[7]); xp[8].sqr();  // 120
			xp[9]=new FP(xp[8]); xp[9].sqr();  // 240
			xp[10]=new FP(xp[9]); xp[10].mul(xp[5]);  // 255		
			

			n=FP.MODBITS;
			if (FP.MODTYPE == FP.GENERALISED_MERSENNE)   // Goldilocks ONLY
				n/=2;
			if (FP.MOD8==5)
			{
				n-=3;
				c=(ctx.ROM_FIELD.MConst+5)/8;
			} else {
				n-=2;
				c=(ctx.ROM_FIELD.MConst+3)/4;
			}

			bw=0; w=1; while (w<c) {w*=2; bw+=1;}
			k=w-c;

			i=10; var key=new FP(0);
			if (k!=0)
			{
				while (ac[i]>k) i--;
				key.copy(xp[i]); 
				k-=ac[i];
			}
			while (k!=0)
			{
				i--;
				if (ac[i]>k) continue;
				key.mul(xp[i]);
				k-=ac[i]; 
			}

// phase 2 
			xp[1].copy(xp[2]);
			xp[2].copy(xp[5]);
			xp[3].copy(xp[10]);
	
			j=3; m=8;
			nw=n-bw;
			var t=new FP(0);
			while (2*m<nw)
			{
				t.copy(xp[j++]);
				for (i=0;i<m;i++)
					t.sqr(); 
				xp[j].copy(xp[j-1]);
				xp[j].mul(t);
				m*=2;
			}
			lo=nw-m;
			var r=new FP(xp[j]);

			while (lo!=0)
			{
				m/=2; j--;
				if (lo<m) continue;
				lo-=m;
				t.copy(r);
				for (i=0;i<m;i++)
					t.sqr();
				r.copy(t);
				r.mul(xp[j]);
			}

// phase 3
			if (bw!=0)
			{
				for (i=0;i<bw;i++ )
					r.sqr();
				r.mul(key); 
			}

			if (FP.MODTYPE == FP.GENERALISED_MERSENNE)   // Goldilocks ONLY
			{
				key.copy(r);
				r.sqr();
				r.mul(this);
				for (i=0;i<n+1;i++)
					r.sqr();
				r.mul(key);
			}
			return r;
		},

	/**
         * Inverting an FP
         *
         * @this {FP}
         */
        inverse: function() {

			if (FP.MODTYPE == FP.PSEUDO_MERSENNE || FP.MODTYPE == FP.GENERALISED_MERSENNE)
			{
				var y=this.fpow();
				if (FP.MOD8==5)
				{
					var t=new FP(this);
					t.sqr();
					this.mul(t);
					y.sqr();

				} 
				y.sqr();
				y.sqr();
				this.mul(y);
				return this;
			} else {
				var m2=new ctx.BIG(0);
				m2.rcopy(ctx.ROM_FIELD.Modulus);
				m2.dec(2); m2.norm();
				this.copy(this.pow(m2));
				return this;
			}
        },

	/**
         * Tests for equality of two FP instances
         *
         * @this {FP}
         * @param x FP instance to compare
         */
        equals: function(a) {
			var ft=new FP(0); ft.copy(this);
			var sd=new FP(0); sd.copy(a);
            ft.reduce();
            sd.reduce();

            if (ctx.BIG.comp(ft.f, sd.f) === 0) {
                return true;
            }

            return false;
        },

	/**
         * Raises an FP to the power of a BIG
         *
         * @this {FP}
         * @param e BIG instance exponent
         */
        pow: function(e) {
            var i,w=[],
                tb=[],
                t=new ctx.BIG(e),
                nb, lsbs, r;
			this.norm();
            t.norm();
            nb= 1 + Math.floor((t.nbits() + 3) / 4);

            for (i=0;i<nb;i++) {
                lsbs=t.lastbits(4);
                t.dec(lsbs);
                t.norm();
                w[i]=lsbs;
                t.fshr(4);
            }
            tb[0]=new FP(1);
            tb[1]=new FP(this);
            for (i=2;i<16;i++) {
                tb[i]=new FP(tb[i-1]);
                tb[i].mul(this);
            }
            r=new FP(tb[w[nb-1]]);
            for (i=nb-2;i>=0;i--) {
                r.sqr();
                r.sqr();
                r.sqr();
                r.sqr();
                r.mul(tb[w[i]]);
            }
            r.reduce();
            return r;
        },

	/**
         * return jacobi symbol (this/Modulus)
         *
         * @this {FP}
         */
        jacobi: function() {
            var p = new ctx.BIG(0),
                w = this.redc();

            p.rcopy(ctx.ROM_FIELD.Modulus);

            return w.jacobi(p);
        },

	/**
         * Fast Modular square root of a an FP, mod Modulus
         *
         * @this {FP}
         */
        sqrt: function() {
            var i, v, r;

            this.reduce();
            if (FP.MOD8 == 5) {
                i = new FP(0);
                i.copy(this);
                i.f.shl(1);
				if (FP.MODTYPE == FP.PSEUDO_MERSENNE || FP.MODTYPE == FP.GENERALISED_MERSENNE) {
					v=i.fpow();
				} else {
					var b = new ctx.BIG(0);
					b.rcopy(ctx.ROM_FIELD.Modulus);
					b.dec(5);
					b.norm();
					b.shr(3);
					v = i.pow(b);
				}
                i.mul(v);
                i.mul(v);
                i.f.dec(1);
                r = new FP(0);
                r.copy(this);
                r.mul(v);
                r.mul(i);
                r.reduce();

                return r;
            } else {
				if (FP.MODTYPE == FP.PSEUDO_MERSENNE || FP.MODTYPE == FP.GENERALISED_MERSENNE) {
					var r=this.fpow();
					r.mul(this);
					return r;
				} else {
					var b = new ctx.BIG(0);
					b.rcopy(ctx.ROM_FIELD.Modulus);
					b.inc(1);
					b.norm();
					b.shr(2);
					return this.pow(b);
				}
            }
        }

    };

    FP.logb2 = function(v) {
        var r;

        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);
        r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;

        return r;
    };

	FP.quo = function(n,m) {
		var num,den,hb=ctx.BIG.CHUNK>>1;
		if (FP.TBITS<hb)
		{
			var sh=hb-FP.TBITS;
			num=(n.w[ctx.BIG.NLEN-1]<<sh)|(n.w[ctx.BIG.NLEN-2]>>(ctx.BIG.BASEBITS-sh));
			den=(m.w[ctx.BIG.NLEN-1]<<sh)|(m.w[ctx.BIG.NLEN-2]>>(ctx.BIG.BASEBITS-sh));
		} else {
			num=n.w[ctx.BIG.NLEN-1];
			den=m.w[ctx.BIG.NLEN-1];			
		}
		return Math.floor(num/(den+1))
	};

    /**
      * reduce a ctx.DBIG to a ctx.BIG using a "special" modulus 
      *
      * @this {FP}
      */    
    FP.mod = function(d) {
        var b = new ctx.BIG(0),
            i, t, v, tw, tt, lo, carry, m, dd;

        if (FP.MODTYPE == FP.PSEUDO_MERSENNE) {
            t = d.split(FP.MODBITS);
            b.hcopy(d);

            if (ctx.ROM_FIELD.MConst != 1) {
                v = t.pmul(ctx.ROM_FIELD.MConst);
            } else {
                v = 0;
            }

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

            tw = t.w[ctx.BIG.NLEN - 1];
            t.w[ctx.BIG.NLEN - 1] &= FP.TMASK;
            t.inc(ctx.ROM_FIELD.MConst * ((tw >> FP.TBITS) + (v << (ctx.BIG.BASEBITS - FP.TBITS))));
            //      b.add(t);
            t.norm();

            return t;
        }

        if (FP.MODTYPE == FP.MONTGOMERY_FRIENDLY) {
            for (i = 0; i < ctx.BIG.NLEN; i++) {
                d.w[ctx.BIG.NLEN + i] += d.muladd(d.w[i], ctx.ROM_FIELD.MConst - 1, d.w[i], ctx.BIG.NLEN + i - 1);
            }

            for (i = 0; i < ctx.BIG.NLEN; i++) {
                b.w[i] = d.w[ctx.BIG.NLEN + i];
            }

            b.norm();
        }

        if (FP.MODTYPE == FP.GENERALISED_MERSENNE) { // GoldiLocks Only
            t = d.split(FP.MODBITS);
            b.hcopy(d);
            b.add(t);
            dd = new ctx.DBIG(0);
            dd.hcopy(t);
            dd.shl(FP.MODBITS / 2);

            tt = dd.split(FP.MODBITS);
            lo = new ctx.BIG();
            lo.hcopy(dd);

            b.add(tt);
            b.add(lo);
            //b.norm();
            tt.shl(FP.MODBITS / 2);
            b.add(tt);

            carry = b.w[ctx.BIG.NLEN - 1] >> FP.TBITS;
            b.w[ctx.BIG.NLEN - 1] &= FP.TMASK;
            b.w[0] += carry;

            b.w[Math.floor(224 / ctx.BIG.BASEBITS)] += carry << (224 % ctx.BIG.BASEBITS);
            b.norm();
        }

        if (FP.MODTYPE == FP.NOT_SPECIAL) {
            m = new ctx.BIG(0);
            m.rcopy(ctx.ROM_FIELD.Modulus);

            b.copy(ctx.BIG.monty(m, ctx.ROM_FIELD.MConst, d));
        }

        return b;
    };

    return FP;
};

if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
    module.exports = {
        FP: FP
    };
}
