/*
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 "mpin256_ZZZ.h"


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


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

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

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

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

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

	FP_YYY_redc(x,&(f->b.a.a.a));
    BIG_XXX_toBytes(&t[8*MODBYTES_XXX],x);
	FP_YYY_redc(x,&(f->b.a.a.b));
    BIG_XXX_toBytes(&t[9*MODBYTES_XXX],x);

    FP_YYY_redc(x,&(f->b.a.b.a));
    BIG_XXX_toBytes(&t[10*MODBYTES_XXX],x);
	FP_YYY_redc(x,&(f->b.a.b.b));
    BIG_XXX_toBytes(&t[11*MODBYTES_XXX],x);

    FP_YYY_redc(x,&(f->b.b.a.a));
    BIG_XXX_toBytes(&t[12*MODBYTES_XXX],x);
    FP_YYY_redc(x,&(f->b.b.a.b));
    BIG_XXX_toBytes(&t[13*MODBYTES_XXX],x);

    FP_YYY_redc(x,&(f->b.b.b.a));
    BIG_XXX_toBytes(&t[14*MODBYTES_XXX],x);
    FP_YYY_redc(x,&(f->b.b.b.b));
    BIG_XXX_toBytes(&t[15*MODBYTES_XXX],x);

    ECP_ZZZ_get(x,y,P);
    BIG_XXX_toBytes(&t[16*MODBYTES_XXX],x);
    BIG_XXX_toBytes(&t[17*MODBYTES_XXX],y);

    OCT_empty(w);
    switch (sha)
    {
    case SHA256:
        HASH256_init(&sha256);
        for (i=0; i<18*MODBYTES_XXX; i++) HASH256_process(&sha256,t[i]);
        HASH256_hash(&sha256,h);
        break;
    case SHA384:
        HASH384_init(&sha512);
        for (i=0; i<18*MODBYTES_XXX; i++) HASH384_process(&sha512,t[i]);
        HASH384_hash(&sha512,h);
        break;
    case SHA512:
        HASH512_init(&sha512);
        for (i=0; i<18*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)
{
    ECP8_ZZZ Q,T;
    int res=0;
    if (!ECP8_ZZZ_fromOctet(&Q,W1)) res=MPIN_INVALID_POINT;
    if (!ECP8_ZZZ_fromOctet(&T,W2)) res=MPIN_INVALID_POINT;
    if (res==0)
    {
        ECP8_ZZZ_add(&Q,&T); 
        ECP8_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)
{
    ECP8_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 (!ECP8_ZZZ_fromOctet(&P,G)) res=MPIN_INVALID_POINT;

    if (res==0)
    {
        PAIR_ZZZ_G2mul(&P,x);
        ECP8_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;
    ECP8_ZZZ Q;
    int res=0;

    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);

	ECP8_ZZZ_generator(&Q);

    if (res==0)
    {
        BIG_XXX_fromBytes(s,S->val);
        PAIR_ZZZ_G2mul(&Q,s);
        ECP8_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;
	BIG_XXX x;

#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 px,py,y;
    FP48_YYY g;
    ECP8_ZZZ Q,sQ;
    ECP_ZZZ P,R;
    int res=0;

	ECP8_ZZZ_generator(&Q);

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


    if (res==0)
    {
        if (!ECP8_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 (!FP48_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 */
                FP48_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);
                    FP48_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];
    FP48_YYY ge,gf,t,table[MR_TS];
    int res=0;

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

    FP48_YYY_copy(&t,&gf);

    for (s=1,m=0; m<MR_TS; m++)
    {
        distance[m]=s;
        FP48_YYY_copy(&table[m],&t);
        s*=2;
        FP48_YYY_usqr(&t,&t);
        FP48_YYY_reduce(&t);
    }

    FP48_YYY_one(&t);

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

        FP48_YYY_mul(&t,&table[i]);
        FP48_YYY_reduce(&t);
        dn+=distance[i];
    }

    FP48_YYY_conj(&gf,&t);
    steps=0;
    dm=0;
    while (dm-dn<MAXPIN)
    {
        steps++;
        if (steps>4*TRAP) break;
        i=ge.a.a.a.a.a.g[0]%MR_TS;

        FP48_YYY_mul(&ge,&table[i]);
        FP48_YYY_reduce(&ge);
        dm+=distance[i];
        if (FP48_YYY_equals(&ge,&t))
        {
            res=dm-dn;
            break;
        }
        if (FP48_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;
    ECP8_ZZZ Q;
    FP48_YYY g;
	BIG_XXX x;
    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 (!ECP8_ZZZ_fromOctet(&Q,CP)) res=MPIN_INVALID_POINT;
        }
        else
        {
			ECP8_ZZZ_generator(&Q);
        }
    }
    if (res==0)
    {
        PAIR_ZZZ_ate(&g,&Q,&T);
        PAIR_ZZZ_fexp(&g);

        FP48_YYY_toOctet(G1,&g);
        if (G2!=NULL)
        {
            PAIR_ZZZ_ate(&g,&Q,&P);
            PAIR_ZZZ_fexp(&g);
            FP48_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)
{
    FP48_YYY g1,g2;
	FP16_YYY c;

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

    FP48_YYY_fromOctet(&g1,G1);
    FP48_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);

        FP48_YYY_pinpow(&g2,pin,PBLEN);
        FP48_YYY_mul(&g1,&g2);

		PAIR_ZZZ_G1mul(&W,x);

		FP48_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;
    FP48_YYY g;
    FP16_YYY c;
    ECP_ZZZ R,U,A;
    ECP8_ZZZ sQ;
    BIG_XXX w,h;

    if (!ECP8_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);
        FP48_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;
    ECP8_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);

	ECP8_ZZZ_generator(&Q);

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

    return res;
}
