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

/* MPIN Functions */

/* Version 3.0 - supports Time Permits */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "mpin192_ZZZ.h"

#define ROUNDUP(a,b) ((a)-1)/(b)+1

/* Special mpin hashing */
static void mpin_hash(int sha,FP8_YYY *f, ECP_ZZZ *P,octet *w)
{
    int i;
    BIG_XXX x,y;
    char h[64];
    hash256 sha256;
    hash512 sha512;
    char t[10*MODBYTES_XXX];  // to hold 10 BIGs
    int hlen=sha;


    FP_YYY_redc(x,&(f->a.a.a));
    BIG_XXX_toBytes(&t[0],x);
    FP_YYY_redc(x,&(f->a.a.b));
    BIG_XXX_toBytes(&t[MODBYTES_XXX],x);
    FP_YYY_redc(x,&(f->a.b.a));
    BIG_XXX_toBytes(&t[2*MODBYTES_XXX],x);
    FP_YYY_redc(x,&(f->a.b.b));
    BIG_XXX_toBytes(&t[3*MODBYTES_XXX],x);

    FP_YYY_redc(x,&(f->b.a.a));
    BIG_XXX_toBytes(&t[4*MODBYTES_XXX],x);
    FP_YYY_redc(x,&(f->b.a.b));
    BIG_XXX_toBytes(&t[5*MODBYTES_XXX],x);
    FP_YYY_redc(x,&(f->b.b.a));
    BIG_XXX_toBytes(&t[6*MODBYTES_XXX],x);
    FP_YYY_redc(x,&(f->b.b.b));
    BIG_XXX_toBytes(&t[7*MODBYTES_XXX],x);

    ECP_ZZZ_get(x,y,P);
    BIG_XXX_toBytes(&t[8*MODBYTES_XXX],x);
    BIG_XXX_toBytes(&t[9*MODBYTES_XXX],y);

    OCT_empty(w);
    switch (sha)
    {
    case SHA256:
        HASH256_init(&sha256);
        for (i=0; i<10*MODBYTES_XXX; i++) HASH256_process(&sha256,t[i]);
        HASH256_hash(&sha256,h);
        break;
    case SHA384:
        HASH384_init(&sha512);
        for (i=0; i<10*MODBYTES_XXX; i++) HASH384_process(&sha512,t[i]);
        HASH384_hash(&sha512,h);
        break;
    case SHA512:
        HASH512_init(&sha512);
        for (i=0; i<10*MODBYTES_XXX; i++) HASH512_process(&sha512,t[i]);
        HASH512_hash(&sha512,h);
        break;
    }

    OCT_jbytes(w,h,AESKEY_ZZZ);
    for (i=0; i<hlen; i++) h[i]=0;
}

/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
/* maps a random u to a point on the curve */
static void map(ECP_ZZZ *P,BIG_XXX u,int cb)
{
    BIG_XXX x,q;

    BIG_XXX_rcopy(q,Modulus_YYY);
    BIG_XXX_copy(x,u);
    BIG_XXX_mod(x,q);

    while (!ECP_ZZZ_setx(P,x,cb))
    {
        BIG_XXX_inc(x,1);
        BIG_XXX_norm(x);
    }
}

/* returns u derived from P. Random value in range 1 to return value should then be added to u */
static int unmap(BIG_XXX u,int *cb,ECP_ZZZ *P)
{
    int s,r=0;
    BIG_XXX x;

    s=ECP_ZZZ_get(x,x,P);
    BIG_XXX_copy(u,x);
    do
    {
        BIG_XXX_dec(u,1);
        BIG_XXX_norm(u);
        r++;
    }
    while (!ECP_ZZZ_setx(P,u,s));
    ECP_ZZZ_setx(P,x,s);

    *cb=s;

    return r;
}

/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
/* Note that u and v are indistinguisible from random strings */
int MPIN_ZZZ_ENCODING(csprng *RNG,octet *E)
{
    int rn,m,su,sv,res=0;

    BIG_XXX q,u,v;
    ECP_ZZZ P,W;

    if (!ECP_ZZZ_fromOctet(&P,E)) res=MPIN_INVALID_POINT;
    if (res==0)
    {
        BIG_XXX_rcopy(q,Modulus_YYY);

        BIG_XXX_randomnum(u,q,RNG);

        su=RAND_byte(RNG);
        if (su<0) su=-su;
        su%=2;
        map(&W,u,su);
        ECP_ZZZ_sub(&P,&W);

        rn=unmap(v,&sv,&P);
        m=RAND_byte(RNG);
        if (m<0) m=-m;
        m%=rn;
        BIG_XXX_inc(v,m+1);
        E->val[0]=su+2*sv;
        BIG_XXX_toBytes(&(E->val[1]),u);
        BIG_XXX_toBytes(&(E->val[PFS_ZZZ+1]),v);
    }
    return res;
}

int MPIN_ZZZ_DECODING(octet *D)
{
    int su,sv;
    BIG_XXX u,v;
    ECP_ZZZ P,W;
    int res=0;

    if ((D->val[0]&0x04)!=0) res=MPIN_INVALID_POINT;
    if (res==0)
    {

        BIG_XXX_fromBytes(u,&(D->val[1]));
        BIG_XXX_fromBytes(v,&(D->val[PFS_ZZZ+1]));

        su=D->val[0]&1;
        sv=(D->val[0]>>1)&1;
        map(&W,u,su);
        map(&P,v,sv);
        ECP_ZZZ_add(&P,&W);
        ECP_ZZZ_toOctet(D,&P,false);
    }

    return res;
}

/* R=R1+R2 in group G1 */
int MPIN_ZZZ_RECOMBINE_G1(octet *R1,octet *R2,octet *R)
{
    ECP_ZZZ P,T;
    int res=0;
    if (res==0)
    {
        if (!ECP_ZZZ_fromOctet(&P,R1)) res=MPIN_INVALID_POINT;
        if (!ECP_ZZZ_fromOctet(&T,R2)) res=MPIN_INVALID_POINT;
    }
    if (res==0)
    {
        ECP_ZZZ_add(&P,&T);
        ECP_ZZZ_toOctet(R,&P,false);
    }
    return res;
}

/* W=W1+W2 in group G2 */
int MPIN_ZZZ_RECOMBINE_G2(octet *W1,octet *W2,octet *W)
{
    ECP4_ZZZ Q,T;
    int res=0;
    if (!ECP4_ZZZ_fromOctet(&Q,W1)) res=MPIN_INVALID_POINT;
    if (!ECP4_ZZZ_fromOctet(&T,W2)) res=MPIN_INVALID_POINT;
    if (res==0)
    {
        ECP4_ZZZ_add(&Q,&T);
        ECP4_ZZZ_toOctet(W,&Q);
    }
    return res;
}

/* create random secret S */
int MPIN_ZZZ_RANDOM_GENERATE(csprng *RNG,octet* S)
{
    BIG_XXX r,s;

    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
    BIG_XXX_randomnum(s,r,RNG);
#ifdef AES_S
    BIG_XXX_mod2m(s,2*AES_S);
#endif
    BIG_XXX_toBytes(S->val,s);
    S->len=MODBYTES_XXX;
    return 0;
}

/* Extract PIN from TOKEN for identity CID */
int MPIN_ZZZ_EXTRACT_PIN(int sha,octet *CID,int pin,octet *TOKEN)
{
    pin%=MAXPIN;
    return MPIN_ZZZ_EXTRACT_FACTOR(sha,CID,pin,PBLEN,TOKEN);
}

/* Extract a factor < 32 bits for identity CID */
int MPIN_ZZZ_EXTRACT_FACTOR(int sha,octet *CID,int factor,int facbits,octet *TOKEN)
{
    ECP_ZZZ P,R;
    int res=0;
    char h[MODBYTES_XXX];
    octet H= {0,sizeof(h),h};

    if (!ECP_ZZZ_fromOctet(&P,TOKEN))  res=MPIN_INVALID_POINT;
    if (res==0)
    {
        mhashit(sha,-1,CID,&H);
        ECP_ZZZ_mapit(&R,&H);

        ECP_ZZZ_pinmul(&R,factor,facbits);
        ECP_ZZZ_sub(&P,&R);

        ECP_ZZZ_toOctet(TOKEN,&P,false);
    }
    return res;
}

/* Extract a factor < 32 bits for identity CID */
int MPIN_ZZZ_RESTORE_FACTOR(int sha,octet *CID,int factor,int facbits,octet *TOKEN)
{
    ECP_ZZZ P,R;
    int res=0;
    char h[MODBYTES_XXX];
    octet H= {0,sizeof(h),h};

    if (!ECP_ZZZ_fromOctet(&P,TOKEN))  res=MPIN_INVALID_POINT;
    if (res==0)
    {
        mhashit(sha,-1,CID,&H);
        ECP_ZZZ_mapit(&R,&H);

        ECP_ZZZ_pinmul(&R,factor,facbits);
        ECP_ZZZ_add(&P,&R);

        ECP_ZZZ_toOctet(TOKEN,&P,false);
    }
    return res;
}

/* Implement step 2 on client side of MPin protocol - SEC=-(x+y)*SEC */
int MPIN_ZZZ_CLIENT_2(octet *X,octet *Y,octet *SEC)
{
    BIG_XXX px,py,r;
    ECP_ZZZ P;
    int res=0;
    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
    if (!ECP_ZZZ_fromOctet(&P,SEC)) res=MPIN_INVALID_POINT;
    if (res==0)
    {
        BIG_XXX_fromBytes(px,X->val);
        BIG_XXX_fromBytes(py,Y->val);
        BIG_XXX_add(px,px,py);
        BIG_XXX_mod(px,r);
        PAIR_ZZZ_G1mul(&P,px);
        ECP_ZZZ_neg(&P);
        ECP_ZZZ_toOctet(SEC,&P,false);
    }
    return res;
}

/*
 W=x*H(G);
 if RNG == NULL then X is passed in
 if RNG != NULL the X is passed out
 if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
*/

int MPIN_ZZZ_GET_G1_MULTIPLE(csprng *RNG,int type,octet *X,octet *G,octet *W)
{
    ECP_ZZZ P;
    BIG_XXX r,x;
    int res=0;
    if (RNG!=NULL)
    {
        BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
        BIG_XXX_randomnum(x,r,RNG);
#ifdef AES_S
        BIG_XXX_mod2m(x,2*AES_S);
#endif
        X->len=MODBYTES_XXX;
        BIG_XXX_toBytes(X->val,x);
    }
    else
        BIG_XXX_fromBytes(x,X->val);

    if (type==0)
    {
        if (!ECP_ZZZ_fromOctet(&P,G)) res=MPIN_INVALID_POINT;
    }
    else
    {
        ECP_ZZZ_mapit(&P,G);
    }

    if (res==0)
    {
        PAIR_ZZZ_G1mul(&P,x);
        ECP_ZZZ_toOctet(W,&P,false);
    }
    return res;
}

/*
 if RNG == NULL then X is passed in
 if RNG != NULL the X is passed out
 W=x*G where G is point on the curve
 if type==1 W=(x^-1)G
*/

int MPIN_ZZZ_GET_G2_MULTIPLE(csprng *RNG,int type,octet *X,octet *G,octet *W)
{
    ECP4_ZZZ P;
    BIG_XXX r,x;
    int res=0;
    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
    if (RNG!=NULL)
    {
        BIG_XXX_randomnum(x,r,RNG);
#ifdef AES_S
        BIG_XXX_mod2m(x,2*AES_S);
#endif
        X->len=MODBYTES_XXX;
        BIG_XXX_toBytes(X->val,x);
    }
    else
    {
        BIG_XXX_fromBytes(x,X->val);
        if (type==1) BIG_XXX_invmodp(x,x,r);
    }

    if (!ECP4_ZZZ_fromOctet(&P,G)) res=MPIN_INVALID_POINT;

    if (res==0)
    {
        PAIR_ZZZ_G2mul(&P,x);
        ECP4_ZZZ_toOctet(W,&P);
    }
    return res;
}



/* Client secret CST=s*H(CID) where CID is client ID and s is master secret */
/* CID is hashed externally */
int MPIN_ZZZ_GET_CLIENT_SECRET(octet *S,octet *CID,octet *CST)
{
    return MPIN_ZZZ_GET_G1_MULTIPLE(NULL,1,S,CID,CST);
}

/* Implement step 1 on client side of MPin protocol */
int MPIN_ZZZ_CLIENT_1(int sha,int date,octet *CLIENT_ID,csprng *RNG,octet *X,int pin,octet *TOKEN,octet *SEC,octet *xID,octet *xCID,octet *PERMIT)
{
    BIG_XXX r,x;
    ECP_ZZZ P,T,W;
    int res=0;
    char h[MODBYTES_XXX];
    octet H= {0,sizeof(h),h};

    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
    if (RNG!=NULL)
    {
        BIG_XXX_randomnum(x,r,RNG);
#ifdef AES_S
        BIG_XXX_mod2m(x,2*AES_S);
#endif
        X->len=MODBYTES_XXX;
        BIG_XXX_toBytes(X->val,x);
    }
    else
        BIG_XXX_fromBytes(x,X->val);

    mhashit(sha,-1,CLIENT_ID,&H);

    ECP_ZZZ_mapit(&P,&H);

    if (!ECP_ZZZ_fromOctet(&T,TOKEN)) res=MPIN_INVALID_POINT;

    if (res==0)
    {
        pin%=MAXPIN;

        ECP_ZZZ_copy(&W,&P);				// W=H(ID)
        ECP_ZZZ_pinmul(&W,pin,PBLEN);			// W=alpha.H(ID)
        ECP_ZZZ_add(&T,&W);					// T=Token+alpha.H(ID) = s.H(ID)

        if (date)
        {
            if (PERMIT!=NULL)
            {
                if (!ECP_ZZZ_fromOctet(&W,PERMIT)) res=MPIN_INVALID_POINT;
                ECP_ZZZ_add(&T,&W);					// SEC=s.H(ID)+s.H(T|ID)
            }
            mhashit(sha,date,&H,&H);

            ECP_ZZZ_mapit(&W,&H);
            if (xID!=NULL)
            {
                PAIR_ZZZ_G1mul(&P,x);				// P=x.H(ID)
                ECP_ZZZ_toOctet(xID,&P,false);  // xID
                PAIR_ZZZ_G1mul(&W,x);               // W=x.H(T|ID)
                ECP_ZZZ_add(&P,&W);
            }
            else
            {
                ECP_ZZZ_add(&P,&W);
                PAIR_ZZZ_G1mul(&P,x);
            }
            if (xCID!=NULL) ECP_ZZZ_toOctet(xCID,&P,false);  // U
        }
        else
        {
            if (xID!=NULL)
            {
                PAIR_ZZZ_G1mul(&P,x);				// P=x.H(ID)
                ECP_ZZZ_toOctet(xID,&P,false);  // xID
            }
        }
    }

    if (res==0)
    {
        ECP_ZZZ_toOctet(SEC,&T,false);  // V
    }
    return res;
}

/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
int MPIN_ZZZ_GET_SERVER_SECRET(octet *S,octet *SST)
{
    BIG_XXX r,s;
    ECP4_ZZZ Q;
    int res=0;

    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);

    ECP4_ZZZ_generator(&Q);

    if (res==0)
    {
        BIG_XXX_fromBytes(s,S->val);
        PAIR_ZZZ_G2mul(&Q,s);
        ECP4_ZZZ_toOctet(SST,&Q);
    }

    return res;
}


/* Time Permit CTT=s*H(date|H(CID)) where s is master secret */
int MPIN_ZZZ_GET_CLIENT_PERMIT(int sha,int date,octet *S,octet *CID,octet *CTT)
{
    BIG_XXX s;
    ECP_ZZZ P;
    char h[MODBYTES_XXX];
    octet H= {0,sizeof(h),h};

    mhashit(sha,date,CID,&H);

    ECP_ZZZ_mapit(&P,&H);

    BIG_XXX_fromBytes(s,S->val);

    PAIR_ZZZ_G1mul(&P,s);

    ECP_ZZZ_toOctet(CTT,&P,false);
    return 0;
}

// if date=0 only use HID, set HCID=NULL
// if date and PE, use HID and HCID

/* Outputs H(CID) and H(CID)+H(T|H(CID)) for time permits. If no time permits set HTID=NULL */
void MPIN_ZZZ_SERVER_1(int sha,int date,octet *CID,octet *HID,octet *HTID)
{
    char h[MODBYTES_XXX];
    octet H= {0,sizeof(h),h};
    ECP_ZZZ P,R;

#ifdef USE_ANONYMOUS
    ECP_ZZZ_mapit(&P,CID);
#else
    mhashit(sha,-1,CID,&H);
    ECP_ZZZ_mapit(&P,&H);
#endif

    ECP_ZZZ_toOctet(HID,&P,false);  // new

    if (date)
    {
#ifdef USE_ANONYMOUS
        mhashit(sha,date,CID,&H);
#else
        mhashit(sha,date,&H,&H);
#endif
        ECP_ZZZ_mapit(&R,&H);
        ECP_ZZZ_add(&P,&R);
        ECP_ZZZ_toOctet(HTID,&P,false);
    }
}

/* Implement M-Pin on server side */
int MPIN_ZZZ_SERVER_2(int date,octet *HID,octet *HTID,octet *Y,octet *SST,octet *xID,octet *xCID,octet *mSEC,octet *E,octet *F,octet *Pa)
{
    BIG_XXX y;
    FP24_YYY g;
    ECP4_ZZZ Q,sQ;
    ECP_ZZZ P,R;
    int res=0;

    ECP4_ZZZ_generator(&Q);

    // key-escrow less scheme: use Pa instead of Q in pairing computation
    // Q left for backward compatiblity
    if (Pa!=NULL)
    {
        if (!ECP4_ZZZ_fromOctet(&Q, Pa)) res=MPIN_INVALID_POINT;
    }


    if (res==0)
    {
        if (!ECP4_ZZZ_fromOctet(&sQ,SST)) res=MPIN_INVALID_POINT;
    }

    if (res==0)
    {
        if (date)
        {
            if (!ECP_ZZZ_fromOctet(&R,xCID))  res=MPIN_INVALID_POINT;
        }
        else
        {
            if (!ECP_ZZZ_fromOctet(&R,xID))  res=MPIN_INVALID_POINT;
        }
    }
    if (res==0)
    {
        BIG_XXX_fromBytes(y,Y->val);
        if (date)
        {
            if (!ECP_ZZZ_fromOctet(&P,HTID))  res=MPIN_INVALID_POINT;
        }
        else
        {
            if (!ECP_ZZZ_fromOctet(&P,HID))  res=MPIN_INVALID_POINT;
        }
    }
    if (res==0)
    {
        PAIR_ZZZ_G1mul(&P,y);  // y(A+AT)
        ECP_ZZZ_add(&P,&R); // x(A+AT)+y(A+T)
        if (!ECP_ZZZ_fromOctet(&R,mSEC))  res=MPIN_INVALID_POINT; // V
    }
    if (res==0)
    {

        PAIR_ZZZ_double_ate(&g,&Q,&R,&sQ,&P);
        PAIR_ZZZ_fexp(&g);

        if (!FP24_YYY_isunity(&g))
        {
            if (HID!=NULL && xID!=NULL && E!=NULL && F !=NULL)
            {
                /* xID is set to NULL if there is no way to calculate PIN error */
                FP24_YYY_toOctet(E,&g);

                /* Note error is in the PIN, not in the time permit! Hence the need to exclude Time Permit from this check */

                if (date)
                {
                    if (!ECP_ZZZ_fromOctet(&P,HID)) res=MPIN_INVALID_POINT;
                    if (!ECP_ZZZ_fromOctet(&R,xID)) res=MPIN_INVALID_POINT; // U

                    if (res==0)
                    {
                        PAIR_ZZZ_G1mul(&P,y);  // yA
                        ECP_ZZZ_add(&P,&R); // yA+xA
                    }
                }
                if (res==0)
                {
                    PAIR_ZZZ_ate(&g,&Q,&P);
                    PAIR_ZZZ_fexp(&g);
                    FP24_YYY_toOctet(F,&g);
                }
            }
            res=MPIN_BAD_PIN;
        }
    }

    return res;
}

#if MAXPIN==10000
#define MR_TS 10  /* 2^10/10 approx = sqrt(MAXPIN) */
#define TRAP 200  /* 2*sqrt(MAXPIN) */
#endif

#if MAXPIN==1000000
#define MR_TS 14
#define TRAP 2000
#endif

/* Pollards kangaroos used to return PIN error */
int MPIN_ZZZ_KANGAROO(octet *E,octet *F)
{
    int i,j,m,s,dn,dm,steps;
    int distance[MR_TS];
    FP24_YYY ge,gf,t,table[MR_TS];
    int res=0;

    FP24_YYY_fromOctet(&ge,E);
    FP24_YYY_fromOctet(&gf,F);

    FP24_YYY_copy(&t,&gf);

    for (s=1,m=0; m<MR_TS; m++)
    {
        distance[m]=s;
        FP24_YYY_copy(&table[m],&t);
        s*=2;
        FP24_YYY_usqr(&t,&t);
        FP24_YYY_reduce(&t);
    }

    FP24_YYY_one(&t);

    for (dn=0,j=0; j<TRAP; j++)
    {
        i=t.a.a.a.a.g[0]%MR_TS;

        FP24_YYY_mul(&t,&table[i]);
        FP24_YYY_reduce(&t);
        dn+=distance[i];
    }

    FP24_YYY_conj(&gf,&t);
    steps=0;
    dm=0;
    while (dm-dn<MAXPIN)
    {
        steps++;
        if (steps>4*TRAP) break;

        i=ge.a.a.a.a.g[0]%MR_TS;

        FP24_YYY_mul(&ge,&table[i]);
        FP24_YYY_reduce(&ge);
        dm+=distance[i];
        if (FP24_YYY_equals(&ge,&t))
        {
            res=dm-dn;
            break;
        }
        if (FP24_YYY_equals(&ge,&gf))
        {
            res=dn-dm;
            break;
        }
    }
    if (steps>4*TRAP || dm-dn>=MAXPIN)
    {
        res=0;    /* Trap Failed  - probable invalid token */
    }

    return res;
}

/* Functions to support M-Pin Full */

int MPIN_ZZZ_PRECOMPUTE(octet *TOKEN,octet *CID,octet *CP,octet *G1,octet *G2)
{
    ECP_ZZZ P,T;
    ECP4_ZZZ Q;
    FP24_YYY g;
    int res=0;

    if (!ECP_ZZZ_fromOctet(&T,TOKEN)) res=MPIN_INVALID_POINT;

    if (res==0)
    {
        ECP_ZZZ_mapit(&P,CID);
        if (CP!=NULL)
        {
            if (!ECP4_ZZZ_fromOctet(&Q,CP)) res=MPIN_INVALID_POINT;
        }
        else
        {
            ECP4_ZZZ_generator(&Q);
        }
    }
    if (res==0)
    {
        PAIR_ZZZ_ate(&g,&Q,&T);
        PAIR_ZZZ_fexp(&g);

        FP24_YYY_toOctet(G1,&g);
        if (G2!=NULL)
        {
            PAIR_ZZZ_ate(&g,&Q,&P);
            PAIR_ZZZ_fexp(&g);
            FP24_YYY_toOctet(G2,&g);
        }
    }
    return res;
}

/* calculate common key on client side */
/* wCID = w.(A+AT) */
int MPIN_ZZZ_CLIENT_KEY(int sha,octet *G1,octet *G2,int pin,octet *R,octet *X,octet *H,octet *wCID,octet *CK)
{
    FP24_YYY g1,g2;
    FP8_YYY c;

    ECP_ZZZ W;
    int res=0;
    BIG_XXX r,z,x,h;

    FP24_YYY_fromOctet(&g1,G1);
    FP24_YYY_fromOctet(&g2,G2);
    BIG_XXX_fromBytes(z,R->val);
    BIG_XXX_fromBytes(x,X->val);
    BIG_XXX_fromBytes(h,H->val);

    if (!ECP_ZZZ_fromOctet(&W,wCID)) res=MPIN_INVALID_POINT;

    if (res==0)
    {
        BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
        BIG_XXX_add(z,z,h);    // new
        BIG_XXX_mod(z,r);

        FP24_YYY_pinpow(&g2,pin,PBLEN);
        FP24_YYY_mul(&g1,&g2);

        PAIR_ZZZ_G1mul(&W,x);

        FP24_YYY_compow(&c,&g1,z,r);
        mpin_hash(sha,&c,&W,CK);

    }
    return res;
}

/* calculate common key on server side */
/* Z=r.A - no time permits involved */

int MPIN_ZZZ_SERVER_KEY(int sha,octet *Z,octet *SST,octet *W,octet *H,octet *HID,octet *xID,octet *xCID,octet *SK)
{
    int res=0;
    FP24_YYY g;
    FP8_YYY c;
    ECP_ZZZ R,U,A;
    ECP4_ZZZ sQ;
    BIG_XXX w,h;

    if (!ECP4_ZZZ_fromOctet(&sQ,SST)) res=MPIN_INVALID_POINT;
    if (!ECP_ZZZ_fromOctet(&R,Z)) res=MPIN_INVALID_POINT;


    if (!ECP_ZZZ_fromOctet(&A,HID)) res=MPIN_INVALID_POINT;

    // new
    if (xCID!=NULL)
    {
        if (!ECP_ZZZ_fromOctet(&U,xCID)) res=MPIN_INVALID_POINT;
    }
    else
    {
        if (!ECP_ZZZ_fromOctet(&U,xID)) res=MPIN_INVALID_POINT;
    }
    BIG_XXX_fromBytes(w,W->val);
    BIG_XXX_fromBytes(h,H->val);


    PAIR_ZZZ_ate(&g,&sQ,&A);
    PAIR_ZZZ_fexp(&g);

    if (res==0)
    {
        PAIR_ZZZ_G1mul(&A,h);
        ECP_ZZZ_add(&R,&A);  // new
        PAIR_ZZZ_ate(&g,&sQ,&R);
        PAIR_ZZZ_fexp(&g);
        PAIR_ZZZ_G1mul(&U,w);
        FP24_YYY_trace(&c,&g);
        mpin_hash(sha,&c,&U,SK);
    }
    return res;
}

/* Generate Y = H(TimeValue, xCID/xID) */
void MPIN_ZZZ_GET_Y(int sha,int TimeValue,octet *xCID,octet *Y)
{
    BIG_XXX q,y;
    char h[MODBYTES_XXX];
    octet H= {0,sizeof(h),h};

    mhashit(sha,TimeValue,xCID,&H);
    BIG_XXX_fromBytes(y,H.val);
    BIG_XXX_rcopy(q,CURVE_Order_ZZZ);
    BIG_XXX_mod(y,q);
    BIG_XXX_toBytes(Y->val,y);
    Y->len=PGS_ZZZ;
}

/* One pass MPIN Client */
int MPIN_ZZZ_CLIENT(int sha,int date,octet *ID,csprng *RNG,octet *X,int pin,octet *TOKEN,octet *V,octet *U,octet *UT,octet *TP,octet *MESSAGE,int TimeValue,octet *Y)
{
    int rtn=0;
    char m[M_SIZE_ZZZ];
    octet M= {0,sizeof(m),m};

    octet *pID;
    if (date == 0)
        pID = U;
    else
        pID = UT;

    rtn = MPIN_ZZZ_CLIENT_1(sha,date,ID,RNG,X,pin,TOKEN,V,U,UT,TP);
    if (rtn != 0)
        return rtn;

    OCT_joctet(&M,pID);
    if (MESSAGE!=NULL)
    {
        OCT_joctet(&M,MESSAGE);
    }

    MPIN_ZZZ_GET_Y(sha,TimeValue,&M,Y);

    rtn = MPIN_ZZZ_CLIENT_2(X,Y,V);
    if (rtn != 0)
        return rtn;

    return 0;
}

/* One pass MPIN Server */
int MPIN_ZZZ_SERVER(int sha,int date,octet *HID,octet *HTID,octet *Y,octet *sQ,octet *U,octet *UT,octet *V,octet *E,octet *F,octet *ID,octet *MESSAGE,int TimeValue, octet *Pa)
{
    int rtn=0;
    char m[M_SIZE_ZZZ];
    octet M= {0,sizeof(m),m};

    octet *pU;
    if (date == 0)
        pU = U;
    else
        pU = UT;

    MPIN_ZZZ_SERVER_1(sha,date,ID,HID,HTID);

    OCT_joctet(&M,pU);
    if (MESSAGE!=NULL)
    {
        OCT_joctet(&M,MESSAGE);
    }

    MPIN_ZZZ_GET_Y(sha,TimeValue,&M,Y);

    rtn = MPIN_ZZZ_SERVER_2(date,HID,HTID,Y,sQ,U,UT,V,E,F,Pa);
    if (rtn != 0)
        return rtn;

    return 0;
}

int MPIN_ZZZ_GET_DVS_KEYPAIR(csprng *R,octet *Z,octet *Pa)
{
    BIG_XXX z,r;
    ECP4_ZZZ Q;
    int res=0;

    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);

    if (R!=NULL)
    {
        BIG_XXX_randomnum(z,r,R);
        Z->len=MODBYTES_XXX;
        BIG_XXX_toBytes(Z->val,z);
    }
    else
        BIG_XXX_fromBytes(z,Z->val);

    BIG_XXX_invmodp(z,z,r);

    ECP4_ZZZ_generator(&Q);

    if (res==0)
    {
        PAIR_ZZZ_G2mul(&Q,z);
        ECP4_ZZZ_toOctet(Pa,&Q);
    }

    return res;
}
