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

use std::time::{SystemTime};
use std::time::UNIX_EPOCH;

use ecp::ECP;
use fp2::FP2;
use ecp2::ECP2;
use fp4::FP4;
use fp12::FP12;
use big::BIG;
use rand::RAND;
use hash256::HASH256;
use hash384::HASH384;
use hash512::HASH512;
use pair;
use rom;

/* MPIN API Functions */

/* Configure mode of operation */

pub const PERMITS:bool=true;
pub const PINERROR:bool=true;
pub const FULL: bool=true;
pub const SINGLE_PASS:bool=false;

pub const EFS: usize=rom::MODBYTES as usize;
pub const EGS: usize=rom::MODBYTES as usize;
pub const PAS: usize=16;
pub const BAD_PARAMS: isize=-11;
pub const INVALID_POINT: isize=-14;
pub const WRONG_ORDER: isize=-18;
pub const BAD_PIN: isize=-19;
pub const SHA256: usize=32;
pub const SHA384: usize=48;
pub const SHA512: usize=64;

/* Configure your PIN here */

pub const MAXPIN: i32=10000;  /* PIN less than this */
pub const PBLEN: i32=14;      /* Number of bits in PIN */
pub const TS: usize=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
pub const TRAP:usize=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */

pub const HASH_TYPE: usize=SHA256;

#[allow(non_snake_case)]
fn hash(sha: usize,c: &mut FP4,U: &mut ECP,r: &mut [u8]) -> bool {
	let mut w:[u8;EFS]=[0;EFS];
	let mut t:[u8;6*EFS]=[0;6*EFS];

	c.geta().geta().tobytes(&mut w); for i in 0..EFS {t[i]=w[i]}
	c.geta().getb().tobytes(&mut w); for i in EFS..2*EFS {t[i]=w[i-EFS]}
	c.getb().geta().tobytes(&mut w); for i in 2*EFS..3*EFS {t[i]=w[i-2*EFS]}
	c.getb().getb().tobytes(&mut w); for i in 3*EFS..4*EFS {t[i]=w[i-3*EFS]}

	U.getx().tobytes(&mut w); for i in 4*EFS..5*EFS {t[i]=w[i-4*EFS]}
	U.gety().tobytes(&mut w); for i in 5*EFS..6*EFS {t[i]=w[i-5*EFS]}

	if sha==SHA256 {
		let mut h=HASH256::new();
		h.process_array(&t);
		let sh=h.hash();
		for i in 0..PAS {r[i]=sh[i]}	
		return true;	
	}
	if sha==SHA384 {
		let mut h=HASH384::new();
		h.process_array(&t);
		let sh=h.hash();
		for i in 0..PAS {r[i]=sh[i]}		
		return true;
	}
	if sha==SHA512 {
		let mut h=HASH512::new();
		h.process_array(&t);
		let sh=h.hash();
		for i in 0..PAS {r[i]=sh[i]}
		return true;		
	}
	return false;

}

/* Hash number (optional) and string to point on curve */

fn hashit(sha: usize,n: usize,id: &[u8],w: &mut [u8]) -> bool {
	let mut r:[u8;64]=[0;64];
	let mut didit=false;
	if sha==SHA256 {
		let mut h=HASH256::new();
		if n>0 {h.process_num(n as i32)}
		h.process_array(id);
        let hs=h.hash();	
        for i in 0..sha {r[i]=hs[i];}	
        didit=true;
	}
	if sha==SHA384 {
		let mut h=HASH384::new();
		if n>0 {h.process_num(n as i32)}
		h.process_array(id);
		let hs=h.hash();
        for i in 0..sha {r[i]=hs[i];}			
		didit=true;
	}
	if sha==SHA512 {
		let mut h=HASH512::new();
		if n>0 {h.process_num(n as i32)}
		h.process_array(id);
		let hs=h.hash();
        for i in 0..sha {r[i]=hs[i];}	
        didit=true;		
	}
	if !didit {return false}

	let rm=rom::MODBYTES as usize;

	if sha>rm {
		for i in 0..rm {w[i]=r[i]}
	} else {
		for i in 0..sha {w[i]=r[i]}	
		for i in sha..rm {w[i]=0}
	}

	return true;
}

#[allow(non_snake_case)]
fn mapit(h: &[u8]) -> ECP {
	let mut q=BIG::new_ints(&rom::MODULUS);
	let mut x=BIG::frombytes(h);
	x.rmod(&mut q);
	let mut P:ECP;

	loop {
		P=ECP::new_bigint(&x,0);
		if !P.is_infinity() {break}
		x.inc(1); x.norm();
	}
	if rom::CURVE_PAIRING_TYPE!=rom::BN_CURVE {
		let mut c=BIG::new_ints(&rom::CURVE_COF);
		P=P.mul(&mut c);
	}	
	return P;
}

/* return time in slots since epoch */
pub fn today() -> usize {
  	return (SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()/(60*1440)) as usize;
}

/* 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 */
#[allow(non_snake_case)]
fn emap(u: &BIG,cb: isize) -> ECP {
	let mut P:ECP;
	let mut x=BIG::new_copy(u);
	let mut p=BIG::new_ints(&rom::MODULUS);
	x.rmod(&mut p);
	loop {
		P=ECP::new_bigint(&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 */
#[allow(non_snake_case)]
fn unmap(u: &mut BIG,P: &mut ECP) -> isize {
	let s=P.gets();
	let mut R:ECP;
	let mut r=0;
	let x=P.getx();
	u.copy(&x);
	loop {
		u.dec(1); u.norm();
		r+=1;
		R=ECP::new_bigint(u,s);
		if !R.is_infinity() {break}
	}
	return r as isize;
}

pub fn hash_id(sha: usize,id: &[u8],w: &mut [u8]) -> bool {
	return hashit(sha,0,id,w);
}

/* 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 */
#[allow(non_snake_case)]
pub fn encoding(rng: &mut RAND,e: &mut [u8]) ->isize {
	let mut t:[u8;EFS]=[0;EFS];

	for i in 0..EFS {t[i]=e[i+1]}
	let mut u=BIG::frombytes(&t);
	for i in 0..EFS {t[i]=e[i+EFS+1]}
	let mut v=BIG::frombytes(&t);
		
	let mut P=ECP::new_bigs(&u,&v);
	if P.is_infinity() {return INVALID_POINT}

	let p=BIG::new_ints(&rom::MODULUS);
	u=BIG::randomnum(&p,rng);

	let mut su=rng.getbyte() as isize; /*if (su<0) su=-su;*/ su%=2;
		
	let mut W=emap(&mut u,su);
	P.sub(&mut W);
	let sv=P.gets();
	let rn=unmap(&mut v,&mut P);
	let mut m=rng.getbyte() as isize; /*if (m<0) m=-m;*/ m%=rn;
	v.inc(m+1);
	e[0]=(su+2*sv) as u8;
	u.tobytes(&mut t);
	for i in 0..EFS {e[i+1]=t[i]}
	v.tobytes(&mut t);
	for i in 0..EFS {e[i+EFS+1]=t[i]}		
		
	return 0;
}

#[allow(non_snake_case)]
pub fn decoding(d: &mut [u8]) -> isize {
	let mut t:[u8;EFS]=[0;EFS];

	if (d[0]&0x04)!=0 {return INVALID_POINT}

	for i in 0..EFS {t[i]=d[i+1]}
	let mut u=BIG::frombytes(&t);
	for i in 0..EFS {t[i]=d[i+EFS+1]}
	let mut v=BIG::frombytes(&t);

	let su=(d[0]&1) as isize;
	let sv=((d[0]>>1)&1) as isize;
	let mut W=emap(&mut u,su);
	let mut P=emap(&mut v,sv);
	P.add(&mut W);
	u=P.getx();
	v=P.gety();
	d[0]=0x04;
	u.tobytes(&mut t);
	for i in 0..EFS {d[i+1]=t[i]}
	v.tobytes(&mut t);
	for i in 0..EFS {d[i+EFS+1]=t[i]}		
		
	return 0;
}

/* R=R1+R2 in group G1 */
#[allow(non_snake_case)]
pub fn recombine_g1(r1: &[u8],r2: &[u8],r: &mut [u8]) -> isize {
	let mut P=ECP::frombytes(&r1);
	let mut Q=ECP::frombytes(&r2);

	if P.is_infinity() || Q.is_infinity() {return INVALID_POINT}

	P.add(&mut Q);

	P.tobytes(r);
	return 0;
}

/* W=W1+W2 in group G2 */
#[allow(non_snake_case)]
pub fn recombine_g2(w1: &[u8],w2: &[u8],w: &mut [u8]) -> isize {
	let mut P=ECP2::frombytes(&w1);
	let mut Q=ECP2::frombytes(&w2);

	if P.is_infinity() || Q.is_infinity() {return INVALID_POINT}

	P.add(&mut Q);
	
	P.tobytes(w);
	return 0;
}
	
/* create random secret S */
pub fn random_generate(rng: &mut RAND,s: &mut [u8]) -> isize {
	let r=BIG::new_ints(&rom::CURVE_ORDER);
	let mut sc=BIG::randomnum(&r,rng);
	if rom::AES_S>0 {
		sc.mod2m(2*rom::AES_S);
	}		
	sc.tobytes(s);
	return 0;
}

/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
#[allow(non_snake_case)]
pub fn get_server_secret(s: &[u8],sst: &mut [u8]) -> isize {

	let mut Q=ECP2::new_fp2s(&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PXA),&BIG::new_ints(&rom::CURVE_PXB)),&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PYA),&BIG::new_ints(&rom::CURVE_PYB)));

	let mut sc=BIG::frombytes(s);
	Q=pair::g2mul(&mut Q,&mut sc);
	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
*/
#[allow(non_snake_case)]
pub fn get_g1_multiple(rng: Option<&mut RAND>,typ: usize,x: &mut [u8],g: &[u8],w: &mut [u8]) -> isize {
	let mut sx:BIG;
	let r=BIG::new_ints(&rom::CURVE_ORDER);

	if let Some(mut rd)=rng
	{
		sx=BIG::randomnum(&r,rd);
		if rom::AES_S>0 {
			sx.mod2m(2*rom::AES_S);
		}
		sx.tobytes(x);
	} else {
		sx=BIG::frombytes(x);
	}
	let mut P:ECP;

	if typ==0 {
		P=ECP::frombytes(g);
		if P.is_infinity() {return INVALID_POINT}
	} else {
		P=mapit(g)
	}



	pair::g1mul(&mut P,&mut sx).tobytes(w);
	return 0;
}


/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
/* CID is hashed externally */
pub fn get_client_secret(s: &mut [u8],cid: &[u8],cst: &mut [u8]) -> isize {
	return get_g1_multiple(None,1,s,cid,cst);
}

/* Extract PIN from TOKEN for identity CID */
#[allow(non_snake_case)]
pub fn extract_pin(sha: usize,cid: &[u8],pin: i32,token: &mut [u8]) -> isize {
	let mut P=ECP::frombytes(&token);
	const RM:usize=rom::MODBYTES as usize;
	let mut h:[u8;RM]=[0;RM];
	if P.is_infinity() {return INVALID_POINT}
	hashit(sha,0,cid,&mut h);
	let mut R=mapit(&h);

	R=R.pinmul(pin%MAXPIN,PBLEN);
	P.sub(&mut R);

	P.tobytes(token);

	return 0;
}

/* Functions to support M-Pin Full */
#[allow(non_snake_case)]
pub fn precompute(token: &[u8],cid: &[u8],g1: &mut [u8],g2: &mut [u8]) -> isize {
	let mut T=ECP::frombytes(&token);
	if T.is_infinity() {return INVALID_POINT} 

	let mut P=mapit(&cid);

	let mut Q=ECP2::new_fp2s(&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PXA),&BIG::new_ints(&rom::CURVE_PXB)),&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PYA),&BIG::new_ints(&rom::CURVE_PYB)));

	let mut g=pair::ate(&mut Q,&mut T);
	g=pair::fexp(&g);
	g.tobytes(g1);

	g=pair::ate(&mut Q,&mut P);
	g=pair::fexp(&g);
	g.tobytes(g2);

	return 0;
}

/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
#[allow(non_snake_case)]
pub fn get_client_permit(sha: usize,date: usize,s: &[u8],cid: &[u8],ctt: &mut [u8]) ->isize {
	const RM:usize=rom::MODBYTES as usize;
	let mut h:[u8;RM]=[0;RM];	
	hashit(sha,date,cid,&mut h);
	let mut P=mapit(&h);

	let mut sc=BIG::frombytes(s);
	pair::g1mul(&mut P,&mut sc).tobytes(ctt);
	return 0;
}

/* Implement step 1 on client side of MPin protocol */
#[allow(non_snake_case)]
pub fn client_1(sha: usize,date: usize,client_id: &[u8],rng: Option<&mut RAND>,x: &mut [u8],pin: usize,token: &[u8],sec: &mut [u8],xid: Option<&mut [u8]>,xcid: Option<&mut [u8]>,permit: Option<&[u8]>) ->isize {
	let r=BIG::new_ints(&rom::CURVE_ORDER);
		
	let mut sx:BIG;

	if let Some(mut rd)=rng
	{
		sx=BIG::randomnum(&r,rd);
		if rom::AES_S>0 {
			sx.mod2m(2*rom::AES_S);
		}
		sx.tobytes(x);
	} else {
		sx=BIG::frombytes(x);
	}

	const RM:usize=rom::MODBYTES as usize;
	let mut h:[u8;RM]=[0;RM];

	hashit(sha,0,&client_id,&mut h);
	let mut P=mapit(&h);
	
	let mut T=ECP::frombytes(&token);
	if T.is_infinity() {return INVALID_POINT}

	let mut W=P.pinmul((pin as i32)%MAXPIN,PBLEN);
	T.add(&mut W);
	if date!=0 {
		if let Some(rpermit)=permit {W=ECP::frombytes(&rpermit);}
		if W.is_infinity() {return INVALID_POINT}
		T.add(&mut W);
		let mut h2:[u8;RM]=[0;RM];		
		hashit(sha,date,&h,&mut h2);
		W=mapit(&h2);
		if let Some(mut rxid)=xid {
			P=pair::g1mul(&mut P,&mut sx);
			P.tobytes(&mut rxid);
			W=pair::g1mul(&mut W,&mut sx);
			P.add(&mut W);
		} else {
			P.add(&mut W);
			P=pair::g1mul(&mut P,&mut sx);
		}
		if let Some(mut rxcid)=xcid {P.tobytes(&mut rxcid)}
	} else {
		if let Some(mut rxid)=xid {
			P=pair::g1mul(&mut P,&mut sx);
			P.tobytes(&mut rxid);
		}
	}

	T.tobytes(sec);
	return 0;
}

/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
#[allow(non_snake_case)]
pub fn server_1(sha: usize,date: usize,cid: &[u8],hid: &mut [u8],htid: Option<&mut [u8]>) {
	const RM:usize=rom::MODBYTES as usize;
	let mut h:[u8;RM]=[0;RM];

	hashit(sha,0,cid,&mut h);	

	let mut P=mapit(&h);
	
	P.tobytes(hid);
	if date!=0 {
		let mut h2:[u8;RM]=[0;RM];		
		hashit(sha,date,&h,&mut h2);
		let mut R=mapit(&h2);
		P.add(&mut R);
		if let Some(rhtid)=htid {P.tobytes(rhtid);}
	} 
}

/* Implement step 2 on client side of MPin protocol */
#[allow(non_snake_case)]
pub fn client_2(x: &[u8],y: &[u8],sec: &mut [u8]) -> isize {
	let mut r=BIG::new_ints(&rom::CURVE_ORDER);
	let mut P=ECP::frombytes(sec);
	if P.is_infinity() {return INVALID_POINT}

	let mut px=BIG::frombytes(x);
	let py=BIG::frombytes(y);
	px.add(&py);
	px.rmod(&mut r);
	//px.rsub(r)

	P=pair::g1mul(&mut P,&mut px);
	P.neg();
	P.tobytes(sec);
	
	return 0;
}

/* return time since epoch */
pub fn get_time() -> usize {
  	return (SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) as usize;	
}

/* Generate Y = H(epoch, xCID/xID) */
pub fn get_y(sha: usize,timevalue: usize,xcid: &[u8],y: &mut [u8]) {
	const RM:usize=rom::MODBYTES as usize;
	let mut h:[u8;RM]=[0;RM];

	hashit(sha,timevalue,xcid,&mut h);	

	let mut sy= BIG::frombytes(&h);
	let mut q=BIG::new_ints(&rom::CURVE_ORDER);
	sy.rmod(&mut q);
	if rom::AES_S>0 {
		sy.mod2m(2*rom::AES_S);
	}
	sy.tobytes(y);
}

/* Implement step 2 of MPin protocol on server side */
#[allow(non_snake_case)]
pub fn server_2(date: usize,hid: &[u8],htid: Option<&[u8]>,y: &[u8],sst: &[u8],xid: Option<&[u8]>,xcid: Option<&[u8]>,msec: &[u8],e: Option<&mut [u8]>,f: Option<&mut [u8]>) -> isize {
//	q:=NewBIGints(Modulus)
	let mut Q=ECP2::new_fp2s(&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PXA),&BIG::new_ints(&rom::CURVE_PXB)),&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PYA),&BIG::new_ints(&rom::CURVE_PYB)));

	let mut sQ=ECP2::frombytes(&sst);
	if sQ.is_infinity() {return INVALID_POINT}	

	let mut R:ECP;
	if date!=0 {
		if let Some(rxcid)=xcid {R=ECP::frombytes(&rxcid);}
		else {return BAD_PARAMS}
	} else {
		if let Some(rxid)=xid {R=ECP::frombytes(&rxid)}
		else {return BAD_PARAMS}
	}
	if R.is_infinity() {return INVALID_POINT}

	let mut sy=BIG::frombytes(&y);
	let mut P:ECP;
	if date!=0 {
		if let Some(rhtid)=htid {P=ECP::frombytes(&rhtid)}
		else {return BAD_PARAMS}
	} else {
		P=ECP::frombytes(&hid);
	}
	
	if P.is_infinity() {return INVALID_POINT}

	P=pair::g1mul(&mut P,&mut sy);
	P.add(&mut R);
	R=ECP::frombytes(&msec);
	if R.is_infinity() {return INVALID_POINT}

	let mut g:FP12;
//		FP12 g1=new FP12(0);

	g=pair::ate2(&mut Q,&mut R,&mut sQ,&mut P);
	g=pair::fexp(&g);

	if !g.isunity() {
		
		if let Some(rxid)=xid {
			if let Some(re)=e {
				if let Some(rf)=f {

					g.tobytes(re);
					if date!=0 {
						P=ECP::frombytes(&hid);
						if P.is_infinity() {return INVALID_POINT}		
						R=ECP::frombytes(&rxid);
						if R.is_infinity() {return INVALID_POINT}			
						P=pair::g1mul(&mut P,&mut sy);
						P.add(&mut R);									
					}
					g=pair::ate(&mut Q,&mut P);
					g=pair::fexp(&g);
					g.tobytes(rf);

				}
			}
		}
	
		return BAD_PIN;
	}

	return 0;
}

/* Pollards kangaroos used to return PIN error */
pub fn kangaroo(e: &[u8],f: &[u8]) -> isize {
	let mut ge=FP12::frombytes(e);
	let mut gf=FP12::frombytes(f);
	let mut distance: [isize;TS]=[0;TS];
	let mut t=FP12::new_copy(&gf);

	let mut table: [FP12;TS]=[FP12::new();TS];
	let mut s:isize=1;
	for m in 0..TS {
		distance[m]=s;
		table[m]=FP12::new_copy(&t);
		s*=2;
		t.usqr();
	}
	t.one();
	let mut dn:isize=0;
	let mut i:usize;
	for _ in 0..TRAP {
		i=(t.geta().geta().geta().lastbits(20)%(TS as isize)) as usize;
		t.mul(&mut table[i]);
		dn+=distance[i];
	}
	gf.copy(&t); gf.conj();
	let mut steps:usize=0; let mut dm:isize=0;
	let mut res:isize=0;
	while dm-dn<MAXPIN as isize {
		steps+=1;
		if steps>4*TRAP {break}
		i=(ge.geta().geta().geta().lastbits(20)%(TS as isize)) as usize;
		ge.mul(&mut table[i]);
		dm+=distance[i];
		if ge.equals(&mut t) {
			res=dm-dn;
			break;
		}
		if ge.equals(&mut gf) {
			res=dn-dm;
			break;
		}

	}
	if steps>4*TRAP || dm-dn>=MAXPIN as isize {res=0 }    // Trap Failed  - probable invalid token
	return res;
}

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

pub fn hash_all(sha: usize,hid: &[u8],xid: &[u8],xcid: Option<&[u8]>,sec: &[u8],y: &[u8],r: &[u8],w: &[u8],h: &mut[u8]) -> bool {
	let mut tlen:usize=0;
	const RM:usize=rom::MODBYTES as usize;	
	let mut t: [u8;10*RM+4]=[0;10*RM+4];

	for i in 0 .. hid.len() {t[i]=hid[i]}
	tlen+=hid.len();

	if let Some(rxcid)=xcid {
		for i in 0..rxcid.len() {t[i+tlen]=rxcid[i]}
		tlen+=rxcid.len();
	} else {
		for i in 0..xid.len() {t[i+tlen]=xid[i]}
		tlen+=xid.len();
	}	

	for i in 0..sec.len() {t[i+tlen]=sec[i]}
	tlen+=sec.len();		
	for i in 0..y.len() {t[i+tlen]=y[i]}
	tlen+=y.len();
	for i in 0..r.len() {t[i+tlen]=r[i]}
	tlen+=r.len();		
	for i in 0..w.len() {t[i+tlen]=w[i]}
	tlen+=w.len();	
	if tlen!=10*RM+4 {return false}

	return hashit(sha,0,&t,h);
}

/* calculate common key on client side */
/* wCID = w.(A+AT) */
#[allow(non_snake_case)]
pub fn client_key(sha: usize,g1: &[u8],g2: &[u8],pin: usize,r: &[u8],x: &[u8],h: &[u8],wcid: &[u8],ck: &mut [u8]) -> isize {

	let mut g1=FP12::frombytes(&g1);
	let mut g2=FP12::frombytes(&g2);
	let mut z=BIG::frombytes(&r);
	let mut x=BIG::frombytes(&x);
	let h=BIG::frombytes(&h);

	let mut W=ECP::frombytes(&wcid);
	if W.is_infinity() {return INVALID_POINT} 

	W=pair::g1mul(&mut W,&mut x);

	let mut f=FP2::new_bigs(&BIG::new_ints(&rom::CURVE_FRA),&BIG::new_ints(&rom::CURVE_FRB));
	let mut r=BIG::new_ints(&rom::CURVE_ORDER);
	let q=BIG::new_ints(&rom::MODULUS);

	z.add(&h);	//new
	z.rmod(&mut r);

	let mut m=BIG::new_copy(&q);
	m.rmod(&mut r);

	let mut a=BIG::new_copy(&z);
	a.rmod(&mut m);

	let mut b=BIG::new_copy(&z);
	b.div(&mut m);

	g2.pinpow(pin as i32,PBLEN);
	g1.mul(&mut g2);

	let mut c=g1.trace();
	g2.copy(&g1);
	g2.frob(&mut f);
	let cp=g2.trace();
	g1.conj();
	g2.mul(&mut g1);
	let cpm1=g2.trace();
	g2.mul(&mut g1);
	let cpm2=g2.trace();

	c=c.xtr_pow2(&cp,&cpm1,&cpm2,&mut a,&mut b);

	hash(sha,&mut c,&mut W,ck);

	return 0
}

/* calculate common key on server side */
/* Z=r.A - no time permits involved */
#[allow(non_snake_case)]
pub fn server_key(sha: usize,z: &[u8],sst: &[u8],w: &[u8],h: &[u8],hid: &[u8],xid: &[u8],xcid: Option<&[u8]>,sk: &mut [u8]) -> isize {
	let mut sQ=ECP2::frombytes(&sst);
	if sQ.is_infinity() {return INVALID_POINT} 
	let mut R=ECP::frombytes(&z);
	if R.is_infinity() {return INVALID_POINT} 
	let mut A=ECP::frombytes(&hid);
	if A.is_infinity() {return INVALID_POINT} 

	let mut U=ECP::new();
	if let Some(rxcid)=xcid {
		U.copy(&ECP::frombytes(&rxcid));
	} else {
		U.copy(&ECP::frombytes(&xid));
	}
	
	if U.is_infinity() {return INVALID_POINT} 

	let mut w=BIG::frombytes(&w);
	let mut h=BIG::frombytes(&h);
	A=pair::g1mul(&mut A,&mut h);	// new
	R.add(&mut A);

	U=pair::g1mul(&mut U,&mut w);
	let mut g=pair::ate(&mut sQ,&mut R);
	g=pair::fexp(&g);

	let mut c=g.trace();

	hash(sha,&mut c,&mut U,sk);

	return 0
}


