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

package XXX
//import "fmt"

const WEIERSTRASS int=0
const EDWARDS int=1
const MONTGOMERY int=2
const NOT int=0
const BN int=1
const BLS int=2
const D_TYPE int=0
const M_TYPE int=1
const POSITIVEX int=0
const NEGATIVEX int=1

const CURVETYPE int=@CT@
const CURVE_PAIRING_TYPE int=@PF@
const SEXTIC_TWIST int=@ST@
const SIGN_OF_X int=@SX@

const HASH_TYPE int=@HT@
const AESKEY int=@AK@

/* Elliptic Curve Point Structure */

type ECP struct {
	x *FP
	y *FP
	z *FP
//	INF bool
}

/* Constructors */
func NewECP() *ECP {
	E:=new(ECP)
	E.x=NewFPint(0)
	E.y=NewFPint(1)
	if CURVETYPE==EDWARDS {
		E.z=NewFPint(1)
	} else {
		E.z=NewFPint(0)
	}
//	E.INF=true
	return E
}

/* set (x,y) from two BIGs */
func NewECPbigs(ix *BIG,iy *BIG) *ECP {
	E:=new(ECP)
	E.x=NewFPbig(ix)
	E.y=NewFPbig(iy)
	E.z=NewFPint(1)
	E.x.norm()
	rhs:=RHS(E.x)

	if CURVETYPE==MONTGOMERY {
		if rhs.jacobi()!=1 {
			E.inf()
		}
	} else {
		y2:=NewFPcopy(E.y)
		y2.sqr()
		if !y2.Equals(rhs) {
			E.inf()
		}
	}
	return E
}

/* set (x,y) from BIG and a bit */
func NewECPbigint(ix *BIG,s int) *ECP {
	E:=new(ECP)
	E.x=NewFPbig(ix)
	E.y=NewFPint(0)
	E.x.norm()
	rhs:=RHS(E.x)
	E.z=NewFPint(1)
	if rhs.jacobi()==1 {
		ny:=rhs.sqrt()
		if ny.redc().parity()!=s {ny.neg()}
		E.y.copy(ny)
		//E.INF=false
	} else {E.inf()}
	return E;
}

/* set from x - calculate y from curve equation */
func NewECPbig(ix *BIG) *ECP {
	E:=new(ECP)	
	E.x=NewFPbig(ix)
	E.y=NewFPint(0)
	E.x.norm()
	rhs:=RHS(E.x)
	E.z=NewFPint(1)
	if rhs.jacobi()==1 {
		if CURVETYPE!=MONTGOMERY {E.y.copy(rhs.sqrt())}
		//E.INF=false
	} else {E.inf()}
	return E
}

/* test for O point-at-infinity */
func (E *ECP) Is_infinity() bool {
//	if E.INF {return true}
	E.x.reduce(); E.z.reduce()
	if CURVETYPE==EDWARDS {
		E.y.reduce();
		return (E.x.iszilch() && E.y.Equals(E.z))
	} 
	if CURVETYPE==WEIERSTRASS {
		E.y.reduce();
		return (E.x.iszilch() && E.z.iszilch())
	}
	if CURVETYPE==MONTGOMERY {
		return E.z.iszilch()
	}
	return true
}

/* Conditional swap of P and Q dependant on d */
func (E *ECP) cswap(Q *ECP,d int) {
	E.x.cswap(Q.x,d)
	if CURVETYPE!=MONTGOMERY {E.y.cswap(Q.y,d)}
	E.z.cswap(Q.z,d)
/*
	bd:=true
	if d==0 {bd=false}
	bd=bd&&(E.INF!=Q.INF)
	E.INF=(bd!=E.INF)
	Q.INF=(bd!=Q.INF)
*/
}

/* Conditional move of Q to P dependant on d */
func (E *ECP) cmove(Q *ECP,d int) {
	E.x.cmove(Q.x,d)
	if CURVETYPE!=MONTGOMERY {E.y.cmove(Q.y,d)}
	E.z.cmove(Q.z,d);
/*
	bd:=true
	if d==0 {bd=false}
	E.INF=(E.INF!=((E.INF!=Q.INF)&&bd))
*/
}

/* return 1 if b==c, no branching */
func teq(b int32,c int32) int {
	x:=b^c
	x-=1  // if x=0, x now -1
	return int((x>>31)&1)
}

/* this=P */
func (E *ECP) Copy(P *ECP) {
	E.x.copy(P.x);
	if CURVETYPE!=MONTGOMERY {E.y.copy(P.y)}
	E.z.copy(P.z);
//	E.INF=P.INF;
}

/* this=-this */
func (E *ECP) neg() {
//	if E.Is_infinity() {return}
	if CURVETYPE==WEIERSTRASS {
		E.y.neg(); E.y.norm()
	}
	if CURVETYPE==EDWARDS {
		E.x.neg(); E.x.norm()
	}
	return;
}

/* Constant time select from pre-computed table */
func (E *ECP) selector(W []*ECP,b int32) {
	MP:=NewECP()
	m:=b>>31;
	babs:=(b^m)-m;

	babs=(babs-1)/2

	E.cmove(W[0],teq(babs,0))  // conditional move
	E.cmove(W[1],teq(babs,1))
	E.cmove(W[2],teq(babs,2))
	E.cmove(W[3],teq(babs,3))
	E.cmove(W[4],teq(babs,4))
	E.cmove(W[5],teq(babs,5))
	E.cmove(W[6],teq(babs,6))
	E.cmove(W[7],teq(babs,7))
 
	MP.Copy(E);
	MP.neg()
	E.cmove(MP,int(m&1));
}

/* set this=O */
func (E *ECP) inf() {
//	E.INF=true;
	E.x.zero()
	if CURVETYPE!=MONTGOMERY {E.y.one()}
	if CURVETYPE!=EDWARDS {
		E.z.zero()
	} else {E.z.one()}
}

/* Test P == Q */
func( E *ECP) Equals(Q *ECP) bool {
//	if E.Is_infinity() && Q.Is_infinity() {return true}
//	if E.Is_infinity() || Q.Is_infinity() {return false}

	a:=NewFPint(0)
	b:=NewFPint(0)
	a.copy(E.x); a.mul(Q.z); a.reduce()
	b.copy(Q.x); b.mul(E.z); b.reduce()
	if !a.Equals(b) {return false}
	if CURVETYPE!=MONTGOMERY {
		a.copy(E.y); a.mul(Q.z); a.reduce()
		b.copy(Q.y); b.mul(E.z); b.reduce()
		if !a.Equals(b) {return false}
	}

	return true
}

/* Calculate RHS of curve equation */
func RHS(x *FP) *FP {
	//x.norm()
	r:=NewFPcopy(x)
	r.sqr();

	if CURVETYPE==WEIERSTRASS { // x^3+Ax+B
		b:=NewFPbig(NewBIGints(CURVE_B))
		r.mul(x);
		if CURVE_A==-3 {
			cx:=NewFPcopy(x)
			cx.imul(3)
			cx.neg(); cx.norm()
			r.add(cx)
		}
		r.add(b)
	}
	if CURVETYPE==EDWARDS { // (Ax^2-1)/(Bx^2-1) 
		b:=NewFPbig(NewBIGints(CURVE_B))

		one:=NewFPint(1)
		b.mul(r)
		b.sub(one)
		b.norm()
		if CURVE_A==-1 {r.neg()}
		r.sub(one); r.norm()
		b.inverse()
		r.mul(b)
	}
	if CURVETYPE==MONTGOMERY { // x^3+Ax^2+x
		x3:=NewFPint(0)
		x3.copy(r)
		x3.mul(x)
		r.imul(CURVE_A)
		r.add(x3)
		r.add(x)
	}
	r.reduce()
	return r
}

/* set to affine - from (x,y,z) to (x,y) */
func (E *ECP) Affine() {
	if E.Is_infinity() {return}
	one:=NewFPint(1)
	if E.z.Equals(one) {return}
	E.z.inverse()
	E.x.mul(E.z); E.x.reduce()

	if CURVETYPE!=MONTGOMERY {
		E.y.mul(E.z); E.y.reduce()
	}
	E.z.copy(one)
}

/* extract x as a BIG */
func (E *ECP) GetX() *BIG {
	W:=NewECP(); W.Copy(E)
	W.Affine()
	return W.x.redc()
}
/* extract y as a BIG */
func (E *ECP) GetY() *BIG {
	W:=NewECP(); W.Copy(E)
	W.Affine()
	return W.y.redc()
}

/* get sign of Y */
func (E *ECP) GetS() int {
	//E.Affine()
	y:=E.GetY()
	return y.parity()
}
/* extract x as an FP */
func (E *ECP) getx() *FP {
	return E.x;
}
/* extract y as an FP */
func (E *ECP) gety() *FP {
	return E.y
}
/* extract z as an FP */
func (E *ECP) getz() *FP {
	return E.z
}

/* convert to byte array */
func (E *ECP) ToBytes(b []byte,compress bool) {
	var t [int(MODBYTES)]byte
	MB:=int(MODBYTES)
	W:=NewECP(); W.Copy(E);
	W.Affine()
	W.x.redc().ToBytes(t[:])
	for i:=0;i<MB;i++ {b[i+1]=t[i]}

	if 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(t[:])
	for i:=0;i<MB;i++ {b[i+MB+1]=t[i]}
}

/* convert from byte array to point */
func ECP_fromBytes(b []byte) *ECP {
	var t [int(MODBYTES)]byte
	MB:=int(MODBYTES)
	p:=NewBIGints(Modulus)

	for i:=0;i<MB;i++ {t[i]=b[i+1]}
	px:=FromBytes(t[:])
	if Comp(px,p)>=0 {return NewECP()}

	if CURVETYPE==MONTGOMERY {
		return NewECPbig(px)
	}

	if b[0]==0x04 {
		for i:=0;i<MB;i++ {t[i]=b[i+MB+1]}
		py:=FromBytes(t[:])
		if Comp(py,p)>=0 {return NewECP()}
		return NewECPbigs(px,py)
	}

	if b[0]==0x02 || b[0]==0x03 {
		return NewECPbigint(px,int(b[0]&1))
	}

	return NewECP()
}

/* convert to hex string */
func (E *ECP) ToString() string {
	W:=NewECP(); W.Copy(E);
	W.Affine()
	if W.Is_infinity() {return "infinity"}
	if CURVETYPE==MONTGOMERY {
		return "("+W.x.redc().ToString()+")"
	} else {return "("+W.x.redc().ToString()+","+W.y.redc().ToString()+")"}
}

/* this*=2 */
func (E *ECP) dbl() {

//	if E.INF {return}
	if CURVETYPE==WEIERSTRASS {
		if CURVE_A==0 {
			t0:=NewFPcopy(E.y)                      /*** Change ***/    // Edits made
			t0.sqr()
			t1:=NewFPcopy(E.y)
			t1.mul(E.z)
			t2:=NewFPcopy(E.z)
			t2.sqr()

			E.z.copy(t0)
			E.z.add(t0); E.z.norm(); 
			E.z.add(E.z); E.z.add(E.z); E.z.norm()
			t2.imul(3*CURVE_B_I)

			x3:=NewFPcopy(t2)
			x3.mul(E.z)

			y3:=NewFPcopy(t0)
			y3.add(t2); y3.norm()
			E.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(E.x); t1.mul(E.y) 
			E.x.copy(t0); E.x.norm(); E.x.mul(t1); E.x.add(E.x)
			E.x.norm(); 
			E.y.copy(y3); E.y.norm();
		} else {
			t0:=NewFPcopy(E.x)
			t1:=NewFPcopy(E.y)
			t2:=NewFPcopy(E.z)
			t3:=NewFPcopy(E.x)
			z3:=NewFPcopy(E.z)
			y3:=NewFPint(0)
			x3:=NewFPint(0)
			b:=NewFPint(0)

			if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))}

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

			t3.mul(E.y) //4
			t3.add(t3); t3.norm() //5
			z3.mul(E.x);   //6
			z3.add(z3);  z3.norm()//7
			y3.copy(t2) 
				
			if CURVE_B_I==0 {
				y3.mul(b)
			} else {
				y3.imul(CURVE_B_I)
			}
				
			y3.sub(z3) //y3.norm(); //9  ***
			x3.copy(y3); x3.add(y3); x3.norm() //10

			y3.add(x3) //y3.norm();//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)  //t3.norm(); //16
			t2.add(t3)  //t2.norm(); //17

			if CURVE_B_I==0 {
				z3.mul(b)
			} else {
				z3.imul(CURVE_B_I)
			}

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

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

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

			E.x.copy(x3); E.x.norm() 
			E.y.copy(y3); E.y.norm()
			E.z.copy(z3); E.z.norm()
		}
	}

	if CURVETYPE==EDWARDS {
		C:=NewFPcopy(E.x)
		D:=NewFPcopy(E.y)
		H:=NewFPcopy(E.z)
		J:=NewFPint(0)
	
		E.x.mul(E.y); E.x.add(E.x); E.x.norm()
		C.sqr()
		D.sqr()
		if CURVE_A==-1 {C.neg()}	
		E.y.copy(C); E.y.add(D); E.y.norm()

		H.sqr(); H.add(H)
		E.z.copy(E.y)
		J.copy(E.y); J.sub(H); J.norm()
		E.x.mul(J)
		C.sub(D); C.norm()
		E.y.mul(C)
		E.z.mul(J)


	}
	if CURVETYPE==MONTGOMERY {
		A:=NewFPcopy(E.x)
		B:=NewFPcopy(E.x)	
		AA:=NewFPint(0)
		BB:=NewFPint(0)
		C:=NewFPint(0)
	
	//	if E.INF {return}

		A.add(E.z); A.norm()
		AA.copy(A); AA.sqr()
		B.sub(E.z); B.norm()
		BB.copy(B); BB.sqr()
		C.copy(AA); C.sub(BB)
		C.norm()

		E.x.copy(AA); E.x.mul(BB)

		A.copy(C); A.imul((CURVE_A+2)/4)

		BB.add(A); BB.norm()
		E.z.copy(BB); E.z.mul(C)
	}
	return;
}

/* this+=Q */
func (E *ECP) Add(Q *ECP) {
/*
	if E.INF {
		E.Copy(Q)
		return
	}
	if Q.INF {return}
*/
	if CURVETYPE==WEIERSTRASS {
		if CURVE_A==0 {
			b:=3*CURVE_B_I
			t0:=NewFPcopy(E.x)
			t0.mul(Q.x)
			t1:=NewFPcopy(E.y)
			t1.mul(Q.y)
			t2:=NewFPcopy(E.z)
			t2.mul(Q.z)
			t3:=NewFPcopy(E.x)
			t3.add(E.y); t3.norm()
			t4:=NewFPcopy(Q.x)
			t4.add(Q.y); t4.norm()
			t3.mul(t4)
			t4.copy(t0); t4.add(t1)

			t3.sub(t4); t3.norm()
			t4.copy(E.y)
			t4.add(E.z); t4.norm()
			x3:=NewFPcopy(Q.y)
			x3.add(Q.z); x3.norm()

			t4.mul(x3)
			x3.copy(t1)
			x3.add(t2)
	
			t4.sub(x3); t4.norm()
			x3.copy(E.x); x3.add(E.z); x3.norm()
			y3:=NewFPcopy(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)

			z3:=NewFPcopy(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)

			E.x.copy(x3); E.x.norm()
			E.y.copy(y3); E.y.norm()
			E.z.copy(z3); E.z.norm()	
		} else {

			t0:=NewFPcopy(E.x)
			t1:=NewFPcopy(E.y)
			t2:=NewFPcopy(E.z)
			t3:=NewFPcopy(E.x)
			t4:=NewFPcopy(Q.x)
			z3:=NewFPint(0)
			y3:=NewFPcopy(Q.x)
			x3:=NewFPcopy(Q.y)
			b:=NewFPint(0)

			if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))}

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

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

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

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

			y3.rsub(x3); y3.norm() //18
			z3.copy(t2) 
				
			if CURVE_B_I==0 {
				z3.mul(b)
			} else {
				z3.imul(CURVE_B_I)
			}
				
			x3.copy(y3); x3.sub(z3); x3.norm() //20
			z3.copy(x3); z3.add(x3) //z3.norm(); //21

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

			if CURVE_B_I==0 {
				y3.mul(b)
			} else {
				y3.imul(CURVE_B_I)
			}

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

			y3.sub(t2) //y3.norm(); //28

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

			t1.copy(t0); t1.add(t0) //t1.norm(); //32
			t0.add(t1) //t0.norm();//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) 
			E.x.copy(x3); E.x.norm() 
			E.y.copy(y3); E.y.norm()
			E.z.copy(z3); E.z.norm()

		}
	}
	if CURVETYPE==EDWARDS {
		b:=NewFPbig(NewBIGints(CURVE_B))
		A:=NewFPcopy(E.z)
		B:=NewFPint(0)
		C:=NewFPcopy(E.x)
		D:=NewFPcopy(E.y)
		EE:=NewFPint(0)
		F:=NewFPint(0)
		G:=NewFPint(0)
	
		A.mul(Q.z);
		B.copy(A); B.sqr()
		C.mul(Q.x)
		D.mul(Q.y)

		EE.copy(C); EE.mul(D); EE.mul(b)
		F.copy(B); F.sub(EE)
		G.copy(B); G.add(EE)

		if CURVE_A==1 {
			EE.copy(D); EE.sub(C)
		}
		C.add(D)

		B.copy(E.x); B.add(E.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)
		E.x.copy(A); E.x.mul(B)
		G.norm()
		if CURVE_A==1 {
			EE.norm(); C.copy(EE); C.mul(G)
		}
		if CURVE_A==-1 {
			C.norm(); C.mul(G)
		}
		E.y.copy(A); E.y.mul(C)
		E.z.copy(F); E.z.mul(G)
	}
	return
}

/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
func (E *ECP) dadd(Q *ECP,W *ECP) {
	A:=NewFPcopy(E.x)
	B:=NewFPcopy(E.x)
	C:=NewFPcopy(Q.x)
	D:=NewFPcopy(Q.x)
	DA:=NewFPint(0)
	CB:=NewFPint(0)
			
	A.add(E.z)
	B.sub(E.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()

	E.x.copy(A)
	E.z.copy(W.x); E.z.mul(B)

//	if E.z.iszilch() {
//		E.inf()
//	} else {E.INF=false;}

}

/* this-=Q */
func (E *ECP) Sub(Q *ECP) {
	NQ:=NewECP(); NQ.Copy(Q);
	NQ.neg()
	E.Add(NQ)
}

/* constant time multiply by small integer of length bts - use ladder */
func (E *ECP) pinmul(e int32,bts int32) *ECP {	
	if CURVETYPE==MONTGOMERY {
		return E.mul(NewBIGint(int(e)))
	} else {
		P:=NewECP()
		R0:=NewECP()
		R1:=NewECP(); R1.Copy(E)

		for i:=bts-1;i>=0;i-- {
			b:=int((e>>uint32(i))&1)
			P.Copy(R1)
			P.Add(R0)
			R0.cswap(R1,b)
			R1.Copy(P)
			R0.dbl()
			R0.cswap(R1,b)
		}
		P.Copy(R0)
		P.Affine()
		return P
	}
}

/* return e.this */

func (E *ECP) mul(e *BIG) *ECP {
	if (e.iszilch() || E.Is_infinity()) {return NewECP()}
	P:=NewECP()
	if CURVETYPE==MONTGOMERY {
/* use Ladder */
		D:=NewECP();
		R0:=NewECP(); R0.Copy(E)
		R1:=NewECP(); R1.Copy(E)
		R1.dbl()
		D.Copy(E); D.Affine()
		nb:=e.nbits()
		for i:=nb-2;i>=0;i-- {
			b:=int(e.bit(i))
			P.Copy(R1)
			P.dadd(R0,D)
			R0.cswap(R1,b)
			R1.Copy(P)
			R0.dbl()
			R0.cswap(R1,b)
		}
		P.Copy(R0)
	} else {
// fixed size windows 
		mt:=NewBIG()
		t:=NewBIG()
		Q:=NewECP()
		C:=NewECP()

		var W []*ECP
		var w [1+(NLEN*int(BASEBITS)+3)/4]int8

		//E.Affine();

		Q.Copy(E);
		Q.dbl();

		W=append(W,NewECP());
		W[0].Copy(E);

		for i:=1;i<8;i++ {
			W=append(W,NewECP())
			W[i].Copy(W[i-1])
			W[i].Add(Q)
		}

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

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

// convert exponent to signed 4-bit window 
		for i:=0;i<nb;i++ {
			w[i]=int8(t.lastbits(5)-16)
			t.dec(int(w[i])); t.norm()
			t.fshr(4)	
		}
		w[nb]=int8(t.lastbits(5))

		P.Copy(W[(int(w[nb])-1)/2])  
		for i:=nb-1;i>=0;i-- {
			Q.selector(W,int32(w[i]))
			P.dbl()
			P.dbl()
			P.dbl()
			P.dbl()
			P.Add(Q)
		}
		P.Sub(C) /* apply correction */
	}
	P.Affine()
	return P
}

/* Public version */
func (E *ECP) Mul(e *BIG) *ECP {
	return E.mul(e)
}

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

func (E *ECP) Mul2(e *BIG,Q *ECP,f *BIG) *ECP {
	te:=NewBIG()
	tf:=NewBIG()
	mt:=NewBIG()
	S:=NewECP()
	T:=NewECP()
	C:=NewECP()
	var W [] *ECP
	//ECP[] W=new ECP[8];
	var w [1+(NLEN*int(BASEBITS)+1)/2]int8		

	//E.Affine()
	//Q.Affine()

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

// precompute table 
	for i:=0;i<8;i++ {
		W=append(W,NewECP())
	}
	W[1].Copy(E); W[1].Sub(Q)
	W[2].Copy(E); W[2].Add(Q);
	S.Copy(Q); S.dbl();
	W[0].Copy(W[1]); W[0].Sub(S);
	W[3].Copy(W[2]); W[3].Add(S);
	T.Copy(E); T.dbl();
	W[5].Copy(W[1]); W[5].Add(T);
	W[6].Copy(W[2]); W[6].Add(T);
	W[4].Copy(W[5]); W[4].Sub(S);
	W[7].Copy(W[6]); W[7].Add(S);

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

	s:=int(te.parity());
	te.inc(1); te.norm(); ns:=int(te.parity()); mt.copy(te); mt.inc(1); mt.norm()
	te.cmove(mt,s)
	T.cmove(E,ns)
	C.Copy(T)

	s=int(tf.parity())
	tf.inc(1); tf.norm(); ns=int(tf.parity()); mt.copy(tf); mt.inc(1); mt.norm()
	tf.cmove(mt,s)
	S.cmove(Q,ns)
	C.Add(S)

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

// convert exponent to signed 2-bit window 
	for i:=0;i<nb;i++ {
		a:=(te.lastbits(3)-4)
		te.dec(int(a)); te.norm()
		te.fshr(2)
		b:=(tf.lastbits(3)-4)
		tf.dec(int(b)); tf.norm()
		tf.fshr(2)
		w[i]=int8(4*a+b)
	}
	w[nb]=int8(4*te.lastbits(3)+tf.lastbits(3))
	S.Copy(W[(w[nb]-1)/2])  

	for i:=nb-1;i>=0;i-- {
		T.selector(W,int32(w[i]));
		S.dbl()
		S.dbl()
		S.Add(T)
	}
	S.Sub(C) /* apply correction */
	S.Affine()
	return S
}

func (E *ECP) cfp() {
	cf:=CURVE_Cof_I;
	if cf==1 {return}
	if cf==4 {
		E.dbl(); E.dbl()
		//E.Affine();
		return;
	} 
	if cf==8 {
		E.dbl(); E.dbl(); E.dbl()
		//E.Affine();
		return;
	}
	c:=NewBIGints(CURVE_Cof);
	E.Copy(E.mul(c));
}

func ECP_mapit(h []byte) *ECP {
	q:=NewBIGints(Modulus)
	x:=FromBytes(h[:])
	x.Mod(q)
	var P *ECP

	for true {
		for true {
			if CURVETYPE!=MONTGOMERY {
				P=NewECPbigint(x,0)
			} else {
				P=NewECPbig(x)
			}
			x.inc(1); x.norm()
			if !P.Is_infinity() {break}
		}
		P.cfp()
		if !P.Is_infinity() {break}
	}
			
	return P
}

func ECP_generator() *ECP {
	var G *ECP

	gx:=NewBIGints(CURVE_Gx)
	if CURVETYPE!=MONTGOMERY {
		gy:=NewBIGints(CURVE_Gy)
		G=NewECPbigs(gx,gy)
	} else {
		G=NewECPbig(gx)
	}
	return G
}

/*
func main() {
	Gx:=NewBIGints(CURVE_Gx);
	var Gy *BIG
	var P *ECP

	if CURVETYPE!=MONTGOMERY {Gy=NewBIGints(CURVE_Gy)}
	r:=NewBIGints(CURVE_Order)

	//r.dec(7);
	
	fmt.Printf("Gx= "+Gx.ToString())
	fmt.Printf("\n")

	if CURVETYPE!=MONTGOMERY {
		fmt.Printf("Gy= "+Gy.ToString())
		fmt.Printf("\n")
	}	

	if CURVETYPE!=MONTGOMERY {
		P=NewECPbigs(Gx,Gy)
	} else  {P=NewECPbig(Gx)}

	fmt.Printf("P= "+P.ToString());		
	fmt.Printf("\n")

	R:=P.mul(r);
		//for (int i=0;i<10000;i++)
		//	R=P.mul(r);
	
	fmt.Printf("R= "+R.ToString())
	fmt.Printf("\n")
}
*/