/*
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 xxx::big;
use xxx::ff;
use xxx::ff::FF;

use rand::RAND;
use hash256::HASH256;
use hash384::HASH384;
use hash512::HASH512;

pub const RFS:usize =(big::MODBYTES as usize)*ff::FFLEN;
pub const SHA256:usize=32;
pub const SHA384:usize=48;
pub const SHA512:usize=64;

pub const HASH_TYPE:usize=SHA256;

pub struct RsaPrivateKey {
	p:FF,
	q:FF,
	dp:FF,
	dq:FF,
	c:FF
}

pub struct RsaPublicKey {
	e: isize,
	n: FF
}

pub fn new_private_key(n: usize) -> RsaPrivateKey {
	RsaPrivateKey {p:FF::new_int(n),q:FF::new_int(n),dp:FF::new_int(n),dq:FF::new_int(n),c:FF::new_int(n)}
}

pub fn new_public_key(m: usize) -> RsaPublicKey {
	RsaPublicKey {e:0,n:FF::new_int(m)}
}

fn hashit(sha: usize,a: Option<&[u8]>,n: isize,w: &mut [u8]) {
	if sha==SHA256 {
		let mut h=HASH256::new();
		if let Some(x)=a {
			h.process_array(x);
		}
		if n>=0 {h.process_num(n as i32)}
        let hs=h.hash();	
        for i in 0..sha {w[i]=hs[i]}
	}
	if sha==SHA384 {
		let mut h=HASH384::new();
		if let Some(x)=a {
			h.process_array(x);
		}
		if n>=0 {h.process_num(n as i32)}
        let hs=h.hash();	
        for i in 0..sha {w[i]=hs[i]}
	}
	if sha==SHA512 {
		let mut h=HASH512::new();
		if let Some(x)=a {
			h.process_array(x);
		}
		if n>=0 {h.process_num(n as i32)}
        let hs=h.hash();	
        for i in 0..sha {w[i]=hs[i]}
	}
}

pub fn key_pair(rng: &mut RAND,e: isize,prv: &mut RsaPrivateKey,pbc: &mut RsaPublicKey) { /* IEEE1363 A16.11/A16.12 more or less */
	let n=pbc.n.getlen()/2;
	let mut t=FF::new_int(n);
	let mut p1=FF::new_int(n);
	let mut q1=FF::new_int(n);

	loop {
		prv.p.random(rng);
		while prv.p.lastbits(2)!=3 {prv.p.inc(1)}		
		while !FF::prime(&prv.p,rng) {			
			prv.p.inc(4);		
		}
		
		p1.copy(&prv.p);
		p1.dec(1);

		if p1.cfactor(e) {continue}
		break;
	}

	loop {
		prv.q.random(rng);
		while prv.q.lastbits(2)!=3 {prv.q.inc(1)}
		while !FF::prime(&prv.q,rng) {
			prv.q.inc(4);
		}
			
		q1.copy(&prv.q);
		q1.dec(1);

		if q1.cfactor(e) {continue}

		break;
	}
	
	pbc.n=FF::mul(&prv.p,&prv.q);
	pbc.e=e;

	t.copy(&p1);
	t.shr();
	prv.dp.set(e);
	prv.dp.invmodp(&t);
	if prv.dp.parity()==0 {prv.dp.add(&t)}
	prv.dp.norm();

	t.copy(&q1);
	t.shr();
	prv.dq.set(e);
	prv.dq.invmodp(&t);
	if prv.dq.parity()==0 {prv.dq.add(&t)}
	prv.dq.norm();

	prv.c.copy(&prv.p);
	prv.c.invmodp(&prv.q);
}

/* Mask Generation Function */

pub fn mgf1(sha: usize,z: &[u8],olen: usize,k: &mut [u8]) {
	let hlen=sha;

	let mut j=0;
	for i in 0..k.len() {k[i]=0}

	let mut cthreshold=olen/hlen; 
	if olen%hlen!=0 {cthreshold+=1}
	for counter in 0..cthreshold {
		let mut b:[u8;64]=[0;64];		
		hashit(sha,Some(z),counter as isize,&mut b);

		if j+hlen>olen {
			for i in 0..(olen%hlen) {k[j]=b[i]; j+=1}
		} else {
			for i in 0..hlen {k[j]=b[i]; j+=1}
		}
	}	
}

/* SHAXXX identifier strings */
const SHA256ID:[u8;19]= [0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20];
const SHA384ID:[u8;19]= [0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30];
const SHA512ID:[u8;19]= [0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40];

pub fn pkcs15(sha: usize,m: &[u8],w: &mut [u8]) -> bool {
	let olen=ff::FF_BITS/8;
	let hlen=sha;
	let idlen=19;
	let mut b:[u8;64]=[0;64];  /* Not good */	

	if olen<idlen+hlen+10 {return false}
	hashit(sha,Some(m),-1,&mut b);

	for i in 0..w.len() {w[i]=0}
	let mut i=0;
	w[i]=0; i+=1;
	w[i]=1; i+=1;
	for _ in 0..olen-idlen-hlen-3 {w[i]=0xff; i+=1}
	w[i]=0; i+=1;

	if hlen==SHA256 {
		for j in 0..idlen {w[i]=SHA256ID[j]; i+=1}
	}
	if hlen==SHA384 {
		for j in 0..idlen {w[i]=SHA384ID[j]; i+=1}
	}
	if hlen==SHA512 {
		for j in 0..idlen {w[i]=SHA512ID[j]; i+=1}
	}
	for j in 0..hlen {w[i]=b[j]; i+=1}

	return true;
}

/* OAEP Message Encoding for Encryption */
pub fn oaep_encode(sha: usize,m: &[u8],rng: &mut RAND,p: Option<&[u8]>,f: &mut [u8]) -> bool { 
	let olen=RFS-1;
	let mlen=m.len();

	let hlen=sha;

	let mut seed:[u8;64]=[0;64];

	let seedlen=hlen;
	if mlen>olen-hlen-seedlen-1 {return false} 

	let mut dbmask:[u8;RFS]=[0;RFS];

	hashit(sha,p,-1,f);
	let slen=olen-mlen-hlen-seedlen-1;      

	for i in 0..slen {f[hlen+i]=0}
	f[hlen+slen]=1;
	for i in 0..mlen {f[hlen+slen+1+i]=m[i]}

	for i in 0..seedlen {seed[i]=rng.getbyte()}
	
	mgf1(sha,&seed,olen-seedlen,&mut dbmask);

	for i in 0..olen-seedlen {dbmask[i]^=f[i]}

	mgf1(sha,&dbmask[0..olen-seedlen],seedlen,f);

	for i in 0..seedlen {f[i]^=seed[i]}

	for i in 0..olen-seedlen {f[i+seedlen]=dbmask[i]}

	/* pad to length RFS */
	let d=1;
	for i in (d..RFS).rev() {
		f[i]=f[i-d];
	}
	for i in (0..d).rev() {
		f[i]=0;
	}
	return true;
}

/* OAEP Message Decoding for Decryption */
pub fn oaep_decode(sha: usize,p: Option<&[u8]>,f: &mut [u8]) -> usize {
	let olen=RFS-1;

	let hlen=sha;
	let mut seed:[u8;64]=[0;64];
	let seedlen=hlen;
	let mut chash:[u8;64]=[0;64];
	
	if olen<seedlen+hlen+1 {return 0}
	let mut dbmask:[u8;RFS]=[0;RFS];
	//for i in 0..olen-seedlen {dbmask[i]=0}

	if f.len()<RFS {
		let d=RFS-f.len();
		for i in (d..RFS).rev() {
			f[i]=f[i-d];
		}
		for i in (0..d).rev() {
			f[i]=0;
		}
	}

	hashit(sha,p,-1,&mut chash);

	let x=f[0];

	for i in seedlen..olen {
		dbmask[i-seedlen]=f[i+1];
	}

	mgf1(sha,&dbmask[0..olen-seedlen],seedlen,&mut seed);
	for i in 0..seedlen {seed[i]^=f[i+1]}
	mgf1(sha,&seed,olen-seedlen,f);
	for i in 0..olen-seedlen {dbmask[i]^=f[i]}

	let mut comp=true;
	for i in 0..hlen {
		if chash[i]!=dbmask[i] {comp=false}
	}

	for i in 0..olen-seedlen-hlen {
		dbmask[i]=dbmask[i+hlen]
	}

	for i in 0..hlen {
		seed[i]=0; chash[i]=0
	}
		
	let mut k=0;
	loop {
		if k>=olen-seedlen-hlen {return 0}
		if dbmask[k]!=0 {break}
		k+=1;
	}

	let t=dbmask[k];
	if !comp || x!=0 || t!=0x01 {
		for i in 0..olen-seedlen {dbmask[i]=0}
		return 0;
	}

	for i in 0..olen-seedlen-hlen-k-1 {
		f[i]=dbmask[i+k+1];
	}
	
	for i in 0..olen-seedlen  {dbmask[i]=0}

	return olen-seedlen-hlen-k-1;
}

/* destroy the Private Key structure */
pub fn private_key_kill(prv: &mut RsaPrivateKey) {
	prv.p.zero();
	prv.q.zero();
	prv.dp.zero();
	prv.dq.zero();
	prv.c.zero();
}

/* RSA encryption with the public key */
pub fn encrypt(pbc: &RsaPublicKey,f: &[u8],g: &mut [u8]) {
	let m=pbc.n.getlen();
	let mut r=FF::new_int(m);

	FF::frombytes(&mut r,f);
	r.power(pbc.e,&pbc.n);
	r.tobytes(g);
}

/* RSA decryption with the private key */
pub fn decrypt(prv: &RsaPrivateKey,g: &[u8],f: &mut [u8]) {
	let n=prv.p.getlen();
	let mut r=FF::new_int(2*n);

	FF::frombytes(&mut r,g);
	let mut jp=r.dmod(&prv.p);
	let mut jq=r.dmod(&prv.q);

	jp.skpow(&prv.dp,&prv.p);
	jq.skpow(&prv.dq,&prv.q);

	r.zero();
	r.dscopy(&jp);
	jp.rmod(&prv.q);
	if FF::comp(&jp,&jq)>0 {jq.add(&prv.q)}
	jq.sub(&jp);
	jq.norm();

	let mut t=FF::mul(&prv.c,&jq);
	jq=t.dmod(&prv.q);

	t=FF::mul(&jq,&prv.p);
	r.add(&t);
	r.norm();

	r.tobytes(f);
}

