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

/* AMCL BIG number class */

/* General purpose Constructor */
var BIG = function(x) {
	this.w=new Array(ROM.NLEN);
	switch (typeof(x))
	{
	case "object":
		this.copy(x);
		break;
	case "number":
		this.zero();
		this.w[0]=x;
		break;
	default:
		this.zero();
	}
};

BIG.prototype={
/* set to zero */
	zero: function()
	{
		for (var i=0;i<ROM.NLEN;i++) this.w[i]=0;
		return this;
	},
/* set to one */
	one: function()
	{
		this.w[0]=1;
		for (var i=1;i<ROM.NLEN;i++) this.w[i]=0;
		return this;
	},

	get: function(i)
	{
		return this.w[i];
	},

	set: function(i,x)
	{
		this.w[i]=x;
	},
/* test for zero */
	iszilch: function()
	{
		for (var i=0;i<ROM.NLEN;i++)
			if (this.w[i]!==0) return false;
		return true;
	},
/* test for unity */
	isunity: function()
	{
		for (var i=1;i<ROM.NLEN;i++)
			if (this.w[i]!==0) return false;
		if (this.w[0]!=1) return false;
		return true;
	},

/* Conditional swap of two bigs depending on d using XOR - no branches */
	cswap: function(b,d)
	{
		var i;
		var t,c=d;
		c=~(c-1);

		for (i=0;i<ROM.NLEN;i++)
		{
			t=c&(this.w[i]^b.w[i]);
			this.w[i]^=t;
			b.w[i]^=t;
		}
	},

/* Conditional move of big depending on d using XOR - no branches */
	cmove: function(b,d)
	{
		var i;
		var t,c=d;
		c=~(c-1);

		for (i=0;i<ROM.NLEN;i++)
		{
			this.w[i]^=(this.w[i]^b.w[i])&c;
		}
	},

/* copy from another BIG */
	copy: function(y)
	{
		for (var i=0;i<ROM.NLEN;i++)
			this.w[i]=y.w[i];
		return this;
	},
/* copy from bottom half of DBIG */
	hcopy: function(y)
	{
		for (var i=0;i<ROM.NLEN;i++)
			this.w[i]=y.w[i];
		return this;
	},
/* copy from ROM */
	rcopy: function(y)
	{
		for (var i=0;i<ROM.NLEN;i++)
			this.w[i]=y[i];
		return this;
	},

	xortop: function(x)
	{
		this.w[ROM.NLEN-1]^=x;
	},

	ortop: function(x)
	{
		this.w[ROM.NLEN-1]|=x;
	},

/* normalise BIG - force all digits < 2^BASEBITS */
	norm: function()
	{
		var d,carry=0;
		for (var i=0;i<ROM.NLEN-1;i++)
		{
			d=this.w[i]+carry;
			this.w[i]=d&ROM.MASK;
			carry=d>>ROM.BASEBITS;
		}
		this.w[ROM.NLEN-1]=(this.w[ROM.NLEN-1]+carry);

		return (this.w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS));

	},
/* quick shift right by less than a word */
	fshr: function(k)
	{
		var r=this.w[0]&((1<<k)-1); /* shifted out part */
		for (var i=0;i<ROM.NLEN-1;i++)
			this.w[i]=(this.w[i]>>k)|((this.w[i+1]<<(ROM.BASEBITS-k))&ROM.MASK);
		this.w[ROM.NLEN-1]=this.w[ROM.NLEN-1]>>k;
		return r;
	},
/* General shift right by k bits */
	shr: function(k)
	{
		var n=k%ROM.BASEBITS;
		var m=Math.floor(k/ROM.BASEBITS);
		for (var i=0;i<ROM.NLEN-m-1;i++)
			this.w[i]=(this.w[m+i]>>n)|((this.w[m+i+1]<<(ROM.BASEBITS-n))&ROM.MASK);
		this.w[ROM.NLEN-m-1]=this.w[ROM.NLEN-1]>>n;
		for (i=ROM.NLEN-m;i<ROM.NLEN;i++) this.w[i]=0;
		return this;
	},
/* quick shift left by less than a word */
	fshl: function(k)
	{
		this.w[ROM.NLEN-1]=((this.w[ROM.NLEN-1]<<k))|(this.w[ROM.NLEN-2]>>(ROM.BASEBITS-k));
		for (var i=ROM.NLEN-2;i>0;i--)
			this.w[i]=((this.w[i]<<k)&ROM.MASK)|(this.w[i-1]>>(ROM.BASEBITS-k));
		this.w[0]=(this.w[0]<<k)&ROM.MASK;

		return (this.w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS)); /* return excess - only used in FF.java */
	},
/* General shift left by k bits */
	shl: function(k)
	{
		var i,n=k%ROM.BASEBITS;
		var m=Math.floor(k/ROM.BASEBITS);

		this.w[ROM.NLEN-1]=((this.w[ROM.NLEN-1-m]<<n))|(this.w[ROM.NLEN-m-2]>>(ROM.BASEBITS-n));
		for (i=ROM.NLEN-2;i>m;i--)
			this.w[i]=((this.w[i-m]<<n)&ROM.MASK)|(this.w[i-m-1]>>(ROM.BASEBITS-n));
		this.w[m]=(this.w[0]<<n)&ROM.MASK;
		for (i=0;i<m;i++) this.w[i]=0;
		return this;
	},
/* return length in bits */
	nbits: function()
	{
		var bts,k=ROM.NLEN-1;
		var c;
		this.norm();
		while (k>=0 && this.w[k]===0) k--;
		if (k<0) return 0;
		bts=ROM.BASEBITS*k;
		c=this.w[k];
		while (c!==0) {c=Math.floor(c/2); bts++;}
		return bts;
	},
/* convert this to string */
	toString: function()
	{
		var b;
		var s="";
		var len=this.nbits();
		if (len%4===0) len=Math.floor(len/4);
		else {len=Math.floor(len/4); len++;}
		if (len<ROM.MODBYTES*2) len=ROM.MODBYTES*2;
		for (var i=len-1;i>=0;i--)
		{
			b=new BIG(0);
			b.copy(this);
			b.shr(i*4);
			s+=(b.w[0]&15).toString(16);
		}
		return s;
	},
/* this+=y */
	add: function(y)
	{
		for (var i=0;i<ROM.NLEN;i++) this.w[i]+=y.w[i];
		return this;
	},
/* return this+x */
	plus: function(x)
	{
		var s=new BIG(0);
		for (var i=0;i<ROM.NLEN;i++)
			s.w[i]=this.w[i]+x.w[i];
		return s;
	},
/* this+=i, where i is int */
	inc: function(i)
	{
		this.norm();
		this.w[0]+=i;
		return this;
	},
/* this-=y */
	sub: function(y)
	{
		for (var i=0;i<ROM.NLEN;i++) this.w[i]-=y.w[i];
		return this;
	},

/* reverse subtract this=x-this */
	rsub: function(x)
	{
		for (var i=0;i<ROM.NLEN;i++)
			this.w[i]=x.w[i]-this.w[i];
		return this;
	},
/* this-=i, where i is int */
	dec: function(i)
	{
		this.norm();
		this.w[0]-=i;
		return this;
	},
/* return this-x */
	minus: function(x) {
		var d=new BIG(0);
		for (var i=0;i<ROM.NLEN;i++)
			d.w[i]=this.w[i]-x.w[i];
		return d;
	},
/* multiply by small integer */
	imul: function(c)
	{
		for (var i=0;i<ROM.NLEN;i++) this.w[i]*=c;
		return this;
	},
/* convert this BIG to byte array */
	tobytearray: function(b,n)
	{
		this.norm();
		var c=new BIG(0);
		c.copy(this);

		for (var i=ROM.MODBYTES-1;i>=0;i--)
		{
			b[i+n]=c.w[0]&0xff;
			c.fshr(8);
		}
		return this;
	},
/* convert this to byte array */
	toBytes: function(b)
	{
		this.tobytearray(b,0);
	},

/* set this[i]+=x*y+c, and return high part */
	muladd: function(x,y,c,i)
	{
		var prod=x*y+c+this.w[i];
		this.w[i]=prod&ROM.MASK;
		return ((prod-this.w[i])*ROM.MODINV);
	},
/* multiply by larger int */
	pmul: function(c)
	{
		var ak,carry=0;
		this.norm();
		for (var i=0;i<ROM.NLEN;i++)
		{
			ak=this.w[i];
			this.w[i]=0;
			carry=this.muladd(ak,c,carry,i);
		}
		return carry;
	},
/* multiply by still larger int - results requires a DBIG */
	pxmul: function(c)
	{
		var m=new DBIG(0);
		var carry=0;
		for (var j=0;j<ROM.NLEN;j++)
			carry=m.muladd(this.w[j],c,carry,j);
		m.w[ROM.NLEN]=carry;
		return m;
	},
/* divide by 4 */
	div3: function()
	{
		var ak,base,carry=0;
		this.norm();
		base=(1<<ROM.BASEBITS);
		for (var i=ROM.NLEN-1;i>=0;i--)
		{
			ak=(carry*base+this.w[i]);
			this.w[i]=Math.floor(ak/3);
			carry=ak%3;
		}
		return carry;
	},

/* set x = x mod 2^m */
	mod2m: function(m)
	{
		var i,wd,bt;
		var msk;
		wd=Math.floor(m/ROM.BASEBITS);
		bt=m%ROM.BASEBITS;
		msk=(1<<bt)-1;
		this.w[wd]&=msk;
		for (i=wd+1;i<ROM.NLEN;i++) this.w[i]=0;
	},

/* a=1/a mod 2^256. This is very fast! */
	invmod2m: function()
	{
		var U=new BIG(0);
		var b=new BIG(0);
		var c=new BIG(0);

		U.inc(BIG.invmod256(this.lastbits(8)));

		for (var i=8;i<256;i<<=1)
		{
			b.copy(this); b.mod2m(i);
			var t1=BIG.smul(U,b); t1.shr(i);
			c.copy(this); c.shr(i); c.mod2m(i);

			var t2=BIG.smul(U,c); t2.mod2m(i);
			t1.add(t2);
			b=BIG.smul(t1,U); t1.copy(b);
			t1.mod2m(i);

			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
			t1.shl(i);
			U.add(t1);
		}
		this.copy(U);
	},

/* reduce this mod m */
	mod: function(m)
	{
		var k=0;

		this.norm();
		if (BIG.comp(this,m)<0) return;
		do
		{
			m.fshl(1);
			k++;
		} while (BIG.comp(this,m)>=0);

		while (k>0)
		{
			m.fshr(1);
			if (BIG.comp(this,m)>=0)
			{
				this.sub(m);
				this.norm();
			}
			k--;
		}
	},
/* this/=m */
	div: function(m)
	{
		var k=0;
		this.norm();
		var e=new BIG(1);
		var b=new BIG(0);
		b.copy(this);
		this.zero();

		while (BIG.comp(b,m)>=0)
		{
			e.fshl(1);
			m.fshl(1);
			k++;
		}

		while (k>0)
		{
			m.fshr(1);
			e.fshr(1);
			if (BIG.comp(b,m)>=0)
			{
				this.add(e);
				this.norm();
				b.sub(m);
				b.norm();
			}
			k--;
		}
	},
/* return parity of this */
	parity: function()
	{
		return this.w[0]%2;
	},
/* return n-th bit of this */
	bit: function(n)
	{
		if ((this.w[Math.floor(n/ROM.BASEBITS)]&(1<<(n%ROM.BASEBITS)))>0) return 1;
		else return 0;
	},
/* return last n bits of this */
	lastbits: function(n)
	{
		var msk=(1<<n)-1;
		this.norm();
		return (this.w[0])&msk;
	},
/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
	jacobi: function(p)
	{
		var n8,k,m=0;
		var t=new BIG(0);
		var x=new BIG(0);
		var n=new BIG(0);
		var zilch=new BIG(0);
		var one=new BIG(1);
		if (p.parity()===0 || BIG.comp(this,zilch)===0 || BIG.comp(p,one)<=0) return 0;
		this.norm();
		x.copy(this);
		n.copy(p);
		x.mod(p);

		while (BIG.comp(n,one)>0)
		{
			if (BIG.comp(x,zilch)===0) return 0;
			n8=n.lastbits(3);
			k=0;
			while (x.parity()===0)
			{
				k++;
				x.shr(1);
			}
			if (k%2==1) m+=(n8*n8-1)/8;
			m+=(n8-1)*(x.lastbits(2)-1)/4;
			t.copy(n);
			t.mod(x);
			n.copy(x);
			x.copy(t);
			m%=2;

		}
		if (m===0) return 1;
		else return -1;
	},
/* this=1/this mod p. Binary method */
	invmodp: function(p)
	{
		this.mod(p);
		var u=new BIG(0);
		u.copy(this);
		var v=new BIG(0);
		v.copy(p);
		var x1=new BIG(1);
		var x2=new BIG(0);
		var t=new BIG(0);
		var one=new BIG(1);

		while (BIG.comp(u,one)!==0 && BIG.comp(v,one)!==0)
		{
			while (u.parity()===0)
			{
				u.shr(1);
				if (x1.parity()!==0)
				{
					x1.add(p);
					x1.norm();
				}
				x1.shr(1);
			}
			while (v.parity()===0)
			{
				v.shr(1);
				if (x2.parity()!==0)
				{
					x2.add(p);
					x2.norm();
				}
				x2.shr(1);
			}
			if (BIG.comp(u,v)>=0)
			{
				u.sub(v);
				u.norm();
				if (BIG.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 (BIG.comp(x2,x1)>=0) x2.sub(x1);
				else
				{
					t.copy(p);
					t.sub(x1);
					x2.add(t);
				}
				x2.norm();
			}
		}
		if (BIG.comp(u,one)===0) this.copy(x1);
		else this.copy(x2);
	},
/* return this^e mod m */
	powmod:function(e,m)
	{
		var bt;
		this.norm();
		e.norm();
		var a=new BIG(1);
		var z=new BIG(0);
		z.copy(e);
		var s=new BIG(0);
		s.copy(this);
		var i=0;
		while (true)
		{
			i++;
			bt=z.parity();
			z.fshr(1);
			if (bt==1) a=BIG.modmul(a,s,m);
//ROM.debug=false;
			if (z.iszilch()) break;
			s=BIG.modsqr(s,m);
		}
		return a;
	}

};
/* convert from byte array to BIG */
BIG.frombytearray=function(b,n)
{
	var m=new BIG(0);

	for (var i=0;i<ROM.MODBYTES;i++)
	{
		m.fshl(8); m.w[0]+=b[i+n]&0xff;
		//m.inc(b[i]&0xff);
	}
	return m;
};

BIG.fromBytes=function(b)
{
	return BIG.frombytearray(b,0);
};

/* return a*b where product fits a BIG */
BIG.smul=function(a,b)
{
	var carry;
	var c=new BIG(0);
	for (var i=0;i<ROM.NLEN;i++)
	{
		carry=0;
		for (var j=0;j<ROM.NLEN;j++)
			if (i+j<ROM.NLEN) carry=c.muladd(a.w[i],b.w[j],carry,i+j);
	}
	return c;
};
/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
BIG.comp=function(a,b)
{
	for (var i=ROM.NLEN-1;i>=0;i--)
	{
		if (a.w[i]==b.w[i]) continue;
		if (a.w[i]>b.w[i]) return 1;
		else  return -1;
	}
	return 0;
};

/* get 8*MODBYTES size random number */
BIG.random=function(rng)
{
	var m=new BIG(0);
	var i,b,j=0,r=0;

/* generate random BIG */
	for (i=0;i<8*ROM.MODBYTES;i++)
	{
		if (j===0) r=rng.getByte();
		else r>>=1;

		b=r&1;
		m.shl(1); m.w[0]+=b;// m.inc(b);
		j++; j&=7;
	}
	return m;
};

/* Create random BIG in portable way, one bit at a time */
BIG.randomnum=function(q,rng)
{
	var d=new DBIG(0);
	var i,b,j=0,r=0;
	for (i=0;i<2*ROM.MODBITS;i++)
	{
		if (j===0) r=rng.getByte();
		else r>>=1;

		b=r&1;
		d.shl(1); d.w[0]+=b;
		j++; j&=7;
	}

	var m=d.mod(q);

	return m;
};

/* return NAF value as +/- 1, 3 or 5. x and x3 should be normed.
nbs is number of bits processed, and nzs is number of trailing 0s detected */
BIG.nafbits=function(x,x3,i)
{
	var n=[];
	var nb=x3.bit(i)-x.bit(i);
	var j;
	n[1]=1;
	n[0]=0;
	if (nb===0) {n[0]=0; return n;}
	if (i===0) {n[0]=nb; return n;}
	if (nb>0) n[0]=1;
	else      n[0]=(-1);

	for (j=i-1;j>0;j--)
	{
		n[1]++;
		n[0]*=2;
		nb=x3.bit(j)-x.bit(j);
		if (nb>0) n[0]+=1;
		if (nb<0) n[0]-=1;
		if (n[0]>5 || n[0]<-5) break;
	}

	if (n[0]%2!==0 && j!==0)
	{ /* backtrack */
		if (nb>0) n[0]=(n[0]-1)/2;
		if (nb<0) n[0]=(n[0]+1)/2;
		n[1]--;
	}
	while (n[0]%2===0)
	{ /* remove trailing zeros */
		n[0]/=2;
		n[2]++;
		n[1]--;
	}
	return n;
};

/* return a*b as DBIG */
BIG.mul=function(a,b)
{
	var n,c=new DBIG(0);
	a.norm();
	b.norm();

	c.w[0]=a.w[0]*b.w[0];
	c.w[1]=a.w[1]*b.w[0]+a.w[0]*b.w[1];
	c.w[2]=a.w[2]*b.w[0]+a.w[1]*b.w[1]+a.w[0]*b.w[2];
	c.w[3]=a.w[3]*b.w[0]+a.w[2]*b.w[1]+a.w[1]*b.w[2]+a.w[0]*b.w[3];
	c.w[4]=a.w[4]*b.w[0]+a.w[3]*b.w[1]+a.w[2]*b.w[2]+a.w[1]*b.w[3]+a.w[0]*b.w[4];
	c.w[5]=a.w[5]*b.w[0]+a.w[4]*b.w[1]+a.w[3]*b.w[2]+a.w[2]*b.w[3]+a.w[1]*b.w[4]+a.w[0]*b.w[5];
	c.w[6]=a.w[6]*b.w[0]+a.w[5]*b.w[1]+a.w[4]*b.w[2]+a.w[3]*b.w[3]+a.w[2]*b.w[4]+a.w[1]*b.w[5]+a.w[0]*b.w[6];
	c.w[7]=a.w[7]*b.w[0]+a.w[6]*b.w[1]+a.w[5]*b.w[2]+a.w[4]*b.w[3]+a.w[3]*b.w[4]+a.w[2]*b.w[5]+a.w[1]*b.w[6]+a.w[0]*b.w[7];
	c.w[8]=a.w[8]*b.w[0]+a.w[7]*b.w[1]+a.w[6]*b.w[2]+a.w[5]*b.w[3]+a.w[4]*b.w[4]+a.w[3]*b.w[5]+a.w[2]*b.w[6]+a.w[1]*b.w[7]+a.w[0]*b.w[8];
	c.w[9]=a.w[9]*b.w[0]+a.w[8]*b.w[1]+a.w[7]*b.w[2]+a.w[6]*b.w[3]+a.w[5]*b.w[4]+a.w[4]*b.w[5]+a.w[3]*b.w[6]+a.w[2]*b.w[7]+a.w[1]*b.w[8]+a.w[0]*b.w[9];
	c.w[10]=a.w[10]*b.w[0]+a.w[9]*b.w[1]+a.w[8]*b.w[2]+a.w[7]*b.w[3]+a.w[6]*b.w[4]+a.w[5]*b.w[5]+a.w[4]*b.w[6]+a.w[3]*b.w[7]+a.w[2]*b.w[8]+a.w[1]*b.w[9]+a.w[0]*b.w[10];

	c.w[11]=a.w[10]*b.w[1]+a.w[9]*b.w[2]+a.w[8]*b.w[3]+a.w[7]*b.w[4]+a.w[6]*b.w[5]+a.w[5]*b.w[6]+a.w[4]*b.w[7]+a.w[3]*b.w[8]+a.w[2]*b.w[9]+a.w[1]*b.w[10];
	c.w[12]= a.w[10]*b.w[2]+a.w[9]*b.w[3]+a.w[8]*b.w[4]+a.w[7]*b.w[5]+a.w[6]*b.w[6]+a.w[5]*b.w[7]+a.w[4]*b.w[8]+a.w[3]*b.w[9]+a.w[2]*b.w[10];
	c.w[13]= a.w[10]*b.w[3]+a.w[9]*b.w[4]+a.w[8]*b.w[5]+a.w[7]*b.w[6]+a.w[6]*b.w[7]+a.w[5]*b.w[8]+a.w[4]*b.w[9]+a.w[3]*b.w[10];
	c.w[14]= a.w[10]*b.w[4]+a.w[9]*b.w[5]+a.w[8]*b.w[6]+a.w[7]*b.w[7]+a.w[6]*b.w[8]+a.w[5]*b.w[9]+a.w[4]*b.w[10];
	c.w[15]= a.w[10]*b.w[5]+a.w[9]*b.w[6]+a.w[8]*b.w[7]+a.w[7]*b.w[8]+a.w[6]*b.w[9]+a.w[5]*b.w[10];
	c.w[16]= a.w[10]*b.w[6]+a.w[9]*b.w[7]+a.w[8]*b.w[8]+a.w[7]*b.w[9]+a.w[6]*b.w[10];
	c.w[17]= a.w[10]*b.w[7]+a.w[9]*b.w[8]+a.w[8]*b.w[9]+a.w[7]*b.w[10];
	c.w[18]= a.w[10]*b.w[8]+a.w[9]*b.w[9]+a.w[8]*b.w[10];
	c.w[19]= a.w[10]*b.w[9]+a.w[9]*b.w[10];
	c.w[20]= a.w[10]*b.w[10];
//	for (var j=9;j<ROM.NLEN;j++)
//	{
//		t=0; for (var i=0;i<=j;i++) t+=a.w[j-i]*b.w[i];
//		c.w[j]=t;
//	}
//	for (var j=ROM.NLEN;j<ROM.DNLEN-2;j++)
//	{
//		t=0; for (var i=j-ROM.NLEN+1;i<ROM.NLEN;i++) t+=a.w[j-i]*b.w[i];
//		c.w[j]=t;
//	}
//	t=a.w[ROM.NLEN-1]*b.w[ROM.NLEN-1];
//	c.w[ROM.DNLEN-2]=t;
	var co=0;
	for (var i=0;i<ROM.DNLEN-1;i++)
	{
		n=c.w[i]+co;
		c.w[i]=n&ROM.MASK;
		co=(n-c.w[i])*ROM.MODINV;
	}
	c.w[ROM.DNLEN-1]=co;

	return c;
};

/* return a^2 as DBIG */
BIG.sqr=function(a)
{
	var n,c=new DBIG(0);
	a.norm();

	c.w[0]=a.w[0]*a.w[0];
	c.w[1]=2*(a.w[1]*a.w[0]);
	c.w[2]=2*(a.w[2]*a.w[0])+a.w[1]*a.w[1];
	c.w[3]=2*(a.w[3]*a.w[0]+a.w[2]*a.w[1]);
	c.w[4]=2*(a.w[4]*a.w[0]+a.w[3]*a.w[1])+a.w[2]*a.w[2];
	c.w[5]=2*(a.w[5]*a.w[0]+a.w[4]*a.w[1]+a.w[3]*a.w[2]);
	c.w[6]=2*(a.w[6]*a.w[0]+a.w[5]*a.w[1]+a.w[4]*a.w[2])+a.w[3]*a.w[3];
	c.w[7]=2*(a.w[7]*a.w[0]+a.w[6]*a.w[1]+a.w[5]*a.w[2]+a.w[4]*a.w[3]);
	c.w[8]=2*(a.w[8]*a.w[0]+a.w[7]*a.w[1]+a.w[6]*a.w[2]+a.w[5]*a.w[3])+a.w[4]*a.w[4];
	c.w[9]=2*(a.w[9]*a.w[0]+a.w[8]*a.w[1]+a.w[7]*a.w[2]+a.w[6]*a.w[3]+a.w[5]*a.w[4]);
	c.w[10]=2*(a.w[10]*a.w[0]+a.w[9]*a.w[1]+a.w[8]*a.w[2]+a.w[7]*a.w[3]+a.w[6]*a.w[4])+a.w[5]*a.w[5];

	c.w[11]=2*(a.w[10]*a.w[1]+a.w[9]*a.w[2]+a.w[8]*a.w[3]+a.w[7]*a.w[4]+a.w[6]*a.w[5]);
	c.w[12]=2*(a.w[10]*a.w[2]+a.w[9]*a.w[3]+a.w[8]*a.w[4]+a.w[7]*a.w[5])+a.w[6]*a.w[6];
	c.w[13]=2*(a.w[10]*a.w[3]+a.w[9]*a.w[4]+a.w[8]*a.w[5]+a.w[7]*a.w[6]);
	c.w[14]=2*(a.w[10]*a.w[4]+a.w[9]*a.w[5]+a.w[8]*a.w[6])+a.w[7]*a.w[7];
	c.w[15]=2*(a.w[10]*a.w[5]+a.w[9]*a.w[6]+a.w[8]*a.w[7]);
	c.w[16]=2*(a.w[10]*a.w[6]+a.w[9]*a.w[7])+a.w[8]*a.w[8];
	c.w[17]=2*(a.w[10]*a.w[7]+a.w[9]*a.w[8]);
	c.w[18]=2*(a.w[10]*a.w[8])+a.w[9]*a.w[9];
	c.w[19]=2*(a.w[10]*a.w[9]);
	c.w[20]= a.w[10]*a.w[10];
/*
	c.w[0]=a.w[0]*a.w[0];
	t=a.w[1]*a.w[0]; t+=t; c.w[1]=t;
	for (j=2;j<ROM.NLEN-1;j+=2)
	{
		t=a.w[j]*a.w[0]; for (var i=1;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t; t+=a.w[j>>1]*a.w[j>>1];
		c.w[j]=t;
		t=a.w[j+1]*a.w[0]; for (var i=1;i<(j+2)>>1;i++) t+=a.w[j+1-i]*a.w[i]; t+=t;
		c.w[j+1]=t;
	}
	j=ROM.NLEN-1;
	t=a.w[j]*a.w[0]; for (var i=1;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t; t+=a.w[j>>1]*a.w[j>>1];
	c.w[j]=t;

	j=ROM.NLEN;
	t=a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+1]; for (var i=j-ROM.NLEN+2;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t;
	c.w[j]=t;
	for (j=ROM.NLEN+1;j<ROM.DNLEN-2;j+=2)
	{
		t=a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+1]; for (var i=j-ROM.NLEN+2;i<(j+1)>>1;i++) t+=a.w[j-i]*a.w[i]; t+=t; t+=a.w[j>>1]*a.w[j>>1];
		c.w[j]=t;
		t=a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+2]; for (var i=j-ROM.NLEN+3;i<(j+2)>>1;i++) t+=a.w[j+1-i]*a.w[i]; t+=t;
		c.w[j+1]=t;
	}

	t=a.w[ROM.NLEN-1]*a.w[ROM.NLEN-1];
	c.w[ROM.DNLEN-2]=t;
*/
	var co=0;
	for (var i=0;i<ROM.DNLEN-1;i++)
	{
		n=c.w[i]+co;
		c.w[i]=n&ROM.MASK;
		co=(n-c.w[i])*ROM.MODINV;
	}
	c.w[ROM.DNLEN-1]=co;

	return c;
};

/* reduce a DBIG to a BIG using a "special" modulus */
BIG.mod=function(d)
{
	var i,j,b=new BIG(0);
	if (ROM.MODTYPE==ROM.PSEUDO_MERSENNE)
	{
		var v,tw;
		var t=d.split(ROM.MODBITS);
		b.hcopy(d);

		v=t.pmul(ROM.MConst);
		tw=t.w[ROM.NLEN-1];
		t.w[ROM.NLEN-1]&=ROM.TMASK;
		t.inc(ROM.MConst*((tw>>ROM.TBITS)+(v<<(ROM.BASEBITS-ROM.TBITS))));
		b.add(t);
	}

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

	if (ROM.MODTYPE==ROM.NOT_SPECIAL)
	{
		var md=new BIG(0);
		md.rcopy(ROM.Modulus);
		var sum;

		sum=d.w[0];
		for (j=0;j<ROM.NLEN;j++)
		{
			for (i=0;i<j;i++) sum+=d.w[i]*md.w[j-i];
			d.w[j]=((sum&ROM.MASK)*ROM.MConst)&ROM.MASK; sum+=d.w[j]*md.w[0];
			sum=d.w[j+1]+(sum*ROM.MODINV);
		}
		for (j=ROM.NLEN;j<ROM.DNLEN-2;j++)
		{
			for (i=j-ROM.NLEN+1;i<ROM.NLEN;i++) sum+=d.w[i]*md.w[j-i];
			d.w[j]=sum&ROM.MASK;
			sum=d.w[j+1]+((sum-d.w[j])*ROM.MODINV);
		}

		sum+=d.w[ROM.NLEN-1]*md.w[ROM.NLEN-1];
		d.w[ROM.DNLEN-2]=sum&ROM.MASK;
		sum=d.w[ROM.DNLEN-1]+((sum-d.w[ROM.DNLEN-2])*ROM.MODINV);
		d.w[ROM.DNLEN-1]=sum&ROM.MASK;

		for (i=0;i<ROM.NLEN;i++)
			b.w[i]=d.w[ROM.NLEN+i];
	}
	b.norm();
	return b;
};

/* return a*b mod m */
BIG.modmul=function(a,b,m)
{
	a.mod(m);
	b.mod(m);
	var d=BIG.mul(a,b);
	return d.mod(m);
};

/* return a^2 mod m */
BIG.modsqr=function(a,m)
{
	a.mod(m);
	var d=BIG.sqr(a);
	return d.mod(m);
};

/* return -a mod m */
BIG.modneg=function(a,m)
{
	a.mod(m);
	return m.minus(a);
};

/* calculate Field Excess */
BIG.EXCESS=function(a)
{
	return ((a.w[ROM.NLEN-1]&ROM.OMASK)>>(ROM.MODBITS%ROM.BASEBITS));
};

/* Arazi and Qi inversion mod 256 */
BIG.invmod256=function(a)
{
	var U,t1,t2,b,c;
	t1=0;
	c=(a>>1)&1;
	t1+=c;
	t1&=1;
	t1=2-t1;
	t1<<=1;
	U=t1+1;

// i=2
	b=a&3;
	t1=U*b; t1>>=2;
	c=(a>>2)&3;
	t2=(U*c)&3;
	t1+=t2;
	t1*=U; t1&=3;
	t1=4-t1;
	t1<<=2;
	U+=t1;

// i=4
	b=a&15;
	t1=U*b; t1>>=4;
	c=(a>>4)&15;
	t2=(U*c)&15;
	t1+=t2;
	t1*=U; t1&=15;
	t1=16-t1;
	t1<<=4;
	U+=t1;

	return U;
};

