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

/* MiotCL Weierstrass elliptic curve functions over FP2 */

package XXX

//import "fmt"

type ECP4 struct {
	x *FP4
	y *FP4
	z *FP4
}

func NewECP4() *ECP4 {
	E := new(ECP4)
	E.x = NewFP4()
	E.y = NewFP4int(1)
	E.z = NewFP4()
	return E
}

/* Test this=O? */
func (E *ECP4) Is_infinity() bool {
	E.x.reduce()
	E.y.reduce()
	E.z.reduce()
	return E.x.iszilch() && E.z.iszilch()
}

/* copy this=P */
func (E *ECP4) Copy(P *ECP4) {
	E.x.copy(P.x)
	E.y.copy(P.y)
	E.z.copy(P.z)
}

/* set this=O */
func (E *ECP4) inf() {
	E.x.zero()
	E.y.one()
	E.z.zero()
}

/* set this=-this */
func (E *ECP4) neg() {
	E.y.norm()
	E.y.neg()
	E.y.norm()
}

/* Conditional move of Q to P dependant on d */
func (E *ECP4) cmove(Q *ECP4, d int) {
	E.x.cmove(Q.x, d)
	E.y.cmove(Q.y, d)
	E.z.cmove(Q.z, d)
}

/* Constant time select from pre-computed table */
func (E *ECP4) selector(W []*ECP4, b int32) {
	MP := NewECP4()
	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))
}

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

	a := NewFP4copy(E.x)
	b := NewFP4copy(Q.x)
	a.mul(Q.z)
	b.mul(E.z)

	if !a.Equals(b) {
		return false
	}
	a.copy(E.y)
	b.copy(Q.y)
	a.mul(Q.z)
	b.mul(E.z)
	if !a.Equals(b) {
		return false
	}

	return true
}

/* set to Affine - (x,y,z) to (x,y) */
func (E *ECP4) Affine() {
	if E.Is_infinity() {
		return
	}
	one := NewFP4int(1)
	if E.z.Equals(one) {
		E.x.reduce()
		E.y.reduce()
		return
	}
	E.z.inverse()

	E.x.mul(E.z)
	E.x.reduce()
	E.y.mul(E.z)
	E.y.reduce()
	E.z.copy(one)
}

/* extract affine x as FP2 */
func (E *ECP4) GetX() *FP4 {
	W := NewECP4()
	W.Copy(E)
	W.Affine()
	return W.x
}

/* extract affine y as FP2 */
func (E *ECP4) GetY() *FP4 {
	W := NewECP4()
	W.Copy(E)
	W.Affine()
	return W.y
}

/* extract projective x */
func (E *ECP4) getx() *FP4 {
	return E.x
}

/* extract projective y */
func (E *ECP4) gety() *FP4 {
	return E.y
}

/* extract projective z */
func (E *ECP4) getz() *FP4 {
	return E.z
}

/* convert to byte array */
func (E *ECP4) ToBytes(b []byte) {
	var t [int(MODBYTES)]byte
	MB := int(MODBYTES)

	W := NewECP4()
	W.Copy(E)
	W.Affine()

	W.x.geta().GetA().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i] = t[i]
	}
	W.x.geta().GetB().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i+MB] = t[i]
	}
	W.x.getb().GetA().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i+2*MB] = t[i]
	}
	W.x.getb().GetB().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i+3*MB] = t[i]
	}

	W.y.geta().GetA().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i+4*MB] = t[i]
	}
	W.y.geta().GetB().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i+5*MB] = t[i]
	}
	W.y.getb().GetA().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i+6*MB] = t[i]
	}
	W.y.getb().GetB().ToBytes(t[:])
	for i := 0; i < MB; i++ {
		b[i+7*MB] = t[i]
	}

}

/* convert from byte array to point */
func ECP4_fromBytes(b []byte) *ECP4 {
	var t [int(MODBYTES)]byte
	MB := int(MODBYTES)

	for i := 0; i < MB; i++ {
		t[i] = b[i]
	}
	ra := FromBytes(t[:])
	for i := 0; i < MB; i++ {
		t[i] = b[i+MB]
	}
	rb := FromBytes(t[:])

	ra4 := NewFP2bigs(ra, rb)

	for i := 0; i < MB; i++ {
		t[i] = b[i+2*MB]
	}
	ra = FromBytes(t[:])
	for i := 0; i < MB; i++ {
		t[i] = b[i+3*MB]
	}
	rb = FromBytes(t[:])

	rb4 := NewFP2bigs(ra, rb)
	rx := NewFP4fp2s(ra4, rb4)

	for i := 0; i < MB; i++ {
		t[i] = b[i+4*MB]
	}
	ra = FromBytes(t[:])
	for i := 0; i < MB; i++ {
		t[i] = b[i+5*MB]
	}
	rb = FromBytes(t[:])

	ra4 = NewFP2bigs(ra, rb)

	for i := 0; i < MB; i++ {
		t[i] = b[i+6*MB]
	}
	ra = FromBytes(t[:])
	for i := 0; i < MB; i++ {
		t[i] = b[i+7*MB]
	}
	rb = FromBytes(t[:])

	rb4 = NewFP2bigs(ra, rb)
	ry := NewFP4fp2s(ra4, rb4)

	return NewECP4fp4s(rx, ry)
}

/* convert this to hex string */
func (E *ECP4) ToString() string {
	W := NewECP4()
	W.Copy(E)
	W.Affine()
	if W.Is_infinity() {
		return "infinity"
	}
	return "(" + W.x.toString() + "," + W.y.toString() + ")"
}

/* Calculate RHS of twisted curve equation x^3+B/i */
func RHS4(x *FP4) *FP4 {
	r := NewFP4copy(x)
	r.sqr()
	b2 := NewFP2big(NewBIGints(CURVE_B))
	b := NewFP4fp2(b2)

	if SEXTIC_TWIST == D_TYPE {
		b.div_i()
	}
	if SEXTIC_TWIST == M_TYPE {
		b.times_i()
	}
	r.mul(x)
	r.add(b)

	r.reduce()
	return r
}

/* construct this from (x,y) - but set to O if not on curve */
func NewECP4fp4s(ix *FP4, iy *FP4) *ECP4 {
	E := new(ECP4)
	E.x = NewFP4copy(ix)
	E.y = NewFP4copy(iy)
	E.z = NewFP4int(1)
	E.x.norm()
	rhs := RHS4(E.x)
	y2 := NewFP4copy(E.y)
	y2.sqr()
	if !y2.Equals(rhs) {
		E.inf()
	}
	return E
}

/* construct this from x - but set to O if not on curve */
func NewECP4fp4(ix *FP4) *ECP4 {
	E := new(ECP4)
	E.x = NewFP4copy(ix)
	E.y = NewFP4int(1)
	E.z = NewFP4int(1)
	E.x.norm()
	rhs := RHS4(E.x)
	if rhs.sqrt() {
		E.y.copy(rhs)
	} else {
		E.inf()
	}
	return E
}

/* this+=this */
func (E *ECP4) dbl() int {
	iy := NewFP4copy(E.y)
	if SEXTIC_TWIST == D_TYPE {
		iy.times_i()
	}

	t0 := NewFP4copy(E.y) //***** Change
	t0.sqr()
	if SEXTIC_TWIST == D_TYPE {
		t0.times_i()
	}
	t1 := NewFP4copy(iy)
	t1.mul(E.z)
	t2 := NewFP4copy(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)
	if SEXTIC_TWIST == M_TYPE {
		t2.times_i()
	}
	x3 := NewFP4copy(t2)
	x3.mul(E.z)

	y3 := NewFP4copy(t0)

	y3.add(t2)
	y3.norm()
	E.z.mul(t1)
	t1.copy(t2)
	t1.add(t2)
	t2.add(t1)
	t2.norm()
	t0.sub(t2)
	t0.norm() //y^2-9bz^2
	y3.mul(t0)
	y3.add(x3) //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
	t1.copy(E.x)
	t1.mul(iy) //
	E.x.copy(t0)
	E.x.norm()
	E.x.mul(t1)
	E.x.add(E.x) //(y^2-9bz^2)xy2

	E.x.norm()
	E.y.copy(y3)
	E.y.norm()

	return 1
}

/* this+=Q - return 0 for add, 1 for double, -1 for O */
func (E *ECP4) Add(Q *ECP4) int {

	b := 3 * CURVE_B_I
	t0 := NewFP4copy(E.x)
	t0.mul(Q.x) // x.Q.x
	t1 := NewFP4copy(E.y)
	t1.mul(Q.y) // y.Q.y

	t2 := NewFP4copy(E.z)
	t2.mul(Q.z)
	t3 := NewFP4copy(E.x)
	t3.add(E.y)
	t3.norm() //t3=X1+Y1
	t4 := NewFP4copy(Q.x)
	t4.add(Q.y)
	t4.norm()  //t4=X2+Y2
	t3.mul(t4) //t3=(X1+Y1)(X2+Y2)
	t4.copy(t0)
	t4.add(t1) //t4=X1.X2+Y1.Y2

	t3.sub(t4)
	t3.norm()
	if SEXTIC_TWIST == D_TYPE {
		t3.times_i() //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
	}
	t4.copy(E.y)
	t4.add(E.z)
	t4.norm() //t4=Y1+Z1
	x3 := NewFP4copy(Q.y)
	x3.add(Q.z)
	x3.norm() //x3=Y2+Z2

	t4.mul(x3) //t4=(Y1+Z1)(Y2+Z2)
	x3.copy(t1)
	x3.add(t2) //X3=Y1.Y2+Z1.Z2

	t4.sub(x3)
	t4.norm()
	if SEXTIC_TWIST == D_TYPE {
		t4.times_i() //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
	}
	x3.copy(E.x)
	x3.add(E.z)
	x3.norm() // x3=X1+Z1
	y3 := NewFP4copy(Q.x)
	y3.add(Q.z)
	y3.norm()  // y3=X2+Z2
	x3.mul(y3) // x3=(X1+Z1)(X2+Z2)
	y3.copy(t0)
	y3.add(t2) // y3=X1.X2+Z1+Z2
	y3.rsub(x3)
	y3.norm() // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1

	if SEXTIC_TWIST == D_TYPE {
		t0.times_i() // x.Q.x
		t1.times_i() // y.Q.y
	}
	x3.copy(t0)
	x3.add(t0)
	t0.add(x3)
	t0.norm()
	t2.imul(b)
	if SEXTIC_TWIST == M_TYPE {
		t2.times_i()
	}
	z3 := NewFP4copy(t1)
	z3.add(t2)
	z3.norm()
	t1.sub(t2)
	t1.norm()
	y3.imul(b)
	if SEXTIC_TWIST == M_TYPE {
		y3.times_i()
	}
	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()

	return 0
}

/* set this-=Q */
func (E *ECP4) Sub(Q *ECP4) int {
	NQ := NewECP4()
	NQ.Copy(Q)
	NQ.neg()
	D := E.Add(NQ)
	return D
}

func ECP4_frob_constants() [3]*FP2 {

	Fra := NewBIGints(Fra)
	Frb := NewBIGints(Frb)
	X := NewFP2bigs(Fra, Frb)

	F0 := NewFP2copy(X)
	F0.sqr()
	F2 := NewFP2copy(F0)
	F2.mul_ip()
	F2.norm()
	F1 := NewFP2copy(F2)
	F1.sqr()
	F2.mul(F1)
	F1.copy(X)
	if SEXTIC_TWIST == M_TYPE {
		F1.mul_ip()
		F1.inverse()
		F0.copy(F1)
		F0.sqr()
	}
	F0.mul_ip()
	F0.norm()
	F1.mul(F0)
	F := [3]*FP2{F0, F1, F2}
	return F
}

/* set this*=q, where q is Modulus, using Frobenius */
func (E *ECP4) frob(F [3]*FP2, n int) {
	for i := 0; i < n; i++ {
		E.x.frob(F[2])
		E.x.pmul(F[0])

		E.y.frob(F[2])
		E.y.pmul(F[1])
		E.y.times_i()

		E.z.frob(F[2])
	}
}

func (E *ECP4) reduce() {
	E.x.reduce()
	E.y.reduce()
	E.z.reduce()
}

/* P*=e */
func (E *ECP4) mul(e *BIG) *ECP4 {
	/* fixed size windows */
	mt := NewBIG()
	t := NewBIG()
	P := NewECP4()
	Q := NewECP4()
	C := NewECP4()

	if E.Is_infinity() {
		return NewECP4()
	}

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

	/* precompute table */
	Q.Copy(E)
	Q.dbl()

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

	for i := 1; i < 8; i++ {
		W = append(W, NewECP4())
		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[(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)
	P.Affine()
	return P
}

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

func ECP4_generator() *ECP4 {
	var G *ECP4
	G = NewECP4fp4s(
		NewFP4fp2s(
			NewFP2bigs(NewBIGints(CURVE_Pxaa), NewBIGints(CURVE_Pxab)),
			NewFP2bigs(NewBIGints(CURVE_Pxba), NewBIGints(CURVE_Pxbb))),
		NewFP4fp2s(
			NewFP2bigs(NewBIGints(CURVE_Pyaa), NewBIGints(CURVE_Pyab)),

			NewFP2bigs(NewBIGints(CURVE_Pyba), NewBIGints(CURVE_Pybb))))
	return G
}

/* needed for SOK */
func ECP4_mapit(h []byte) *ECP4 {
	q := NewBIGints(Modulus)
	hv := FromBytes(h[:])
	one := NewBIGint(1)
	var X2 *FP2
	var X *FP4
	var Q *ECP4
	hv.Mod(q)
	for true {
		X2 = NewFP2bigs(one, hv)
		X = NewFP4fp2(X2)
		Q = NewECP4fp4(X)
		if !Q.Is_infinity() {
			break
		}
		hv.inc(1)
		hv.norm()
	}

	F := ECP4_frob_constants()
	x := NewBIGints(CURVE_Bnx)
	xQ := Q.mul(x)
	x2Q := xQ.mul(x)
	x3Q := x2Q.mul(x)
	x4Q := x3Q.mul(x)

	if SIGN_OF_X == NEGATIVEX {
		xQ.neg()
		x3Q.neg()
	}

	x4Q.Sub(x3Q)
	x4Q.Sub(Q)

	x3Q.Sub(x2Q)
	x3Q.frob(F, 1)

	x2Q.Sub(xQ)
	x2Q.frob(F, 2)

	xQ.Sub(Q)
	xQ.frob(F, 3)

	Q.dbl()
	Q.frob(F, 4)

	Q.Add(x4Q)
	Q.Add(x3Q)
	Q.Add(x2Q)
	Q.Add(xQ)

	Q.Affine()
	return Q
}

/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3.. */
// Bos & Costello https://eprint.iacr.org/2013/458.pdf
// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
// Side channel attack secure
func mul8(Q []*ECP4, u []*BIG) *ECP4 {
	W := NewECP4()
	P := NewECP4()
	var T1 []*ECP4
	var T2 []*ECP4
	mt := NewBIG()
	var t []*BIG
	var bt int8
	var k int

	var w1 [NLEN*int(BASEBITS) + 1]int8
	var s1 [NLEN*int(BASEBITS) + 1]int8
	var w2 [NLEN*int(BASEBITS) + 1]int8
	var s2 [NLEN*int(BASEBITS) + 1]int8

	for i := 0; i < 8; i++ {
		t = append(t, NewBIGcopy(u[i]))
		//Q[i].Affine();
	}

	T1 = append(T1, NewECP4())
	T1[0].Copy(Q[0]) // Q[0]
	T1 = append(T1, NewECP4())
	T1[1].Copy(T1[0])
	T1[1].Add(Q[1]) // Q[0]+Q[1]
	T1 = append(T1, NewECP4())
	T1[2].Copy(T1[0])
	T1[2].Add(Q[2]) // Q[0]+Q[2]
	T1 = append(T1, NewECP4())
	T1[3].Copy(T1[1])
	T1[3].Add(Q[2]) // Q[0]+Q[1]+Q[2]
	T1 = append(T1, NewECP4())
	T1[4].Copy(T1[0])
	T1[4].Add(Q[3]) // Q[0]+Q[3]
	T1 = append(T1, NewECP4())
	T1[5].Copy(T1[1])
	T1[5].Add(Q[3]) // Q[0]+Q[1]+Q[3]
	T1 = append(T1, NewECP4())
	T1[6].Copy(T1[2])
	T1[6].Add(Q[3]) // Q[0]+Q[2]+Q[3]
	T1 = append(T1, NewECP4())
	T1[7].Copy(T1[3])
	T1[7].Add(Q[3]) // Q[0]+Q[1]+Q[2]+Q[3]

	//  Use Frobenius
	F := ECP4_frob_constants()

	for i := 0; i < 8; i++ {
		T2 = append(T2, NewECP4())
		T2[i].Copy(T1[i])
		T2[i].frob(F, 4)
	}

	// Make them odd
	pb1 := 1 - t[0].parity()
	t[0].inc(pb1)

	pb2 := 1 - t[4].parity()
	t[4].inc(pb2)

	// Number of bits
	mt.zero()
	for i := 0; i < 8; i++ {
		t[i].norm()
		mt.or(t[i])
	}

	nb := 1 + mt.nbits()

	// Sign pivot
	s1[nb-1] = 1
	s2[nb-1] = 1
	for i := 0; i < nb-1; i++ {
		t[0].fshr(1)
		s1[i] = 2*int8(t[0].parity()) - 1
		t[4].fshr(1)
		s2[i] = 2*int8(t[4].parity()) - 1

	}

	// Recoded exponents
	for i := 0; i < nb; i++ {
		w1[i] = 0
		k = 1
		for j := 1; j < 4; j++ {
			bt = s1[i] * int8(t[j].parity())
			t[j].fshr(1)
			t[j].dec(int(bt) >> 1)
			t[j].norm()
			w1[i] += bt * int8(k)
			k *= 2
		}
		w2[i] = 0
		k = 1
		for j := 5; j < 8; j++ {
			bt = s2[i] * int8(t[j].parity())
			t[j].fshr(1)
			t[j].dec(int(bt) >> 1)
			t[j].norm()
			w2[i] += bt * int8(k)
			k *= 2
		}
	}

	// Main loop
	P.selector(T1, int32(2*w1[nb-1]+1))
	W.selector(T2, int32(2*w2[nb-1]+1))
	P.Add(W)
	for i := nb - 2; i >= 0; i-- {
		P.dbl()
		W.selector(T1, int32(2*w1[i]+s1[i]))
		P.Add(W)
		W.selector(T2, int32(2*w2[i]+s2[i]))
		P.Add(W)

	}

	// apply correction
	W.Copy(P)
	W.Sub(Q[0])
	P.cmove(W, pb1)
	W.Copy(P)
	W.Sub(Q[4])
	P.cmove(W, pb2)

	P.Affine()
	return P
}
