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

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

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