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

/* RSA API high-level functions  */

package XXX

//import "fmt"
import "github.com/milagro-crypto/amcl/version3/go/amcl"

const RFS int=int(MODBYTES)*FFLEN

const RSA_HASH_TYPE int=amcl.SHA256


type rsa_private_key struct {
	p,q,dp,dq,c *FF
}

func New_private_key(n int) *rsa_private_key {
	SK:=new(rsa_private_key)
	SK.p=NewFFint(n)
	SK.q=NewFFint(n)
	SK.dp=NewFFint(n)
	SK.dq=NewFFint(n)
	SK.c=NewFFint(n)
	return SK
}

type rsa_public_key struct {
	e int
	n *FF
}

func New_public_key(m int) *rsa_public_key{
	PK:=new(rsa_public_key)
	PK.e=0
	PK.n=NewFFint(m)
	return PK
}

func hashit(sha int,A []byte,n int) []byte {
	var R []byte
	if sha==amcl.SHA256 {
		H:=amcl.NewHASH256()
		if A!=nil {H.Process_array(A)}
		if n>=0 {H.Process_num(int32(n))}
		R=H.Hash()
	}
	if sha==amcl.SHA384 {
		H:=amcl.NewHASH384()
		if A!=nil {H.Process_array(A)}
		if n>=0 {H.Process_num(int32(n))}
		R=H.Hash()
	}
	if sha==amcl.SHA512 {
		H:=amcl.NewHASH512()
		if A!=nil {H.Process_array(A)}
		if n>=0 {H.Process_num(int32(n))}
		R=H.Hash()
	}
	return R
}

func RSA_KEY_PAIR(rng *amcl.RAND,e int,PRIV *rsa_private_key,PUB *rsa_public_key) { /* IEEE1363 A16.11/A16.12 more or less */
	n:=PUB.n.getlen()/2
	t:=NewFFint(n)
	p1:=NewFFint(n)
	q1:=NewFFint(n)

	for true {
		PRIV.p.random(rng)
		for PRIV.p.lastbits(2)!=3 {PRIV.p.inc(1)}	
		for !prime(PRIV.p,rng) {
			PRIV.p.inc(4)
		}
			
		p1.copy(PRIV.p)
		p1.dec(1)

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

	for true {
		PRIV.q.random(rng);
		for PRIV.q.lastbits(2)!=3 {PRIV.q.inc(1)}
		for !prime(PRIV.q,rng) {
			PRIV.q.inc(4)
		}
			
		q1.copy(PRIV.q);
		q1.dec(1);

		if q1.cfactor(e) {continue}

		break;
	}
	
	PUB.n=ff_mul(PRIV.p,PRIV.q);
	PUB.e=e;

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

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

	PRIV.c.copy(PRIV.p)
	PRIV.c.invmodp(PRIV.q)

}

/* Mask Generation Function */

func MGF1(sha int,Z []byte,olen int,K []byte) {
	hlen:=sha

	var k int=0
	for i:=0;i<len(K);i++ {K[i]=0}

	cthreshold:=olen/hlen 
	if olen%hlen!=0 {cthreshold++}
	for counter:=0;counter<cthreshold;counter++ {
		B:=hashit(sha,Z,counter)

		if (k+hlen>olen) {
			for i:=0;i<olen%hlen;i++ {K[k]=B[i]; k++}
		} else {
			for i:=0;i<hlen;i++ {K[k]=B[i]; k++}
		}
	}	
}

/* SHAXXX identifier strings */
var SHA256ID= [...]byte {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}
var SHA384ID= [...]byte {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30};
var SHA512ID= [...]byte {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40};

func RSA_PKCS15(sha int,m []byte,w []byte) bool {
	olen:=FF_BITS/8
	hlen:=sha
	idlen:=19

	if olen<idlen+hlen+10 {return false}
	H:=hashit(sha,m,-1)

	for i:=0;i<len(w);i++ {w[i]=0}
	i:=0
	w[i]=0; i++
	w[i]=1; i++
	for j:=0;j<olen-idlen-hlen-3;j++ {w[i]=0xff; i++}
	w[i]=0; i++

	if hlen==amcl.SHA256 {
		for j:=0;j<idlen;j++ {w[i]=SHA256ID[j]; i++}
	}
	if hlen==amcl.SHA384 {
		for j:=0;j<idlen;j++ {w[i]=SHA384ID[j]; i++}
	}
	if hlen==amcl.SHA512 {
		for j:=0;j<idlen;j++ {w[i]=SHA512ID[j]; i++}
	}
	for j:=0;j<hlen;j++ {w[i]=H[j]; i++}

	return true
}


/* OAEP Message Encoding for Encryption */
func RSA_OAEP_ENCODE(sha int,m []byte,rng *amcl.RAND,p []byte) []byte { 
	olen:=RFS-1
	mlen:=len(m)
	var f [RFS]byte

	hlen:=sha

	SEED:=make([]byte,hlen);

	seedlen:=hlen
	if (mlen>olen-hlen-seedlen-1) {return nil} 

	DBMASK:=make([]byte,olen-seedlen)

	h:=hashit(sha,p,-1);

	for i:=0;i<hlen;i++ {f[i]=h[i]}

	slen:=olen-mlen-hlen-seedlen-1      

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

	for i:=0;i<seedlen;i++ {SEED[i]=rng.GetByte()}
	MGF1(sha,SEED,olen-seedlen,DBMASK)

	for i:=0;i<olen-seedlen;i++ {DBMASK[i]^=f[i]}

	MGF1(sha,DBMASK,seedlen,f[:])

	for i:=0;i<seedlen;i++ {f[i]^=SEED[i]}

	for i:=0;i<olen-seedlen;i++ {f[i+seedlen]=DBMASK[i]}

	/* pad to length RFS */
	d:=1
	for i:=RFS-1;i>=d;i-- {
		f[i]=f[i-d]
	}
	for i:=d-1;i>=0;i-- {
		f[i]=0
	}
	return f[:]
}

/* OAEP Message Decoding for Decryption */
func RSA_OAEP_DECODE(sha int,p []byte,f []byte) [] byte {
	olen:=RFS-1

	hlen:=sha
	SEED:=make([]byte,hlen)
	seedlen:=hlen;
	CHASH:=make([]byte,hlen)
	
	if olen<seedlen+hlen+1 {return nil}
	DBMASK:=make([]byte,olen-seedlen)
	for i:=0;i<olen-seedlen;i++ {DBMASK[i]=0}

	if len(f)<RFS {
		d:=RFS-len(f)
		for i:=RFS-1;i>=d;i-- {
			f[i]=f[i-d]
		}
		for i:=d-1;i>=0;i-- {
			f[i]=0
		}
	}

	h:=hashit(sha,p,-1)
	for i:=0;i<hlen;i++ {CHASH[i]=h[i]}

	x:=f[0]

	for i:=seedlen;i<olen;i++ {
		DBMASK[i-seedlen]=f[i+1]
	}

	MGF1(sha,DBMASK,seedlen,SEED)
	for i:=0;i<seedlen;i++ {SEED[i]^=f[i+1]}
	MGF1(sha,SEED,olen-seedlen,f)
	for i:=0;i<olen-seedlen;i++ {DBMASK[i]^=f[i]}

	comp:=true
	for i:=0;i<hlen;i++ {
		if CHASH[i]!=DBMASK[i] {comp=false}
	}

	for i:=0;i<olen-seedlen-hlen;i++ {
		DBMASK[i]=DBMASK[i+hlen]
	}

	for i:=0;i<hlen;i++ {
		SEED[i]=0; CHASH[i]=0
	}
		
	var k int
	for k=0;;k++ {
		if k>=olen-seedlen-hlen {return nil}
		if DBMASK[k]!=0 {break}
	}

	t:=DBMASK[k]
	if (!comp || x!=0 || t!=0x01) {
		for i:=0;i<olen-seedlen;i++ {DBMASK[i]=0}
		return nil
	}

	var r = make([]byte,olen-seedlen-hlen-k-1)

	for i:=0;i<olen-seedlen-hlen-k-1;i++ {
		r[i]=DBMASK[i+k+1]
	}
	
	for i:=0;i<olen-seedlen;i++  {DBMASK[i]=0}

	return r
}

/* destroy the Private Key structure */
func RSA_PRIVATE_KEY_KILL(PRIV *rsa_private_key) {
	PRIV.p.zero();
	PRIV.q.zero();
	PRIV.dp.zero();
	PRIV.dq.zero();
	PRIV.c.zero();
}

/* RSA encryption with the public key */
func RSA_ENCRYPT(PUB *rsa_public_key,F []byte,G []byte) {
	n:=PUB.n.getlen()
	f:=NewFFint(n)

	ff_fromBytes(f,F)
	f.power(PUB.e,PUB.n)
	f.toBytes(G)
}

/* RSA decryption with the private key */
func RSA_DECRYPT(PRIV *rsa_private_key,G []byte,F []byte) {
	n:=PRIV.p.getlen()
	g:=NewFFint(2*n)

	ff_fromBytes(g,G);
	jp:=g.dmod(PRIV.p)
	jq:=g.dmod(PRIV.q)

	jp.skpow(PRIV.dp,PRIV.p)
	jq.skpow(PRIV.dq,PRIV.q)

	g.zero()
	g.dscopy(jp)
	jp.mod(PRIV.q)
	if ff_comp(jp,jq)>0 {jq.add(PRIV.q)}
	jq.sub(jp)
	jq.norm()

	t:=ff_mul(PRIV.c,jq)
	jq=t.dmod(PRIV.q)

	t=ff_mul(jq,PRIV.p)
	g.add(t)
	g.norm()

	g.toBytes(F)
}

