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

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;
	}
}
