/*
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.
*/
//
//  ecp2.swift
//  
//
//  Created by Michael Scott on 07/07/2015.
//  Copyright (c) 2015 Michael Scott. All rights reserved.
//

/* CLINT Weierstrass elliptic curve functions over FP2 */

final class ECP2 {
    private var x:FP2
    private var y:FP2
    private var z:FP2
    private var INF:Bool

    /* Constructor - set self=O */
    init()
    {
        INF=true
        x=FP2(0)
        y=FP2(1)
        z=FP2(1)
    }
    /* Test self=O? */
    func is_infinity() -> Bool
    {
        return INF
    }
    /* copy self=P */
    func copy(P:ECP2)
    {
        x.copy(P.x)
        y.copy(P.y)
        z.copy(P.z)
        INF=P.INF
    }
    /* set self=O */
    func inf() {
        INF=true
        x.zero()
        y.zero()
        z.zero()
    }
    /* Conditional move of Q to P dependant on d */
    func cmove(Q:ECP2,_ d:Int32)
    {
        x.cmove(Q.x,d);
        y.cmove(Q.y,d);
        z.cmove(Q.z,d);

        var bd:Bool
        if d==0 {bd=false}
        else {bd=true}
        INF = (INF != ((INF != Q.INF) && bd))
    }

    /* return 1 if b==c, no branching */
    private static func teq(b:Int32,_ c:Int32) -> Int32
    {
        var x=b^c
        x-=1  // if x=0, x now -1
        return ((x>>31)&1)
    }
    /* Constant time select from pre-computed table */
    func select(W:[ECP2],_ b:Int32)
    {
        let MP=ECP2()
        let m=b>>31
        var babs=(b^m)-m

        babs=(babs-1)/2

        cmove(W[0],ECP2.teq(babs,0)) // conditional move
        cmove(W[1],ECP2.teq(babs,1))
        cmove(W[2],ECP2.teq(babs,2))
        cmove(W[3],ECP2.teq(babs,3))
        cmove(W[4],ECP2.teq(babs,4))
        cmove(W[5],ECP2.teq(babs,5))
        cmove(W[6],ECP2.teq(babs,6))
        cmove(W[7],ECP2.teq(babs,7))

        MP.copy(self)
        MP.neg()
        cmove(MP,(m&1))
    }

    /* Test if P == Q */
    func equals(Q:ECP2) -> Bool
    {
        if is_infinity() && Q.is_infinity() {return true}
        if is_infinity() || Q.is_infinity() {return false}

        let zs2=FP2(z); zs2.sqr()
        let zo2=FP2(Q.z); zo2.sqr()
        let zs3=FP2(zs2); zs3.mul(z)
        let zo3=FP2(zo2); zo3.mul(Q.z)
        zs2.mul(Q.x)
        zo2.mul(x)
        if !zs2.equals(zo2) {return false}
        zs3.mul(Q.y)
        zo3.mul(y)
        if !zs3.equals(zo3) {return false}

        return true;
    }
    /* set self=-self */
    func neg()
    {
        if is_infinity() {return}
        y.neg(); y.norm()
        return
    }
    /* set to Affine - (x,y,z) to (x,y) */
    func affine() {
        if is_infinity() {return}
        let one=FP2(1)
        if z.equals(one) {return}
        z.inverse()

        let z2=FP2(z)
        z2.sqr()
        x.mul(z2); x.reduce()
        y.mul(z2)
        y.mul(z);  y.reduce()
        z.copy(one)
    }
    /* extract affine x as FP2 */
    func getX() -> FP2
    {
        affine()
        return x
    }
    /* extract affine y as FP2 */
    func getY() -> FP2
    {
        affine()
        return y
    }
    /* extract projective x */
    func getx() -> FP2
    {
        return x
    }
    /* extract projective y */
    func gety() -> FP2
    {
        return y
    }
    /* extract projective z */
    func getz() -> FP2
    {
        return z
    }
    /* convert to byte array */
    func toBytes(inout b:[UInt8])
    {
        let RM=Int(ROM.MODBYTES)
        var t=[UInt8](count:RM,repeatedValue:0)

        affine();
        x.getA().toBytes(&t)
        for var i=0;i<RM;i++
            {b[i]=t[i]}
        x.getB().toBytes(&t);
        for var i=0;i<RM;i++
            {b[i+RM]=t[i]}

        y.getA().toBytes(&t);
        for var i=0;i<RM;i++
            {b[i+2*RM]=t[i]}
        y.getB().toBytes(&t);
        for var i=0;i<RM;i++
            {b[i+3*RM]=t[i]}
    }
    /* convert from byte array to point */
    static func fromBytes(b:[UInt8]) -> ECP2
    {
        let RM=Int(ROM.MODBYTES)
        var t=[UInt8](count:RM,repeatedValue:0)


        for var i=0;i<RM;i++ {t[i]=b[i]}
        var ra=BIG.fromBytes(t);
        for var i=0;i<RM;i++ {t[i]=b[i+RM]}
        var rb=BIG.fromBytes(t);
        let rx=FP2(ra,rb)

        for var i=0;i<RM;i++ {t[i]=b[i+2*RM]}
        ra=BIG.fromBytes(t)
        for var i=0;i<RM;i++ {t[i]=b[i+3*RM]}
        rb=BIG.fromBytes(t)
        let ry=FP2(ra,rb)

        return ECP2(rx,ry)
    }
/* convert self to hex string */
    func toString() -> String
    {
        if is_infinity() {return "infinity"}
        affine()
        return "("+x.toString()+","+y.toString()+")"
    }

/* Calculate RHS of twisted curve equation x^3+B/i */
    static func RHS(x:FP2) -> FP2
    {
        x.norm()
        let r=FP2(x)
        r.sqr()
        let b=FP2(BIG(ROM.CURVE_B))
        b.div_ip();
        r.mul(x);
        r.add(b);

        r.reduce();
        return r;
    }
/* construct self from (x,y) - but set to O if not on curve */
    init(_ ix:FP2,_ iy:FP2)
    {
        x=FP2(ix)
        y=FP2(iy)
        z=FP2(1)
        let rhs=ECP2.RHS(x)
        let y2=FP2(y)
        y2.sqr()
        if y2.equals(rhs) {INF=false}
        else {x.zero(); INF=true}
    }
    /* construct this from x - but set to O if not on curve */
    init(_ ix:FP2)
    {
        x=FP2(ix)
        y=FP2(1)
        z=FP2(1)
        let rhs=ECP2.RHS(x)
        if rhs.sqrt()
        {
            y.copy(rhs);
            INF=false;
        }
        else {x.zero(); INF=true;}
    }

    /* this+=this */
    func dbl() -> Int
    {
        if (INF) {return -1}
        if y.iszilch()
        {
            inf();
            return -1;
        }

        let w1=FP2(x)
        let w2=FP2(0)
        let w3=FP2(x)
        let w8=FP2(x)

        w1.sqr()
        w8.copy(w1)
        w8.imul(3)

        w2.copy(y); w2.sqr()
        w3.copy(x); w3.mul(w2)
        w3.imul(4)
        w1.copy(w3); w1.neg()
        w1.norm()

        x.copy(w8); x.sqr()
        x.add(w1)
        x.add(w1)
        x.norm()

        z.mul(y)
        z.add(z)

        w2.add(w2)
        w2.sqr()
        w2.add(w2)
        w3.sub(x)
        y.copy(w8); y.mul(w3)
        w2.norm()
        y.sub(w2)
        y.norm()
        z.norm()

        return 1
    }
/* this+=Q - return 0 for add, 1 for double, -1 for O */
    func add(Q:ECP2) -> Int
    {
        if INF
        {
            copy(Q)
            return -1
        }
        if Q.INF {return -1}

        var aff=false

        if Q.z.isunity() {aff=true}

        var A:FP2
        var C:FP2
        let B=FP2(z)
        let D=FP2(z)
        if (!aff)
        {
            A=FP2(Q.z)
            C=FP2(Q.z)

            A.sqr(); B.sqr()
            C.mul(A); D.mul(B)

            A.mul(x)
            C.mul(y)
        }
        else
        {
            A=FP2(x)
            C=FP2(y)

            B.sqr()
            D.mul(B)
        }

        B.mul(Q.x); B.sub(A)
        D.mul(Q.y); D.sub(C)

        if B.iszilch()
        {
            if D.iszilch()
            {
				dbl()
				return 1
            }
            else
            {
				INF=true
				return -1
            }
        }

        if !aff {z.mul(Q.z)}
        z.mul(B)

        let e=FP2(B); e.sqr()
        B.mul(e)
        A.mul(e)

        e.copy(A)
        e.add(A); e.add(B)
        x.copy(D); x.sqr(); x.sub(e)

        A.sub(x)
        y.copy(A); y.mul(D)
        C.mul(B); y.sub(C)

        x.norm()
        y.norm()
        z.norm()

        return 0
    }

    /* set self-=Q */
    func sub(Q:ECP2) -> Int
    {
        Q.neg()
        let D=add(Q)
        Q.neg()
        return D
    }
/* set self*=q, where q is Modulus, using Frobenius */
    func frob(X:FP2)
    {
        if INF {return}
        let X2=FP2(X)
        X2.sqr()
        x.conj()
        y.conj()
        z.conj()
        z.reduce()
        x.mul(X2)
        y.mul(X2)
        y.mul(X)
    }
    /* normalises m-array of ECP2 points. Requires work vector of m FP2s */

    private static func multiaffine(m:Int,_ P:[ECP2])
    {
        let t1=FP2(0)
        let t2=FP2(0)

        var work=[FP2]()
        for var i=0;i<m;i++
            {work.append(FP2(0))}

        work[0].one()
        work[1].copy(P[0].z)

        for var i=2;i<m;i++
        {
            work[i].copy(work[i-1])
            work[i].mul(P[i-1].z)
        }

        t1.copy(work[m-1]); t1.mul(P[m-1].z)

        t1.inverse()

        t2.copy(P[m-1].z)
        work[m-1].mul(t1)

        for var i=m-2;;i--
        {
            if (i==0)
            {
				work[0].copy(t1)
				work[0].mul(t2)
				break;
            }
            work[i].mul(t2)
            work[i].mul(t1)
            t2.mul(P[i].z)
        }
    /* now work[] contains inverses of all Z coordinates */

        for var i=0;i<m;i++
        {
            P[i].z.one()
            t1.copy(work[i]); t1.sqr()
            P[i].x.mul(t1)
            t1.mul(work[i])
            P[i].y.mul(t1)
        }
    }

    /* P*=e */
    func mul(e:BIG) -> ECP2
    {
    /* fixed size windows */
        let mt=BIG()
        let t=BIG()
        let P=ECP2()
        let Q=ECP2()
        let C=ECP2()

        var W=[ECP2]();
        for var i=0;i<8;i++ {W.append(ECP2())}

        var w=[Int8](count:1+(ROM.NLEN*Int(ROM.BASEBITS)+3)/4,repeatedValue:0)

        if is_infinity() {return ECP2()}

        affine()

    /* precompute table */
        Q.copy(self)
        Q.dbl()
        W[0].copy(self)

        for var i=1;i<8;i++
        {
            W[i].copy(W[i-1])
            W[i].add(Q)
        }

    /* convert the table to affine */

        ECP2.multiaffine(8,W);

    /* make exponent odd - add 2P if even, P if odd */
        t.copy(e)
        let s=t.parity()
        t.inc(1); t.norm(); let ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm()
        t.cmove(mt,s)
        Q.cmove(self,ns)
        C.copy(Q)

        let nb=1+(t.nbits()+3)/4
    /* convert exponent to signed 4-bit window */
        for var i=0;i<nb;i++
        {
            w[i]=Int8(t.lastbits(5)-16)
            t.dec(Int32(w[i])); t.norm()
            t.fshr(4)
        }
        w[nb]=Int8(t.lastbits(5))

        P.copy(W[(w[nb]-1)/2])
        for var i=nb-1;i>=0;i--
        {
            Q.select(W,Int32(w[i]))
            P.dbl()
            P.dbl()
            P.dbl()
            P.dbl()
            P.add(Q)
        }
        P.sub(C);
        P.affine()
        return P;
    }

    /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
    static func mul4(Q:[ECP2],_ u:[BIG]) -> ECP2
    {
        var a=[Int32](count:4,repeatedValue:0)
        let T=ECP2()
        let C=ECP2()
        let P=ECP2()

        var W=[ECP2]();
        for var i=0;i<8;i++ {W.append(ECP2())}

        let mt=BIG()
        var t=[BIG]()

        var w=[Int8](count:ROM.NLEN*Int(ROM.BASEBITS)+1,repeatedValue:0)

        for var i=0;i<4;i++
        {
            t.append(BIG(u[i]))
            Q[i].affine()
        }

    /* precompute table */

        W[0].copy(Q[0]); W[0].sub(Q[1])
        W[1].copy(W[0])
        W[2].copy(W[0])
        W[3].copy(W[0])
        W[4].copy(Q[0]); W[4].add(Q[1])
        W[5].copy(W[4])
        W[6].copy(W[4])
        W[7].copy(W[4])
        T.copy(Q[2]); T.sub(Q[3])
        W[1].sub(T)
        W[2].add(T)
        W[5].sub(T)
        W[6].add(T)
        T.copy(Q[2]); T.add(Q[3])
        W[0].sub(T)
        W[3].add(T)
        W[4].sub(T)
        W[7].add(T)

        ECP2.multiaffine(8,W);

    /* if multiplier is even add 1 to multiplier, and add P to correction */
        mt.zero(); C.inf()
        for var i=0;i<4;i++
        {
            if (t[i].parity()==0)
            {
				t[i].inc(1); t[i].norm()
                C.add(Q[i])
            }
            mt.add(t[i]); mt.norm()
        }

        let nb=1+mt.nbits();

    /* convert exponent to signed 1-bit window */
        for var j=0;j<nb;j++
        {
            for var i=0;i<4;i++
            {
				a[i]=(t[i].lastbits(2)-2)
				t[i].dec(a[i]); t[i].norm()
				t[i].fshr(1)
            }
            w[j]=Int8(8*a[0]+4*a[1]+2*a[2]+a[3])
        }
        w[nb]=Int8(8*t[0].lastbits(2)+4*t[1].lastbits(2))
        w[nb]+=Int8(2*t[2].lastbits(2)+t[3].lastbits(2))

        P.copy(W[(w[nb]-1)/2])
        for var i=nb-1;i>=0;i--
        {
            T.select(W,Int32(w[i]))
            P.dbl()
            P.add(T)
        }
        P.sub(C) /* apply correction */

        P.affine()
        return P
    }



}
