/*
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 API Functions */

package org.apache.milagro.amcl.BLS24;

import java.util.Date;

import org.apache.milagro.amcl.RAND;
import org.apache.milagro.amcl.HASH256;
import org.apache.milagro.amcl.HASH384;
import org.apache.milagro.amcl.HASH512;
import org.apache.milagro.amcl.AES;

public class MPIN192
{

//	public static final int SHA256=32;
//	public static final int SHA384=48;
//	public static final int SHA512=64;

	public static final int EFS=BIG.MODBYTES;
	public static final int EGS=BIG.MODBYTES;
//	public static final int PAS=16;
	public static final int INVALID_POINT=-14;
	public static final int BAD_PARAMS=-11;
	public static final int WRONG_ORDER=-18;
	public static final int BAD_PIN=-19;

/* Configure your PIN here */

	public static final int MAXPIN=10000;  /* PIN less than this */
	public static final int PBLEN=14;      /* Number of bits in PIN */
	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */

//	public static final int HASH_TYPE=SHA256;


/* Hash number (optional) and string to array size of Bigs */

	public static byte[] hashit(int sha,int n,byte[] B,int len)
	{
		byte[] R=null;

		if (sha==ECP.SHA256)
		{
			HASH256 H=new HASH256();
			if (n>0) H.process_num(n);

			H.process_array(B);
			R=H.hash();
		}
		if (sha==ECP.SHA384)
		{
			HASH384 H=new HASH384();
			if (n>0) H.process_num(n);
			H.process_array(B);
			R=H.hash();
		}
		if (sha==ECP.SHA512)
		{
			HASH512 H=new HASH512();
			if (n>0) H.process_num(n);
			H.process_array(B);
			R=H.hash();
		}
		if (R==null) return null;
		byte[] W=new byte[len];

		if (sha>=len)
			for (int i=0;i<len;i++) W[i]=R[i];
		else
		{
			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
            for (int i=0;i<len-sha;i++) W[i]=0;

			//for (int i=0;i<sha;i++) W[i]=R[i];
			//for (int i=sha;i<len;i++) W[i]=0;
		}
		return W;
	}

	/* return time in slots since epoch */
	public static int today() {
		Date date=new Date();
		return (int) (date.getTime()/(1000*60*1440));
	}

	public static byte[] HASH_ID(int sha,byte[] ID,int len)
	{
		return hashit(sha,0,ID,len);
	}

/* Hash the M-Pin transcript - new */

	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
	{
		int i,ilen,tlen=0;

		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
		if (xCID!=null) ilen+=xCID.length;
		else ilen+=xID.length;

		byte[] T = new byte[ilen];

		for (i=0;i<HID.length;i++) T[i]=HID[i];
		tlen+=HID.length;
		if (xCID!=null)
		{
			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
			tlen+=xCID.length;
		}	
		else
		{
			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
			tlen+=xID.length;
		}	
		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
		tlen+=SEC.length;		
		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
		tlen+=Y.length;	
		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
		tlen+=R.length;		
		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
		tlen+=W.length;		

		return hashit(sha,0,T,len);
	}

/* return time since epoch */
	public static int GET_TIME() {
		Date date=new Date();
		return (int) (date.getTime()/1000);
	}

	public static byte[] mpin_hash(int sha,FP8 c,ECP U)
	{
		byte[] w=new byte[EFS];
		byte[] t=new byte[10*EFS];
		byte[] h=null;
		c.geta().geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
		c.geta().geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
		c.geta().getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
		c.geta().getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
	
		c.getb().geta().getA().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
		c.getb().geta().getB().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
		c.getb().getb().getA().toBytes(w); for (int i=6*EFS;i<7*EFS;i++) t[i]=w[i-6*EFS];
		c.getb().getb().getB().toBytes(w); for (int i=7*EFS;i<8*EFS;i++) t[i]=w[i-7*EFS];

		
		U.getX().toBytes(w); for (int i=8*EFS;i<9*EFS;i++) t[i]=w[i-8*EFS];
		U.getY().toBytes(w); for (int i=9*EFS;i<10*EFS;i++) t[i]=w[i-9*EFS];
		
		if (sha==ECP.SHA256)
		{
			HASH256 H=new HASH256();
			H.process_array(t);
			h=H.hash();
		}
		if (sha==ECP.SHA384)
		{
			HASH384 H=new HASH384();
			H.process_array(t);
			h=H.hash();
		}
		if (sha==ECP.SHA512)
		{
			HASH512 H=new HASH512();
			H.process_array(t);
			h=H.hash();
		}
		if (h==null) return null;
		byte[] R=new byte[ECP.AESKEY];
		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
		return R;
	}

/* 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 */
	public static ECP map(BIG u,int cb)
	{
		ECP P;
		BIG x=new BIG(u);
		BIG p=new BIG(ROM.Modulus);
		x.mod(p);
		while (true)
		{
			P=new ECP(x,cb);
			if (!P.is_infinity()) break;
			x.inc(1);  x.norm();
		}
		return P;
	}

/* returns u derived from P. Random value in range 1 to return value should then be added to u */
	public static int unmap(BIG u,ECP P)
	{
		int s=P.getS();
		ECP R;
		int r=0;
		BIG x=P.getX();
		u.copy(x);
		while (true)
		{
			u.dec(1); u.norm();
			r++;
			R=new ECP(u,s);
			if (!R.is_infinity()) break;
		}
		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 */
	public static int ENCODING(RAND rng,byte[] E)
	{
		int rn,m,su,sv;
		byte[] T=new byte[EFS];

		for (int i=0;i<EFS;i++) T[i]=E[i+1];
		BIG u=BIG.fromBytes(T);
		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
		BIG v=BIG.fromBytes(T);
		
		ECP P=new ECP(u,v);
		if (P.is_infinity()) return INVALID_POINT;

		BIG p=new BIG(ROM.Modulus);
		u=BIG.randomnum(p,rng);

		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
		
		ECP W=map(u,su);
		P.sub(W); //P.affine();
		sv=P.getS();
		rn=unmap(v,P);
		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
		v.inc(m+1);
		E[0]=(byte)(su+2*sv);
		u.toBytes(T);
		for (int i=0;i<EFS;i++) E[i+1]=T[i];
		v.toBytes(T);
		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
		
		return 0;
	}

	public static int DECODING(byte[] D)
	{
		int su,sv;
		byte[] T=new byte[EFS];

		if ((D[0]&0x04)!=0) return INVALID_POINT;

		for (int i=0;i<EFS;i++) T[i]=D[i+1];
		BIG u=BIG.fromBytes(T);
		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
		BIG v=BIG.fromBytes(T);

		su=D[0]&1;
		sv=(D[0]>>1)&1;
		ECP W=map(u,su);
		ECP P=map(v,sv);
		P.add(W); //P.affine();
		u=P.getX();
		v=P.getY();
		D[0]=0x04;
		u.toBytes(T);
		for (int i=0;i<EFS;i++) D[i+1]=T[i];
		v.toBytes(T);
		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
		
		return 0;
	}

/* R=R1+R2 in group G1 */
	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
	{
		ECP P=ECP.fromBytes(R1);
		ECP Q=ECP.fromBytes(R2);

		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;

		P.add(Q); //P.affine();

		P.toBytes(R,false);
		return 0;
	}

/* W=W1+W2 in group G2 */
	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
	{
		ECP4 P=ECP4.fromBytes(W1);
		ECP4 Q=ECP4.fromBytes(W2);

		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;

		P.add(Q); //P.affine();
	
		P.toBytes(W);
		return 0;
	}
	
/* create random secret S */
	public static int RANDOM_GENERATE(RAND rng,byte[] S)
	{
		BIG s;
		BIG r=new BIG(ROM.CURVE_Order);
		s=BIG.randomnum(r,rng);
		//if (ROM.AES_S>0)
		//{
		//	s.mod2m(2*ROM.AES_S);
		//}
		s.toBytes(S);
		return 0;
	}

/* Extract PIN from TOKEN for identity CID */
	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
	{
		ECP P=ECP.fromBytes(TOKEN);
		if (P.is_infinity()) return INVALID_POINT;
		byte[] h=hashit(sha,0,CID,EFS);
		ECP R=ECP.mapit(h);


		pin%=MAXPIN;

		R=R.pinmul(pin,PBLEN);
		P.sub(R); //P.affine();

		P.toBytes(TOKEN,false);

		return 0;
	}

/* Implement step 2 on client side of MPin protocol */
	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
	{
		BIG r=new BIG(ROM.CURVE_Order);
		ECP P=ECP.fromBytes(SEC);
		if (P.is_infinity()) return INVALID_POINT;

		BIG px=BIG.fromBytes(X);
		BIG py=BIG.fromBytes(Y);
		px.add(py);
		px.mod(r);
	//	px.rsub(r);

		P=PAIR192.G1mul(P,px);
		P.neg();
		P.toBytes(SEC,false);
		return 0;
	}

/* Implement step 1 on client side of MPin protocol */
	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
	{
		BIG r=new BIG(ROM.CURVE_Order);
		BIG x;
		if (rng!=null)
		{
			x=BIG.randomnum(r,rng);
			//if (ROM.AES_S>0)
			//{
			//	x.mod2m(2*ROM.AES_S);
			//}
			x.toBytes(X);
		}
		else
		{
			x=BIG.fromBytes(X);
		}
		ECP P,T,W;
		BIG px;
//		byte[] t=new byte[EFS];

		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
		P=ECP.mapit(h);
	
		T=ECP.fromBytes(TOKEN);
		if (T.is_infinity()) return INVALID_POINT;

		pin%=MAXPIN;
		W=P.pinmul(pin,PBLEN);
		T.add(W);
		if (date!=0)
		{
			W=ECP.fromBytes(PERMIT);
			if (W.is_infinity()) return INVALID_POINT;
			T.add(W);
			h=hashit(sha,date,h,EFS);
			W=ECP.mapit(h);
			if (xID!=null)
			{
				P=PAIR192.G1mul(P,x);
				P.toBytes(xID,false);
				W=PAIR192.G1mul(W,x);
				P.add(W); //P.affine();
			}
			else
			{
				P.add(W); //P.affine();
				P=PAIR192.G1mul(P,x);
			}
			if (xCID!=null) P.toBytes(xCID,false);
		}
		else
		{
			if (xID!=null)
			{
				P=PAIR192.G1mul(P,x);
				P.toBytes(xID,false);
			}
		}

		//T.affine();
		T.toBytes(SEC,false);
		return 0;
	}

/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
	{
		ECP4 Q=ECP4.generator();
		BIG s=BIG.fromBytes(S);
		Q=PAIR192.G2mul(Q,s);
		Q.toBytes(SST);
		return 0;
	}

/*
 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
*/
	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
	{
		BIG x;
		BIG r=new BIG(ROM.CURVE_Order);
		if (rng!=null)
		{
			x=BIG.randomnum(r,rng);
			//if (ROM.AES_S>0)
			//{
			//	x.mod2m(2*ROM.AES_S);
			//}
			x.toBytes(X);
		}
		else
		{
			x=BIG.fromBytes(X);
		}
		ECP P;
		if (type==0)
		{
			P=ECP.fromBytes(G);
			if (P.is_infinity()) return INVALID_POINT;
		}
		else
			P=ECP.mapit(G);

		PAIR192.G1mul(P,x).toBytes(W,false);
		return 0;
	}

/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
/* CID is hashed externally */
	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
	{
		return GET_G1_MULTIPLE(null,1,S,CID,CST);
	}

/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
	{
		byte[] h=hashit(sha,date,CID,EFS);
		ECP P=ECP.mapit(h);

		BIG s=BIG.fromBytes(S);
		ECP OP=PAIR192.G1mul(P,s);

		OP.toBytes(CTT,false);
		return 0;
	}

/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
	{
		byte[] h=hashit(sha,0,CID,EFS);
		ECP R,P=ECP.mapit(h);

		P.toBytes(HID,false);   // new
		if (date!=0)
		{
	//		if (HID!=null) P.toBytes(HID,false);
			h=hashit(sha,date,h,EFS);
			R=ECP.mapit(h);
			P.add(R); //P.affine();
			P.toBytes(HTID,false);
		}
	//	else P.toBytes(HID,false);
	}

/* Implement step 2 of MPin protocol on server side */
	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
	{
		BIG q=new BIG(ROM.Modulus);
		ECP4 Q=ECP4.generator();

		ECP4 sQ=ECP4.fromBytes(SST);
		if (sQ.is_infinity()) return INVALID_POINT;	

		ECP R;
		if (date!=0)
			R=ECP.fromBytes(xCID);
		else 
		{
			if (xID==null) return BAD_PARAMS;
			R=ECP.fromBytes(xID);
		}
		if (R.is_infinity()) return INVALID_POINT;

		BIG y=BIG.fromBytes(Y);
		ECP P;
		if (date!=0) P=ECP.fromBytes(HTID);
		else 
		{
			if (HID==null) return BAD_PARAMS;
			P=ECP.fromBytes(HID);
		}
	
		if (P.is_infinity()) return INVALID_POINT;

		P=PAIR192.G1mul(P,y);
		P.add(R); //P.affine();
		R=ECP.fromBytes(mSEC);
		if (R.is_infinity()) return INVALID_POINT;

		FP24 g;

		g=PAIR192.ate2(Q,R,sQ,P);
		g=PAIR192.fexp(g);

		if (!g.isunity())
		{
			if (HID!=null && xID!=null && E!=null && F!=null)
			{
				g.toBytes(E);
				if (date!=0)
				{
					P=ECP.fromBytes(HID);
					if (P.is_infinity()) return INVALID_POINT;
					R=ECP.fromBytes(xID);
					if (R.is_infinity()) return INVALID_POINT;

					P=PAIR192.G1mul(P,y);
					P.add(R); //P.affine();
				}
				g=PAIR192.ate(Q,P);
				g=PAIR192.fexp(g);
				g.toBytes(F);
			}
			return BAD_PIN;
		}

		return 0;
	}

/* Pollards kangaroos used to return PIN error */
	public static int KANGAROO(byte[] E,byte[] F)
	{
		FP24 ge=FP24.fromBytes(E);
		FP24 gf=FP24.fromBytes(F);
		int[] distance = new int[TS];
		FP24 t=new FP24(gf);
		FP24[] table=new FP24[TS];
		int i,j,m,s,dn,dm,res,steps;

		s=1;
		for (m=0;m<TS;m++)
		{
			distance[m]=s;
			table[m]=new FP24(t);
			s*=2;
			t.usqr();
		}
		t.one();
		dn=0;
		for (j=0;j<TRAP;j++)
		{
			i=t.geta().geta().geta().getA().lastbits(20)%TS;
			t.mul(table[i]);
			dn+=distance[i];
		}
		gf.copy(t); gf.conj();
		steps=0; dm=0;
		res=0;
		while (dm-dn<MAXPIN)
		{
			steps++;
			if (steps>4*TRAP) break;
			i=ge.geta().geta().geta().getA().lastbits(20)%TS;
			ge.mul(table[i]);
			dm+=distance[i];
			if (ge.equals(t))
			{
				res=dm-dn;
				break;
			}
			if (ge.equals(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 */

	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
	{
		ECP P,T;
		FP24 g;

		T=ECP.fromBytes(TOKEN);
		if (T.is_infinity()) return INVALID_POINT; 

		P=ECP.mapit(CID);

		ECP4 Q=ECP4.generator();

		g=PAIR192.ate(Q,T);
		g=PAIR192.fexp(g);
		g.toBytes(G1);

		g=PAIR192.ate(Q,P);
		g=PAIR192.fexp(g);
		g.toBytes(G2);

		return 0;
	}



/* calculate common key on client side */
/* wCID = w.(A+AT) */
	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
	{
		byte[] t;

		FP24 g1=FP24.fromBytes(G1);
		FP24 g2=FP24.fromBytes(G2);
		BIG z=BIG.fromBytes(R);
		BIG x=BIG.fromBytes(X);
		BIG h=BIG.fromBytes(H);

		ECP W=ECP.fromBytes(wCID);
		if (W.is_infinity()) return INVALID_POINT; 

		W=PAIR192.G1mul(W,x);

//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
		BIG r=new BIG(ROM.CURVE_Order);
//		BIG q=new BIG(ROM.Modulus);

		z.add(h);	//new
		z.mod(r);

		g2.pinpow(pin,PBLEN);
		g1.mul(g2);

		FP8 c=g1.compow(z,r);

		t=mpin_hash(sha,c,W);

		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];

		return 0;
	}

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

	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
	{
		byte[] t;

		ECP4 sQ=ECP4.fromBytes(SST);
		if (sQ.is_infinity()) return INVALID_POINT; 
		ECP R=ECP.fromBytes(Z);
		if (R.is_infinity()) return INVALID_POINT; 
		ECP A=ECP.fromBytes(HID);
		if (A.is_infinity()) return INVALID_POINT; 

		ECP U;
		if (xCID!=null)
			U=ECP.fromBytes(xCID);
		else
			U=ECP.fromBytes(xID);
		if (U.is_infinity()) return INVALID_POINT; 

		BIG w=BIG.fromBytes(W);
		BIG h=BIG.fromBytes(H);
		A=PAIR192.G1mul(A,h);	// new
		R.add(A); //R.affine();

		U=PAIR192.G1mul(U,w);
		FP24 g=PAIR192.ate(sQ,R);
		g=PAIR192.fexp(g);

		FP8 c=g.trace();

		t=mpin_hash(sha,c,U);

		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];

		return 0;
	}

/* Generate Y = H(epoch, xCID/xID) */
	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
	{
		byte[] h = hashit(sha,TimeValue,xCID,EFS);
		BIG y = BIG.fromBytes(h);
		BIG q=new BIG(ROM.CURVE_Order);
		y.mod(q);
		//if (ROM.AES_S>0)
		//{
		//	y.mod2m(2*ROM.AES_S);
		//}
		y.toBytes(Y);
	}
        
/* One pass MPIN Client */
	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
	{
		int rtn=0;
        
		byte[] pID;
		if (date == 0)
			pID = xID;
		else
			pID = xCID;
          
		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
		if (rtn != 0)
			return rtn;
        
		GET_Y(sha,TimeValue,pID,Y);
        
		rtn = CLIENT_2(X,Y,SEC);
		if (rtn != 0)
		return rtn;
        
		return 0;
	}
        
/* One pass MPIN Server */
	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
	{
		int rtn=0;
        
		byte[] pID;
		if (date == 0)
			pID = xID;
		else
			pID = xCID;
          
		SERVER_1(sha,date,CID,HID,HTID);
        
		GET_Y(sha,TimeValue,pID,Y);
          
		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
		if (rtn != 0)
			return rtn;
        
		return 0;
	}
}
